MDK Logo

Chart components

Data visualization components for mining metrics

Chart components for visualizing time-series data, metrics, and statistics. Built on Chart.js and Lightweight Charts, supporting:

  • Chart types: components that render datasets (AreaChart, BarChart, DoughnutChart, GaugeChart, LineChart)
  • Domain chart wrappers: opinionated chart components with preset layouts and series config (AverageDowntimeChart, ThresholdLineChart, OperationsEnergyCostChart)
  • Composition elements: layout chrome, legends, stats rows, and chart utilities (ChartContainer, ChartStatsFooter, DetailLegend, helpers)

Prerequisites

All chart type components

ComponentDescription
LineChartTime-series or trend visualization
BarChartVertical/horizontal bar chart for comparisons
AreaChartFilled line chart for volume/cumulative data
DoughnutChartCircular chart for part-to-whole relationships
GaugeChartPresentational arc gauge for normalized percentages
AverageDowntimeChartStacked bar chart for curtailment and operational downtime rates
ThresholdLineChartLine chart with configurable horizontal threshold bands
OperationsEnergyCostChartDoughnut chart comparing operational and energy costs

AreaChart

Filled area chart for cumulative or range data.

Presentational Chart.js area chart (line series with fill). Data and options follow the same Chart.js model as LineChart, without a separate MDK data wrapper type.

Import

import { AreaChart } from '@tetherto/mdk-react-devkit/core'

Props

PropStatusTypeDefaultDescription
dataRequiredChartDatanoneChart.js line chart data (datasets typically use fill: true for an area look)
optionsOptionalChartOptionsnoneChart.js options (merged with defaults)
tooltipOptionalChartTooltipConfignoneCustom HTML tooltip config; when set, replaces the default Chart.js tooltip
heightOptionalnumber300Chart height in pixels
classNameOptionalstringnoneRoot class name from the host app

Basic usage

const data = {
  labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
  datasets: [
    {
      label: 'Revenue',
      data: [100, 120, 115, 134, 168],
      fill: true,
      backgroundColor: 'rgba(114, 245, 158, 0.2)',
      borderColor: '#72F59E',
    },
  ],
}

<AreaChart data={data} />

BarChart

Bar/column chart with gradient fills, stacking, and data labels. Built on Chart.js.

The BarChart component renders Chart.js bar or column series. It manages:

  1. Data (data): labels and datasets passed to Chart.js.
  2. Chart options (options): merged with MDK defaults.
  3. Formatting (formatYLabel, formatDataLabel, tooltip): axis labels, data labels, and HTML tooltips.
  4. Presentation (isStacked, isHorizontal, showLegend, legendPosition, legendAlign, showDataLabels): layout and legend.
  5. Size (height): chart height in pixels.

Import

import { BarChart } from '@tetherto/mdk-react-devkit/core'

Props

PropStatusTypeDefaultDescription
dataRequiredChartDatanoneChart.js data object
optionsOptionalChartOptionsnoneChart.js options (merged with defaults)
formatYLabelOptionalfunctionnoneFormat Y-axis tick labels
formatDataLabelOptionalfunctionnoneFormat data label values
tooltipOptionalChartTooltipConfignoneCustom HTML tooltip config
isStackedOptionalbooleanfalseStack bars on top of each other
isHorizontalOptionalbooleanfalseRender bars horizontally
showLegendOptionalbooleantrueShow Chart.js legend
legendPositionOptional'top' | 'right' | 'bottom' | 'left''top'Legend position
legendAlignOptional'start' | 'center' | 'end''start'Legend alignment
showDataLabelsOptionalbooleanfalseShow values above bars
heightOptionalnumber300Chart height in pixels

Basic usage

const data = {
  labels: ['Jan', 'Feb', 'Mar', 'Apr'],
  datasets: [
    {
      label: 'Hashrate (TH/s)',
      data: [120, 150, 180, 200],
      backgroundColor: '#72F59E',
    },
  ],
}

<BarChart data={data} height={300} />

Data from hooks

