feat: GeoScene frontend POC + Docker deploy for remote host
Migrate maps to @geoscene/core, polish monitoring/alerts UX, fix timeline basemap flicker and district alert regions, and ship compose/nginx Docker deploy assets with CBPOA_ROOT data mounts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,57 +11,72 @@ export interface AlertSlice {
|
||||
|
||||
interface AlertSeverityDonutProps {
|
||||
data: AlertSlice[];
|
||||
embed?: boolean;
|
||||
}
|
||||
|
||||
const tooltipStyle = {
|
||||
backgroundColor: '#FFFFFF',
|
||||
border: `1px solid ${CHART_COLORS.tooltipBorder}`,
|
||||
borderRadius: '8px',
|
||||
borderRadius: '10px',
|
||||
fontSize: '12px',
|
||||
};
|
||||
|
||||
function AlertSeverityDonutComponent({ data }: AlertSeverityDonutProps) {
|
||||
function AlertSeverityDonutComponent({ data, embed }: AlertSeverityDonutProps) {
|
||||
const hasData = data.some((d) => d.value > 0);
|
||||
|
||||
return (
|
||||
<div className="card p-4">
|
||||
<div className="text-[11px] font-medium text-text-secondary uppercase tracking-wide mb-4">
|
||||
预警严重度分布
|
||||
</div>
|
||||
{hasData ? (
|
||||
<div className="flex items-center justify-center">
|
||||
<ResponsiveContainer width="100%" height={240}>
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={data}
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
innerRadius={50}
|
||||
outerRadius={80}
|
||||
paddingAngle={4}
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
>
|
||||
{data.map((entry) => (
|
||||
<Cell key={entry.name} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
<Tooltip
|
||||
contentStyle={tooltipStyle}
|
||||
formatter={(value: number, name: string) => [value, name]}
|
||||
/>
|
||||
<Legend
|
||||
wrapperStyle={{ fontSize: '12px' }}
|
||||
formatter={(value: string) => <span className="text-text-primary">{value}</span>}
|
||||
/>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
const body = (
|
||||
<>
|
||||
{embed ? (
|
||||
<div className="workbench-panel__head">
|
||||
<div>
|
||||
<h3 className="workbench-panel__title">预警严重度分布</h3>
|
||||
<p className="workbench-panel__sub">P1 紧急 / P2 关注</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<EmptyState title="暂无预警数据" />
|
||||
<div className="text-[11px] font-medium text-text-secondary uppercase tracking-wide mb-4">
|
||||
预警严重度分布
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={embed ? 'workbench-panel__body' : undefined}>
|
||||
{hasData ? (
|
||||
<div className="flex items-center justify-center">
|
||||
<ResponsiveContainer width="100%" height={240}>
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={data}
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
innerRadius={50}
|
||||
outerRadius={80}
|
||||
paddingAngle={4}
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
>
|
||||
{data.map((entry) => (
|
||||
<Cell key={entry.name} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
<Tooltip
|
||||
contentStyle={tooltipStyle}
|
||||
formatter={(value: number, name: string) => [value, name]}
|
||||
/>
|
||||
<Legend
|
||||
wrapperStyle={{ fontSize: '12px' }}
|
||||
formatter={(value: string) => <span className="text-text-primary">{value}</span>}
|
||||
/>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
) : (
|
||||
<EmptyState title="暂无预警数据" />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
if (embed) return <>{body}</>;
|
||||
return <div className="card p-4">{body}</div>;
|
||||
}
|
||||
|
||||
export const AlertSeverityDonut = memo(AlertSeverityDonutComponent);
|
||||
|
||||
Reference in New Issue
Block a user