feat(energy): hydrogen daily — period bar chart with anomaly coloring
Mirrors the electric-view treatment: a 时段每日加氢量 bar chart sits between the customer toggle and the table. Bars use the cyan→blue gradient by default; days where |chainPct| >= 30% render in solid emerald (positive) or red (negative), giving an at-a-glance view of anomalous days that's reinforced by the table's row tinting below. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { ChevronRight } from 'lucide-react';
|
import { ChevronRight } from 'lucide-react';
|
||||||
import { motion, AnimatePresence } from 'motion/react';
|
import { motion, AnimatePresence } from 'motion/react';
|
||||||
|
import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer, Cell, Tooltip } from 'recharts';
|
||||||
import TrendBadge from './TrendBadge';
|
import TrendBadge from './TrendBadge';
|
||||||
import { HYDROGEN_DAILY } from './mock';
|
import { HYDROGEN_DAILY } from './mock';
|
||||||
import type { CustomerType, DateQuickPick, HydrogenDailyRow } from './types';
|
import type { CustomerType, DateQuickPick, HydrogenDailyRow } from './types';
|
||||||
@@ -57,6 +58,9 @@ export default function HydrogenDaily() {
|
|||||||
.sort((a, b) => b.date.localeCompare(a.date));
|
.sort((a, b) => b.date.localeCompare(a.date));
|
||||||
}, [pick, customer]);
|
}, [pick, customer]);
|
||||||
|
|
||||||
|
// 柱图:按日期升序,用于"从左到右时间流"
|
||||||
|
const trendData = useMemo(() => [...rows].sort((a, b) => a.date.localeCompare(b.date)), [rows]);
|
||||||
|
|
||||||
const totalKg = rows.reduce((a, r) => a + r.totalKg, 0);
|
const totalKg = rows.reduce((a, r) => a + r.totalKg, 0);
|
||||||
|
|
||||||
const toggle = (date: string) => setExpanded(prev => {
|
const toggle = (date: string) => setExpanded(prev => {
|
||||||
@@ -99,6 +103,51 @@ export default function HydrogenDaily() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 时段加氢量柱图 */}
|
||||||
|
{trendData.length > 0 && (
|
||||||
|
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm p-4">
|
||||||
|
<div className="flex items-center justify-between mb-2">
|
||||||
|
<span className="text-sm font-bold text-slate-700">时段每日加氢量</span>
|
||||||
|
<span className="text-[11px] text-slate-400 font-bold">单位 Kg</span>
|
||||||
|
</div>
|
||||||
|
<ResponsiveContainer width="100%" height={160}>
|
||||||
|
<BarChart data={trendData} margin={{ top: 8, right: 4, bottom: 0, left: 0 }}>
|
||||||
|
<XAxis
|
||||||
|
dataKey="date"
|
||||||
|
tickFormatter={(v: string) => v.slice(5)}
|
||||||
|
tick={{ fontSize: 10, fill: '#94a3b8' }}
|
||||||
|
tickLine={false}
|
||||||
|
axisLine={false}
|
||||||
|
interval="preserveStartEnd"
|
||||||
|
minTickGap={8}
|
||||||
|
/>
|
||||||
|
<YAxis hide />
|
||||||
|
<Tooltip
|
||||||
|
formatter={(v) => [`${Number(v ?? 0).toLocaleString('zh-CN', { maximumFractionDigits: 2 })} Kg`, '加氢量']}
|
||||||
|
labelFormatter={(d) => `日期 ${d}`}
|
||||||
|
contentStyle={{ borderRadius: 12, fontSize: 12 }}
|
||||||
|
cursor={{ fill: 'rgba(34, 211, 238, 0.06)' }}
|
||||||
|
/>
|
||||||
|
<Bar dataKey="totalKg" radius={[4, 4, 0, 0]}>
|
||||||
|
{trendData.map((r, i) => {
|
||||||
|
const isAbnormal = Math.abs(r.chainPct) >= 0.3;
|
||||||
|
const fill = isAbnormal
|
||||||
|
? r.chainPct > 0 ? '#10b981' : '#ef4444'
|
||||||
|
: 'url(#hydrogenBarGrad)';
|
||||||
|
return <Cell key={i} fill={fill} />;
|
||||||
|
})}
|
||||||
|
</Bar>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="hydrogenBarGrad" x1="0" x2="0" y1="0" y2="1">
|
||||||
|
<stop offset="0%" stopColor="#22d3ee" />
|
||||||
|
<stop offset="100%" stopColor="#3b82f6" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</BarChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 表格 */}
|
{/* 表格 */}
|
||||||
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm overflow-hidden">
|
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm overflow-hidden">
|
||||||
{/* 表头 */}
|
{/* 表头 */}
|
||||||
|
|||||||
Reference in New Issue
Block a user