Blocks Module

The blocks module contains the building blocks for creating dashboard components.

Base Block

This module defines the abstract base class for all dashboard blocks.

class dashboard_lego.blocks.base.BaseBlock(block_id: str, datasource: DataSource | AsyncDataSource, **kwargs)[source]

Bases: ABC

An abstract base class that defines the contract for all dashboard blocks.

hierarchy:

[Feature | Global Interactivity | BaseBlock Refactoring]

relates-to:
  • motivated_by: “Architectural Conclusion: Decouple block instantiation from state registration to solve chicken-and-egg problem with DashboardPage”

  • implements: “interface: ‘BaseBlock’”

  • uses: [“interface: ‘DataSource’”, “class: ‘StateManager’”]

rationale:

“Registration logic was moved from __init__ to a separate method to allow DashboardPage to inject the StateManager post-instantiation.”

contract:
  • pre: “A unique block_id and a valid datasource must be provided.”

  • post: “The block is ready for state registration and layout rendering.”

__init__(block_id: str, datasource: DataSource | AsyncDataSource, **kwargs)[source]

Initializes the BaseBlock.

Parameters:
  • block_id – A unique identifier for this block instance.

  • datasource – An instance of DataSource or AsyncDataSource that implements the DataSource interface.

  • allow_duplicate_output – If True, allows this block to share output targets with other blocks (useful for overlay scenarios).

set_initial_external_values(initial_values: Dict[str, Any]) None[source]

Receive initial values for externally subscribed states.

Called by DashboardPage before layout() to provide initial state values.

Hierarchy:

[Feature | Initial State Sync | BaseBlock]

Relates-to:
  • motivated_by: “Blocks need initial external state values before rendering”

  • implements: “method: ‘set_initial_external_values’”

Contract:
  • pre: “initial_values contains {state_id: value} for external states”

  • post: “Block has initial external state values available for layout()”

Parameters:

initial_values – Dict mapping state_id to initial value

output_target() tuple[str, str][source]

Returns the output target for this block’s callback.

Hierarchy:

[Architecture | Output Targets | BaseBlock]

Relates-to:
  • motivated_by: “Architectural Conclusion: Explicit output targets enable proper callback binding and component property updates”

  • implements: “method: ‘output_target’”

  • uses: [“method: ‘_generate_id’”, “method: ‘_get_component_prop’”]

Rationale:

“Default implementation returns container with ‘children’ property.”

Contract:
  • pre: “Block is properly initialized.”

  • post: “Returns tuple of (component_id, property_name) for callback output.”

Returns:

Tuple of (component_id, property_name) for the block’s output target.

list_control_inputs() List[tuple[str, str]][source]

Returns list of control inputs for this block.

Hierarchy:

[Architecture | Block-centric Callbacks | BaseBlock]

Relates-to:
  • motivated_by: “Architectural Conclusion: Block-centric callbacks improve performance and maintainability by reducing callback complexity”

  • implements: “method: ‘list_control_inputs’”

  • uses: [“attribute: ‘publishes’”]

Rationale:

“Default implementation extracts inputs from publishes attribute.”

Contract:
  • pre: “Block is properly initialized.”

  • post: “Returns list of (component_id, property_name) tuples for inputs.”

Returns:

List of (component_id, property_name) tuples for control inputs.

update_from_controls(control_values: Dict[str, Any]) Any[source]

Updates the block based on control values.

CRITICAL: Passes control_values dict directly to callback, NOT as **kwargs. Python doesn’t allow dict objects as keyword argument names.

Hierarchy:

[Architecture | Block-centric Callbacks | BaseBlock]

Relates-to:
  • motivated_by: “Architectural Conclusion: Block-centric callbacks improve performance and maintainability by reducing callback complexity”

  • implements: “method: ‘update_from_controls’”

  • uses: [“attribute: ‘subscribes’”]

Contract:
  • pre: “Block has at least one subscription callback”

  • post: “Returns result of subscription callback”

  • spec_compliance: “Passes control_values as single dict argument”

Complexity:

3

Decision_cache:

“Find callback matching changed states instead of using first one”

Parameters:

control_values – Dictionary of control name -> value mappings (e.g. {‘x_col’: ‘Price’})

Returns:

The result of the subscription callback

abstractmethod layout() Component[source]

Returns the Dash component layout for the block.

get_figure(params: Dict[str, Any] | None = None) Figure | None[source]

Export standalone Plotly figure (chart blocks only).

Returns:

Plotly Figure for chart blocks, None for non-chart blocks.

register_callbacks(app: Any)[source]

This method’s role is now handled by the StateManager.

class dashboard_lego.blocks.base.BaseBlock(block_id: str, datasource: DataSource | AsyncDataSource, **kwargs)[source]

Bases: ABC

An abstract base class that defines the contract for all dashboard blocks.

hierarchy:

[Feature | Global Interactivity | BaseBlock Refactoring]

relates-to:
  • motivated_by: “Architectural Conclusion: Decouple block instantiation from state registration to solve chicken-and-egg problem with DashboardPage”

  • implements: “interface: ‘BaseBlock’”

  • uses: [“interface: ‘DataSource’”, “class: ‘StateManager’”]

rationale:

“Registration logic was moved from __init__ to a separate method to allow DashboardPage to inject the StateManager post-instantiation.”

contract:
  • pre: “A unique block_id and a valid datasource must be provided.”

  • post: “The block is ready for state registration and layout rendering.”

__init__(block_id: str, datasource: DataSource | AsyncDataSource, **kwargs)[source]

Initializes the BaseBlock.

Parameters:
  • block_id – A unique identifier for this block instance.

  • datasource – An instance of DataSource or AsyncDataSource that implements the DataSource interface.

  • allow_duplicate_output – If True, allows this block to share output targets with other blocks (useful for overlay scenarios).

set_initial_external_values(initial_values: Dict[str, Any]) None[source]

Receive initial values for externally subscribed states.

Called by DashboardPage before layout() to provide initial state values.

Hierarchy:

[Feature | Initial State Sync | BaseBlock]

Relates-to:
  • motivated_by: “Blocks need initial external state values before rendering”

  • implements: “method: ‘set_initial_external_values’”

Contract:
  • pre: “initial_values contains {state_id: value} for external states”

  • post: “Block has initial external state values available for layout()”

Parameters:

initial_values – Dict mapping state_id to initial value

output_target() tuple[str, str][source]

Returns the output target for this block’s callback.

Hierarchy:

[Architecture | Output Targets | BaseBlock]

Relates-to:
  • motivated_by: “Architectural Conclusion: Explicit output targets enable proper callback binding and component property updates”

  • implements: “method: ‘output_target’”

  • uses: [“method: ‘_generate_id’”, “method: ‘_get_component_prop’”]

Rationale:

“Default implementation returns container with ‘children’ property.”

Contract:
  • pre: “Block is properly initialized.”

  • post: “Returns tuple of (component_id, property_name) for callback output.”

Returns:

Tuple of (component_id, property_name) for the block’s output target.

list_control_inputs() List[tuple[str, str]][source]

Returns list of control inputs for this block.

Hierarchy:

[Architecture | Block-centric Callbacks | BaseBlock]