Hand-built Chart.js data (above) is valid. When app hooks return { labels, series } declarative input, convert with buildBarChartData in chart utilities, optionally merge per-series datalabels, then pass the result to data.

Stacked bar chart

const data = {
  labels: ['Site A', 'Site B', 'Site C'],
  datasets: [
    { label: 'Online', data: [100, 80, 120], backgroundColor: '#72F59E' },
    { label: 'Offline', data: [10, 20, 5], backgroundColor: '#FF6B6B' },
  ],
}

<BarChart data={data} isStacked />

Horizontal bar chart

<BarChart
  data={data}
  isHorizontal
  formatYLabel={(value) => `${value} TH/s`}
/>

With data labels

<BarChart
  data={data}
  showDataLabels
  formatDataLabel={(value) => `${value.toFixed(1)}%`}
/>

DoughnutChart

Doughnut/pie chart for proportional data.

Import

import { DoughnutChart } from '@tetherto/mdk-react-devkit/core'

Props

PropStatusTypeDefaultDescription
dataRequiredDoughnutChartDataset[]noneArray of { label, value, color? } slices (see data shape)
unitOptionalstring''Unit suffix shown in the default tooltip
optionsOptionalChartOptionsnoneChart.js doughnut options (merged with defaults)
cutoutOptionalstring'75%'Inner radius cutout (doughnut ring thickness)
borderWidthOptionalnumber4Border width between segments
heightOptionalnumber260Chart height in pixels
legendPositionOptionalstring'top'Where to place the custom legend relative to the chart
tooltipOptionalChartTooltipConfignoneCustom HTML tooltip; when set, replaces the default doughnut tooltip
classNameOptionalstringnoneRoot class name from the host app

Data shape for doughnut charts

Pass data as an array of { label, value, color? }. The chart maps this into Chart.js internally (labels, single dataset, segment colors). Omit color to use the default palette rotation.

Basic usage

const data = [
  { label: 'Online', value: 85, color: '#72F59E' },
  { label: 'Offline', value: 10, color: '#FF6B6B' },
  { label: 'Maintenance', value: 5, color: '#FFD700' },
]

<DoughnutChart data={data} />

GaugeChart

Speedometer-style presentational arc gauge for displaying a single normalized value, providing:

  1. Percent (percent): fill level from 0 to 1 (values outside that range are clamped).
  2. Arc appearance (colors, arcWidth, nrOfLevels): segment colors, relative thickness, and segment count.
  3. Center label (hideText): percentage text in the center of the gauge (hidden when hideText is true).
  4. Accessibility (id): stable id wired into SVG labels (defaults to mdk-gauge-chart).
  5. Layout (height, maxWidth, className): container height, max width, and host root class.

SVG speedometer-style gauge driven by a 0–1 percent value.

The GaugeChart is SVG-based; strokes and labels may paint past the host element’s layout bounds. For a hard edge, wrap the gauge in an element with overflow: hidden, or add vertical spacing. ChartContainer does not set overflow clipping on the chart slot—it is for title, loading/empty, and footer chrome like other charts (see Composition); it may add spacing that makes overlap less visible, but it is not a substitute for clipping when you need it.

Import

import { GaugeChart } from '@tetherto/mdk-react-devkit/core'

The gauge is driven by a normalized percent in the range 0–1 (for example 0.75 is 75%). It is not a value / max API, and it does not accept label or unit props (see ChartContainer for layout notes).

Props

PropStatusTypeDefaultDescription
percentRequirednumbernoneFill level from 0 to 1 (clamped)
colorsOptionalstring[]green → soft green → red (theme)Arc segment colors as HEX strings
arcWidthOptionalnumber0.2Arc thickness as a fraction of the gauge radius (01)
nrOfLevelsOptionalnumber3Number of colored segments on the arc
hideTextOptionalbooleanfalseHide the percentage text in the center
idOptionalstring'mdk-gauge-chart'Stable id for SVG accessibility labels
heightOptionalnumber | string200Container height (pixels or CSS length, e.g. '50%')
maxWidthOptionalnumber500Maximum width in pixels
classNameOptionalstringnoneRoot class name from the host app

Basic usage

<GaugeChart percent={0.75} />

In a chart card (same shell as other charts)

ChartContainer adds title, loading, and empty chrome; it does not apply overflow: hidden to the chart body. When you still see bleed next to siblings or footers, wrap GaugeChart in an extra element with overflow: hidden.

import { ChartContainer, GaugeChart } from '@tetherto/mdk-react-devkit/core'

<ChartContainer title="Utilization" loading={false} empty={false}>
  <div style={{ overflow: 'hidden' }}>
    <GaugeChart percent={0.75} />
  </div>
</ChartContainer>

Custom colors and arc

<GaugeChart
  percent={0.6}
  colors={['#72F59E', '#FFD700', '#FF6B6B']}
  arcWidth={0.25}
  nrOfLevels={3}
  hideText={false}
  height={220}
/>

LineChart

Time-series line chart built on Lightweight Charts for high-performance rendering.

The LineChart component renders time-series lines. It manages:

  1. Series data (data): LineChartData with millisecond x values (see data shape).
  2. Context (timeline, unit): timeline identifier and unit label for tooltips.
  3. Formatting (yTicksFormatter, priceFormatter, customLabel): tick and tooltip text.
  4. Presentation (backgroundColor, beginAtZero, showPointMarkers, showDateInTooltip, uniformDistribution): axis and marker behavior.
  5. Size (height): chart height in pixels.

Import

import { LineChart } from '@tetherto/mdk-react-devkit/core'

Props

PropStatusTypeDefaultDescription
dataRequiredLineChartDatanoneObject with a datasets array (see data shape)
timelineOptionalstringnoneTimeline identifier
yTicksFormatterOptionalfunctionnoneFormat Y-axis ticks
priceFormatterOptionalfunctionnoneFormat tooltip values
customLabelOptionalstringnoneCustom tooltip label
unitOptionalstring''Unit label for values
backgroundColorOptionalstringnoneChart background color
beginAtZeroOptionalbooleanfalseStart Y-axis at zero
showPointMarkersOptionalbooleanfalseShow data point markers
showDateInTooltipOptionalbooleanfalseShow date in tooltip
uniformDistributionOptionalbooleanfalseUniform time distribution
heightOptionalnumber240Chart height in pixels

Data shape for line charts

LineChartData is { datasets: LineDataset[] }. Each LineDataset has label, borderColor, optional visible / borderWidth / extraTooltipData, and data: { x, y }[] where x is a time value in milliseconds (for example from Date.prototype.valueOf()) and y is the series value (number, or null / undefined for gaps).

Basic usage

const data = {
  datasets: [
    {
      label: 'Hashrate',
      borderColor: '#72F59E',
      data: [
        { x: 1704067200000, y: 150 },
        { x: 1704153600000, y: 155 },
        { x: 1704240000000, y: 160 },
      ],
    },
  ],
}

<LineChart data={data} height={300} unit="TH/s" />

Multiple lines

const hashrateData = [
  { x: 1704067200000, y: 150 },
  { x: 1704153600000, y: 155 },
]
const targetData = [
  { x: 1704067200000, y: 140 },
  { x: 1704153600000, y: 145 },
]

const data = {
  datasets: [
    {
      label: 'Hashrate',
      borderColor: '#72F59E',
      data: hashrateData,
    },
    {
      label: 'Target',
      borderColor: '#FFD700',
      data: targetData,
    },
  ],
}

<LineChart data={data} showPointMarkers beginAtZero />

AverageDowntimeChart

Opinionated stacked bar chart wrapping ChartContainer and BarChart with domain-specific downtime series and a rate formatter.

Stacked bar chart showing monthly average downtime broken into Curtailment and Op. Issues series. Wraps ChartContainer and BarChart. It manages:

  1. Data (data): period labels and per-series rate arrays (values are fractions 0–1).
  2. Formatting (yTicksFormatter): formats Y-axis ticks, tooltips, and optional bar data labels.
  3. Presentation (showDataLabels, title, unit): bar data labels and header text.
  4. Layout (height, barWidth): chart height and bar width in pixels.
  5. State (isLoading, emptyMessage): loading overlay and empty-state copy.

