Miner metrics components
Activity, stat cards, and aggregated metric displays for the miner details view
Components that render miner telemetry: fleet-wide activity rollups, single-value stat cards, and the combined miner metric layout used by the details view.
For miner identity (MinerInfoCard), see the Miner details overview. For per-chip thermal data, see Chips.
Prerequisites
-
Complete the @mdk/foundation installation and add the dependency
-
Components on this page read live metrics from
device.last.snap.statson aDevice
Components
| Component | Description |
|---|---|
MinersActivityChart | Miner uptime and activity visualization |
SingleStatCard | Single metric display card |
SecondaryStatCard | Secondary metric with comparison |
StatsGroupCard | Grouped statistics display |
MinerMetricCard | Primary and secondary miner stats card |
MinersActivityChart
Displays miner activity status with color-coded indicators for online, offline, warning states.
Import
import { MinersActivityChart } from '@mdk/foundation'Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | MinersActivityData | {} | Counts keyed by status name |
large | boolean | false | Switch to large indicator and label sizing |
isLoading | boolean | false | Render a spinner instead of the chart |
isError | boolean | false | Render CoreAlert instead of the chart (unless isDemoMode) |
error | { data?: { message?: string } } | null | null | Message surfaced inside the error alert |
showLabel | boolean | true | Show the per-status text label under each indicator |
isDemoMode | boolean | false | Render zeros on error rather than the alert (for demos) |
MinersActivityData is an open record. The component renders one indicator per status key it knows about; unknown keys are ignored.
Statuses rendered
The chart fixes the order and color of each indicator:
- Offline: gray
- Error: red, with a tooltip noting that minor errors not affecting hash rate are excluded
- Sleep: power mode
- Low: yellow, low power mode
- Normal: green, normal power mode
- High: purple, high power mode
- Empty: socket with no miner connected (rendered as
emptylabel)
Basic usage
<MinersActivityChart
data={{
total: 100,
offline: 4,
error: 1,
low: 8,
normal: 80,
high: 7,
}}
/>Loading and error states
<MinersActivityChart isLoading />
<MinersActivityChart
isError
error={{ data: { message: 'Failed to fetch activity data' } }}
/>
{/* Demo dashboards: render zeros on error instead of the alert */}
<MinersActivityChart isError isDemoMode />Styling
.mdk-miners-activity-chart__root: root flex row.mdk-miners-activity-chart__item: per-status indicator wrapper.mdk-miners-activity-chart__item--large: large variant.mdk-miners-activity-chart__label: status label.mdk-miners-activity-chart__label--large: large label.mdk-miners-activity-chart__spinner: loading spinner.mdk-miners-activity-chart__spinner--large: large spinner
SingleStatCard
Single metric display card with optional flash animation for alerts.
Import
import { SingleStatCard } from '@mdk/foundation'Props
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | none | Stat label |
subtitle | string | '' | Secondary label rendered below the name |
value | number | string | null | null | Stat value |
unit | string | '' | Unit suffix; combined with value via formatValueUnit |
color | string | 'inherit' | CSS color applied via the --stat-color custom property |
flash | boolean | false | Apply the standard flash animation |
superflash | boolean | false | Apply the faster flash animation |
tooltipText | string | '' | Override for the tooltip label (defaults to name) |
variant | 'primary' | 'secondary' | 'tertiary' | 'primary' | Layout variant |
row | boolean | false | Stack name and value horizontally |
A tooltip is rendered automatically whenever value is set; pass tooltipText to override the label portion. Values longer than six characters get a --long-value modifier for narrower number formatting.
Basic usage
<SingleStatCard name="Temperature" value={42} unit="°C" />
<SingleStatCard name="Hash rate" value="95.5" unit="TH/s" />
<SingleStatCard name="Uptime" value="99.7" unit="%" />Variants
<SingleStatCard name="Temperature" value={42} unit="°C" variant="primary" />
<SingleStatCard name="Fan speed" value={4200} unit="RPM" variant="secondary" />
<SingleStatCard name="Power" value={3250} unit="W" variant="tertiary" />Alerts with flash
<SingleStatCard name="Temperature" value={92} unit="°C" color="red" flash />
<SingleStatCard name="Status" value="Overheat" color="#ff0000" superflash />Row layout
<SingleStatCard name="Efficiency" value="32.5" unit="J/TH" row />Styling
.mdk-single-stat-card: root element.mdk-single-stat-card--primary,--secondary,--tertiary: variants.mdk-single-stat-card--flash,--superflash: animation modifiers.mdk-single-stat-card--row: row layout.mdk-single-stat-card--long-value: applied automatically when value exceeds 6 characters.mdk-single-stat-card__name,__subtitle,__value,__text: inner elements
SecondaryStatCard
Simple secondary statistic display with name and value.
Import
import { SecondaryStatCard } from '@mdk/foundation'Props
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | '' | Stat label |
value | string | number | '' | Stat value |
className | string | none | Additional class merged onto the root |
Basic usage
<SecondaryStatCard name="Hash rate" value="95.5 TH/s" />
<SecondaryStatCard name="Uptime" value={99.8} />
<SecondaryStatCard name="Efficiency" value="92%" />Styling
.mdk-secondary-stat-card: root element.mdk-secondary-stat-card__name: stat label.mdk-secondary-stat-card__value: stat value
StatsGroupCard
Aggregated statistics display for selected miners with primary and secondary stat rows.
Import
import { StatsGroupCard } from '@mdk/foundation'Props
| Prop | Type | Default | Description |
|---|---|---|---|
miners | Device[] | DeviceData[] | none | Devices to aggregate; falls back to selectSelectedDevices from Redux when omitted |
isMinerMetrics | boolean | false | Render with MinerMetricCard instead of the default stat card grid |
Aggregated stats
Primary stats (always rendered):
- Hash rate: sum of
snap.stats.hashrate_mhs.t_5macross the selection, formatted viagetHashrateUnit - Temperature: max of
snap.stats.temperature_c.max, in °C - Frequency: average of
snap.stats.frequency_mhz.avg, in MHz - Consumption: sum of
snap.stats.power_w(suppressed for miner types where power is not reported) - Efficiency: derived
consumption / hash ratein J/TH, only when both are present
Secondary stats (rendered only when exactly one device is selected):
- Power mode: from
snap.config.power_mode - Uptime: humanized via
date-fns/formatDistanceStrictfromsnap.stats.uptime_ms - LED: on/off text from
snap.config.led_status - Status: from
snap.stats.status
Basic usage
<StatsGroupCard miners={selectedMiners} />Render with the miner metric layout
<StatsGroupCard isMinerMetrics />When isMinerMetrics is true, the card delegates rendering to MinerMetricCard. Secondary stats only show when the live Redux selection contains exactly one miner.
Styling
.mdk-stats-group-card: root element.mdk-stats-group-card__row: stat row container
MinerMetricCard
Card showing efficiency, hash rate, temperature, frequency, and consumption as primary stats, with an optional grid of secondary stats below.
Import
import { MinerMetricCard } from '@mdk/foundation'Props
| Prop | Type | Default | Description |
|---|---|---|---|
primaryStats | StatItem[] | none | Stats keyed by name from the fixed labels (see below) |
secondaryStats | StatItem[] | none | Free-form stats rendered in the optional secondary grid |
showSecondaryStats | boolean | true | Toggle the secondary stats grid |
The StatItem type is exported from the same module:
type StatItem = {
name?: string
value?: number | string
unit?: string
tooltipText?: string
}Recognised primary stat names
primaryStats is read by name. Unknown entries are ignored; only these labels render:
Efficiency: rendered top-right. Hidden if value is undefined or non-numeric.Hash rate: top-left primary boxTemperature: top-right primary box. Also drives the displayed Frequency value (the source rounds and formats the temperature value as a Frequency stand-in; pass both stats explicitly to keep them aligned).Frequency: bottom-left primary box (uses the formattedTemperaturenumeric for backwards-compat with upstream callers)Consumption: bottom-right primary box. Formatted with three decimals; falls back tokWhunit when value is0.
Basic usage
<MinerMetricCard
primaryStats={[
{ name: 'Efficiency', value: 32.5, unit: 'J/TH' },
{ name: 'Hash rate', value: 95.5, unit: 'TH/s' },
{ name: 'Temperature', value: 65, unit: '°C' },
{ name: 'Frequency', value: 500, unit: 'MHz' },
{ name: 'Consumption', value: 3.25, unit: 'kW' },
]}
secondaryStats={[
{ name: 'Fan speed', value: '6000 RPM' },
{ name: 'Uptime', value: '3 days' },
]}
/>Hide the secondary grid
<MinerMetricCard
primaryStats={primaryStats}
secondaryStats={[]}
showSecondaryStats={false}
/>Styling
.mdk-miner-metric-card: root element.mdk-miner-metric-card__title: card title (Miner Metrics).mdk-miner-metric-card__body: layout wrapper.mdk-miner-metric-card__efficiency: top-right efficiency block.mdk-miner-metric-card__content: primary and secondary stat grid.mdk-miner-metric-card__box: pair of primary stat items.mdk-miner-metric-card__item: single label/value cell.mdk-miner-metric-card__label: stat label.mdk-miner-metric-card__value: stat value.mdk-miner-metric-card__grid-box: secondary stats grid

