yanghao 1 неделя назад
Родитель
Сommit
1ab5de7617

+ 89 - 43
src/views/pms/stat/rhkb/inventorySituation.vue

@@ -61,6 +61,8 @@ const trendChartRef = ref<HTMLDivElement>()
 let distributionChart: echarts.ECharts | null = null
 let trendChart: echarts.ECharts | null = null
 let distributionResizeObserver: ResizeObserver | null = null
+let trendResizeObserver: ResizeObserver | null = null
+let trendResizeFrame: number | null = null
 
 const panelOptions: Array<{ label: string; value: ActivePanel }> = [
   { label: '存货分布', value: 'distribution' },
@@ -141,7 +143,8 @@ function getChartLayout(chartRef: Ref<HTMLDivElement | undefined>) {
     distributionLegendGap: compact ? 4 : 10,
     distributionLegendFontSize: compact ? 10 : 14,
     trendGridTop: compact ? 10 : 32,
-    trendGridRight: compact ? 12 : THEME.grid.right,
+    trendGridLeft: compact ? 34 : 48,
+    trendGridRight: compact ? 34 : 48,
     trendGridBottom: compact ? 2 : THEME.grid.bottom,
     legendTop: compact ? 0 : 4,
     legendRight: compact ? 2 : 6,
@@ -155,7 +158,8 @@ function getChartLayout(chartRef: Ref<HTMLDivElement | undefined>) {
     barGap: compact ? '12%' : '5%',
     barCategoryGap: compact ? '46%' : '36%',
     labelDistance: compact ? 4 : 7,
-    labelFontSize: compact ? 10 : 12
+    distributionLabelFontSize: compact ? 6 : 8,
+    trendLabelFontSize: compact ? 10 : 12
   }
 }
 
@@ -238,37 +242,8 @@ function getDistributionOption(
         fontFamily: FONT_FAMILY
       }
     }),
-    graphic: [
-      {
-        type: 'text',
-        left: '19.5%',
-        top: '45%',
-        style: {
-          text: `总库存\n${formatAmount(inventoryTotal)}万元`,
-          textAlign: 'center',
-          fill: THEME.text.strong,
-          fontSize: layout.compact ? 8 : 10,
-          fontWeight: 700,
-          lineHeight: layout.distributionTitleLineHeight + 6,
-          fontFamily: FONT_FAMILY
-        }
-      },
-      {
-        type: 'text',
-        left: '67%',
-        top: '45%',
-        style: {
-          text: `总积压\n${formatAmount(backlogTotal)}万元`,
-          textAlign: 'center',
-          fill: THEME.text.strong,
-          fontSize: layout.compact ? 8 : 10,
-          fontWeight: 700,
-          lineHeight: layout.distributionTitleLineHeight + 6,
-          fontFamily: FONT_FAMILY
-        }
-      }
-    ],
     series: [
+      // ===== 第一个饼图:库存数据(带外标签) =====
       {
         name: '库存',
         type: 'pie',
@@ -283,17 +258,14 @@ function getDistributionOption(
           bleedMargin: 0,
           formatter: '{b}\n{d}%',
           color: 'inherit',
-          fontSize: layout.labelFontSize,
+          fontSize: layout.distributionLabelFontSize,
           fontWeight: 500,
           fontFamily: FONT_FAMILY
         },
         labelLine: {
           show: true,
-          // length: layout.compact ? 6 : 10,
-          // length2: layout.compact ? 8 : 14,
           minTurnAngle: 90,
           lineStyle: {
-            color: distributionColors[0],
             width: 1.5,
             opacity: 1
           }
@@ -320,6 +292,34 @@ function getDistributionOption(
           }
         }))
       },
+      // ===== 第二个饼图:库存中心文字(不显示饼图) =====
+      {
+        name: '库存中心文字',
+        type: 'pie',
+        radius: ['0%', '0%'],
+        center: ['25%', layout.distributionPieCenterY],
+        label: {
+          show: true,
+          position: 'center',
+          formatter: `总库存\n${formatAmount(inventoryTotal)}万元`,
+          color: THEME.text.strong,
+          fontSize: layout.compact ? 8 : 10,
+          fontWeight: 700,
+          lineHeight: layout.distributionTitleLineHeight + 6,
+          fontFamily: FONT_FAMILY
+        },
+        data: [{ name: '中心文字', value: 1 }],
+        animation: false,
+        tooltip: { show: false },
+        legend: { show: false },
+        // ✅ 关键:禁用所有交互
+        silent: true,
+        emphasis: {
+          scale: false,
+          label: { show: false }
+        }
+      },
+      // ===== 第三个饼图:积压数据(带外标签) =====
       {
         name: '积压库存',
         type: 'pie',
@@ -334,17 +334,14 @@ function getDistributionOption(
           bleedMargin: 0,
           formatter: '{b}\n{d}%',
           color: 'inherit',
-          fontSize: layout.labelFontSize,
+          fontSize: layout.distributionLabelFontSize,
           fontWeight: 500,
           fontFamily: FONT_FAMILY
         },
         labelLine: {
           show: true,
-          // length: layout.compact ? 6 : 10,
-          // length2: layout.compact ? 8 : 14,
           minTurnAngle: 90,
           lineStyle: {
-            color: distributionColors[0],
             width: 1.5,
             opacity: 1
           }
@@ -372,6 +369,33 @@ function getDistributionOption(
               }
             }
           }))
+      },
+      // ===== 第四个饼图:积压中心文字(不显示饼图) =====
+      {
+        name: '积压中心文字',
+        type: 'pie',
+        radius: ['0%', '0%'],
+        center: ['73%', layout.distributionPieCenterY],
+        label: {
+          show: true,
+          position: 'center',
+          formatter: `总积压\n${formatAmount(backlogTotal)}万元`,
+          color: THEME.text.strong,
+          fontSize: layout.compact ? 8 : 10,
+          fontWeight: 700,
+          lineHeight: layout.distributionTitleLineHeight + 6,
+          fontFamily: FONT_FAMILY
+        },
+        data: [{ name: '中心文字', value: 1 }],
+        animation: false,
+        tooltip: { show: false },
+        legend: { show: false },
+        // ✅ 关键:禁用所有交互
+        silent: true,
+        emphasis: {
+          scale: false,
+          label: { show: false }
+        }
       }
     ]
   }
