|
@@ -0,0 +1,139 @@
|
|
|
|
|
+import React from 'react';
|
|
|
|
|
+
|
|
|
|
|
+// 定义弹出框数据类型
|
|
|
|
|
+interface PopupData {
|
|
|
|
|
+ title: string;
|
|
|
|
|
+ metrics: {
|
|
|
|
|
+ label: string;
|
|
|
|
|
+ value: string;
|
|
|
|
|
+ unit?: string;
|
|
|
|
|
+ }[];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface PopupInfoBoxProps {
|
|
|
|
|
+ data?: PopupData;
|
|
|
|
|
+ position?: { x: number; y: number };
|
|
|
|
|
+ onClose?: () => void;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const PopupInfoBox: React.FC<PopupInfoBoxProps> = ({
|
|
|
|
|
+ data,
|
|
|
|
|
+ position = { x: 717.28, y: 273.13 },
|
|
|
|
|
+ onClose
|
|
|
|
|
+}) => {
|
|
|
|
|
+ // 默认数据
|
|
|
|
|
+ const defaultData: PopupData = {
|
|
|
|
|
+ title: "粮食源头",
|
|
|
|
|
+ metrics: [
|
|
|
|
|
+ { label: "种植面积", value: "15", unit: "万亩" },
|
|
|
|
|
+ { label: "年产量", value: "200", unit: "万吨" },
|
|
|
|
|
+ { label: "带动农户", value: "5000", unit: "户" }
|
|
|
|
|
+ ]
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const displayData = data || defaultData;
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div
|
|
|
|
|
+ className="absolute overflow-clip"
|
|
|
|
|
+ style={{
|
|
|
|
|
+ left: `${position.x}px`,
|
|
|
|
|
+ top: `${position.y}px`,
|
|
|
|
|
+ width: '580px',
|
|
|
|
|
+ height: '351px'
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ {/* 箭头指示器 */}
|
|
|
|
|
+ <div className="absolute flex items-center justify-center left-0 top-0">
|
|
|
|
|
+ <div className="flex-none rotate-[180deg]">
|
|
|
|
|
+ <div className="content-stretch flex items-start overflow-clip relative">
|
|
|
|
|
+ {/* 箭头装饰 */}
|
|
|
|
|
+ <div className="flex h-[calc(1px*((var(--transform-inner-width)*1)+(var(--transform-inner-height)*0)))] items-center justify-center leading-[0] relative shrink-0 w-[calc(1px*((var(--transform-inner-height)*1)+(var(--transform-inner-width)*0)))]">
|
|
|
|
|
+ <div className="flex-none rotate-[90deg] scale-y-[-100%]">
|
|
|
|
|
+ <div className="grid-cols-[max-content] grid-rows-[max-content] inline-grid justify-items-start relative">
|
|
|
|
|
+ <div className="col-[1] h-[80px] ml-[7.5px] mt-[17px] relative row-[1] w-[2px]">
|
|
|
|
|
+ <div className="absolute bottom-[-1.25%] left-0 right-[-50%] top-[-1.25%]">
|
|
|
|
|
+ <img
|
|
|
|
|
+ alt="箭头装饰"
|
|
|
|
|
+ className="block max-w-none size-full"
|
|
|
|
|
+ src="/supply-chain/ArrowDecoration.svg"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="col-[1] ml-0 mt-0 relative row-[1] size-[17px]">
|
|
|
|
|
+ <img
|
|
|
|
|
+ alt="圆圈装饰"
|
|
|
|
|
+ className="block max-w-none size-full"
|
|
|
|
|
+ src="/supply-chain/CircleDecoration.svg"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 弹出框主体 */}
|
|
|
|
|
+ <div className="h-[320px] relative shrink-0 w-[476px]">
|
|
|
|
|
+ {/* 边框背景 */}
|
|
|
|
|
+ <div className="absolute inset-[-0.06%_-0.09%_-0.06%_-0.04%]">
|
|
|
|
|
+ <img
|
|
|
|
|
+ alt="弹出框边框"
|
|
|
|
|
+ className="block max-w-none size-full"
|
|
|
|
|
+ src="/supply-chain/PopupBorder.svg"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 内容区域 */}
|
|
|
|
|
+ <div className="absolute content-stretch flex flex-col gap-[12px] items-center left-[29.81px] top-[31.73px] w-[420px]">
|
|
|
|
|
+ {/* 标题区域 */}
|
|
|
|
|
+ <div className="content-stretch flex flex-col gap-[12px] items-start relative shrink-0 w-full">
|
|
|
|
|
+ <div className="box-border content-stretch flex gap-[10px] h-[62px] items-center px-0 py-[4px] relative shrink-0">
|
|
|
|
|
+ <div className="flex flex-col font-bold justify-center leading-[0] not-italic relative shrink-0 text-[24px] text-white whitespace-nowrap">
|
|
|
|
|
+ <p className="leading-[32px]">{displayData.title}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="box-border content-stretch flex gap-[10px] h-[62px] items-center px-0 py-[4px] relative shrink-0 w-full">
|
|
|
|
|
+ <div className="flex flex-col font-bold justify-center leading-[0] not-italic relative shrink-0 text-[24px] text-white whitespace-nowrap">
|
|
|
|
|
+ <p className="leading-[32px]">详细信息</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 数据指标区域 */}
|
|
|
|
|
+ <div className="content-stretch flex flex-col gap-[12px] items-start relative shrink-0 w-full">
|
|
|
|
|
+ <div className="content-stretch flex gap-[20px] items-start relative shrink-0">
|
|
|
|
|
+ {displayData.metrics.slice(0, 3).map((metric, index) => (
|
|
|
|
|
+ <div key={index} className="box-border content-stretch flex gap-[10px] items-center px-0 py-[4px] relative shrink-0">
|
|
|
|
|
+ <div className="flex flex-col font-bold justify-center leading-[0] not-italic relative shrink-0 text-[24px] text-white whitespace-nowrap">
|
|
|
|
|
+ <p className="leading-[32px]">{metric.label}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="content-stretch flex gap-[20px] items-start relative shrink-0">
|
|
|
|
|
+ {displayData.metrics.slice(0, 3).map((metric, index) => (
|
|
|
|
|
+ <div key={index} className="box-border content-stretch flex gap-[10px] items-center px-0 py-[4px] relative shrink-0">
|
|
|
|
|
+ <div className="flex flex-col font-bold justify-center leading-[0] not-italic relative shrink-0 text-[24px] text-[#C5FF92] whitespace-nowrap">
|
|
|
|
|
+ <p className="leading-[32px]">{metric.value} {metric.unit}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 关闭按钮 */}
|
|
|
|
|
+ <button
|
|
|
|
|
+ className="absolute right-4 top-4 text-white text-xl hover:text-[#C5FF92] transition-colors"
|
|
|
|
|
+ onClick={onClose}
|
|
|
|
|
+ >
|
|
|
|
|
+ ×
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export default PopupInfoBox;
|