Relates-to:
  • motivated_by: “Architectural Conclusion: Block-centric callbacks improve performance and maintainability by reducing callback complexity”

  • implements: “method: ‘list_control_inputs’”

  • uses: [“attribute: ‘publishes’”]

Rationale:

“Default implementation extracts inputs from publishes attribute.”

Contract:
  • pre: “Block is properly initialized.”

  • post: “Returns list of (component_id, property_name) tuples for inputs.”

Returns:

List of (component_id, property_name) tuples for control inputs.

update_from_controls(control_values: Dict[str, Any]) Any[source]

Updates the block based on control values.

CRITICAL: Passes control_values dict directly to callback, NOT as **kwargs. Python doesn’t allow dict objects as keyword argument names.

Hierarchy:

[Architecture | Block-centric Callbacks | BaseBlock]

Relates-to:
  • motivated_by: “Architectural Conclusion: Block-centric callbacks improve performance and maintainability by reducing callback complexity”

  • implements: “method: ‘update_from_controls’”

  • uses: [“attribute: ‘subscribes’”]

Contract:
  • pre: “Block has at least one subscription callback”

  • post: “Returns result of subscription callback”

  • spec_compliance: “Passes control_values as single dict argument”

Complexity:

3

Decision_cache:

“Find callback matching changed states instead of using first one”

Parameters:

control_values – Dictionary of control name -> value mappings (e.g. {‘x_col’: ‘Price’})

Returns:

The result of the subscription callback

abstractmethod layout() Component[source]

Returns the Dash component layout for the block.

get_figure(params: Dict[str, Any] | None = None) Figure | None[source]

Export standalone Plotly figure (chart blocks only).

Returns:

Plotly Figure for chart blocks, None for non-chart blocks.

register_callbacks(app: Any)[source]

This method’s role is now handled by the StateManager.

Block-Level Transformations (v0.15.0+)

All blocks support an optional transform_fn parameter that enables block-specific data transformations without affecting other blocks or the original datasource.

Parameters:

  • transform_fn (Optional[Callable[[pd.DataFrame], pd.DataFrame]]): A function that transforms the DataFrame before visualization. The function receives the DataFrame after global filters have been applied and should return a transformed DataFrame.

Example:

from dashboard_lego.blocks.typed_chart import TypedChartBlock

# Simple aggregation transform
chart = TypedChartBlock(
    block_id="category_sales",
    datasource=datasource,
    plot_type='bar',
    plot_params={'x': 'category', 'y': 'total'},
    transform_fn=lambda df: df.groupby('category')['sales'].sum().reset_index(name='total')
)

Common Use Cases:

  • Aggregation: lambda df: df.groupby('column').agg({'metric': 'sum'})

  • Filtering: lambda df: df[df['value'] > threshold]

  • Pivot: lambda df: df.pivot_table(index='x', columns='y', values='z')

  • Complex transforms: Define a function with multiple steps

Technical Details:

  • Transform executes after global filters (Build → Global Filter → Block Transform)

  • Each block with transform_fn gets an independent specialized datasource clone

  • Original datasource remains unchanged (immutable pattern)

  • Transforms are cached for performance

See Core Concepts for detailed information on block-level transformations.

Chart Blocks

Typed Chart Block (v0.15.0+)

Unified chart block for both static and interactive charts.

TypedChartBlock - High-level chart block with built-in plot types.

NO chart_generator needed - just specify plot_type!

hierarchy:

[Blocks | Charts | TypedChartBlock]

relates-to:
  • motivated_by: “v0.15.0: High-level API requiring minimal user code”

  • implements: “block: ‘TypedChartBlock’ with plot registry”

  • uses: [“module: ‘plot_registry’”, “class: ‘BaseBlock’”]

contract:
  • pre: “plot_type exists in PLOT_REGISTRY”

  • post: “Chart renders using registered plot function”

  • invariant: “plot_kwargs passed through to plot function”

  • guarantee: “Plot function receives pre-filtered DataFrame”

complexity:

6

decision_cache:

“Registry pattern for extensibility without subclassing”

class dashboard_lego.blocks.typed_chart.Control(component: ~typing.Type[~dash.development.base_component.Component], props: ~typing.Dict[str, ~typing.Any] = <factory>, col_props: ~typing.Dict[str, ~typing.Any] | None = <factory>, dep_param_name: str | None = None, auto_size: bool = True, max_ch: int | None = 40)[source]

Bases: object

UI control definition for TypedChartBlock.

Hierarchy:

[Blocks | Controls | Control]

Relates-to:
  • motivated_by: “Need responsive control layouts with content-based sizing”

  • implements: “dataclass: ‘Control’”

Contract:
  • pre: “component is valid Dash component type”

  • post: “Control can be rendered with responsive layout and optional auto-sizing”

component

Dash component class (dcc.Dropdown, dcc.Slider, etc.)

Type:

Type[dash.development.base_component.Component]

props

Props dictionary for the component

Type:

Dict[str, Any]

col_props

Bootstrap column sizing (default: {“xs”: 12, “md”: “auto”}). Can be explicitly set for custom layout (e.g., {“xs”: 12, “md”: 12} for full width). Explicit values take precedence over auto-sizing defaults.

Type:

Dict[str, Any] | None

dep_param_name

Optional parameter name override for datasource (default: None)

Type:

str | None

auto_size

Enable content-based sizing instead of full width (default: True). When True, uses md=”auto” if not explicitly set in col_props. Explicit col_props values are always respected regardless of auto_size.

Type:

bool

max_ch

Maximum width in characters for auto-sized controls (default: 40)

Type:

int | None

component: Type[Component]
props: Dict[str, Any]
col_props: Dict[str, Any] | None
dep_param_name: str | None = None
auto_size: bool = True
max_ch: int | None = 40
__init__(component: ~typing.Type[~dash.development.base_component.Component], props: ~typing.Dict[str, ~typing.Any] = <factory>, col_props: ~typing.Dict[str, ~typing.Any] | None = <factory>, dep_param_name: str | None = None, auto_size: bool = True, max_ch: int | None = 40) None
class dashboard_lego.blocks.typed_chart.TypedChartBlock(block_id: str, datasource: DataSource, plot_type: str, plot_params: Dict[str, Any], plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, loading_type: str = 'default', graph_config: Dict[str, Any] | None = None, graph_style: Dict[str, Any] | None = None, **kwargs)[source]

Bases: BaseBlock

High-level chart block using plot type registry.

NO chart_generator needed - specify plot_type and plot_params!

Hierarchy:

[Blocks | Charts | TypedChartBlock]

Relates-to:
  • motivated_by: “Eliminate chart_generator requirement for common plots”

  • implements: “block: ‘TypedChartBlock’”

  • uses: [“module: ‘plot_registry’”, “class: ‘BaseBlock’”]

Rationale:

“Registry pattern allows zero-code chart creation for 90% of cases”

Contract:
  • pre: “plot_type exists in PLOT_REGISTRY”

  • post: “Chart renders via registered function with kwargs passed through”

  • invariant: “Block never stores data, always calls get_processed_data()”

  • kwargs_flow: “plot_kwargs → plot_function(**plot_kwargs)”

Complexity:

6

Decision_cache:

“Single block type for all chart types via registry”

Example

>>> chart = TypedChartBlock(
...     block_id="sales_hist",
...     datasource=datasource,
...     plot_type='histogram',
...     plot_params={'x': 'price'},
...     plot_kwargs={'bins': 30, 'title': 'Price Distribution'},
...     subscribes_to='control-category'
... )
__init__(block_id: str, datasource: DataSource, plot_type: str, plot_params: Dict[str, Any], plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, loading_type: str = 'default', graph_config: Dict[str, Any] | None = None, graph_style: Dict[str, Any] | None = None, **kwargs)[source]

Initialize TypedChartBlock.

Hierarchy:

[Blocks | Charts | TypedChartBlock | Initialization]

Relates-to:
  • motivated_by: “High-level API requiring minimal code”

  • motivated_by: “v0.15.0: Block-specific data transformations”

  • implements: “method: ‘__init__’”

Contract:
  • pre: “plot_type valid, plot_params contains required keys”

  • post: “Block ready to render”

  • kwargs_flow: “plot_kwargs stored and passed to plot function”

  • transform_flow: “transform_fn → specialized datasource via BaseBlock”

Complexity:

5

Parameters:
  • block_id – Unique identifier for this block

  • datasource – DataSource instance

  • plot_type – Type from PLOT_REGISTRY Examples: ‘histogram’, ‘scatter’, ‘overlay_histogram’

  • plot_params – Plot-specific parameters (column names, bins, etc.) Example: {‘x’: ‘age’, ‘y’: ‘salary’, ‘color’: ‘dept’}

  • plot_kwargs – Additional kwargs PASSED TO plot function Example: {‘title’: ‘My Chart’, ‘opacity’: 0.7} KEY POINT: These go directly to plotly!

  • title – Block title (shown in card header)

  • controls – Optional embedded controls

  • subscribes_to – External state IDs to subscribe to

  • transform_fn – Optional block-specific data transformation Applied AFTER global filters Signature: lambda df: df (returns transformed DataFrame) Examples: - lambda df: df.groupby(‘category’)[‘sales’].sum().reset_index() - lambda df: df.pivot_table(index=’region’, columns=’product’, values=’revenue’) - lambda df: df[df[‘price’] > 100]

  • card_style – Card styling

  • card_className – Card styling

  • loading_type – Loading animation type

  • graph_config – Plotly graph configuration

output_target() tuple[str, str][source]

Returns output target for chart blocks.

Hierarchy:

[Blocks | Charts | TypedChartBlock | OutputTarget]

Contract:
  • pre: “Block initialized”

  • post: “Returns (component_id, ‘figure’)”

update_from_controls(control_values: Dict[str, Any]) Figure[source]

Update chart from block-centric callback.

CRITICAL: TypedChartBlock with embedded controls has subscribes={} (empty), so BaseBlock.update_from_controls() returns None. We MUST override this to call _update_chart directly with control_values dict.

Hierarchy:

[Blocks | TypedChartBlock | Update]

Relates-to:
  • motivated_by: “BaseBlock.update_from_controls returns None if subscribes empty”

  • implements: “method: ‘update_from_controls’ override”

Contract:
  • pre: “control_values is {ctrl_name: value} dict from StateManager”

  • post: “Returns updated Plotly Figure”

  • spec_compliance: “Calls _update_chart with control_values as first arg”

Complexity:

2

Parameters:

control_values – Dict mapping control names to values (e.g. {‘x_col’: ‘Price’})

Returns:

Updated Plotly Figure

get_figure(params: Dict[str, Any] | None = None) Figure[source]

Export standalone Plotly figure without Dash server.

This is the official API for getting a Plotly figure object that can be saved, displayed, or further customized without running a dashboard.

Parameters:

params – Optional parameters for datasource filtering. For blocks with controls, provide control values as dict. Example: {‘x_col’: ‘Price’, ‘y_col’: ‘Sales’}

Returns:

  • figure.write_html(‘chart.html’)

  • figure.write_image(‘chart.png’) # requires kaleido

  • figure.to_json()

  • figure.show()

Return type:

Plotly Figure object ready for export via

Example

>>> chart = TypedChartBlock(
...     block_id="sales",
...     datasource=datasource,
...     plot_type="bar",
...     plot_params={"x": "Product", "y": "Sales"}
... )
>>> fig = chart.get_figure()
>>> fig.write_html("sales_chart.html")
list_control_inputs() list[tuple[str, str]][source]

Returns list of control inputs for block-centric callbacks.

CRITICAL: Must return the SAME IDs used in publishes registration. Uses string IDs (f”{block_id}-{ctrl}”), not pattern-matching dicts.

Hierarchy:

[Blocks | Charts | TypedChartBlock | ControlInputs]

Contract:
  • pre: “Block initialized with controls”

  • post: “Returns list of (component_id, ‘value’) tuples matching publishes”

Returns:

List of control input specifications for Dash callbacks

layout() Component[source]

Render block layout with card, title, controls, and chart.

Hierarchy:

[Blocks | Charts | TypedChartBlock | Layout]

Relates-to:
  • motivated_by: “Standard card-based layout for all chart types”

  • implements: “method: ‘layout’”

Contract:
  • pre: “Block initialized, theme may be available”

  • post: “Returns Dash Component tree”

Complexity:

3

Returns:

Dash Component (Card with chart)

class dashboard_lego.blocks.typed_chart.TypedChartBlock(block_id: str, datasource: DataSource, plot_type: str, plot_params: Dict[str, Any], plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, loading_type: str = 'default', graph_config: Dict[str, Any] | None = None, graph_style: Dict[str, Any] | None = None, **kwargs)[source]

Bases: BaseBlock

High-level chart block using plot type registry.

NO chart_generator needed - specify plot_type and plot_params!

Hierarchy:

[Blocks | Charts | TypedChartBlock]

Relates-to:
  • motivated_by: “Eliminate chart_generator requirement for common plots”

  • implements: “block: ‘TypedChartBlock’”

  • uses: [“module: ‘plot_registry’”, “class: ‘BaseBlock’”]

Rationale:

“Registry pattern allows zero-code chart creation for 90% of cases”

Contract:
  • pre: “plot_type exists in PLOT_REGISTRY”

  • post: “Chart renders via registered function with kwargs passed through”

  • invariant: “Block never stores data, always calls get_processed_data()”

  • kwargs_flow: “plot_kwargs → plot_function(**plot_kwargs)”

Complexity:

6

Decision_cache:

“Single block type for all chart types via registry”

Example

>>> chart = TypedChartBlock(
...     block_id="sales_hist",
...     datasource=datasource,
...     plot_type='histogram',
...     plot_params={'x': 'price'},
...     plot_kwargs={'bins': 30, 'title': 'Price Distribution'},
...     subscribes_to='control-category'
... )
__init__(block_id: str, datasource: DataSource, plot_type: str, plot_params: Dict[str, Any], plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, loading_type: str = 'default', graph_config: Dict[str, Any] | None = None, graph_style: Dict[str, Any] | None = None, **kwargs)[source]

Initialize TypedChartBlock.

Hierarchy:

[Blocks | Charts | TypedChartBlock | Initialization]

Relates-to:
  • motivated_by: “High-level API requiring minimal code”

  • motivated_by: “v0.15.0: Block-specific data transformations”

  • implements: “method: ‘__init__’”

