feat: add area diagnostics
This commit is contained in:
@@ -1031,6 +1031,7 @@ function AreaDetailPanel({
|
||||
<div className="h-72 rounded-md border border-[var(--border)] p-3">
|
||||
<AreaMetricTrendChart metrics={detail.monthly_metrics} />
|
||||
</div>
|
||||
<AreaDiagnosticsPanel diagnostics={detail.diagnostics} />
|
||||
<div className="grid gap-4 lg:grid-cols-2">
|
||||
<AreaMetricHistoryTable metrics={detail.monthly_metrics} />
|
||||
<AreaNeighborhoodTable
|
||||
@@ -1051,6 +1052,57 @@ function AreaDetailPanel({
|
||||
);
|
||||
}
|
||||
|
||||
function AreaDiagnosticsPanel({ diagnostics }: { diagnostics: AreaDetail["diagnostics"] }) {
|
||||
if (!diagnostics) {
|
||||
return (
|
||||
<div className="rounded-md border border-[var(--border)] px-4 py-8 text-sm text-[var(--muted-foreground)]">
|
||||
暂无历史分位
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-md border border-[var(--border)] p-3">
|
||||
<div className="mb-3 flex items-center justify-between gap-3">
|
||||
<p className="text-sm font-semibold text-slate-950">历史分位与异常</p>
|
||||
<Badge variant={diagnostics.anomaly_count > 0 ? "warning" : "success"}>
|
||||
{diagnostics.anomaly_count} 项异常
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
|
||||
{diagnostics.metrics.map((metric) => (
|
||||
<div key={metric.key} className="rounded-md border border-[var(--border)] bg-white p-3">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-sm font-medium text-slate-950">{metric.label}</span>
|
||||
<Badge variant={metric.anomaly ? "warning" : "muted"}>{metric.severity}</Badge>
|
||||
</div>
|
||||
<p className="mt-2 text-lg font-semibold text-slate-950">
|
||||
{formatMetricValue(metric.current_value, metric.unit)}
|
||||
</p>
|
||||
<div className="mt-3 h-2 rounded-full bg-[var(--muted)]">
|
||||
<div
|
||||
className={
|
||||
metric.anomaly
|
||||
? "h-2 rounded-full bg-[var(--warning)]"
|
||||
: "h-2 rounded-full bg-[var(--primary)]"
|
||||
}
|
||||
style={{ width: `${Math.max(0, Math.min(100, metric.percentile))}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-2 flex items-center justify-between text-xs text-[var(--muted-foreground)]">
|
||||
<span>P{formatNumber(metric.percentile, 1)}</span>
|
||||
<span>
|
||||
{formatMetricValue(metric.historical_min, metric.unit)}-
|
||||
{formatMetricValue(metric.historical_max, metric.unit)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AreaMetricTrendChart({ metrics }: { metrics: AreaDetail["monthly_metrics"] }) {
|
||||
const data = [...metrics].reverse();
|
||||
if (data.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user