LineChart Highlighting
Controlled highlighting on LineChart: set highlightedItem and highlightedAxis from Dash callbacks, plus per-series highlightScope highlight/fade behavior.
Overview
Controlled highlighting on LineChart: set highlightedItem and highlightedAxis from Dash callbacks, plus per-series highlightScope highlight/fade behavior.
The examples on this page read a MUI X Pro license key from the MUI_PRO_API_KEY environment variable and pass it as licenseKey. Without it the charts render with the unlicensed watermark.
Live examples
# File: docs/linechart_highlighting/demo.py
"""LineChart Highlighting demo — rendered on /linechart-highlighting via `.. exec::`.
Ported verbatim from the pre-migration pages/linechart_highlighting.py (same ids, same callbacks).
"""
import os
import json
import dash_mantine_components as dmc
import dash
from dash import html, callback, Input, Output, ctx
from dash_mui_charts import LineChart
MUI_LICENSE_KEY = os.environ.get('MUI_PRO_API_KEY', '')
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
sales_2023 = [120, 135, 150, 145, 160, 175, 190, 185, 200, 210, 195, 220]
sales_2024 = [130, 145, 165, 160, 180, 195, 210, 205, 225, 235, 220, 250]
CARD = 'page-card'
PRE_STYLE = {
'fontSize': '12px',
'margin': 0,
'padding': '10px 14px',
'borderRadius': '6px',
'background': 'var(--mantine-color-body)',
'border': '1px solid var(--mantine-color-default-border)',
'color': 'var(--mantine-color-text)',
'maxHeight': '200px',
'overflow': 'auto',
}
component = html.Div([
# ==========================================================================
# Controlled Item Highlight
# ==========================================================================
html.Div([
html.H4("Controlled Item Highlight"),
html.P(
"Click a button to programmatically highlight a data point. "
"The highlight persists until you clear it or set a new one. "
"Hovering the chart also updates the highlight state.",
style={'color': 'var(--mantine-color-dimmed)', 'fontSize': '14px'}
),
html.Div([
html.Button("Highlight Jan 2023", id='highlight-jan-btn',
style={'marginRight': '8px', 'marginBottom': '8px', 'padding': '6px 14px',
'borderRadius': '4px', 'border': '1px solid var(--mantine-color-default-border)',
'background': 'var(--mantine-color-blue-6)', 'color': 'white', 'cursor': 'pointer'}),
html.Button("Highlight Jun 2024", id='highlight-jun-btn',
style={'marginRight': '8px', 'marginBottom': '8px', 'padding': '6px 14px',
'borderRadius': '4px', 'border': '1px solid var(--mantine-color-default-border)',
'background': 'var(--mantine-color-green-7)', 'color': 'white', 'cursor': 'pointer'}),
html.Button("Clear", id='clear-highlight-btn',
style={'marginBottom': '8px', 'padding': '6px 14px',
'borderRadius': '4px', 'border': '1px solid var(--mantine-color-default-border)',
'background': 'var(--mantine-color-gray-6)', 'color': 'white', 'cursor': 'pointer'}),
], style={'marginBottom': '12px'}),
LineChart(
id='item-highlight-chart',
licenseKey=MUI_LICENSE_KEY,
height=350,
series=[
{
'id': 'sales-2023',
'data': sales_2023,
'label': 'Sales 2023',
'color': '#1976d2',
'showMark': True,
'highlightScope': {'highlight': 'series', 'fade': 'global'},
},
{
'id': 'sales-2024',
'data': sales_2024,
'label': 'Sales 2024',
'color': '#4caf50',
'showMark': True,
'highlightScope': {'highlight': 'series', 'fade': 'global'},
},
],
xAxis=[{
'id': 'x-axis',
'data': months,
'scaleType': 'point',
}],
grid={'horizontal': True},
tooltip={'trigger': 'item'},
),
html.P("highlightedItem:", style={'fontSize': '12px', 'color': 'var(--mantine-color-dimmed)',
'marginTop': '12px', 'marginBottom': '4px'}),
html.Pre(id='item-highlight-output', children='null (no highlight)', style=PRE_STYLE),
dmc.CodeHighlight(
language="python",
code="""# Controlled item highlight — set via callback, reads on hover
LineChart(
id='item-highlight-chart',
series=[
{
'id': 'sales-2023',
'data': sales_2023,
'showMark': True,
'highlightScope': {'highlight': 'series', 'fade': 'global'},
},
],
tooltip={'trigger': 'item'},
)
@callback(
Output('item-highlight-chart', 'highlightedItem'),
Input('highlight-btn', 'n_clicks'),
prevent_initial_call=True,
)
def set_highlight(n):
return {'seriesId': 'sales-2023', 'dataIndex': 0}""",
mt="md",
),
], className=CARD),
# ==========================================================================
# Controlled Axis Highlight
# ==========================================================================
html.Div([
html.H4("Controlled Axis Highlight"),
html.P(
"Use highlightedAxis to control which axis position is highlighted. "
"Useful for synchronizing highlights across multiple charts.",
style={'color': 'var(--mantine-color-dimmed)', 'fontSize': '14px'}
),
html.Div([
html.Button("Highlight March", id='highlight-mar-axis-btn',
style={'marginRight': '8px', 'marginBottom': '8px', 'padding': '6px 14px',
'borderRadius': '4px', 'border': '1px solid var(--mantine-color-default-border)',
'background': 'var(--mantine-color-blue-6)', 'color': 'white', 'cursor': 'pointer'}),
html.Button("Highlight September", id='highlight-sep-axis-btn',
style={'marginRight': '8px', 'marginBottom': '8px', 'padding': '6px 14px',
'borderRadius': '4px', 'border': '1px solid var(--mantine-color-default-border)',
'background': 'var(--mantine-color-violet-6)', 'color': 'white', 'cursor': 'pointer'}),
html.Button("Clear", id='clear-axis-btn',
style={'marginBottom': '8px', 'padding': '6px 14px',
'borderRadius': '4px', 'border': '1px solid var(--mantine-color-default-border)',
'background': 'var(--mantine-color-gray-6)', 'color': 'white', 'cursor': 'pointer'}),
], style={'marginBottom': '12px'}),
LineChart(
id='axis-highlight-chart',
licenseKey=MUI_LICENSE_KEY,
height=350,
series=[
{
'id': 'sales',
'data': sales_2024,
'label': 'Sales 2024',
'color': '#9c27b0',
'showMark': True,
},
],
xAxis=[{
'id': 'month-axis',
'data': months,
'scaleType': 'point',
}],
grid={'horizontal': True},
axisHighlight={'x': 'band', 'y': 'none'},
),
html.P("highlightedAxis:", style={'fontSize': '12px', 'color': 'var(--mantine-color-dimmed)',
'marginTop': '12px', 'marginBottom': '4px'}),
html.Pre(id='axis-highlight-output', children='[] (no highlight)', style=PRE_STYLE),
dmc.CodeHighlight(
language="python",
code="""LineChart(
id='axis-highlight-chart',
xAxis=[{'id': 'month-axis', 'data': months, 'scaleType': 'point'}],
axisHighlight={'x': 'band', 'y': 'none'},
)
@callback(
Output('axis-highlight-chart', 'highlightedAxis'),
Input('highlight-mar-btn', 'n_clicks'),
prevent_initial_call=True,
)
def set_axis_highlight(n):
return [{'axisId': 'month-axis', 'dataIndex': 2}] # March""",
mt="md",
),
], className=CARD),
# ==========================================================================
# Per-Series Highlight Scope
# ==========================================================================
html.Div([
html.H4("Per-Series Highlight Scope"),
html.P(
"Each series can define its own highlight behavior. Below, all three series "
"use different scopes. Hover over marks (circles) to see the difference:",
style={'color': 'var(--mantine-color-dimmed)', 'fontSize': '14px'}
),
dmc.SimpleGrid(
cols={"base": 1, "sm": 3},
spacing="xs",
mb="sm",
children=[
dmc.Paper(
[dmc.Text("Series A", fw=600, c="orange", size="sm"),
dmc.Text("highlight: 'series' / fade: 'global'", size="xs", c="dimmed"),
dmc.Text("Hovering highlights the entire series and fades everything else.", size="xs")],
p="sm", radius="sm", withBorder=True,
),
dmc.Paper(
[dmc.Text("Series B", fw=600, c="cyan", size="sm"),
dmc.Text("highlight: 'item' / fade: 'global'", size="xs", c="dimmed"),
dmc.Text("Hovering highlights only the hovered point and fades everything else.", size="xs")],
p="sm", radius="sm", withBorder=True,
),
dmc.Paper(
[dmc.Text("Series C", fw=600, c="grape", size="sm"),
dmc.Text("highlight: 'item' / fade: 'none'", size="xs", c="dimmed"),
dmc.Text("Hovering highlights the point but nothing else fades.", size="xs")],
p="sm", radius="sm", withBorder=True,
),
],
),
LineChart(
id='highlight-scope-chart',
licenseKey=MUI_LICENSE_KEY,
height=380,
series=[
{
'id': 'series-a',
'data': sales_2023,
'label': 'Series A (series + fade:global)',
'color': '#ff5722',
'showMark': True,
'highlightScope': {
'highlight': 'series',
'fade': 'global',
},
},
{
'id': 'series-b',
'data': sales_2024,
'label': 'Series B (item + fade:global)',
'color': '#00bcd4',
'showMark': True,
'highlightScope': {
'highlight': 'item',
'fade': 'global',
},
},
{
'id': 'series-c',
'data': [100, 115, 130, 125, 140, 155, 170, 165, 180, 190, 175, 200],
'label': 'Series C (item + fade:none)',
'color': '#9c27b0',
'showMark': True,
'highlightScope': {
'highlight': 'item',
'fade': 'none',
},
},
],
xAxis=[{
'id': 'x-axis-scope',
'data': months,
'scaleType': 'point',
}],
grid={'horizontal': True},
tooltip={'trigger': 'item'},
),
html.P(
"Hover over the data point marks (circles) on each series to see the different behaviors. "
"With trigger='item', you must hover directly on a mark.",
style={'color': 'var(--mantine-color-dimmed)', 'fontStyle': 'italic', 'fontSize': '13px', 'marginTop': '10px'}
),
dmc.CodeHighlight(
language="python",
code="""LineChart(
series=[
{
'id': 'series-a',
'data': data_a,
'showMark': True,
'highlightScope': {
'highlight': 'series', # Entire series lights up
'fade': 'global', # Everything else fades
},
},
{
'id': 'series-b',
'data': data_b,
'showMark': True,
'highlightScope': {
'highlight': 'item', # Only hovered point
'fade': 'global', # Everything else fades
},
},
{
'id': 'series-c',
'data': data_c,
'showMark': True,
'highlightScope': {
'highlight': 'item', # Only hovered point
'fade': 'none', # Nothing fades
},
},
],
tooltip={'trigger': 'item'}, # Must hover on marks
)""",
mt="md",
),
], className=CARD),
# ==========================================================================
# Highlight Scope Reference
# ==========================================================================
html.Div([
html.H4("Highlight Scope Reference"),
html.P(
"The highlightScope configuration controls how items are highlighted and how other items fade.",
style={'color': 'var(--mantine-color-dimmed)', 'fontSize': '14px'}
),
dmc.SimpleGrid(
cols={"base": 1, "sm": 2},
spacing="md",
children=[
dmc.Paper([
dmc.Text("highlight options", fw=600, size="sm", mb="xs"),
dmc.Text("'none' — No highlighting", size="sm", c="dimmed"),
dmc.Text("'item' — Highlight single data point on hover", size="sm", c="dimmed"),
dmc.Text("'series' — Highlight entire series on hover", size="sm", c="dimmed"),
], p="md", radius="sm", withBorder=True),
dmc.Paper([
dmc.Text("fade options", fw=600, size="sm", mb="xs"),
dmc.Text("'none' — No fading", size="sm", c="dimmed"),
dmc.Text("'series' — Fade other items in the same series", size="sm", c="dimmed"),
dmc.Text("'global' — Fade all items in all series", size="sm", c="dimmed"),
], p="md", radius="sm", withBorder=True),
],
),
], className=CARD),
], style={'maxWidth': '900px', 'margin': '0 auto'})
# ==========================================================================
# Callbacks
# ==========================================================================
@callback(
Output('item-highlight-chart', 'highlightedItem'),
Input('highlight-jan-btn', 'n_clicks'),
Input('highlight-jun-btn', 'n_clicks'),
Input('clear-highlight-btn', 'n_clicks'),
prevent_initial_call=True,
)
def set_item_highlight(jan_clicks, jun_clicks, clear_clicks):
triggered = ctx.triggered_id
if triggered == 'highlight-jan-btn':
return {'seriesId': 'sales-2023', 'dataIndex': 0}
elif triggered == 'highlight-jun-btn':
return {'seriesId': 'sales-2024', 'dataIndex': 5}
elif triggered == 'clear-highlight-btn':
return None
return dash.no_update
@callback(
Output('item-highlight-output', 'children'),
Input('item-highlight-chart', 'highlightedItem'),
)
def display_item_highlight(current_highlight):
if current_highlight:
return json.dumps(current_highlight, indent=2)
return "null (no highlight)"
@callback(
Output('axis-highlight-chart', 'highlightedAxis'),
Input('highlight-mar-axis-btn', 'n_clicks'),
Input('highlight-sep-axis-btn', 'n_clicks'),
Input('clear-axis-btn', 'n_clicks'),
prevent_initial_call=True,
)
def set_axis_highlight(mar_clicks, sep_clicks, clear_clicks):
triggered = ctx.triggered_id
if triggered == 'highlight-mar-axis-btn':
return [{'axisId': 'month-axis', 'dataIndex': 2}]
elif triggered == 'highlight-sep-axis-btn':
return [{'axisId': 'month-axis', 'dataIndex': 8}]
elif triggered == 'clear-axis-btn':
return []
return dash.no_update
@callback(
Output('axis-highlight-output', 'children'),
Input('axis-highlight-chart', 'highlightedAxis'),
)
def display_axis_highlight(current_highlight):
if current_highlight:
return json.dumps(current_highlight, indent=2)
return "[] (no highlight)"
:defaultExpanded: false :withExpandedButton: true
Source: /linechart-highlighting
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:
- /linechart-highlighting/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt