Chart composition
Chart layout chrome, legends, stats rows, and configuration utilities
Compose chart types from Chart components with wrappers and helpers. ChartContainer adds title, loading, and empty states; ChartStatsFooter and DetailLegend add summary rows and rich legends (for example LineChartCard).
Prerequisites
Components
| Component | Description |
|---|---|
ChartContainer | Wrapper for charts with title and loading states |
ChartStatsFooter | Statistics row displayed below charts |
DetailLegend | Chart legend with detailed value display |
ChartContainer
Wrapper for charts with loading and empty states.
Import
import { ChartContainer } from '@tetherto/mdk-react-devkit/core'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
children | Required | ReactNode | none | Chart body (for example a BarChart or LineChart) |
title | Optional | string | none | Title text |
header | Optional | ReactNode | none | Custom header node |
legendData | Optional | LegendItem[] | none | Legend entries rendered in the container chrome |
highlightedValue | Optional | object | none | Highlighted metric (value, optional unit, className, style); highlight chrome renders only when this prop is set and the chart body is visible (not loading / not empty) |
rangeSelector | Optional | object | none | Range selector props (options, value, onChange, optional className, style, buttonClassName) |
loading | Optional | boolean | none | When true, shows a centered Loader overlay over the chart area |
empty | Optional | boolean | none | When true, shows empty state |
emptyMessage | Optional | string | 'No data available' | Copy shown in the empty overlay when empty is true and loading is not true |
minMaxAvg | Optional | object | none | Min / max / avg strings for the summary row |
timeRange | Optional | string | none | Time range label |
footer | Optional | ReactNode | none | Footer slot |
footerClassName | Optional | string | none | Class name on the footer wrapper |
onToggleDataset | Optional | function | none | Called with dataset index when legend toggles visibility |
className | Optional | string | none | Root class name from the host app |
Basic usage
<ChartContainer loading={isLoading} empty={data.length === 0}>
<BarChart data={data} />
</ChartContainer>ChartStatsFooter
Displays statistics below charts.
Import
import { ChartStatsFooter } from '@tetherto/mdk-react-devkit/core'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
minMaxAvg | Optional | object | none | Min, max, and average strings shown in the primary row when provided |
stats | Optional | ChartStatsFooterItem[] | none | Additional stat rows (label, value) in a columnar grid |
statsPerColumn | Optional | number | 1 | Number of stat items per column when stats is set |
secondaryLabel | Optional | object | none | Secondary block with title and value when provided |
className | Optional | string | none | Root class name from the host app |
The component renders nothing when minMaxAvg, stats, and secondaryLabel are all absent or empty.
Basic usage
<ChartStatsFooter
stats={[
{ label: 'Min', value: '120 TH/s' },
{ label: 'Max', value: '180 TH/s' },
{ label: 'Avg', value: '150 TH/s' },
]}
/>DetailLegend
Detailed chart legend with values.
Import
import { DetailLegend } from '@tetherto/mdk-react-devkit/core'Props
| Prop | Status | Type | Default | Description |
|---|---|---|---|---|
items | Required | DetailLegendItem[] | none | Legend rows (label, color, optional icon, currentValue, percentChange, hidden) |
onToggle | Optional | function | none | Called with label and index when a row is toggled |
className | Optional | string | none | Root class name from the host app |
Basic usage
<DetailLegend
items={[
{ label: 'Online', color: '#72F59E', currentValue: { value: 85, unit: '%' } },
{ label: 'Offline', color: '#FF6B6B', currentValue: { value: 15, unit: '%' } },
]}
/>Chart utilities
Pure functions for building Chart.js data and options. Import from the package root alongside components.
import {
defaultChartOptions,
defaultChartColors,
buildBarChartData,
buildBarChartOptions,
buildChartTooltip,
computeStats,
} from '@tetherto/mdk-react-devkit/core'| Export | Role |
|---|---|
defaultChartOptions | Shared Chart.js defaults used by MDK chart components |
defaultChartColors | Default dataset color palette |
buildBarChartData | Map MDK bar input into Chart.js data |
buildBarChartOptions | Build bar chart options (stacking, axes, formatters) |
buildChartTooltip | HTML tooltip config for Chart.js |
computeStats | Min, max, and average for a numeric array |
Types BarChartInput, BarChartSeries, BarChartLine, and BarChartConstant are exported from the same package for hook-shaped bar data.
Hook-shaped bar data
App and reporting hooks often return declarative bar input instead of Chart.js data. buildBarChartData converts that shape
into { labels, datasets } for BarChart. The pipeline:
- Input (
BarChartInput): optionallabels, requiredseries, optionallinesandconstantsfor mixed bar/line overlays. - Build (
buildBarChartData): returns Chart.jsdatawith MDK gradient styling and layout defaults (barWidth,categoryPercentage,barPercentageare optional on the input). - Data labels (optional): per-series overrides on the input (
formatter,anchor,align,offset,font,padding,display,clamp,clip) map to each built dataset’s Chart.jsdatalabelsby series index. - Render (
<BarChart data={...} />): pass the built object to the component; pair withbuildBarChartOptionswhen you need stacking, axes, or formatters.
BarChartInput shape
| Field | Type | Description |
|---|---|---|
labels | string[] | Optional category labels; omitted labels are derived from series values keys or indices |
series | BarChartSeries[] | Bar datasets (label, values, optional color, stack, gradient, bar layout props) |
lines | BarChartLine[] | Optional line overlays on the same chart |
constants | BarChartConstant[] | Optional horizontal reference lines |
Each BarChartSeries uses values as either number[] (positional) or Record<string, number> (keyed by category label).
Example
Hook output to BarChart example:
import {
BarChart,
buildBarChartData,
ChartContainer,
} from '@tetherto/mdk-react-devkit/core'
// Typical shape returned by app/reporting data hooks
const hookOutput = {
labels: ['Q1', 'Q2', 'Q3'],
series: [
{
label: 'Revenue',
values: [4.2, 3.8, 5.1],
color: '#72F59E',
dataLabels: {
formatter: (v: number) => `${v.toFixed(1)}M`,
anchor: 'end',
align: 'top',
},
},
{
label: 'OpEx',
values: [1.8, 2.0, 1.6],
color: '#FFD700',
},
],
}
const cleanSeries = hookOutput.series.map(({ dataLabels: _dl, ...s }) => s)
const base = buildBarChartData({ labels: hookOutput.labels, series: cleanSeries })
const chartData = {
labels: base.labels,
datasets: base.datasets.map((dataset, i) => {
const overrides = hookOutput.series[i]?.dataLabels
return overrides ? { ...dataset, datalabels: overrides } : dataset
}),
}
const isEmpty =
!hookOutput.series.length ||
hookOutput.series.every((s) => {
const vals = Array.isArray(s.values) ? s.values : Object.values(s.values)
return !vals.length || vals.every((v) => v === 0)
})
<ChartContainer title="Quarterly" empty={isEmpty}>
<BarChart data={chartData} />
</ChartContainer>Empty and all-zero series
Treat bar data as empty when any of the following is true:
seriesis missing or has length0- Every series has empty
values(array or record) - Every numeric value across all series is
0
Prefer ChartContainer empty or a placeholder instead of rendering a flat chart. After building Chart.js data, you can also
use useChartDataCheck from @tetherto/mdk-react-devkit/foundation
with { data: chartData }.