@@ -422,6 +446,7 @@ function getInventoryAgingOption(data: unknown): echarts.EChartsOption {
     animation: false,
     grid: {
       ...THEME.grid,
+      left: layout.trendGridLeft,
       top: layout.trendGridTop,
       right: layout.trendGridRight,
       bottom: layout.trendGridBottom
@@ -434,7 +459,7 @@ function getInventoryAgingOption(data: unknown): echarts.EChartsOption {
     }),
     xAxis: {
       type: 'category',
-      boundaryGap: false,
+      boundaryGap: true,
       data: months,
       axisTick: { show: false },
       axisLabel: {
@@ -487,7 +512,7 @@ function getInventoryAgingOption(data: unknown): echarts.EChartsOption {
         label: {
           show: true,
           color: THEME.color.orange.line,
-          fontSize: layout.labelFontSize,
+          fontSize: layout.trendLabelFontSize,
           fontFamily: FONT_FAMILY,
           formatter(params: any) {
             return `${formatAmount(Number(params.value))}万`
@@ -529,7 +554,7 @@ function initTrendChart() {
 
 function resizeCharts() {
   distributionChart?.resize()
-  trendChart?.resize()
+  scheduleTrendResize()
 }
 
 function handleDistributionResize() {
@@ -539,6 +564,19 @@ function handleDistributionResize() {
   renderDistributionChart()
 }
 
+function scheduleTrendResize() {
+  if (trendResizeFrame !== null) return
+
+  trendResizeFrame = requestAnimationFrame(() => {
+    trendResizeFrame = null
+    if (activePanel.value !== 'trend' || !trendChartRef.value) return
+
+    if (!trendChart) initTrendChart()
+    trendChart?.resize()
+    renderTrendChart()
+  })
+}
+
 function destroyCharts() {
   distributionChart?.dispose()
   trendChart?.dispose()
@@ -632,6 +670,8 @@ onMounted(() => {
       initDistributionChart()
       distributionResizeObserver = new ResizeObserver(handleDistributionResize)
       distributionResizeObserver.observe(distributionChartRef.value!)
+      trendResizeObserver = new ResizeObserver(scheduleTrendResize)
+      trendResizeObserver.observe(trendChartRef.value!)
     })
   })
   window.addEventListener('resize', resizeCharts)
@@ -659,6 +699,12 @@ onUnmounted(() => {
   window.removeEventListener('rhkb:resize', resizeCharts)
   distributionResizeObserver?.disconnect()
   distributionResizeObserver = null
+  trendResizeObserver?.disconnect()
+  trendResizeObserver = null
+  if (trendResizeFrame !== null) {
+    cancelAnimationFrame(trendResizeFrame)
+    trendResizeFrame = null
+  }
   destroyCharts()
 })
 </script>

+ 89 - 43
src/views/pms/stat/rykb/inventory-situation.vue

@@ -61,6 +61,8 @@ const trendChartRef = ref<HTMLDivElement>()
 let distributionChart: echarts.ECharts | null = null
 let trendChart: echarts.ECharts | null = null
 let distributionResizeObserver: ResizeObserver | null = null
+let trendResizeObserver: ResizeObserver | null = null
+let trendResizeFrame: number | null = null
 
 const panelOptions: Array<{ label: string; value: ActivePanel }> = [
   { label: '存货分布', value: 'distribution' },
@@ -141,7 +143,8 @@ function getChartLayout(chartRef: Ref<HTMLDivElement | undefined>) {
     distributionLegendGap: compact ? 4 : 10,
     distributionLegendFontSize: compact ? 10 : 14,
     trendGridTop: compact ? 10 : 32,
-    trendGridRight: compact ? 12 : THEME.grid.right,
+    trendGridLeft: compact ? 34 : 48,
+    trendGridRight: compact ? 34 : 48,
     trendGridBottom: compact ? 2 : THEME.grid.bottom,
     legendTop: compact ? 0 : 4,
     legendRight: compact ? 2 : 6,
@@ -155,7 +158,8 @@ function getChartLayout(chartRef: Ref<HTMLDivElement | undefined>) {
     barGap: compact ? '12%' : '5%',
     barCategoryGap: compact ? '46%' : '36%',
     labelDistance: compact ? 4 : 7,
-    labelFontSize: compact ? 10 : 12
+    distributionLabelFontSize: compact ? 6 : 8,
+    trendLabelFontSize: compact ? 10 : 12
   }
 }
 
@@ -238,37 +242,8 @@ function getDistributionOption(
         fontFamily: FONT_FAMILY
       }
     }),
-    graphic: [
-      {
-        type: 'text',
-        left: '19.5%',
-        top: '45%',
-        style: {
-          text: `总库存\n${formatAmount(inventoryTotal)}万元`,
-          textAlign: 'center',
-          fill: THEME.text.strong,
-          fontSize: layout.compact ? 8 : 10,
-          fontWeight: 700,
-          lineHeight: layout.distributionTitleLineHeight + 6,
-          fontFamily: FONT_FAMILY
-        }
-      },
-      {
-        type: 'text',
-        left: '67%',
-        top: '45%',
-        style: {
-          text: `总积压\n${formatAmount(backlogTotal)}万元`,
-          textAlign: 'center',
-          fill: THEME.text.strong,
-          fontSize: layout.compact ? 8 : 10,
-          fontWeight: 700,
-          lineHeight: layout.distributionTitleLineHeight + 6,
-          fontFamily: FONT_FAMILY
-        }
-      }
-    ],
     series: [
+      // ===== 第一个饼图:库存数据(带外标签) =====
       {
         name: '库存',
         type: 'pie',
@@ -283,17 +258,14 @@ function getDistributionOption(
           bleedMargin: 0,
           formatter: '{b}\n{d}%',
           color: 'inherit',
-          fontSize: layout.labelFontSize,
+          fontSize: layout.distributionLabelFontSize,
           fontWeight: 500,
           fontFamily: FONT_FAMILY
         },
         labelLine: {
           show: true,
-          // length: layout.compact ? 6 : 10,
-          // length2: layout.compact ? 8 : 14,
           minTurnAngle: 90,
           lineStyle: {
-            color: distributionColors[0],
             width: 1.5,
             opacity: 1
           }
@@ -320,6 +292,34 @@ function getDistributionOption(
           }
         }))
       },
+      // ===== 第二个饼图:库存中心文字(不显示饼图) =====
+      {
+        name: '库存中心文字',
+        type: 'pie',
+        radius: ['0%', '0%'],
+        center: ['25%', layout.distributionPieCenterY],
+        label: {
+          show: true,
+          position: 'center',
+          formatter: `总库存\n${formatAmount(inventoryTotal)}万元`,
+          color: THEME.text.strong,
+          fontSize: layout.compact ? 8 : 10,
+          fontWeight: 700,
+          lineHeight: layout.distributionTitleLineHeight + 6,
+          fontFamily: FONT_FAMILY
+        },
+        data: [{ name: '中心文字', value: 1 }],
+        animation: false,
+        tooltip: { show: false },
+        legend: { show: false },
+        // ✅ 关键:禁用所有交互
+        silent: true,
+        emphasis: {
+          scale: false,
+          label: { show: false }
+        }
+      },
+      // ===== 第三个饼图:积压数据(带外标签) =====
       {
         name: '积压库存',
         type: 'pie',
@@ -334,17 +334,14 @@ function getDistributionOption(
           bleedMargin: 0,
           formatter: '{b}\n{d}%',
           color: 'inherit',
-          fontSize: layout.labelFontSize,
+          fontSize: layout.distributionLabelFontSize,
           fontWeight: 500,
           fontFamily: FONT_FAMILY
         },
         labelLine: {
           show: true,
-          // length: layout.compact ? 6 : 10,
-          // length2: layout.compact ? 8 : 14,
           minTurnAngle: 90,
           lineStyle: {
-            color: distributionColors[0],
             width: 1.5,
             opacity: 1
           }
@@ -372,6 +369,33 @@ function getDistributionOption(
               }
             }
           }))
+      },
+      // ===== 第四个饼图:积压中心文字(不显示饼图) =====
+      {
+        name: '积压中心文字',
+        type: 'pie',
+        radius: ['0%', '0%'],
+        center: ['73%', layout.distributionPieCenterY],
+        label: {
+          show: true,
+          position: 'center',
+          formatter: `总积压\n${formatAmount(backlogTotal)}万元`,
+          color: THEME.text.strong,
+          fontSize: layout.compact ? 8 : 10,
+          fontWeight: 700,
+          lineHeight: layout.distributionTitleLineHeight + 6,
+          fontFamily: FONT_FAMILY
+        },
+        data: [{ name: '中心文字', value: 1 }],
+        animation: false,
+        tooltip: { show: false },
+        legend: { show: false },
+        // ✅ 关键:禁用所有交互
+        silent: true,
+        emphasis: {
+          scale: false,
+          label: { show: false }
+        }
       }
     ]
   }
