MDK Logo

Charts

Chart cards on the dashboard — line, timeline, and multi-series visualisations for mining operations

Chart components specialised for Bitcoin mining operations data visualisation, including hashrate trends, power consumption, power mode timelines, and multi-container comparisons.

Prerequisites

ChartWrapper

Wrapper component for charts with built-in loading and empty state handling.

Import

import { ChartWrapper } from '@mdk/foundation'

Props

PropTypeDefaultDescription
childrenReactNodenoneChart content to render
dataRecord<string, unknown> | unknown[]noneChart data object (for LineChart with datasets)
datasetRecord<string, unknown> | unknown[]noneChart dataset (for BarChart with direct dataset)
isLoadingbooleanfalseLoading state
customLoaderReactNode<Loader />Custom loader component
showNoDataPlaceholderbooleantrueShow "no data" placeholder when empty
customNoDataMessagestring | ReactNodenoneCustom empty state message
minHeightnumber400Minimum height in pixels
loadingMinHeightnumberminHeightMinimum height for loading skeleton
classNamestringnoneAdditional CSS class

Basic usage

<ChartWrapper
  data={chartData}
  isLoading={isLoading}
  minHeight={400}
>
  <LineChart data={chartData} />
</ChartWrapper>

With custom loader

<ChartWrapper
  data={chartData}
  isLoading={isLoading}
  customLoader={<CustomSpinner />}
  minHeight={300}
>
  <BarChart data={chartData} />
</ChartWrapper>

With custom empty message

<ChartWrapper
  dataset={barData}
  isLoading={false}
  customNoDataMessage="No hashrate data available for this period"
  minHeight={300}
>
  <BarChart data={barData} />
</ChartWrapper>

States

The component handles three states automatically:

  1. Loading: Shows skeleton loader (or custom loader)
  2. No data: Shows empty state placeholder
  3. Has data: Shows chart content

Styling

  • .mdk-chart-wrapper: Root element
  • .mdk-chart-wrapper__content: Chart content container
  • .mdk-chart-wrapper__content--hidden: Hidden content state
  • .mdk-chart-wrapper__empty: Empty state container
  • .mdk-chart-wrapper__loading: Loading state container

ConsumptionLineChart

Power consumption trend chart built on LineChartCard.

Import

import { ConsumptionLineChart } from '@mdk/foundation'

Props

PropTypeDefaultDescription
dataTailLogEntry[][]Consumption log entries
tagstring't-miner'Data tag filter
isDetailedbooleannoneShow detail legends
skipMinMaxAvgbooleanfalseSkip min/max/avg display
powerAttributestringnonePower attribute key
labelstringnoneDataset label
isOneMinEnabledbooleannoneEnable 1-minute option
totalTransformerConsumptionbooleannoneUse transformer total
rawConsumptionWnumber | stringnoneRaw consumption value
timelineOptionsTimelineOption[]noneTimeline options
timelinestringnoneCurrent timeline
defaultTimelinestringnoneDefault timeline
onTimelineChange(timeline: string) => voidnoneTimeline change handler

Basic usage

<ConsumptionLineChart
  data={consumptionLogs}
  timelineOptions={timelineOptions}
  defaultTimeline="5m"
  onTimelineChange={setTimeline}
/>

ContainerCharts

Container-level chart dashboard with combination selector and multiple chart types.

Import

import { ContainerCharts } from '@mdk/foundation'

Props

PropTypeDefaultDescription
featureEnabledbooleantrueEnable feature gate
disabledMessagestring'Container Charts feature is not enabled'Disabled state message
combinations{ value: string; label: string }[]requiredContainer combination options
isLoadingCombinationsbooleanfalseLoading combinations
titlestring'Container Charts'Section heading
selectedCombinationstring | nullnoneControlled selection
defaultSelectedCombinationstring | nullnullDefault selection
onSelectedCombinationChange(value: string | null) => voidnoneSelection change handler
chartRawDataChartEntry[]nullRaw chart data
isLoadingChartsbooleanfalseLoading charts
getDatasetBorderColorfunctionnoneCustom dataset colors

Basic usage

<ContainerCharts
  combinations={[
    { value: 'bitdeer_a1', label: 'Bitdeer A1' },
    { value: 'bitmain_hydro_b2', label: 'Bitmain Hydro B2' },
  ]}
  chartRawData={chartData}
  onSelectedCombinationChange={setSelected}
/>

Container type charts

