wangrong
7 天以前 5ebdf612b8291106370bba5e79996b28a7452e67
src/modules/report/views/screen/map.vue
@@ -17,7 +17,15 @@
               <template #extra>
                  <cl-select-button v-model="mixMetric" :options="mixOptions" small />
               </template>
               <v-chart :option="mixOption" autoresize class="chart" />
               <screen-drill-chart
                  class="chart"
                  type="pie"
                  :source="data.wasteMix"
                  :metric="mixMetric"
                  :unit="mixUnit"
                  :center="['50%', '50%']"
                  :radius="['38%', '62%']"
               />
            </panel-card>
            <panel-card
@@ -25,7 +33,16 @@
               :demo="isDemoSection('recycleItems')"
               class="dash-card dash-card--flex"
            >
               <v-chart :option="carbonOption" autoresize class="chart" />
               <screen-drill-chart
                  class="chart"
                  type="pie"
                  :source="data.recycleItems"
                  metric="carbon"
                  unit="kgCO₂e"
                  name-suffix="回收"
                  :center="['50%', '50%']"
                  :radius="['36%', '60%']"
               />
            </panel-card>
         </div>
@@ -57,7 +74,14 @@
               <template #extra>
                  <cl-select-button v-model="itemMetric" :options="itemOptions" small />
               </template>
               <v-chart :option="itemOption" autoresize class="chart chart--items" />
               <screen-drill-chart
                  class="chart chart--items"
                  type="bar"
                  :source="data.recycleItems"
                  :metric="itemMetric"
                  :unit="itemUnit"
                  :even-split="false"
               />
            </panel-card>
         </div>
      </div>
@@ -85,12 +109,12 @@
import ScreenMapPanel from '../../components/screen-map-panel.vue';
import CameraMonitor from '../../../monitor/views/cameras.vue';
import { TIME_RANGE_OPTIONS } from '../../data/screen';
import { chartSeries, pieTooltipFormatter, toPieData } from '../../data/screen-chart';
import ScreenDrillChart from '../../components/screen-drill-chart.vue';
import { useChartTheme, useScreenData, useScreenFieldSource } from '../../hooks/use-screen';
const { data, timeRange } = useScreenData();
const { isDemoSection } = useScreenFieldSource();
const { textColor, mutedColor, splitColor, primary, baseGrid, axisStyle, tooltip } = useChartTheme();
const { mutedColor, splitColor, primary, baseGrid, axisStyle, tooltip } = useChartTheme();
const mixMetric = ref<'weight' | 'value' | 'count'>('weight');
const trendMetric = ref<'weight' | 'value' | 'carbon'>('weight');
@@ -141,45 +165,11 @@
   return 'kg';
});
/** 垃圾分类结构(饼) */
const mixOption = computed(() => ({
   tooltip: { trigger: 'item', ...tooltip(), formatter: pieTooltipFormatter() },
   series: [
      {
         type: 'pie',
         radius: ['38%', '62%'],
         center: ['50%', '50%'],
         padAngle: 3,
         itemStyle: { borderRadius: 6 },
         label: { color: textColor.value, formatter: '{b}\n{d}%' },
         data: toPieData(
            chartSeries(data.value.wasteMix, e => e[mixMetric.value]),
            e => e.name,
            e => e.color
         )
      }
   ]
}));
/** 碳减排来源(饼):碳值可为负,按绝对值展示减排量 */
const carbonOption = computed(() => ({
   tooltip: { trigger: 'item', ...tooltip(), formatter: pieTooltipFormatter('kgCO₂e') },
   series: [
      {
         type: 'pie',
         radius: ['36%', '60%'],
         center: ['50%', '50%'],
         padAngle: 3,
         itemStyle: { borderRadius: 6 },
         label: { color: textColor.value, formatter: '{b}\n{d}%' },
         data: toPieData(
            chartSeries(data.value.recycleItems, e => e.carbon, { carbon: true }),
            e => e.name + '回收',
            e => e.color
         )
      }
   ]
}));
const mixUnit = computed(() => {
   if (mixMetric.value === 'value') return '元';
   if (mixMetric.value === 'count') return '次';
   return 'kg';
});
/** 回收趋势(折线) */
const trendOption = computed(() => ({
@@ -207,51 +197,6 @@
   ]
}));
/** 各类回收量(横向条形) */
const itemOption = computed(() => {
   const carbon = itemMetric.value === 'carbon';
   const rows = chartSeries(
      data.value.recycleItems,
      e => Number(e[itemMetric.value] || 0),
      { carbon, evenSplit: false }
   ).reverse();
   return {
      grid: { containLabel: true, left: 8, right: 24, top: 12, bottom: 8 },
      tooltip: {
         trigger: 'axis',
         axisPointer: { type: 'shadow' },
         valueFormatter: (v: number) => `${Number(v || 0).toLocaleString()} ${itemUnit.value}`,
         ...tooltip()
      },
      xAxis: {
         type: 'value',
         name: itemUnit.value,
         nameTextStyle: { color: mutedColor.value },
         splitLine: { lineStyle: { color: splitColor.value, type: 'dashed' } },
         axisLabel: { color: mutedColor.value },
         axisLine: { show: false },
         axisTick: { show: false }
      },
      yAxis: {
         type: 'category',
         data: rows.map(e => e.item.name),
         axisLabel: { color: textColor.value },
         axisLine: { show: false },
         axisTick: { show: false }
      },
      series: [
         {
            type: 'bar',
            barWidth: 14,
            data: rows.map(e => e.value),
            itemStyle: {
               borderRadius: [0, 8, 8, 0],
               color: (params: any) => rows[params.dataIndex]?.item.color || primary.value
            }
         }
      ]
   };
});
</script>
<style lang="scss" scoped>