Upgrade dashboard, builder, and agent resource controls.
Dark UI with hashrate graphs, inline setting help, percent-based threads/RAM, configurable process name and display modes, and LAN-aware run.bat startup banner.
This commit is contained in:
66
server/web/src/components/Charts/HashrateChart.tsx
Normal file
66
server/web/src/components/Charts/HashrateChart.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import {
|
||||
Area,
|
||||
AreaChart,
|
||||
CartesianGrid,
|
||||
ResponsiveContainer,
|
||||
Tooltip,
|
||||
XAxis,
|
||||
YAxis,
|
||||
} from 'recharts';
|
||||
|
||||
export interface ChartPoint {
|
||||
time: string;
|
||||
value: number;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
interface HashrateChartProps {
|
||||
data: ChartPoint[];
|
||||
title?: string;
|
||||
color?: string;
|
||||
unit?: string;
|
||||
}
|
||||
|
||||
export default function HashrateChart({ data, title, color = '#06b6d4', unit = 'H/s' }: HashrateChartProps) {
|
||||
if (data.length === 0) {
|
||||
return (
|
||||
<div className="chart-empty card">
|
||||
<p>{title || 'Chart'} — waiting for data...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="chart-wrap">
|
||||
{title && <h3 className="chart-title">{title}</h3>}
|
||||
<ResponsiveContainer width="100%" height={260}>
|
||||
<AreaChart data={data}>
|
||||
<defs>
|
||||
<linearGradient id={`grad-${color}`} x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor={color} stopOpacity={0.35} />
|
||||
<stop offset="95%" stopColor={color} stopOpacity={0} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#243049" />
|
||||
<XAxis dataKey="time" stroke="#64748b" fontSize={11} tickLine={false} />
|
||||
<YAxis stroke="#64748b" fontSize={11} tickLine={false} tickFormatter={(v) => formatShort(v, unit)} />
|
||||
<Tooltip
|
||||
contentStyle={{ background: '#111827', border: '1px solid #2a3a5c', borderRadius: 8 }}
|
||||
labelStyle={{ color: '#94a3b8' }}
|
||||
formatter={(value: number) => [formatShort(value, unit), title || 'Value']}
|
||||
/>
|
||||
<Area type="monotone" dataKey="value" stroke={color} fill={`url(#grad-${color})`} strokeWidth={2} />
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function formatShort(v: number, unit: string): string {
|
||||
if (unit === 'H/s') {
|
||||
if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;
|
||||
if (v >= 1_000) return `${(v / 1_000).toFixed(1)}K`;
|
||||
return `${v.toFixed(0)}`;
|
||||
}
|
||||
return `${v.toFixed(1)}${unit === '%' ? '%' : ''}`;
|
||||
}
|
||||
Reference in New Issue
Block a user