Charts displayed vary by container type:

  • Bitdeer: Liquid Temp H, Liquid Temp L, Oil Temp, Pressure
  • Bitmain Hydro: Liquid Temp L, Pressure
  • Bitmain Immersion: Liquid Temp L, Oil Temp
  • MicroBT: Liquid Temp L, Pressure

Styling

  • .mdk-container-charts: Root element
  • .mdk-container-charts__title: Section title
  • .mdk-container-charts__select-row: Combination selector row
  • .mdk-container-charts__select-label: Selector label
  • .mdk-container-charts__select: Select dropdown
  • .mdk-container-charts__layout: Charts grid layout
  • .mdk-container-charts__chart-block: Individual chart container
  • .mdk-container-charts__chart-title: Chart block title
  • .mdk-container-charts__loading: Loading state container

HashRateLineChartSelector

Hashrate over time visualization with timeline selector and real-time data support. Switches between a plain hashrate layout and a pool-overlay layout based on hasF2PoolLine.

All props are optional.

Import

import { HashRateLineChartSelector } from '@mdk/foundation'

Behaviour

HashRateLineChartSelector renders one of two layouts based on hasF2PoolLine:

  • hasF2PoolLine={false} (default) — a single hashrate line driven by data and realtimeHashrateData, with timeline range selector and a highlighted current-value readout.
  • hasF2PoolLine={true} — a multi-series chart that overlays the miner's hashrate against per-pool breakdowns, driven by minerTailLogData and minerPoolDataRaw.

Pass the props for the layout you want; props for the other layout have no effect.

Layout

PropTypeDefaultDescription
hasF2PoolLinebooleanfalseSelects the plain (false) or pool-overlay (true) layout

Plain-layout props

Used when hasF2PoolLine is false.

PropTypeDefaultDescription
dataHashRateLogEntry[][]Historical hashrate series rendered as the primary line
realtimeHashrateDataHashRateLogEntrynoneLatest real-time sample merged into the series
fixedTimezonestringnoneFixed display timezone for chart axes
heightnumbernoneChart height in pixels
loadingbooleannoneShows the chart's loading state

Pool-overlay-layout props

Used when hasF2PoolLine is true.

PropTypeDefaultDescription
minerTailLogDataHashRateLogEntry[] | HashRateLogEntry[][][]Hashrate samples for the miner; a flat array or an array of arrays
isMinerTailLogLoadingbooleanfalseInitial-load state for the miner hashrate series
isMinerTailLogFetchingbooleanfalseBackground-refresh indicator for the miner hashrate series
minerPoolDataRawMinerPoolDataItem[][]Per-pool hashrate samples overlaid on the miner line
isMinerpoolInitialLoadingbooleanfalseInitial-load state for the pool series

Shared props

PropTypeDefaultDescription
isOneMinEnabledbooleannoneAdds a 1m option to the timeline range selector in both layouts

HashRateLogEntry type

type HashRateLogEntry = {
  ts: number
  hashrate_mhs_1m_sum_aggr?: number
  [key: string]: unknown
}

MinerPoolDataItem type

type PoolStat = {
  poolType: string
  hashrate: number
}

type MinerPoolDataItem = {
  stats: PoolStat[]
  ts: number | string
}

Basic usage

<HashRateLineChartSelector
  data={hashrateHistory}
  realtimeHashrateData={currentHashrate}
  isOneMinEnabled
  height={400}
  loading={isLoading}
/>

With fixed timezone

<HashRateLineChartSelector
  data={hashrateHistory}
  fixedTimezone="America/New_York"
  height={400}
  loading={false}
/>

With pool overlay

<HashRateLineChartSelector
  hasF2PoolLine
  minerTailLogData={tailLog}
  isMinerTailLogLoading={isInitialLoading}
  isMinerTailLogFetching={isRefetching}
  minerPoolDataRaw={poolSamples}
  isMinerpoolInitialLoading={isPoolInitialLoading}
  isOneMinEnabled
/>

Features

  • Timeline range selector: 5m, 15m, 1h, 6h, 24h, 7d (plus 1m when isOneMinEnabled)
  • Legend toggle: show/hide individual datasets
  • Min/Max/Avg readout derived from the visible series
  • Highlighted current-value readout (plain layout)
  • Pool-type breakdown overlay (pool-overlay layout)

Styling

Built on ChartContainer and LineChart from @mdk/core. The pool-overlay layout adds a .mdk-hash-rate-line-chart-with-pool root wrapper. See core chart styling for customisation options.

LineChartCard

Composable card with timeline selector, legend, line chart, and stats footer.

Import

