Przeglądaj źródła

feat(frontend): 资金流向分析页卡片化 UI 升级

cc 1 dzień temu
rodzic
commit
b5320270e6

+ 46 - 23
ai-electron/frontend/src/graph/MoneyFlowGraph.vue

@@ -136,11 +136,11 @@
         cx: 0,
         cy: 0,
         r: radius,
-        fill: isRoot ? '#3aa0ff' : '#53a8ff',
-        stroke: isRoot ? '#8ec9ff' : '#a7d1ff',
+        fill: isRoot ? '#2a50ec' : '#5b74e8',
+        stroke: isRoot ? '#b9c9ff' : '#c3d0fa',
         lineWidth: 1.5,
-        shadowColor: 'rgba(51, 144, 255, 0.22)',
-        shadowBlur: 18,
+        shadowColor: isRoot ? 'rgba(42, 80, 236, 0.28)' : 'rgba(42, 80, 236, 0.16)',
+        shadowBlur: isRoot ? 20 : 16,
         shadowOffsetX: 0,
         shadowOffsetY: 8,
         cursor: 'pointer' as const,
@@ -172,9 +172,9 @@
           ? {
               cx: toggleCenterX,
               cy: toggleCenterY,
-              r: 14,
+              r: 13,
               fill: '#ffffff',
-              stroke: '#dbeafe',
+              stroke: '#d7e1f8',
               lineWidth: 1,
               shadowColor: 'rgba(15, 23, 42, 0.12)',
               shadowBlur: 8,
@@ -194,7 +194,7 @@
               x: toggleCenterX,
               y: toggleCenterY,
               text: isCollapsed ? '+' : '-',
-              fill: '#2563eb',
+              fill: '#2a50ec',
               fontSize: 16,
               fontWeight: 700,
               textAlign: 'center',
@@ -213,7 +213,7 @@
               x: toggleCenterX,
               y: toggleCenterY + 22,
               text: toggleLabel,
-              fill: '#2563eb',
+              fill: '#5b6577',
               fontSize: 10,
               textAlign: 'center',
               textBaseline: 'middle',
@@ -231,8 +231,8 @@
           y: 0,
           text: titleText,
           fill: '#ffffff',
-          fontSize: 15,
-          fontWeight: 500,
+          fontSize: 14,
+          fontWeight: 600,
           textAlign: 'center',
           textBaseline: 'middle',
           wordWrap: true,
@@ -519,15 +519,15 @@
     if (!raw) {
       return `
         <div style="min-width:156px;padding:8px 10px;box-sizing:border-box;">
-          <div style="color:#334155;font-size:12px;font-weight:600;line-height:18px;">交易关系</div>
+          <div style="color:#1f2937;font-size:12px;font-weight:600;line-height:18px;">交易关系</div>
         </div>
       `;
     }
 
     return `
       <div style="min-width:156px;padding:8px 10px;box-sizing:border-box;">
-        <div style="color:#334155;font-size:12px;font-weight:600;line-height:18px;">${escapeHtml(buildEdgeTitle(raw))}</div>
-        <div style="margin-top:4px;color:#64748b;font-size:11px;line-height:16px;">${escapeHtml(buildEdgeValue(raw))}</div>
+        <div style="color:#1f2937;font-size:12px;font-weight:600;line-height:18px;">${escapeHtml(buildEdgeTitle(raw))}</div>
+        <div style="margin-top:4px;color:#5b6577;font-size:11px;line-height:16px;">${escapeHtml(buildEdgeValue(raw))}</div>
       </div>
     `;
   };
@@ -883,6 +883,20 @@
     });
   };
 
+  const fitGraphView = async () => {
+    const currentGraph = graph.value;
+    if (!isGraphUsable(currentGraph)) return;
+    try {
+      await currentGraph.fitView({ when: 'always', direction: 'both' }, false);
+      if (currentGraph.getZoom() > 1) {
+        await currentGraph.zoomTo(1, false);
+        await currentGraph.fitCenter(false);
+      }
+    } catch (error) {
+      console.warn('[MoneyFlowGraph] fit view failed:', error);
+    }
+  };
+
   const handleResize = () => {
     const currentGraph = graph.value;
     if (!isGraphUsable(currentGraph)) return;
@@ -893,6 +907,7 @@
     }
     lastResizeSize.value = [width, height];
     currentGraph.resize(width, height);
+    void fitGraphView();
     scheduleHitAreaSync();
   };
 
@@ -914,6 +929,7 @@
       width,
       height,
       autoResize: false,
+      padding: 28,
       data: graphData,
       layout: {
         type: 'compact-box',
@@ -934,32 +950,38 @@
       edge: {
         type: 'cubic-horizontal',
         style: {
-          stroke: '#9db7d6',
-          lineWidth: 2.5,
+          stroke: '#b9c6e8',
+          lineWidth: 2,
           cursor: (datum: EdgeData) => (parseIds(getEdgeRaw(datum)?.ids).length ? 'pointer' : 'default'),
           label: (datum: EdgeData) => Boolean(buildEdgeLabelText(getEdgeRaw(datum))),
           labelText: (datum: EdgeData) => buildEdgeLabelText(getEdgeRaw(datum)),
           labelPlacement: 'center',
-          labelAutoRotate: true,
+          labelAutoRotate: false,
           labelWordWrap: true,
           labelMaxWidth: 220,
-          labelFill: '#5e5e5e',
-          labelFontSize: 12,
-          labelBackground: false,
+          labelFill: '#5b6577',
+          labelFontSize: 11,
+          labelBackground: true,
+          labelBackgroundFill: '#ffffff',
+          labelBackgroundOpacity: 0.92,
+          labelBackgroundStroke: '#e7ebf3',
+          labelBackgroundLineWidth: 1,
+          labelBackgroundRadius: 4,
+          labelPadding: [2, 6, 2, 6],
           startArrow: (datum: EdgeData) => getEdgeRaw(datum)?.state === 'left',
-          startArrowFill: '#9db7d6',
+          startArrowFill: '#b9c6e8',
           startArrowSize: EDGE_ARROW_SIZE,
           startArrowOffset: EDGE_ARROW_OFFSET,
           endArrow: (datum: EdgeData) => getEdgeRaw(datum)?.state !== 'left',
-          endArrowFill: '#9db7d6',
+          endArrowFill: '#b9c6e8',
           endArrowSize: EDGE_ARROW_SIZE,
           endArrowOffset: EDGE_ARROW_OFFSET,
         },
         state: {
           active: {
-            stroke: '#3b82f6',
+            stroke: '#2a50ec',
             lineWidth: 3,
-            labelFill: '#334155',
+            labelFill: '#1e3ed0',
           },
         },
       },
@@ -1023,6 +1045,7 @@
       }
     }
 
+    await fitGraphView();
     scheduleHitAreaSync();
   };
 

Plik diff jest za duży
+ 297 - 434
ai-electron/frontend/src/trans/views/capitalFlow/index.vue


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików