ソースを参照

qhse看板安全生产天数修改

yanghao 1 週間 前
コミット
67ac3f5c9f
1 ファイル変更112 行追加57 行削除
  1. 112 57
      src/views/pms/qhse/kanban/index.vue

+ 112 - 57
src/views/pms/qhse/kanban/index.vue

@@ -45,7 +45,6 @@ type SafeDayMap = Record<string, number>
 
 type SummaryTabValue = 'home' | 'certificate'
 type QhseMetricValue = 'ltir' | 'trir' | 'pmva'
-
 const userStore = useUserStore()
 
 const type = ref('day')
@@ -342,10 +341,41 @@ function updateScale() {
 
 const staticData = ref<any>({})
 const safeDay = ref<SafeDayMap>({})
+const safeDayMonths = [
+  '1月',
+  '2月',
+  '3月',
+  '4月',
+  '5月',
+  '6月',
+  '7月',
+  '8月',
+  '9月',
+  '10月',
+  '11月',
+  '12月'
+]
+const safeDayTrendSeries = ref<Array<{ name: string; color: string; values: number[] }>>([])
 const summaryPanel = ref<any>(null)
 const total = ref(0)
 const instrumentExpired = ref(0)
 
+function buildSafeDayTrendSeries(baseData: SafeDayMap) {
+  const palette = ['#4f8dff', '#ff981f', '#52c41a', '#597ef7', '#722ed1', '#f2c94c']
+  const factors = [0.92, 0.95, 0.98, 1, 1.03, 1.05, 1.04, 1.06, 1.08, 1.07, 1.09, 1.1]
+
+  safeDayTrendSeries.value = Object.entries(baseData || {}).map(([name, value], index) => {
+    const baseValue = Number(value) || 0
+    return {
+      name,
+      color: palette[index % palette.length],
+      values: factors.map((factor, factorIndex) =>
+        Math.max(0, Number((baseValue * factor + factorIndex * 0.6).toFixed(1)))
+      )
+    }
+  })
+}
+
 async function getStatic() {
   const res = await IotDangerApi.getDangerStatistics(userStore.user.deptId)
   staticData.value = res.classify || []
@@ -504,99 +534,123 @@ function destroyHazardChart() {
   hazardChart = null
 }
 
-function getSafeDayEntries() {
-  return Object.entries(safeDay.value || {})
-    .map(([label, value]) => ({
-      label,
-      value: Number(value) || 0
-    }))
-    .sort((a, b) => a.value - b.value)
-}
-
 function getSafeDayChartOption(): echarts.EChartsOption {
-  const entries = getSafeDayEntries()
-
   return {
     ...ANIMATION,
+    legend: {
+      top: 0,
+      left: 25,
+      bottom: 10,
+
+      itemWidth: 10,
+      itemHeight: 10,
+      icon: 'circle',
+      textStyle: {
+        color: '#7f92af',
+        fontSize: 12,
+        fontWeight: 600,
+        fontFamily: FONT_FAMILY
+      }
+    },
     grid: {
       left: 32,
-      right: 32,
-      top: 12,
-      bottom: 24,
+      right: 20,
+      top: 42,
+      bottom: 10,
       containLabel: true
     },
     tooltip: createTooltip({
       trigger: 'axis',
+      // position: 'bottom',
       confine: true,
       appendToBody: false,
       axisPointer: {
-        type: 'shadow',
-        shadowStyle: {
-          color: 'rgba(31, 91, 184, 0.08)'
+        type: 'line',
+        lineStyle: {
+          color: 'rgba(79, 141, 255, 0.35)',
+          width: 1
         }
       },
       formatter(params: any) {
         if (!params || (Array.isArray(params) && params.length === 0)) return ''
-        const item = Array.isArray(params) ? params[0] : params
-        return `${item.name}<br/>安全天数:${item.value}`
+        const items = Array.isArray(params) ? params : [params]
+        const lines = items.map(
+          (item) =>
+            `${item.marker}${item.seriesName}:<span style="font-weight:700">${item.value}</span>`
+        )
+        return `${items[0].axisValue}<br/>${lines.join('<br/>')}`
       }
     }),
     xAxis: {
+      type: 'category',
+      boundaryGap: false,
+      data: safeDayMonths,
+      axisLine: {
+        lineStyle: {
+          color: 'rgba(106, 144, 221, 0.45)'
+        }
+      },
+      axisTick: { show: false },
+      axisLabel: {
+        color: '#5b6f8f',
+        fontSize: 12,
+        fontWeight: 600,
+        fontFamily: FONT_FAMILY
+      }
+    },
+    yAxis: {
       type: 'value',
       name: '安全生产天数',
-      nameLocation: 'middle',
-      nameGap: 30,
+      // nameLocation: 'end',
+      nameGap: 0,
+
       nameTextStyle: {
-        color: '#5b6f8f',
+        color: '#657897',
         fontSize: 12,
-        fontWeight: 600,
         fontFamily: FONT_FAMILY
       },
       axisLine: { show: false },
       axisTick: { show: false },
       axisLabel: {
-        color: '#263854',
+        color: '#8a9bb5',
         fontSize: 12,
         fontFamily: FONT_FAMILY
       },
       splitLine: {
         lineStyle: {
-          color: 'rgba(83, 114, 173, 0.6)',
+          color: 'rgba(104, 139, 205, 0.22)',
           type: 'dashed'
         }
       }
     },
-    yAxis: {
-      type: 'category',
-      data: entries.map((item) => item.label),
-      axisLine: { show: false },
-      axisTick: { show: false },
-      axisLabel: {
-        color: '#16263d',
-        fontSize: 14,
-        fontWeight: 700,
-        fontFamily: FONT_FAMILY
-      }
-    },
-    series: [
-      {
-        type: 'bar',
-        data: entries.map((item) => item.value),
-        barWidth: 16,
-        showBackground: true,
-        backgroundStyle: {
-          color: 'rgba(108, 149, 228, 0.08)',
-          borderRadius: 6
-        },
-        itemStyle: {
-          borderRadius: 6,
-          color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
-            { offset: 0, color: '#78a0ec' },
-            { offset: 1, color: '#6a90dd' }
-          ])
-        }
+    series: safeDayTrendSeries.value.map((item) => ({
+      name: item.name,
+      type: 'line',
+      smooth: true,
+      emphasis: {
+        focus: 'series'
+      },
+      // areaStyle: {
+      //   color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+      //     { offset: 0, color: item.color },
+      //     { offset: 1, color: `${item.color}99` }
+      //   ])
+      // },
+      symbolSize: 7,
+      showSymbol: true,
+      data: item.values,
+      lineStyle: {
+        width: 2,
+        color: item.color,
+        bgColor: '#000'
+      },
+      itemStyle: {
+        color: item.color,
+        borderColor: item.color,
+        bgColor: '#000',
+        borderWidth: 1
       }
-    ]
+    }))
   }
 }
 
@@ -868,6 +922,7 @@ async function loadHomeBoard() {
   hazardBars.value[2].value = summaryPanel.value.todoHazard || 0
 
   safeDay.value = (await kanbanApi.getSafeDay(userStore.getUser.deptId)) || {}
+  buildSafeDayTrendSeries(safeDay.value)
 
   await Promise.all([getStatic(), getCertStatic(), getInstrumentOverview()])
 
@@ -1557,7 +1612,7 @@ onUnmounted(() => {
 }
 
 .safe-day-chart-panel {
-  height: 218px;
+  height: 230px;
 }
 
 .qhse-metric-tabs {