Import

import { AverageDowntimeChart } from '@tetherto/mdk-react-devkit/core'

Props

PropStatusTypeDefaultDescription
dataOptionalAverageDowntimeChartDatanonePeriod labels and downtime rate arrays (see data shape)
yTicksFormatterOptionalfunctiondefaultAverageDowntimeRateFormatterFormats Y-axis ticks, tooltips, and data labels; input values are 0–1 rates
showDataLabelsOptionalbooleanfalseShow formatted rate values above each bar segment
titleOptionalstring'Monthly Average Downtime'Header title
unitOptionalstring'%'Unit label shown beneath the title
heightOptionalnumber280Chart height in pixels
barWidthOptionalnumber38Bar width in pixels
isLoadingOptionalbooleanfalseWhen true, shows a loading overlay
emptyMessageOptionalstring'No data available'Copy shown in the empty state
classNameOptionalstringnoneRoot class name from the host app

Data shape for AverageDowntimeChart

Pass data as an AverageDowntimeChartData object:

FieldTypeDescription
labelsstring[]Period labels (e.g. month names)
curtailmentnumber[]Curtailment downtime rates (0–1) per period
operationalIssuesnumber[]Operational issue downtime rates (0–1) per period

Both series arrays are optional; absent series are omitted from the chart.

Basic usage

import { AverageDowntimeChart } from '@tetherto/mdk-react-devkit/core'

<AverageDowntimeChart
  data={{
    labels: ['Jan', 'Feb', 'Mar'],
    curtailment: [0.02, 0.01, 0.03],
    operationalIssues: [0.05, 0.04, 0.06],
  }}
/>

Custom formatter

yTicksFormatter receives raw 0–1 rate values and must return a display string. The default (defaultAverageDowntimeRateFormatter) multiplies by 100 and appends %:

import {
  AverageDowntimeChart,
  defaultAverageDowntimeRateFormatter,
} from '@tetherto/mdk-react-devkit/core'

// Override: show one decimal place
<AverageDowntimeChart
  data={data}
  yTicksFormatter={(rate) => `${(rate * 100).toFixed(1)}%`}
  showDataLabels
/>

Exported helpers

ExportRole
buildAverageDowntimeBarChartDataConverts AverageDowntimeChartData into Chart.js data
buildAverageDowntimeTooltipBuilds the HTML tooltip config for the stacked bars
defaultAverageDowntimeRateFormatterDefault Y-axis / label formatter (rate × 100, % suffix)
hasAverageDowntimeDataReturns true when data has at least one non-empty series

ThresholdLineChart

Time-series line chart wrapping ChartContainer and LineChart, with support for optional horizontal threshold reference lines and interactive legend toggles.

Time-series line chart with optional horizontal threshold bands. Wraps ChartContainer and LineChart. It manages:

  1. Data (data): one or more line series plus optional threshold lines.
  2. Formatting (yTicksFormatter): formats Y-axis ticks.
  3. Presentation (title, unit, isTall, isLegendVisible): header, height variant, and legend toggle.
  4. Layout (height): explicit chart height in pixels (overrides isTall).
  5. State (emptyMessage): empty-state copy.

Import

import { ThresholdLineChart } from '@tetherto/mdk-react-devkit/core'

Props

PropStatusTypeDefaultDescription
dataOptionalThresholdLineChartDatanoneSeries and optional thresholds (see data shape)
yTicksFormatterOptionalfunctionunit-aware defaultFormats Y-axis tick labels; defaults to "${value} ${unit}" when unit is set, otherwise String(value)
titleOptionalstringnoneHeader title; rendered as "${title} (${unit})" when both are set
unitOptionalstringnoneUnit appended to the title and used by the default tick formatter
isTallOptionalbooleanfalseWhen true, uses a taller default height of 360px instead of 280px
isLegendVisibleOptionalbooleantrueShow the interactive legend with dataset visibility toggles
heightOptionalnumber280 (360 when isTall)Chart height in pixels; explicit value overrides isTall
emptyMessageOptionalstring'No data available'Copy shown in the empty state
classNameOptionalstringnoneRoot class name from the host app