Contract:
  • pre: “plot_type valid, plot_params contains required keys”

  • post: “Block ready to render”

  • kwargs_flow: “plot_kwargs stored and passed to plot function”

  • transform_flow: “transform_fn → specialized datasource via BaseBlock”

Complexity:

5

Parameters:
  • block_id – Unique identifier for this block

  • datasource – DataSource instance

  • plot_type – Type from PLOT_REGISTRY Examples: ‘histogram’, ‘scatter’, ‘overlay_histogram’

  • plot_params – Plot-specific parameters (column names, bins, etc.) Example: {‘x’: ‘age’, ‘y’: ‘salary’, ‘color’: ‘dept’}

  • plot_kwargs – Additional kwargs PASSED TO plot function Example: {‘title’: ‘My Chart’, ‘opacity’: 0.7} KEY POINT: These go directly to plotly!

  • title – Block title (shown in card header)

  • controls – Optional embedded controls

  • subscribes_to – External state IDs to subscribe to

  • transform_fn – Optional block-specific data transformation Applied AFTER global filters Signature: lambda df: df (returns transformed DataFrame) Examples: - lambda df: df.groupby(‘category’)[‘sales’].sum().reset_index() - lambda df: df.pivot_table(index=’region’, columns=’product’, values=’revenue’) - lambda df: df[df[‘price’] > 100]

  • card_style – Card styling

  • card_className – Card styling

  • loading_type – Loading animation type

  • graph_config – Plotly graph configuration

output_target() tuple[str, str][source]

Returns output target for chart blocks.

Hierarchy:

[Blocks | Charts | TypedChartBlock | OutputTarget]

Contract:
  • pre: “Block initialized”

  • post: “Returns (component_id, ‘figure’)”

update_from_controls(control_values: Dict[str, Any]) Figure[source]

Update chart from block-centric callback.

CRITICAL: TypedChartBlock with embedded controls has subscribes={} (empty), so BaseBlock.update_from_controls() returns None. We MUST override this to call _update_chart directly with control_values dict.

Hierarchy:

[Blocks | TypedChartBlock | Update]

Relates-to:
  • motivated_by: “BaseBlock.update_from_controls returns None if subscribes empty”

  • implements: “method: ‘update_from_controls’ override”

Contract:
  • pre: “control_values is {ctrl_name: value} dict from StateManager”

  • post: “Returns updated Plotly Figure”

  • spec_compliance: “Calls _update_chart with control_values as first arg”

Complexity:

2

Parameters:

control_values – Dict mapping control names to values (e.g. {‘x_col’: ‘Price’})

Returns:

Updated Plotly Figure

get_figure(params: Dict[str, Any] | None = None) Figure[source]

Export standalone Plotly figure without Dash server.

This is the official API for getting a Plotly figure object that can be saved, displayed, or further customized without running a dashboard.

Parameters:

params – Optional parameters for datasource filtering. For blocks with controls, provide control values as dict. Example: {‘x_col’: ‘Price’, ‘y_col’: ‘Sales’}

Returns:

  • figure.write_html(‘chart.html’)

  • figure.write_image(‘chart.png’) # requires kaleido

  • figure.to_json()

  • figure.show()

Return type:

Plotly Figure object ready for export via

Example

>>> chart = TypedChartBlock(
...     block_id="sales",
...     datasource=datasource,
...     plot_type="bar",
...     plot_params={"x": "Product", "y": "Sales"}
... )
>>> fig = chart.get_figure()
>>> fig.write_html("sales_chart.html")
list_control_inputs() list[tuple[str, str]][source]

Returns list of control inputs for block-centric callbacks.

CRITICAL: Must return the SAME IDs used in publishes registration. Uses string IDs (f”{block_id}-{ctrl}”), not pattern-matching dicts.

Hierarchy:

[Blocks | Charts | TypedChartBlock | ControlInputs]

Contract:
  • pre: “Block initialized with controls”

  • post: “Returns list of (component_id, ‘value’) tuples matching publishes”

Returns:

List of control input specifications for Dash callbacks

layout() Component[source]

Render block layout with card, title, controls, and chart.

Hierarchy:

[Blocks | Charts | TypedChartBlock | Layout]

Relates-to:
  • motivated_by: “Standard card-based layout for all chart types”

  • implements: “method: ‘layout’”

Contract:
  • pre: “Block initialized, theme may be available”

  • post: “Returns Dash Component tree”

Complexity:

3

Returns:

Dash Component (Card with chart)

TypedChartBlock.get_figure(params: Dict[str, Any] | None = None) Figure[source]

Export standalone Plotly figure without Dash server.

This is the official API for getting a Plotly figure object that can be saved, displayed, or further customized without running a dashboard.

Parameters:

params – Optional parameters for datasource filtering. For blocks with controls, provide control values as dict. Example: {‘x_col’: ‘Price’, ‘y_col’: ‘Sales’}

Returns:

  • figure.write_html(‘chart.html’)

  • figure.write_image(‘chart.png’) # requires kaleido

  • figure.to_json()

  • figure.show()

Return type:

Plotly Figure object ready for export via

Example

>>> chart = TypedChartBlock(
...     block_id="sales",
...     datasource=datasource,
...     plot_type="bar",
...     plot_params={"x": "Product", "y": "Sales"}
... )
>>> fig = chart.get_figure()
>>> fig.write_html("sales_chart.html")

Minimal Chart Block (v0.15.2+)

Minimalist chart block for clean visualizations.

MinimalChartBlock - Minimalist-styled chart block.

Wraps TypedChartBlock with automatic minimal styling preset.

hierarchy:

[Blocks | Charts | MinimalChartBlock]

relates-to:
  • motivated_by: “Need minimalist charts with stripped-down visuals”

  • implements: “block: ‘MinimalChartBlock’ wrapping TypedChartBlock”

  • uses: [“class: ‘TypedChartBlock’”, “plotly figure styling”]

contract:
  • pre: “plot_type valid (defaults to scatter), x and y required”

  • post: “Returns chart with minimal styling (hidden grids/labels/legend)”

  • invariant: “plot_kwargs can override any minimal preset setting”

complexity:

4

class dashboard_lego.blocks.minimal_chart.MinimalChartBlock(block_id: str, datasource: DataSource, plot_type: str = 'scatter', plot_params: Dict[str, Any] = None, plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, **kwargs)[source]

Bases: TypedChartBlock

Minimalist-styled chart block with stripped-down visuals.

Wraps TypedChartBlock and applies minimal styling: - Hidden grids, zeroline, tick labels, axis titles - Transparent background - Compact margins - Legend hidden by default (override via plot_kwargs)

Example

>>> chart = MinimalChartBlock(
...     block_id="sparkline",
...     datasource=datasource,
...     plot_type='line',  # optional, defaults to scatter
...     plot_params={'x': 'date', 'y': 'value'},
...     plot_kwargs={'showlegend': True}  # override minimal preset
... )
__init__(block_id: str, datasource: DataSource, plot_type: str = 'scatter', plot_params: Dict[str, Any] = None, plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, **kwargs)[source]

Initialize MinimalChartBlock.

Parameters:
  • block_id – Unique identifier

  • datasource – DataSource instance

  • plot_type – Plot type (default: ‘scatter’)

  • plot_params – Plot parameters (x, y, color, size, etc.)

  • plot_kwargs – Additional plot kwargs (can override minimal styling)

  • title – Block title

  • plot_title – Dynamic plot title with placeholders

  • controls – Embedded controls

  • subscribes_to – External state IDs

  • transform_fn – Block-specific data transformation