@@ -422,6 +446,7 @@ function getInventoryAgingOption(data: unknown): echarts.EChartsOption {
     animation: false,
     grid: {
       ...THEME.grid,
+      left: layout.trendGridLeft,
       top: layout.trendGridTop,
       right: layout.trendGridRight,
       bottom: layout.trendGridBottom
@@ -434,7 +459,7 @@ function getInventoryAgingOption(data: unknown): echarts.EChartsOption {
     }),
     xAxis: {
       type: 'category',
-      boundaryGap: false,
+      boundaryGap: true,
       data: months,
       axisTick: { show: false },
       axisLabel: {
@@ -487,7 +512,7 @@ function getInventoryAgingOption(data: unknown): echarts.EChartsOption {
         label: {
           show: true,
           color: THEME.color.orange.line,
-          fontSize: layout.labelFontSize,
+          fontSize: layout.trendLabelFontSize,
           fontFamily: FONT_FAMILY,
           formatter(params: any) {
             return `${formatAmount(Number(params.value))}万`
@@ -529,7 +554,7 @@ function initTrendChart() {
 
 function resizeCharts() {
   distributionChart?.resize()
-  trendChart?.resize()
+  scheduleTrendResize()
 }
 
 function handleDistributionResize() {
@@ -539,6 +564,19 @@ function handleDistributionResize() {
   renderDistributionChart()
 }
 
+function scheduleTrendResize() {
+  if (trendResizeFrame !== null) return
+
+  trendResizeFrame = requestAnimationFrame(() => {
+    trendResizeFrame = null
+    if (activePanel.value !== 'trend' || !trendChartRef.value) return
+
+    if (!trendChart) initTrendChart()
+    trendChart?.resize()
+    renderTrendChart()
+  })
+}
+
 function destroyCharts() {
   distributionChart?.dispose()
   trendChart?.dispose()
@@ -632,6 +670,8 @@ onMounted(() => {
       initDistributionChart()
       distributionResizeObserver = new ResizeObserver(handleDistributionResize)
       distributionResizeObserver.observe(distributionChartRef.value!)
+      trendResizeObserver = new ResizeObserver(scheduleTrendResize)
+      trendResizeObserver.observe(trendChartRef.value!)
     })
   })
   window.addEventListener('resize', resizeCharts)
@@ -659,6 +699,12 @@ onUnmounted(() => {
   window.removeEventListener('rhkb:resize', resizeCharts)
   distributionResizeObserver?.disconnect()
   distributionResizeObserver = null
+  trendResizeObserver?.disconnect()
+  trendResizeObserver = null
+  if (trendResizeFrame !== null) {
+    cancelAnimationFrame(trendResizeFrame)
+    trendResizeFrame = null
+  }
   destroyCharts()
 })
 </script>