Data shape for ThresholdLineChart

ThresholdLineChartData holds series and optional threshold lines:

FieldTypeDescription
seriesThresholdLineChartSeries[]Line series to render
thresholdsThresholdLineChartThreshold[]Optional horizontal reference lines

Each ThresholdLineChartSeries:

FieldTypeDescription
labelstringSeries label shown in the legend
pointsThresholdLineChartPoint[]Data points ({ timestamp: string | number, value: number })
colorstringOptional line color
fillbooleanOptional area fill below the line

Each ThresholdLineChartThreshold:

FieldTypeDescription
labelstringLabel shown in the legend
valuenumberY-axis value at which the horizontal line is drawn
colorstringOptional line color

Basic usage

import { ThresholdLineChart } from '@tetherto/mdk-react-devkit/core'

<ThresholdLineChart
  title="Power Consumption"
  unit="MW"
  data={{
    series: [
      {
        label: 'Actual',
        color: '#72F59E',
        points: [
          { timestamp: '2025-01-01', value: 32 },
          { timestamp: '2025-01-02', value: 35 },
          { timestamp: '2025-01-03', value: 29 },
        ],
      },
    ],
    thresholds: [
      { label: 'Capacity limit', value: 38, color: '#FF6B6B' },
    ],
  }}
/>

Tall variant

<ThresholdLineChart
  title="Hashrate"
  unit="TH/s"
  isTall
  data={data}
/>

Exported helpers

ExportRole
toThresholdLineChartDataConverts ThresholdLineChartData into LineChartData for the underlying LineChart
hasNonZeroDataReturns true when data contains at least one series with a non-zero value

OperationsEnergyCostChart

Doughnut chart wrapping ChartContainer and DoughnutChart for operations vs energy cost breakdown in USD per MWh.

Doughnut chart comparing operational costs against energy costs in USD per MWh. Wraps ChartContainer and DoughnutChart. It manages:

  1. Data (data): operational and energy cost values in USD.
  2. Presentation (title, unit): header text and unit label.
  3. Layout (height): chart height in pixels.
  4. State (isLoading, emptyMessage): loading overlay and empty-state copy.

Import

import { OperationsEnergyCostChart } from '@tetherto/mdk-react-devkit/core'

Props

PropStatusTypeDefaultDescription
dataOptionalOperationsEnergyCostChartDatanoneCost values in USD (see data shape)
titleOptionalstring'Operations vs Energy Cost'Header title
unitOptionalstring'$/MWh'Unit label shown beneath the title
heightOptionalnumber200Chart height in pixels
isLoadingOptionalbooleanfalseWhen true, shows a loading overlay
emptyMessageOptionalstring'No data available'Copy shown in the empty state
classNameOptionalstringnoneRoot class name from the host app

Data shape for OperationsEnergyCostChart

OperationsEnergyCostChartData has two optional numeric fields:

FieldTypeDescription
operationalCostsUSDnumberOperational costs in USD
energyCostsUSDnumberEnergy costs in USD

Both fields are optional. Slices with a zero or absent value are omitted from the doughnut.

Basic usage

import { OperationsEnergyCostChart } from '@tetherto/mdk-react-devkit/core'

<OperationsEnergyCostChart
  data={{
    operationalCostsUSD: 1200,
    energyCostsUSD: 4800,
  }}
/>

Exported helpers

ExportRole
buildOperationsEnergyCostSlicesConverts OperationsEnergyCostChartData into DoughnutChartDataset[] slices, omitting zero-value entries
buildOperationsEnergyCostTooltipBuilds the HTML tooltip config with two-decimal formatting
hasOperationsEnergyCostDataReturns true when at least one cost field is a positive number

On this page