class dashboard_lego.blocks.minimal_chart.MinimalChartBlock(block_id: str, datasource: DataSource, plot_type: str = 'scatter', plot_params: Dict[str, Any] = None, plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, **kwargs)[source]

Bases: TypedChartBlock

Minimalist-styled chart block with stripped-down visuals.

Wraps TypedChartBlock and applies minimal styling: - Hidden grids, zeroline, tick labels, axis titles - Transparent background - Compact margins - Legend hidden by default (override via plot_kwargs)

Example

>>> chart = MinimalChartBlock(
...     block_id="sparkline",
...     datasource=datasource,
...     plot_type='line',  # optional, defaults to scatter
...     plot_params={'x': 'date', 'y': 'value'},
...     plot_kwargs={'showlegend': True}  # override minimal preset
... )
__init__(block_id: str, datasource: DataSource, plot_type: str = 'scatter', plot_params: Dict[str, Any] = None, plot_kwargs: Dict[str, Any] | None = None, title: str | None = None, plot_title: str | None = None, controls: Dict[str, Control] | None = None, subscribes_to: str | List[str] | Dict[str, Any] | None = None, transform_fn: Callable[[DataFrame], DataFrame] | None = None, **kwargs)[source]

Initialize MinimalChartBlock.

Parameters:
  • block_id – Unique identifier

  • datasource – DataSource instance

  • plot_type – Plot type (default: ‘scatter’)

  • plot_params – Plot parameters (x, y, color, size, etc.)

  • plot_kwargs – Additional plot kwargs (can override minimal styling)

  • title – Block title

  • plot_title – Dynamic plot title with placeholders

  • controls – Embedded controls

  • subscribes_to – External state IDs

  • transform_fn – Block-specific data transformation

Control Class

Control definition for embedded chart controls.

Control building helpers for Dashboard Lego.

Provides shared utilities for creating and normalizing controls across different contexts (magics, quick dashboard, etc.).

hierarchy:

[Blocks | ControlHelpers]

relates-to:
  • motivated_by: “Need consistent control building across magics and quick factory:

    options normalization, col_props defaults, component mapping”

  • implements: “Shared control building utilities”

  • uses: [“Control dataclass”, “dash components”]

contract:
  • pre: “control_specs is list of control specification dicts”

  • post: “returns dict of {control_name: Control} with normalized options”

  • invariant: “deterministic normalization, consistent defaults”

complexity:

3

decision_cache:

“Extracted from magics to avoid duplication between ipython_magics and quick_dashboard control building”

dashboard_lego.blocks.control_helpers.build_controls_from_spec(controls_spec: List[Dict[str, Any]] | None) Dict[str, Control][source]

Build Control objects from specification with normalization.

Supports: dropdown, slider, input Normalizes: options (list[str] → list[dict]), col_props defaults

Parameters:

controls_spec – List of control specifications

Returns:

Control} dict

Return type:

{control_name

Raises:

ValueError – If required fields missing or unknown control type

Example

>>> spec = [
...     {"name": "metric", "type": "dropdown", "options": ["A", "B"]},
...     {"name": "year", "type": "slider", "min": 2020, "max": 2024}
... ]
>>> controls = build_controls_from_spec(spec)
>>> controls["metric"].props["options"]
[{"label": "A", "value": "A"}, {"label": "B", "value": "B"}]

This module defines ControlPanelBlock for standalone control panels.

StaticChartBlock and InteractiveChartBlock removed in v0.15.0. Use TypedChartBlock instead.

hierarchy:

[Blocks | Controls | ControlPanelBlock]

relates-to:
  • motivated_by: “v0.15.0: Simplified architecture with TypedChartBlock”

  • implements: “block: ‘ControlPanelBlock’”

contract:
  • pre: “controls dict provided”

  • post: “Block publishes control values to state”

complexity:

4

class dashboard_lego.blocks.control_panel.Control(component: ~typing.Type[~dash.development.base_component.Component], props: ~typing.Dict[str, ~typing.Any] = <factory>, col_props: ~typing.Dict[str, ~typing.Any] | None = <factory>, dep_param_name: str | None = None, auto_size: bool = True, max_ch: int | None = 40)[source]

UI control definition for ControlPanelBlock or TypedChartBlock.

Hierarchy:

[Blocks | Controls | Control]

Relates-to:
  • motivated_by: “Need responsive control layouts with content-based sizing”

  • implements: “dataclass: ‘Control’ with col_props and auto-size support”

  • uses: [“component: ‘Dash Component’”]

Rationale:

“col_props enables responsive Bootstrap column sizing for controls, auto_size enables content-based width.”

Contract:
  • pre: “component is valid Dash component type”

  • post: “Control can be rendered with responsive layout and optional auto-sizing”

component

Dash component class (dcc.Dropdown, dcc.Slider, etc.)

Type:

Type[dash.development.base_component.Component]

props

Props dictionary for the component

Type:

Dict[str, Any]

col_props

Bootstrap column sizing (default: {“xs”: 12, “md”: “auto”}). Can be explicitly set for custom layout (e.g., {“xs”: 12, “md”: 12} for full width). Explicit values take precedence over auto-sizing defaults.

Type:

Dict[str, Any] | None

dep_param_name

Optional parameter name override for datasource (default: None)

Type:

str | None

auto_size

Enable content-based sizing instead of full width (default: True). When True, uses md=”auto” if not explicitly set in col_props. Explicit col_props values are always respected regardless of auto_size.

Type:

bool

max_ch

Maximum width in characters for auto-sized controls (default: 40)

Type:

int | None

component: Type[Component]
props: Dict[str, Any]
col_props: Dict[str, Any] | None
dep_param_name: str | None = None
auto_size: bool = True
max_ch: int | None = 40
__init__(component: ~typing.Type[~dash.development.base_component.Component], props: ~typing.Dict[str, ~typing.Any] = <factory>, col_props: ~typing.Dict[str, ~typing.Any] | None = <factory>, dep_param_name: str | None = None, auto_size: bool = True, max_ch: int | None = 40) None
class dashboard_lego.blocks.control_panel.ControlPanelBlock(block_id: str, datasource: DataSource, title: str, controls: Dict[str, Control] | List[Dict[str, Any]], subscribes_to: str | List[str] | None = None, value_initializer: Callable | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, controls_row_style: Dict[str, Any] | None = None, controls_row_className: str | None = None, container_style: Dict[str, Any] | None = None, container_className: str | None = None)[source]

Standalone control panel block (no chart visualization).

This block publishes control values to state that other blocks can subscribe to.

Hierarchy:

[Blocks | Controls | ControlPanelBlock]

Relates-to:
  • motivated_by: “Need standalone control panels for dashboard settings”

  • implements: “block: ‘ControlPanelBlock’”

  • uses: [“interface: ‘BaseBlock’”, “dataclass: ‘Control’”]

Rationale:

“Separated control functionality from chart blocks for SRP”

Contract:
  • pre: “controls dict provided”

  • post: “Block renders controls that publish values to state”

Complexity:

4

__init__(block_id: str, datasource: DataSource, title: str, controls: Dict[str, Control] | List[Dict[str, Any]], subscribes_to: str | List[str] | None = None, value_initializer: Callable | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, controls_row_style: Dict[str, Any] | None = None, controls_row_className: str | None = None, container_style: Dict[str, Any] | None = None, container_className: str | None = None)[source]

Initialize ControlPanelBlock.

Hierarchy:

[Blocks | Controls | ControlPanelBlock | Init]

Contract:
  • pre: “controls dict or list of specs provided”

  • post: “Block ready to render and publish values”

Parameters:
  • block_id – Unique identifier

  • datasource – DataSource instance

  • title – Panel title

  • controls – Dict of control_name → Control, or list of control specs (will be converted)

  • value_initializer – Optional function (df) → {control_name: value}

list_control_inputs() list[tuple[str, str]][source]

Returns empty list - ControlPanelBlock only publishes, no callbacks needed.

Hierarchy:

[Blocks | Controls | ControlPanelBlock | NoCallbacks]

Contract:
  • pre: “Block initialized”

  • post: “Returns empty list”

Returns:

Empty list (no block-centric callbacks)

layout() Component[source]

Render control panel layout with theme-aware styling.

Hierarchy:

[Blocks | Controls | ControlPanelBlock | Layout]

Contract:
  • pre: “Block initialized, theme may be available”

  • post: “Returns themed Card with controls”

Returns:

Dash Card component

Metrics Factory (v0.15+)

Factory function to create metric blocks for KPIs.

Metrics Factory - Factory function for creating dashboard block rows.

This module provides the get_metric_row() factory function that creates individual SingleMetricBlock (numeric) or TextBlock (text) instances and returns them with row options for proper DashboardPage integration.

hierarchy:

[Blocks | Metrics | Factory]

relates-to:
  • motivated_by: “PRD: Unified factory for dashboard lamps (numeric metrics and text blocks)”

  • implements: “function: ‘get_metric_row’”

  • uses: [“class: ‘SingleMetricBlock’”, “class: ‘TextBlock’”]

contract:
  • pre: “metrics_spec dict with valid block definitions (numeric or text)”

  • post: “Returns (List[BaseBlock], row_options_dict)”

  • invariant: “Each block is independent, all have h-100 for equal height”

  • layout_compliance: “Compatible with DashboardPage row format”

complexity:

4

decision_cache:

“unified_factory: Content-based type detection for numeric vs text blocks”

dashboard_lego.blocks.metrics_factory.get_metric_row(metrics_spec: Dict[str, Dict[str, Any]], datasource: DataSource | AsyncDataSource, subscribes_to: str | List[str] | None = None, row_options: Dict[str, Any] | None = None, block_id_prefix: str = 'metric') Tuple[List[BaseBlock], Dict[str, Any]][source]

Factory function to create a row of dashboard blocks (numeric metrics or text).

Hierarchy:

[Blocks | Metrics | Factory | GetMetricRow]

Relates-to:
  • motivated_by: “PRD: Unified factory for dashboard lamps supporting both numeric and text content”

  • implements: “function: ‘get_metric_row’ with content-based type detection”

  • uses: [“class: ‘SingleMetricBlock’”, “class: ‘TextBlock’”]

Contract:
  • pre: “metrics_spec contains valid block definitions (numeric or text)”

  • post: “Returns (list_of_blocks, row_options_dict)”

  • invariant: “Each block is independent, all have h-100 for equal height”

  • layout_compliance: “Compatible with DashboardPage”

Complexity:

4

Decision_cache:

“unified_factory: Content-based detection (column+agg = numeric, content_generator = text)”

This function creates a row of equal-height containers (“dashboard lamps”) that can display either numeric metrics (SingleMetricBlock) or text content (TextBlock). Block type is automatically detected from spec keys.

Parameters:
  • metrics_spec

    Dictionary of block definitions, where each key is a block_id and value is a dict. For numeric metrics: - column (str): Column name to aggregate - agg (str|Callable): Aggregation function - title (str): Display title - color (str|dict): Bootstrap theme color (optional, supports conditional) - label (str|dict): Display label (optional, supports conditional) - dtype (str): Type conversion (optional) For text blocks: - content_generator (callable|str): Function that takes DataFrame and returns content - title (str): Display title (optional) - color (str|dict): Bootstrap theme color (optional, supports keyword-based conditional coloring)

    If dict: {‘keyword1’: ‘color1’, ‘keyword2’: ‘color2’, …} - searches for keywords in content

  • datasource – DataSource or AsyncDataSource instance for block data

  • subscribes_to – Optional state IDs to subscribe all blocks to

  • row_options – Optional Bootstrap row styling options

  • block_id_prefix – Prefix for generating block IDs (default: “metric”)

Returns:

Tuple of (list of BaseBlock instances, row options dict) Ready for use with DashboardPage:

page = DashboardPage(…, blocks=[(blocks, opts), …])

Example

blocks, row_opts = get_metric_row(
metrics_spec={
‘revenue’: {

‘column’: ‘Revenue’, ‘agg’: ‘sum’, ‘title’: ‘Total Revenue’, ‘color’: ‘success’

}, ‘status’: {

‘content_generator’: lambda df: f”Status: {df[‘status’].iloc[0]}”, ‘title’: ‘System Status’, ‘color’: ‘info’

}

}, datasource=datasource, subscribes_to=[‘filters-category’]

)

page = DashboardPage(…, blocks=[

(blocks, row_opts), # Mixed blocks row [chart1, chart2] # Charts row

])

dashboard_lego.blocks.metrics_factory.get_metric_row(metrics_spec: Dict[str, Dict[str, Any]], datasource: DataSource | AsyncDataSource, subscribes_to: str | List[str] | None = None, row_options: Dict[str, Any] | None = None, block_id_prefix: str = 'metric') Tuple[List[BaseBlock], Dict[str, Any]][source]

Factory function to create a row of dashboard blocks (numeric metrics or text).

Hierarchy:

[Blocks | Metrics | Factory | GetMetricRow]

Relates-to:
  • motivated_by: “PRD: Unified factory for dashboard lamps supporting both numeric and text content”

  • implements: “function: ‘get_metric_row’ with content-based type detection”

  • uses: [“class: ‘SingleMetricBlock’”, “class: ‘TextBlock’”]

Contract:
  • pre: “metrics_spec contains valid block definitions (numeric or text)”

  • post: “Returns (list_of_blocks, row_options_dict)”

  • invariant: “Each block is independent, all have h-100 for equal height”

  • layout_compliance: “Compatible with DashboardPage”

Complexity:

4

Decision_cache:

“unified_factory: Content-based detection (column+agg = numeric, content_generator = text)”

This function creates a row of equal-height containers (“dashboard lamps”) that can display either numeric metrics (SingleMetricBlock) or text content (TextBlock). Block type is automatically detected from spec keys.

Parameters:
  • metrics_spec

    Dictionary of block definitions, where each key is a block_id and value is a dict. For numeric metrics: - column (str): Column name to aggregate - agg (str|Callable): Aggregation function - title (str): Display title - color (str|dict): Bootstrap theme color (optional, supports conditional) - label (str|dict): Display label (optional, supports conditional) - dtype (str): Type conversion (optional) For text blocks: - content_generator (callable|str): Function that takes DataFrame and returns content - title (str): Display title (optional) - color (str|dict): Bootstrap theme color (optional, supports keyword-based conditional coloring)

    If dict: {‘keyword1’: ‘color1’, ‘keyword2’: ‘color2’, …} - searches for keywords in content

  • datasource – DataSource or AsyncDataSource instance for block data

  • subscribes_to – Optional state IDs to subscribe all blocks to

  • row_options – Optional Bootstrap row styling options

  • block_id_prefix – Prefix for generating block IDs (default: “metric”)

Returns:

Tuple of (list of BaseBlock instances, row options dict) Ready for use with DashboardPage:

page = DashboardPage(…, blocks=[(blocks, opts), …])

Example

blocks, row_opts = get_metric_row(
metrics_spec={
‘revenue’: {

‘column’: ‘Revenue’, ‘agg’: ‘sum’, ‘title’: ‘Total Revenue’, ‘color’: ‘success’

}, ‘status’: {

‘content_generator’: lambda df: f”Status: {df[‘status’].iloc[0]}”, ‘title’: ‘System Status’, ‘color’: ‘info’

}

}, datasource=datasource, subscribes_to=[‘filters-category’]

)

page = DashboardPage(…, blocks=[

(blocks, row_opts), # Mixed blocks row [chart1, chart2] # Charts row

])

Single Metric Block (v0.15+)

Individual metric display block.

SingleMetricBlock - Atomic block for displaying a single metric value.

This module implements the factory pattern component for metrics display. Each instance calculates and renders ONE metric value in a compact card.

hierarchy:

[Blocks | Metrics | SingleMetricBlock]

relates-to:
  • motivated_by: “SPEC: Metrics factory for layout integration”

  • implements: “class: ‘SingleMetricBlock’”

  • uses: [“class: ‘BaseBlock’”, “class: ‘ThemeConfig’”]

contract:
  • pre: “One metric_spec dict, datasource, optional subscribes_to”

  • post: “layout() returns dbc.Card with metric value”

  • invariant: “Card is compact (height determined by content only)”

  • theme_compliance: “color Bootstrap theme, via ThemeConfig”

complexity:

4

decision_cache:

“atomic_metrics: Independent blocks for flexibility”

class dashboard_lego.blocks.single_metric.SingleMetricBlock(block_id: str, datasource: DataSource, metric_spec: Dict[str, Any], subscribes_to: str | List[str] | None = None, **kwargs)[source]

Bases: BaseBlock

Display a single aggregated metric value in a compact card.

Hierarchy:

[Blocks | Metrics | SingleMetricBlock]

Relates-to:
  • motivated_by: “Factory pattern: atomic metric blocks”

  • implements: “class: ‘SingleMetricBlock’”

Contract:
  • pre: “metric_spec contains column, agg, title, optional color”

  • post: “Renders compact card with metric value”

  • invariant: “Card height adapts to content (no fixed height)”

  • theme_compliance: “Uses ThemeConfig for colors”

Complexity:

4

Example

metric = SingleMetricBlock(

block_id=”revenue_metric”, datasource=datasource, metric_spec={

‘column’: ‘Revenue’, ‘agg’: ‘sum’, ‘title’: ‘Total Revenue’, ‘color’: ‘success’, # Bootstrap theme color ‘dtype’: ‘float64’

}, subscribes_to=[‘control-category’]

)

__init__(block_id: str, datasource: DataSource, metric_spec: Dict[str, Any], subscribes_to: str | List[str] | None = None, **kwargs)[source]

Initialize SingleMetricBlock.

Hierarchy:

[Blocks | Metrics | SingleMetricBlock | Init]

Contract:
  • pre: “metric_spec has required keys: column, agg, title”

  • post: “Block registered with state manager”

Parameters:
  • block_id – Unique block identifier

  • datasource – DataSource instance

  • metric_spec – Metric definition with keys: - column (str): Column name to aggregate - agg (str|Callable): Aggregation func - title (str): Display title - color (str|dict): Bootstrap color (optional, supports conditional) - label (str|dict): Display label (optional, supports conditional) - dtype (str): Type conversion (optional) - color_rules (dict): Conditional coloring (optional, deprecated)

  • subscribes_to – State IDs to subscribe to

layout() Component[source]

Render initial layout with callback-compatible container.

CRITICAL: Must wrap metric card in Div with id=block_id-container to match BaseBlock.output_target() contract for callbacks.

Hierarchy:

[Blocks | Metrics | SingleMetricBlock | Layout]

Relates-to:
  • motivated_by: “BaseBlock lifecycle contract requires container ID”

  • implements: “method: ‘layout’”

  • uses: [“method: ‘_generate_id’”, “method: ‘_update_metric’”]

Contract:
  • pre: “Block initialized with navigation_mode and section_index”

  • post: “Returns Div(id=block_id-container) wrapping metric card”

  • invariant: “Container ID matches output_target() for callbacks”

  • spec_compliance: “Dash callback Output target must exist in DOM”

Complexity:

2

Decision_cache:

“Wrap in container Div to enable state-centric callbacks”

Returns:

html.Div wrapping dbc.Card (not Card directly!)

class dashboard_lego.blocks.single_metric.SingleMetricBlock(block_id: str, datasource: DataSource, metric_spec: Dict[str, Any], subscribes_to: str | List[str] | None = None, **kwargs)[source]

Bases: BaseBlock

Display a single aggregated metric value in a compact card.

Hierarchy:

[Blocks | Metrics | SingleMetricBlock]

Relates-to:
  • motivated_by: “Factory pattern: atomic metric blocks”

  • implements: “class: ‘SingleMetricBlock’”

Contract:
  • pre: “metric_spec contains column, agg, title, optional color”

  • post: “Renders compact card with metric value”

  • invariant: “Card height adapts to content (no fixed height)”

  • theme_compliance: “Uses ThemeConfig for colors”

Complexity:

4

Example

metric = SingleMetricBlock(

block_id=”revenue_metric”, datasource=datasource, metric_spec={

‘column’: ‘Revenue’, ‘agg’: ‘sum’, ‘title’: ‘Total Revenue’, ‘color’: ‘success’, # Bootstrap theme color ‘dtype’: ‘float64’

}, subscribes_to=[‘control-category’]

)

__init__(block_id: str, datasource: DataSource, metric_spec: Dict[str, Any], subscribes_to: str | List[str] | None = None, **kwargs)[source]

Initialize SingleMetricBlock.

Hierarchy:

[Blocks | Metrics | SingleMetricBlock | Init]

Contract:
  • pre: “metric_spec has required keys: column, agg, title”

  • post: “Block registered with state manager”

Parameters:
  • block_id – Unique block identifier

  • datasource – DataSource instance

  • metric_spec – Metric definition with keys: - column (str): Column name to aggregate - agg (str|Callable): Aggregation func - title (str): Display title - color (str|dict): Bootstrap color (optional, supports conditional) - label (str|dict): Display label (optional, supports conditional) - dtype (str): Type conversion (optional) - color_rules (dict): Conditional coloring (optional, deprecated)

  • subscribes_to – State IDs to subscribe to

layout() Component[source]

Render initial layout with callback-compatible container.

CRITICAL: Must wrap metric card in Div with id=block_id-container to match BaseBlock.output_target() contract for callbacks.

Hierarchy:

[Blocks | Metrics | SingleMetricBlock | Layout]

Relates-to:
  • motivated_by: “BaseBlock lifecycle contract requires container ID”

  • implements: “method: ‘layout’”

  • uses: [“method: ‘_generate_id’”, “method: ‘_update_metric’”]

Contract:
  • pre: “Block initialized with navigation_mode and section_index”

  • post: “Returns Div(id=block_id-container) wrapping metric card”

  • invariant: “Container ID matches output_target() for callbacks”

  • spec_compliance: “Dash callback Output target must exist in DOM”

Complexity:

2

Decision_cache:

“Wrap in container Div to enable state-centric callbacks”

Returns:

html.Div wrapping dbc.Card (not Card directly!)

Text Block

This module defines the TextBlock for displaying text content.

class dashboard_lego.blocks.text.TextBlock(block_id: str, datasource: Any, content_generator: Callable[[DataFrame], Component | str] | str, subscribes_to: str | List[str] | None = None, title: str | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, content_style: Dict[str, Any] | None = None, content_className: str | None = None, loading_type: str = 'default', color: str | Dict[str, Any] | None = None)[source]

Bases: BaseBlock

A block for displaying dynamic or static text content, with support for Markdown and customizable styling.

This block optionally subscribes to a state and uses a generator function to render its content based on the data from a datasource.

hierarchy:

[Blocks | Text | TextBlock]

relates-to:
  • motivated_by: “Architectural Conclusion: Dynamic text blocks are essential for displaying model summaries and other formatted content with customizable styling”

  • implements: “block: ‘TextBlock’”

  • uses: [“interface: ‘BaseBlock’”]

rationale:

“Enhanced with style customization parameters to allow fine-grained control over text block appearance while maintaining backward compatibility. subscribes_to is now optional.”

contract:
  • pre: “A content_generator function or string must be provided. subscribes_to is optional.”

  • post: “The block renders a card with content that updates on state change (if subscribed) or displays static content with customizable styling applied.”

__init__(block_id: str, datasource: Any, content_generator: Callable[[DataFrame], Component | str] | str, subscribes_to: str | List[str] | None = None, title: str | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, content_style: Dict[str, Any] | None = None, content_className: str | None = None, loading_type: str = 'default', color: str | Dict[str, Any] | None = None)[source]

Initializes the TextBlock with customizable styling.

Parameters:
  • block_id – A unique identifier for this block instance.

  • datasource – An instance of a class that implements the DataSource interface.

  • content_generator – A function that takes a DataFrame and returns a Dash Component or a Markdown string, or a static string for fixed content.

  • subscribes_to – Optional state ID(s) to which this block subscribes to receive updates. Can be a single state ID string, a list of state IDs, or None for static content. Defaults to None.

  • title – An optional title for the block’s card.

  • card_style – Optional style dictionary for the card component.

  • card_className – Optional CSS class name for the card component.

  • title_style – Optional style dictionary for the title component.

  • title_className – Optional CSS class name for the title component.

  • content_style – Optional style dictionary for the content container.

  • content_className – Optional CSS class name for the content container.

  • loading_type – Type of loading indicator to display.

  • color

    Optional color specification. Can be: - str: Bootstrap theme color name (‘primary’, ‘success’, etc.) - dict: Keyword-based coloring with {‘keyword1’: ‘color1’, ‘keyword2’: ‘color2’, …}

    Searches for keywords in generated content (case-insensitive)

layout() Component[source]

Defines the initial layout of the block with theme-aware styling.

Hierarchy:

[Blocks | Text | TextBlock | Layout]

Relates-to:
  • motivated_by: “PRD: Automatic theme application to text blocks”

  • implements: “method: ‘layout’ with theme integration”

  • uses: [“method: ‘_get_themed_style’”, “attribute: ‘card_style’”]

Rationale:

“Uses theme system for consistent styling with user override capability.”

Contract:
  • pre: “Block is properly initialized, theme_config may be available.”

  • post: “Returns a themed Card component with automatic styling.”

class dashboard_lego.blocks.text.TextBlock(block_id: str, datasource: Any, content_generator: Callable[[DataFrame], Component | str] | str, subscribes_to: str | List[str] | None = None, title: str | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, content_style: Dict[str, Any] | None = None, content_className: str | None = None, loading_type: str = 'default', color: str | Dict[str, Any] | None = None)[source]

Bases: BaseBlock

A block for displaying dynamic or static text content, with support for Markdown and customizable styling.

This block optionally subscribes to a state and uses a generator function to render its content based on the data from a datasource.

hierarchy:

[Blocks | Text | TextBlock]

relates-to:
  • motivated_by: “Architectural Conclusion: Dynamic text blocks are essential for displaying model summaries and other formatted content with customizable styling”

  • implements: “block: ‘TextBlock’”

  • uses: [“interface: ‘BaseBlock’”]

rationale:

“Enhanced with style customization parameters to allow fine-grained control over text block appearance while maintaining backward compatibility. subscribes_to is now optional.”

contract:
  • pre: “A content_generator function or string must be provided. subscribes_to is optional.”

  • post: “The block renders a card with content that updates on state change (if subscribed) or displays static content with customizable styling applied.”

__init__(block_id: str, datasource: Any, content_generator: Callable[[DataFrame], Component | str] | str, subscribes_to: str | List[str] | None = None, title: str | None = None, card_style: Dict[str, Any] | None = None, card_className: str | None = None, title_style: Dict[str, Any] | None = None, title_className: str | None = None, content_style: Dict[str, Any] | None = None, content_className: str | None = None, loading_type: str = 'default', color: str | Dict[str, Any] | None = None)[source]

Initializes the TextBlock with customizable styling.

Parameters:
  • block_id – A unique identifier for this block instance.

  • datasource – An instance of a class that implements the DataSource interface.

  • content_generator – A function that takes a DataFrame and returns a Dash Component or a Markdown string, or a static string for fixed content.

  • subscribes_to – Optional state ID(s) to which this block subscribes to receive updates. Can be a single state ID string, a list of state IDs, or None for static content. Defaults to None.

  • title – An optional title for the block’s card.

  • card_style – Optional style dictionary for the card component.

  • card_className – Optional CSS class name for the card component.

  • title_style – Optional style dictionary for the title component.

  • title_className – Optional CSS class name for the title component.

  • content_style – Optional style dictionary for the content container.

  • content_className – Optional CSS class name for the content container.

  • loading_type – Type of loading indicator to display.

  • color

    Optional color specification. Can be: - str: Bootstrap theme color name (‘primary’, ‘success’, etc.) - dict: Keyword-based coloring with {‘keyword1’: ‘color1’, ‘keyword2’: ‘color2’, …}

    Searches for keywords in generated content (case-insensitive)

layout() Component[source]

Defines the initial layout of the block with theme-aware styling.

Hierarchy:

[Blocks | Text | TextBlock | Layout]

Relates-to:
  • motivated_by: “PRD: Automatic theme application to text blocks”

  • implements: “method: ‘layout’ with theme integration”

  • uses: [“method: ‘_get_themed_style’”, “attribute: ‘card_style’”]

Rationale:

“Uses theme system for consistent styling with user override capability.”

Contract:
  • pre: “Block is properly initialized, theme_config may be available.”

  • post: “Returns a themed Card component with automatic styling.”