import { LineChartCard } from '@mdk/foundation'

Props

PropTypeDefaultDescription
dataLineChartCardDatanoneProcessed chart data
rawDataunknownnoneRaw data to be processed by adapter
dataAdapter(raw: unknown) => LineChartCardDatanoneAdapter function for raw data
titlestringnoneChart title
timelineOptionsTimelineOption[]noneAvailable timeline ranges
timelinestringnoneControlled timeline value
defaultTimelinestring'5m'Default timeline selection
onTimelineChange(timeline: string) => voidnoneTimeline change handler
detailLegendsbooleanfalseShow detailed legends
isLoadingbooleanfalseLoading state
shouldResetZoombooleantrueReset zoom on timeline change
minHeightnumber350Minimum chart height
classNamestringnoneAdditional CSS class

Basic usage

<LineChartCard
  title="Temperature"
  data={chartData}
  timelineOptions={[
    { label: '5m', value: '5m' },
    { label: '1h', value: '1h' },
    { label: '24h', value: '24h' },
  ]}
  defaultTimeline="1h"
/>

With data adapter

<LineChartCard
  title="Power Consumption"
  rawData={rawStats}
  dataAdapter={(raw) => processStatsToChartData(raw)}
  timelineOptions={timelineOptions}
  defaultTimeline="24h"
  isLoading={isLoading}
/>

Styling

  • .mdk-line-chart-card: Root element
  • .mdk-line-chart-card__legends: Detail legends container

PowerModeTimelineChart

Visualizes power mode changes over time using TimelineChart.

Import

import { PowerModeTimelineChart } from '@mdk/foundation'

Props

PropTypeDefaultDescription
dataPowerModeTimelineEntry[][]Historical power mode data
dataUpdatesPowerModeTimelineEntry[][]Real-time updates
isLoadingbooleanfalseLoading state
timezonestring'UTC'Display timezone
titlestring'Power Mode Timeline'Chart title

Basic usage

<PowerModeTimelineChart
  data={powerModeHistory}
  timezone="America/New_York"
  isLoading={isLoading}
/>

With real-time updates

<PowerModeTimelineChart
  data={powerModeHistory}
  dataUpdates={realtimeUpdates}
  timezone={userTimezone}
/>

TimelineChart

Horizontal timeline visualization for time-based events like power mode changes.

Import

import { TimelineChart } from '@mdk/foundation'

Props

PropTypeDefaultDescription
initialDataTimelineChartDatarequiredInitial chart data
newDataTimelineChartDatanoneNew data to merge
skipUpdatesbooleanfalseSkip merging new data
range[number, number]noneTime range bounds
axisTitleText{ x: string; y: string }{ x: 'Time', y: '' }Axis titles
isLoadingbooleanfalseLoading state
titlestringnoneChart title
heightnumber | stringnoneChart height

TimelineChartData type

type TimelineChartData = {
  labels: string[]
  datasets: {
    label: string
    data: { x: number; y: number }[]
    color?: string
  }[]
}

Basic usage

<TimelineChart
  initialData={{
    labels: ['Normal', 'Low Power', 'High Power'],
    datasets: [
      { label: 'Miner 1', data: [...], color: 'blue' },
    ],
  }}
  axisTitleText={{ x: 'Time', y: 'Power Mode' }}
  title="Power Mode Changes"
/>

Styling

  • .mdk-timeline-chart: Root element
  • .mdk-timeline-chart__loading: Loading container

WidgetTopRow

Dashboard header row displaying title, power consumption, and alarm indicators.

Import

import { WidgetTopRow } from '@mdk/foundation'

Props

PropTypeDefaultDescription
titlestringrequiredWidget title
powernumbernonePower consumption value
unitstringnonePower unit (e.g., "kW")
statsErrorMessagestring | ErrorWithTimestamp[]noneError message to display
alarmsAlarmsMapnoneMap of alarm types to alarm items
classNamestringnoneAdditional CSS class

Basic usage

<WidgetTopRow
  title="Container A1"
  power={125000}
  unit="kW"
/>

With alarms

<WidgetTopRow
  title="Container A1"
  power={125000}
  unit="kW"
  alarms={{
    temperature: [{ title: 'High temp', value: 85 }],
    pressure: [{ title: 'Low pressure', value: 0.8 }],
  }}
/>

Styling

  • .mdk-widget-top-row: Root element
  • .mdk-widget-top-row__inner: Inner container
  • .mdk-widget-top-row__title: Title text
  • .mdk-widget-top-row__power: Power display

On this page