SparklineChart
SparklineChart demos: line, area and bar sparklines for KPI cards and tables, synced multi-metric hover, custom curves and callback-driven data.
Overview
Sparklines are compact, inline charts (default 36px height) that show a data trend without axes or labels — ideal for dashboards, KPI cards and table cells. This is a Community component: no MUI X license key required.
from dash_mui_charts import SparklineChart
SparklineChart(
data=[1, 4, 2, 5, 7, 2, 4, 6],
plotType='line', # or 'bar'
color='#1976d2',
area=True,
height=40,
width=150,
)
Key props:
data— list of numbers to plotplotType—'line'(default) or'bar'area— fill the region under the linecolor,height,width— appearance and sizingcurve— line interpolation:'linear','natural','monotoneX','step', and moreshowTooltip/showHighlight— hover value display and point markerbaselineandmargin— area baseline and plot marginshighlightedIndex— controlled highlight, to sync the marked point with a table row, slider or another chart
Basic line sparkline
The simplest sparkline — just pass an array of numbers. Great for showing trends at a glance.
# File: docs/sparkline/basic_example.py
from dash import html
from dash_mui_charts import SparklineChart
sales_trend = [10, 15, 8, 22, 18, 25, 30, 28, 35, 40, 38, 45]
stock_prices = [142.5, 145.2, 143.8, 148.9, 151.2, 149.5, 155.8, 158.2,
154.3, 160.1]
component = html.Div(
[
html.Div(
[
html.Span("Sales Trend: ",
style={"marginRight": "10px", "fontWeight": "bold"}),
SparklineChart(
data=sales_trend,
width=150,
height=30,
color="#1976d2",
),
],
style={"display": "flex", "alignItems": "center",
"marginBottom": "15px"},
),
html.Div(
[
html.Span("Stock Price: ",
style={"marginRight": "10px", "fontWeight": "bold"}),
SparklineChart(
data=stock_prices,
width=150,
height=30,
color="#4caf50",
),
],
style={"display": "flex", "alignItems": "center"},
),
]
)
:defaultExpanded: false :withExpandedButton: true
NPM-style downloads sparkline
A rich interactive sparkline like npm's package download chart. Hover over the chart to see weekly download counts update in real time — the hoverIndex / hoverValue props feed a Dash callback.
# File: docs/sparkline/npm_example.py
from dash import Input, Output, callback, html
from dash_mui_charts import SparklineChart
weekly_downloads = [
125430, 142350, 138200, 156780, 162340, 158900, 171200,
168500, 175600, 182300, 178900, 195400,
]
weeks = [
'Dec 1-7', 'Dec 8-14', 'Dec 15-21', 'Dec 22-28',
'Dec 29-Jan 4', 'Jan 5-11', 'Jan 12-18',
'Jan 19-25', 'Jan 26-Feb 1', 'Feb 2-8', 'Feb 9-15', 'Feb 16-22',
]
component = html.Div(
html.Div(
[
html.Div(
[
html.Span("📦 ", style={"marginRight": "5px"}),
html.Span(
id="npm-week-label",
children="Weekly Downloads",
style={"color": "#666", "fontSize": "14px"},
),
],
style={"marginBottom": "8px"},
),
html.Div(
[
html.Span(
id="npm-download-count",
children=f"{weekly_downloads[-1]:,}",
style={"fontSize": "28px", "fontWeight": "bold",
"color": "#333"},
),
html.Div(
SparklineChart(
id="npm-sparkline",
data=weekly_downloads,
width=200,
height=45,
color="rgb(137, 86, 255)",
area=True,
showHighlight=True,
baseline="min",
margin={"top": 5, "right": 0, "bottom": 0,
"left": 4},
xAxis={"id": "week-axis", "data": weeks},
axisHighlight={"x": "line"},
slotProps={"lineHighlight": {"r": 4}},
clipAreaOffset={"top": 2, "bottom": 2},
),
style={"marginLeft": "auto"},
),
],
style={
"display": "flex",
"alignItems": "flex-end",
"justifyContent": "space-between",
"borderBottom": "2px solid rgba(137, 86, 255, 0.2)",
"paddingBottom": "5px",
},
),
],
style={
"width": "350px",
"backgroundColor": "white",
"padding": "15px 20px",
"borderRadius": "8px",
"boxShadow": "0 2px 8px rgba(0,0,0,0.1)",
},
)
)
@callback(
Output("npm-download-count", "children"),
Output("npm-week-label", "children"),
Input("npm-sparkline", "hoverIndex"),
Input("npm-sparkline", "hoverValue"),
prevent_initial_call=True,
)
def update_npm_display(hover_index, hover_value):
"""Update npm-style display based on hover."""
if hover_index is not None and hover_value is not None:
return f"{int(hover_value):,}", weeks[hover_index]
return f"{weekly_downloads[-1]:,}", "Weekly Downloads"
:defaultExpanded: false :withExpandedButton: true
Synchronized multi-metric dashboard
Multiple sparklines that sync their hover state. Hover over any chart to see all metrics for that time period.
# File: docs/sparkline/synced_example.py
from dash import Input, Output, callback, html
from dash_mui_charts import SparklineChart
revenue_data = [42, 45, 48, 52, 49, 55, 58, 62, 60, 65]
users_data = [1200, 1350, 1420, 1580, 1520, 1680, 1750, 1890, 1820, 1950]
sessions_data = [3500, 3800, 4100, 4500, 4200, 4800, 5100, 5400, 5200, 5600]
metric_labels = ['Week 1', 'Week 2', 'Week 3', 'Week 4', 'Week 5',
'Week 6', 'Week 7', 'Week 8', 'Week 9', 'Week 10']
kpi_card_style = {
"backgroundColor": "white",
"borderRadius": "8px",
"padding": "20px",
"boxShadow": "0 2px 4px rgba(0,0,0,0.1)",
"width": "280px",
}
def _kpi_card(title, value_id, label_id, value, spark):
return html.Div(
[
html.Div(title, style={"fontSize": "12px", "color": "#666",
"marginBottom": "5px"}),
html.Div(
[
html.Span(id=value_id, children=value,
style={"fontSize": "24px",
"fontWeight": "bold"}),
html.Span(id=label_id, children="",
style={"fontSize": "11px", "color": "#999",
"marginLeft": "8px"}),
]
),
spark,
],
)
component = html.Div(
[
html.Div(
_kpi_card(
"Revenue", "sync-revenue-value", "sync-revenue-label",
f"${revenue_data[-1]}K",
SparklineChart(
id="sync-revenue-spark",
data=revenue_data,
width=200,
height=35,
color="#4caf50",
area=True,
showHighlight=True,
xAxis={"id": "rev-axis", "data": metric_labels},
),
),
style={**kpi_card_style, "borderTop": "3px solid #4caf50"},
),
html.Div(
_kpi_card(
"Active Users", "sync-users-value", "sync-users-label",
f"{users_data[-1]:,}",
SparklineChart(
id="sync-users-spark",
data=users_data,
width=200,
height=35,
color="#2196f3",
area=True,
showHighlight=True,
xAxis={"id": "users-axis", "data": metric_labels},
),
),
style={**kpi_card_style, "borderTop": "3px solid #2196f3"},
),
html.Div(
_kpi_card(
"Sessions", "sync-sessions-value", "sync-sessions-label",
f"{sessions_data[-1]:,}",
SparklineChart(
id="sync-sessions-spark",
data=sessions_data,
width=200,
height=35,
color="#ff9800",
area=True,
showHighlight=True,
xAxis={"id": "sessions-axis", "data": metric_labels},
),
),
style={**kpi_card_style, "borderTop": "3px solid #ff9800"},
),
],
style={"display": "flex", "gap": "20px", "flexWrap": "wrap"},
)
@callback(
Output("sync-revenue-value", "children"),
Output("sync-revenue-label", "children"),
Output("sync-users-value", "children"),
Output("sync-users-label", "children"),
Output("sync-sessions-value", "children"),
Output("sync-sessions-label", "children"),
Input("sync-revenue-spark", "hoverIndex"),
Input("sync-users-spark", "hoverIndex"),
Input("sync-sessions-spark", "hoverIndex"),
prevent_initial_call=True,
)
def sync_hover(rev_idx, users_idx, sessions_idx):
"""Sync hover state across multiple sparklines."""
idx = None
for i in [rev_idx, users_idx, sessions_idx]:
if i is not None:
idx = i
break
if idx is not None:
label = metric_labels[idx]
return (
f"${revenue_data[idx]}K", label,
f"{users_data[idx]:,}", label,
f"{sessions_data[idx]:,}", label,
)
return (
f"${revenue_data[-1]}K", "",
f"{users_data[-1]:,}", "",
f"{sessions_data[-1]:,}", "",
)
:defaultExpanded: false :withExpandedButton: true
Area sparkline
Add area=True to fill the area under the line. Use baseline to control where the fill starts: 'min' (default), 'max', or a specific value.
# File: docs/sparkline/area_example.py
from dash import html
from dash_mui_charts import SparklineChart
temperature_week = [72, 75, 78, 82, 79, 74, 71]
def _row(label, spark):
return html.Div(
[
html.Span(label, style={"width": "120px",
"display": "inline-block"}),
spark,
],
style={"marginBottom": "10px"},
)
component = html.Div(
[
# baseline='min' — fills from the minimum value (default)
_row("baseline='min': ",
SparklineChart(data=temperature_week, width=150, height=40,
color="#ff9800", area=True, baseline="min")),
# baseline='max' — fills from the maximum (inverted)
_row("baseline='max': ",
SparklineChart(data=temperature_week, width=150, height=40,
color="#2196f3", area=True, baseline="max")),
# baseline=75 — fills from a specific value
_row("baseline=75: ",
SparklineChart(data=temperature_week, width=150, height=40,
color="#9c27b0", area=True, baseline=75)),
]
)
:defaultExpanded: false :withExpandedButton: true
Bar sparkline
Use plotType='bar' for a bar chart sparkline. Good for discrete values or comparing magnitudes.
# File: docs/sparkline/bar_example.py
from dash import html
from dash_mui_charts import SparklineChart
error_rates = [2, 5, 3, 8, 4, 2, 1, 3, 2, 4]
component = html.Div(
[
html.Div(
[
html.Span("Daily Errors: ",
style={"marginRight": "10px", "fontWeight": "bold"}),
SparklineChart(
data=error_rates,
width=150,
height=40,
plotType="bar",
color="#f44336",
),
],
style={"display": "flex", "alignItems": "center",
"marginBottom": "15px"},
),
html.Div(
[
html.Span("Weekly Sales: ",
style={"marginRight": "10px", "fontWeight": "bold"}),
SparklineChart(
data=[120, 145, 132, 168, 155, 142, 178],
width=150,
height=40,
plotType="bar",
color="#2196f3",
),
],
style={"display": "flex", "alignItems": "center"},
),
]
)
:defaultExpanded: false :withExpandedButton: true
Sparklines in a table
Sparklines are perfect for embedding in data tables to show trends alongside other metrics.
# File: docs/sparkline/table_example.py
from dash import html
from dash_mui_charts import SparklineChart
_th = {"textAlign": "left", "padding": "12px",
"borderBottom": "2px solid #ddd"}
_td = {"padding": "12px"}
_num = {"textAlign": "right", "padding": "12px", "fontWeight": "bold"}
_mid = {"textAlign": "center", "padding": "12px"}
def _spark_row(metric, current, spark, change, change_color):
return html.Tr(
[
html.Td(metric, style=_td),
html.Td(current, style=_num),
html.Td(spark, style=_mid),
html.Td(change, style={"textAlign": "right", "padding": "12px",
"color": change_color}),
]
)
component = html.Table(
[
html.Thead(
html.Tr(
[
html.Th("Metric", style=_th),
html.Th("Current", style={**_th, "textAlign": "right"}),
html.Th("Trend (7 days)",
style={**_th, "textAlign": "center"}),
html.Th("Change", style={**_th, "textAlign": "right"}),
]
)
),
html.Tbody(
[
_spark_row(
"Revenue", "$45,230",
SparklineChart(data=[38, 42, 40, 44, 43, 45, 45],
width=100, height=25, color="#4caf50",
area=True),
"+12%", "#4caf50",
),
_spark_row(
"Users", "2,847",
SparklineChart(data=[2200, 2350, 2400, 2500, 2650, 2750,
2847],
width=100, height=25, color="#2196f3",
area=True),
"+29%", "#4caf50",
),
_spark_row(
"Errors", "23",
SparklineChart(data=[45, 38, 42, 35, 30, 28, 23],
width=100, height=25, color="#f44336"),
"-49%", "#4caf50",
),
_spark_row(
"Response Time", "245ms",
SparklineChart(data=[220, 235, 242, 238, 250, 248, 245],
width=100, height=25, color="#ff9800"),
"+11%", "#f44336",
),
]
),
],
style={"width": "100%", "borderCollapse": "collapse", "marginTop": "10px"},
)
:defaultExpanded: false :withExpandedButton: true
Callback-triggered data changes
Change the sparkline data dynamically from a Dash callback. Select a metric to see different trend data.
# File: docs/sparkline/dynamic_example.py
from dash import Input, Output, callback, dcc, html
from dash_mui_charts import SparklineChart
revenue_data = [42, 45, 48, 52, 49, 55, 58, 62, 60, 65]
users_data = [1200, 1350, 1420, 1580, 1520, 1680, 1750, 1890, 1820, 1950]
sessions_data = [3500, 3800, 4100, 4500, 4200, 4800, 5100, 5400, 5200, 5600]
error_rates = [2, 5, 3, 8, 4, 2, 1, 3, 2, 4]
component = html.Div(
[
html.Div(
[
html.Label("Select Metric:",
style={"marginRight": "10px",
"fontWeight": "bold"}),
dcc.Dropdown(
id="metric-selector",
options=[
{"label": "Revenue", "value": "revenue"},
{"label": "Users", "value": "users"},
{"label": "Sessions", "value": "sessions"},
{"label": "Errors", "value": "errors"},
],
value="revenue",
style={"width": "200px"},
clearable=False,
),
],
style={"marginBottom": "20px"},
),
html.Div(
[
html.Div(id="dynamic-metric-label", children="Revenue Trend",
style={"fontSize": "14px", "color": "#666",
"marginBottom": "5px"}),
html.Div(id="dynamic-metric-value", children="$65K",
style={"fontSize": "32px", "fontWeight": "bold",
"marginBottom": "10px"}),
html.Div(id="dynamic-sparkline-container"),
],
style={
"backgroundColor": "white",
"padding": "20px",
"borderRadius": "8px",
"boxShadow": "0 2px 4px rgba(0,0,0,0.1)",
"width": "300px",
},
),
]
)
@callback(
Output("dynamic-sparkline-container", "children"),
Output("dynamic-metric-label", "children"),
Output("dynamic-metric-value", "children"),
Input("metric-selector", "value"),
)
def update_dynamic_sparkline(metric):
"""Update sparkline based on selected metric."""
data_map = {
"revenue": (revenue_data, "#4caf50", "Revenue Trend",
f"${revenue_data[-1]}K"),
"users": (users_data, "#2196f3", "Active Users",
f"{users_data[-1]:,}"),
"sessions": (sessions_data, "#ff9800", "Sessions",
f"{sessions_data[-1]:,}"),
"errors": (error_rates, "#f44336", "Error Rate",
str(error_rates[-1])),
}
data, color, label, value = data_map[metric]
return SparklineChart(
data=data,
width=260,
height=50,
color=color,
area=True,
showHighlight=True,
showTooltip=True,
), label, value
:defaultExpanded: false :withExpandedButton: true
Custom curves
Use different curve interpolation methods for different visual effects. Available curves: 'linear', 'natural', 'step', 'stepBefore', 'stepAfter', 'monotoneX', 'monotoneY', 'catmullRom', 'bumpX', 'bumpY'.
# File: docs/sparkline/curves_example.py
from dash import html
from dash_mui_charts import SparklineChart
sales_trend = [10, 15, 8, 22, 18, 25, 30, 28, 35, 40, 38, 45]
def _row(label, curve, color):
return html.Div(
[
html.Span(label, style={"width": "100px",
"display": "inline-block"}),
SparklineChart(data=sales_trend, width=120, height=30,
color=color, curve=curve),
],
style={"marginBottom": "10px"},
)
component = html.Div(
[
_row("Linear: ", "linear", "#1976d2"),
_row("Natural: ", "natural", "#4caf50"),
_row("Step: ", "step", "#ff9800"),
_row("MonotoneX: ", "monotoneX", "#9c27b0"),
]
)
:defaultExpanded: false :withExpandedButton: true
Interactive sparkline with hover details
Enable tooltips and highlighting to make sparklines interactive. The hoverIndex and hoverValue props update as you move across the chart.
# File: docs/sparkline/interactive_example.py
import json
from dash import Input, Output, callback, html
from dash_mui_charts import SparklineChart
stock_prices = [142.5, 145.2, 143.8, 148.9, 151.2, 149.5, 155.8, 158.2,
154.3, 160.1]
component = html.Div(
[
html.Div(
[
html.Div(
[
html.Span("Stock Price: ",
style={"fontWeight": "bold"}),
html.Span(id="stock-price-display",
children=f"${stock_prices[-1]:.2f}"),
],
style={"marginBottom": "10px"},
),
SparklineChart(
id="interactive-stock-sparkline",
data=stock_prices,
width=300,
height=60,
color="#1976d2",
area=True,
showTooltip=True,
showHighlight=True,
xAxis={"id": "stock-axis",
"data": ["Day 1", "Day 2", "Day 3", "Day 4",
"Day 5", "Day 6", "Day 7", "Day 8",
"Day 9", "Day 10"]},
axisHighlight={"x": "line"},
),
]
),
html.Div(
[
html.Strong("Hover Data:"),
html.Pre(
id="stock-hover-output",
children="Hover over the chart to see details",
style={
"backgroundColor": "#f5f5f5",
"padding": "15px",
"borderRadius": "5px",
"whiteSpace": "pre-wrap",
"fontSize": "12px",
"overflow": "auto",
"marginTop": "10px",
"minHeight": "60px",
},
),
],
style={"marginTop": "15px"},
),
]
)
@callback(
Output("stock-price-display", "children"),
Output("stock-hover-output", "children"),
Input("interactive-stock-sparkline", "hoverIndex"),
Input("interactive-stock-sparkline", "hoverValue"),
prevent_initial_call=True,
)
def update_stock_display(index, value):
"""Update stock price display based on hover."""
if index is not None and value is not None:
return f"${value:.2f}", json.dumps({
"index": index,
"value": value,
"day": f"Day {index + 1}",
}, indent=2)
return f"${stock_prices[-1]:.2f}", "Hover over the chart to see details"
:defaultExpanded: false :withExpandedButton: true
Related pages
- Styling playground — interactive styling controls with live preview and generated code
- Advanced styling — liquid glass (glassmorphism) sparkline card
Source: /sparkline
Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs:
- /sparkline/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt