Installation
pip install dash-gauge
Introduction
The dash-gauge package provides a suite of interactive and visually appealing components to enhance your Plotly Dash dashboards. Built as wrappers around popular React libraries, this collection includes:
DashGauge: Customizable gauge charts (Grafana, Semicircle, Radial styles).DashRotaryKnob: Interactive rotary knob controls with various skins.DashThermostat: A thermostat-like input component.DashRCJoystick: A virtual joystick component for directional input.Dash7SegmentDisplay: A classic 7-segment display for numbers and hex values.
This page documents each component included in the suite.
# File: docs/dash_gauge/introduction_example.py
import dash
from dash import html, callback, Input, Output
import dash_gauge as dg
import dash_mantine_components as dmc
# app = dash.Dash(__name__) # Define app in your main docs entry point
component = dmc.Container([
dmc.Title("Dash Gauge Component Suite Showcase", order=2, ta="center", mb="lg"),
dmc.SimpleGrid(
cols={"base": 1, "sm": 2, "lg": 3},
spacing="lg",
verticalSpacing="lg",
children=[
# 1. DashGauge Example
dmc.Paper(
p="md", shadow="sm", withBorder=True, children=[
dmc.Stack([
dmc.Text("DashGauge (Semicircle)", fw=500, ta="center"),
dmc.Center(
dg.DashGauge(
id="intro-gauge",
type="semicircle",
value=65,
minValue=0,
maxValue=100,
style={'width': '90%'} # Adjust width as needed
)
)
])
]
),
# 2. DashRotaryKnob Example
dmc.Paper(
p="md", shadow="sm", withBorder=True, children=[
dmc.Stack([
dmc.Text("DashRotaryKnob", fw=500, ta="center"),
dmc.Center(
dg.DashRotaryKnob(
id="intro-knob",
skinName="s12", # Choose a visually interesting skin
value=30,
min=0,
max=100,
style={"width": "100px", "height": "100px"} # Explicit size
)
),
dmc.Text("Value: --", id="intro-knob-output", ta="center", size="sm", c="dimmed")
])
]
),
# 3. DashThermostat Example
dmc.Paper(
p="md", shadow="sm", withBorder=True, children=[
dmc.Stack([
dmc.Text("DashThermostat", fw=500, ta="center"),
dmc.Space(h=20),
dmc.Center(
dg.DashThermostat(
id="intro-thermostat",
value=21,
min=5,
max=35,
valueSuffix="°C",
style={'width': '200px', 'height': '300px'} # Control size
)
)
])
]
),
# 4. DashRCJoystick Example
dmc.Paper(
p="md", shadow="sm", withBorder=True, children=[
dmc.Stack([
dmc.Text("DashRCJoystick", fw=500, ta="center"),
dmc.Center(
dg.DashRCJoystick(
id='intro-joystick',
directionCountMode='Nine',
baseRadius=60, # Slightly smaller for grid
controllerRadius=30,
)
),
dmc.Text("Direction: Center", id="intro-joystick-direction", ta="center", size="sm", c="dimmed"),
dmc.Text("Angle: N/A", id="intro-joystick-angle", ta="center", size="sm", c="dimmed"),
dmc.Text("Distance: 0.00", id="intro-joystick-distance", ta="center", size="sm", c="dimmed"),
])
]
),
]
)
], fluid=True, pt="xl", pb="xl")
# --- Callbacks ---
@callback(
Output("intro-knob-output", "children"),
Input("intro-knob", "value")
)
def update_intro_knob_output(value):
if value is None:
return "Value: --"
return f"Value: {value:.1f}"
@callback(
Output('intro-joystick-direction', 'children'),
Output('intro-joystick-angle', 'children'),
Output('intro-joystick-distance', 'children'),
Input('intro-joystick', 'direction'),
Input('intro-joystick', 'angle'),
Input('intro-joystick', 'distance')
)
def update_intro_joystick_output(direction, angle, distance):
angle_str = f"Angle: {angle:.1f}°" if angle is not None else "Angle: N/A"
distance_str = f"Distance: {distance:.2f}" if distance is not None else "Distance: N/A"
direction_str = f"Direction: {direction}" if direction is not None else "Direction: N/A"
return direction_str, angle_str, distance_str
# Add this section if running this file standalone for testing
# if __name__ == "__main__":
# app = dash.Dash(__name__)
# app.layout = component
# app.run_server(debug=True)
DashGauge
Displays a value on a customizable gauge. Supports different styles, color ranges, sub-arcs, custom labels, and pointers. Ideal for visualizing KPIs, sensor readings, or progress metrics.
# File: docs/dash_gauge/gauge_example.py
import dash
from dash import html, dcc, callback, Input, Output
import dash_gauge as dg
import dash_mantine_components as dmc
# Based on usage_gauge.py
component = dmc.Container([
dmc.Title("DashGauge Examples", order=3, ta="center", mb="lg"),
dmc.SimpleGrid(
cols={"base": 1, "sm": 1, "lg": 3},
spacing="lg",
children=[
dmc.Paper(p="md", shadow="sm", withBorder=True, children=dmc.Stack([
dmc.Text("Basic Gauge", fw=500, ta="center"),
dmc.Center(
dg.DashGauge(
id="basic-gauge-docs",
value=50,
style={'width': '90%'}
)
)
])),
dmc.Paper(p="md", shadow="sm", withBorder=True, children=dmc.Stack([
dmc.Text("Temperature Gauge (Semicircle)", fw=500, ta="center"),
dmc.Center(
dg.DashGauge(
id="temperature-gauge-docs",
type="semicircle",
value=22.5,
minValue=10,
maxValue=35,
arc={
"width": 0.2, "padding": 0.005, "cornerRadius": 1,
"subArcs": [
{"limit": 15, "color": "#EA4228", "showTick": True, "tooltip": {"text": "Too low!"}},
{"limit": 17, "color": "#F5CD19", "showTick": True, "tooltip": {"text": "Low"}},
{"limit": 28, "color": "#5BE12C", "showTick": True, "tooltip": {"text": "OK"}},
{"limit": 30, "color": "#F5CD19", "showTick": True, "tooltip": {"text": "High"}},
{"color": "#EA4228", "tooltip": {"text": "Too high!"}}
]
},
pointer={"color": "#345243", "length": 0.80, "width": 15},
labels={"valueLabel": {"style": {"fontSize": "30px"}}}, # Simplified labels
style={'width': '90%'}
)
)
])),
dmc.Paper(p="md", shadow="sm", withBorder=True, children=dmc.Stack([
dmc.Text("Bandwidth Gauge (Radial)", fw=500, ta="center"),
dmc.Center(
dg.DashGauge(
id="bandwidth-gauge-docs",
type="radial", # Changed type for variety
value=900,
maxValue=3000,
arc={
"nbSubArcs": 150,
"colorArray": ["#5BE12C", "#F5CD19", "#EA4228"],
"width": 0.3, # Adjusted width for radial
"padding": 0.003
},
style={'width': '90%'}
)
)
])),
]
),
dmc.Space(h="xl"),
dmc.Paper(p="md", shadow="sm", withBorder=True, children=dmc.Stack([
dmc.Text("Interactive Gauge", fw=500, ta="center"),
dmc.Text("Use the slider to update the gauge value:", size="sm", ta="center"),
dmc.Slider(
id="gauge-slider-docs",
min=0, max=100, step=1, value=40,
labelTransitionProps={
"transition": "skew-down",
"duration": 150,
"timingFunction": "linear",
},
),
dmc.Center(
dg.DashGauge(
id="interactive-gauge-docs",
type="radial",
value=50, # Initial value linked to slider
arc={
"colorArray": ["#5BE12C", "#EA4228"],
"subArcs": [{"limit": 10}, {"limit": 30}, {}, {}, {}],
"padding": 0.02,
"width": 0.3
},
pointer={"elastic": True, "animationDelay": 0},
labels={
"tickLabels": {"type": "inner", "ticks": [{"value": i} for i in range(20, 101, 20)]}
},
style={'width': '300px', 'marginTop': '20px'} # Control size
)
)
]))
], fluid=True)
@callback(
Output("interactive-gauge-docs", "value"),
Input("gauge-slider-docs", "value")
)
def update_gauge_docs(value):
return value
DashGauge Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | - | Component ID for Dash callbacks. |
value | number | 33 | The value the gauge should indicate. |
type | string | 'grafana' | Style of the gauge. Choices: 'grafana', 'semicircle', 'radial'. |
minValue | number | 0 | Minimum value of the gauge scale. |
maxValue | number | 100 | Maximum value of the gauge scale. |
className | string | dash-gauge | CSS class name for the component. |
style | object | {} | Inline CSS styles for the component. |
marginInPercent | number or object | undefined | Sets the margin for the chart inside the SVG. Can be a single number or {top, bottom, left, right}. |
arc | object | {} | Configuration for the gauge arc (e.g., width, padding, cornerRadius, colorArray, subArcs, gradient). See usage_gauge.py for details. |
pointer | object | {} | Configuration for the gauge pointer/needle (e.g., type, color, length, width, animate, elastic). See usage_gauge.py for details. |
labels | object | {} | Configuration for value and tick labels (e.g., valueLabel, tickLabels, formatTextValue, hideMinMax). See usage_gauge.py for details. |
setProps | func | - | Dash-assigned callback function. |
Note: For detailed examples of arc, pointer, and labels configurations, please refer to the usage_gauge.py file in the GitHub repository.
DashRotaryKnob
An interactive knob component, useful for selecting values within a range (e.g., volume, tuning). Comes with multiple visual skins from the react-rotary-knob-skin-pack.
# File: docs/dash_gauge/knob_example.py
import dash
from dash import html, dcc, callback, Input, Output, State
import dash_gauge as dg
import dash_mantine_components as dmc
# Based on usage_rotary_knob.py
component = dmc.Container([
dmc.Title("DashRotaryKnob Example", order=3, ta="center", mb="lg"),
dmc.Grid(
gutter="xl",
children=[
dmc.GridCol(span={"md": 5, "sm": 12}, children=dmc.Stack(align="center", children=[
dmc.Text("Interactive Knob", fw=500),
dmc.Text(id="knob-value-display-docs", size="lg", mt="sm"),
dg.DashRotaryKnob(
id="interactive-knob-docs",
skinName="s10",
value=50,
min=0,
max=100,
# format="{value}%", # Formatting might be better handled in display callback
style={"width": "150px", "height": "150px"} # Adjust size
),
])),
dmc.GridCol(span={"md": 7, "sm": 12}, children=dmc.Stack([
dmc.Text("Controls", fw=500),
dmc.Slider(
id="knob-slider-docs",
label="Adjust with slider",
min=0, max=100, step=1, value=50,
marks=[{"value": i, "label": str(i)} for i in range(0, 101, 20)],
mb="lg"
),
dmc.Select(
id="skin-selector-docs",
label="Change skin",
data=[{"label": f"Skin s{i}", "value": f"s{i}"} for i in range(1, 19)],
value="s10",
clearable=False,
mb="lg"
),
]))
]
)
], fluid=True)
@callback(
Output("knob-value-display-docs", "children"),
Input("interactive-knob-docs", "value")
)
def update_knob_value_display_docs(value):
if value is None:
return "Current value: --"
return f"Current value: {value:.1f}"
@callback(
Output("interactive-knob-docs", "value"),
Input("knob-slider-docs", "value"),
)
def update_knob_from_slider_docs(value):
return value
@callback(
Output("interactive-knob-docs", "skinName"),
Input("skin-selector-docs", "value"),
)
def update_knob_skin_docs(skin_name):
return skin_name
DashRotaryKnob Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | - | Component ID for Dash callbacks. |
value | number | 0 | The current value of the knob. Updated via interaction or callbacks. |
min | number | 0 | Minimum value of the knob. |
max | number | 100 | Maximum value of the knob. |
step | number | 1 | Increment/decrement step size. |
skinName | string | 's1' | Selects the visual appearance (e.g., 's1', 's5', 's10', up to 's18'). See repository for examples. |
preciseMode | boolean | true | If true, requires Shift key + drag for fine adjustments. |
unlockDistance | number | 0 | Degrees the mouse must move vertically to "unlock" the knob for rotation. |
className | string | '' | CSS class name for the component. |
style | object | {} | Inline CSS styles for the component. |
setProps | func | - | Dash-assigned callback function. |
Note: Explore all 18 skins by changing the skinName prop! See usage_rotary_knob.py for an interactive example. Only skins 1 & 10-15 look good 🤷 "no idea why the other skins don't alin correctly".
DashThermostat
A component mimicking a thermostat interface for setting a target value, typically temperature.
# File: docs/dash_gauge/thermostat_example.py
import dash
from dash import html, dcc, callback, Input, Output, State
import dash_gauge as dg
import dash_mantine_components as dmc
# Based on usage_thermostat.py, but simplified for docs
# Define some example colors
cool_colors = ['#dae8eb', '#2c8e98']
heat_colors = ['#cfac48', '#cd5401']
component = dmc.Container([
dmc.Title("DashThermostat Example", order=3, ta="center", mb="lg"),
dmc.Grid(
gutter="xl",
children=[
dmc.GridCol(span={"md": 6, "sm": 12}, children=dmc.Stack(align="center", children=[
dmc.Text("Thermostat Control", fw=500),
dmc.Space(h=20),
dg.DashThermostat(
id='thermostat-docs',
value=21,
min=5,
max=35,
valueSuffix='°C',
track={'colors': cool_colors}, # Start with cool colors
style={'width': '250px', 'height': '350px', 'marginBottom': '20px'},
)
])),
dmc.GridCol(span={"md": 6, "sm": 12}, children=dmc.Stack([
dmc.Text("Controls", fw=500),
dmc.Text("Set Temperature:", size="sm"),
dmc.Slider(
id="thermostat-slider-docs",
min=5, max=35, step=0.5, value=21,
marks=[{"value": v, "label": f"{v}°"} for v in range(5, 36, 5)],
style={"maxWidth": 300},
mb="lg"
),
dmc.Text("Current Setting:", size="sm"),
dmc.Title(id="thermostat-value-display-docs", order=4, ta="center"),
dmc.Space(h="lg"),
dmc.Text("Toggle Disabled:", size="sm"),
dmc.Switch(id="thermostat-disable-switch-docs", label="Disable Thermostat", checked=False),
dmc.Space(h="lg"),
dmc.Text("Change Track Color:", size="sm"),
dmc.SegmentedControl(
id="thermostat-color-switch-docs",
value="cool",
data=[
{"label": "Cool Mode", "value": "cool"},
{"label": "Heat Mode", "value": "heat"},
],
fullWidth=True,
mb="md",
),
]))
]
)
], fluid=True)
@callback(
Output('thermostat-docs', 'value'),
Input('thermostat-slider-docs', 'value')
)
def update_thermostat_from_slider(value):
return value
@callback(
Output('thermostat-value-display-docs', 'children'),
Input('thermostat-docs', 'value')
)
def display_thermostat_value(value):
if value is None:
return "-- °C"
return f"{value:.1f} °C"
@callback(
Output('thermostat-docs', 'disabled'),
Input('thermostat-disable-switch-docs', 'checked')
)
def toggle_thermostat_disabled(checked):
return checked
@callback(
Output('thermostat-docs', 'track'),
Input('thermostat-color-switch-docs', 'value'),
State('thermostat-docs', 'track') # Get current track state if needed
)
def update_thermostat_track_color(mode, current_track):
# Ensure track is a dictionary before modifying
track_config = current_track if isinstance(current_track, dict) else {}
if mode == 'cool':
track_config['colors'] = cool_colors
elif mode == 'heat':
track_config['colors'] = heat_colors
# Add other track properties if they exist, e.g., thickness
# track_config['thickness'] = current_track.get('thickness', 0.2) # Example
return track_config
DashThermostat Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | - | Component ID for Dash callbacks. |
value | number | Required | The current set value (e.g., temperature). Updated via interaction or callbacks. |
min | number | 0 | Minimum value of the thermostat scale. |
max | number | 100 | Maximum value of the thermostat scale. |
valueSuffix | string | '°' | Text to display after the value (e.g., '°C', '°F', '%). |
disabled | boolean | false | If true, disables user interaction with the thermostat. |
handle | object | undefined | Configuration object for the draggable handle (e.g., size, colors). See react-thermostat docs. |
track | object | undefined | Configuration object for the background track (e.g., colors, thickness, markers). See react-thermostat docs. |
className | string | '' | CSS class name for the component. |
style | object | {} | Inline CSS styles for the component. Note: Component has min-width/height defaults. |
setProps | func | - | Dash-assigned callback function. |
Note: The usage_thermostat.py example demonstrates complex interaction with custom styling and mode switching. It may require CSS files placed in an assets folder.
DashRCJoystick
A virtual joystick component that reports direction, angle, and distance based on user interaction. Useful for controlling elements in simulations, games, or robotics dashboards.
# File: docs/dash_gauge/joystick_example.py
import dash
from dash import html, dcc, callback, Input, Output, State
import dash_gauge as dg
import dash_mantine_components as dmc
# Based on usage_rc_joystick.py
component = dmc.Container([
dmc.Title("DashRCJoystick Example", order=3, ta="center", mb="lg"),
dmc.Grid(
gutter="xl",
children=[
# Left side: Joystick Component
dmc.GridCol(span={"md": 5, "sm": 12}, children=dmc.Stack(align="center", children=[
dmc.Text("Interactive Joystick", fw=500),
dg.DashRCJoystick(
id='my-joystick-docs',
directionCountMode='Nine', # Default to Nine for demo
baseRadius=75,
controllerRadius=35,
style={'marginTop': '20px'} # Add some space
),
])),
# Right side: Displaying Joystick State & Controls
dmc.GridCol(span={"md": 7, "sm": 12}, children=dmc.Stack([
dmc.Text("Joystick State", fw=500),
dmc.Text(id='joystick-output-direction-docs', size="sm"),
dmc.Text(id='joystick-output-angle-docs', size="sm"),
dmc.Text(id='joystick-output-distance-docs', size="sm"),
dmc.Divider(my="md"),
dmc.RadioGroup(
[dmc.Radio(label, value=value) for label, value in
[('5 Directions', 'Five'), ('9 Directions', 'Nine')]],
id='direction-mode-selector-docs',
value='Nine', # Initial value matches component
label="Direction Mode",
size="sm",
mb="md",
),
dmc.Text("Base Radius:", size="sm", fw=500),
dmc.Slider(
id='base-radius-slider-docs', min=50, max=150, step=5, value=75,
marks=[{"value": i, "label": str(i)} for i in range(50, 151, 25)],
mb="md"
),
dmc.Text("Controller Radius:", size="sm", fw=500),
dmc.Slider(
id='controller-radius-slider-docs', min=20, max=70, step=5, value=35,
marks=[{"value": i, "label": str(i)} for i in range(20, 71, 10)],
mb="md"
),
]))
])
], fluid=True)
# Callback to display joystick state changes
@callback(
Output('joystick-output-direction-docs', 'children'),
Output('joystick-output-angle-docs', 'children'),
Output('joystick-output-distance-docs', 'children'),
Input('my-joystick-docs', 'direction'),
Input('my-joystick-docs', 'angle'),
Input('my-joystick-docs', 'distance')
)
def update_joystick_output_docs(direction, angle, distance):
angle_str = f"Angle: {angle:.1f}°" if angle is not None else "Angle: N/A (Center)"
distance_str = f"Distance: {distance:.2f}" if distance is not None else "Distance: N/A"
direction_str = f"Direction: {direction}" if direction is not None else "Direction: N/A"
return direction_str, angle_str, distance_str
# Callback to update joystick configuration from controls
@callback(
Output('my-joystick-docs', 'directionCountMode'),
Output('my-joystick-docs', 'baseRadius'),
Output('my-joystick-docs', 'controllerRadius'),
Input('direction-mode-selector-docs', 'value'),
Input('base-radius-slider-docs', 'value'),
Input('controller-radius-slider-docs', 'value'),
)
def update_joystick_config_docs(direction_mode, base_radius, controller_radius):
return direction_mode, base_radius, controller_radius
DashRCJoystick Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | - | Component ID for Dash callbacks. |
baseRadius | number | 75 | Radius of the joystick's static base circle. |
controllerRadius | number | 35 | Radius of the movable controller knob. |
directionCountMode | string | 'Five' | Determines the reported directions. Choices: 'Five' (Center, Top, Bottom, Left, Right), 'Nine' (includes diagonals). |
insideMode | boolean | false | If true, the controller knob stays within the base radius. |
throttle | number | 0 | Throttle time in milliseconds for onChange events. 0 means no throttle. |
className | string | '' | CSS class name for the container. |
style | object | {} | Inline CSS styles for the container. |
controllerClassName | string | undefined | Additional CSS class for the controller knob. |
| Read-only Props | (These props are updated by the component and read in callbacks) | ||
angle | number | undefined | [Readonly] Current angle of the joystick (degrees). undefined when centered. |
direction | string | 'Center' | [Readonly] Current direction string (e.g., 'Top', 'BottomLeft', 'Center'). Possible values depend on directionCountMode. |
distance | number | 0 | [Readonly] Current distance of the controller from the center (normalized 0-1 based on baseRadius). |
setProps | func | - | Dash-assigned callback function. |
Note: See usage_rc_joystick.py for an example controlling the joystick's appearance and reading its state.