|
|
@@ -19,7 +19,13 @@
|
|
19
|
19
|
<div class="middle-row">
|
|
20
|
20
|
<div class="chart-card">
|
|
21
|
21
|
<div class="chart-title">查堵-物品位置分布</div>
|
|
22
|
|
- <div ref="chart1" class="echarts"></div>
|
|
|
22
|
+ <div class="grid-nine">
|
|
|
23
|
+ <div v-for="cell in gridPositions" :key="cell.position" class="grid-cell" :style="{ backgroundColor: cell.bgColor }">
|
|
|
24
|
+ <div class="cell-position">{{ cell.position }}</div>
|
|
|
25
|
+ <div class="cell-count">{{ cell.count }}次</div>
|
|
|
26
|
+ <div class="cell-percent">{{ cell.percent }}%</div>
|
|
|
27
|
+ </div>
|
|
|
28
|
+ </div>
|
|
23
|
29
|
</div>
|
|
24
|
30
|
<div class="chart-card">
|
|
25
|
31
|
<div class="chart-title">查堵-原因分类</div>
|
|
|
@@ -57,7 +63,7 @@
|
|
57
|
63
|
</template>
|
|
58
|
64
|
|
|
59
|
65
|
<script setup>
|
|
60
|
|
-import { ref, onMounted, reactive, watch } from 'vue'
|
|
|
66
|
+import { ref, onMounted, reactive, watch, computed } from 'vue'
|
|
61
|
67
|
import * as echarts from 'echarts'
|
|
62
|
68
|
import ModuleContainer from './ModuleContainer.vue'
|
|
63
|
69
|
import RankList from './RankList.vue'
|
|
|
@@ -83,7 +89,6 @@ const props = defineProps({
|
|
83
|
89
|
}
|
|
84
|
90
|
})
|
|
85
|
91
|
|
|
86
|
|
-const chart1 = ref(null)
|
|
87
|
92
|
const chart2 = ref(null)
|
|
88
|
93
|
const chart3 = ref(null)
|
|
89
|
94
|
const chart4 = ref(null)
|
|
|
@@ -91,7 +96,6 @@ const chart5 = ref(null)
|
|
91
|
96
|
const chart6 = ref(null)
|
|
92
|
97
|
const chart7 = ref(null)
|
|
93
|
98
|
|
|
94
|
|
-const { setOption: setOption1 } = useEcharts(chart1)
|
|
95
|
99
|
const { setOption: setOption2 } = useEcharts(chart2)
|
|
96
|
100
|
const { setOption: setOption3 } = useEcharts(chart3)
|
|
97
|
101
|
const { setOption: setOption4 } = useEcharts(chart4)
|
|
|
@@ -162,13 +166,7 @@ const loadData = async () => {
|
|
162
|
166
|
])
|
|
163
|
167
|
|
|
164
|
168
|
// 设置图表数据
|
|
165
|
|
- setOption1(pieOption(
|
|
166
|
|
- itemLocationRes?.value?.data?.map(item => ({
|
|
167
|
|
- name: item.itemLocation || '未知',
|
|
168
|
|
- value: item.count || 0
|
|
169
|
|
- })) || [],
|
|
170
|
|
- ['#3b82f6', '#22c55e', '#f97316', '#ec4899', '#8b5cf6', '#14b8a6', '#64748b']
|
|
171
|
|
- ))
|
|
|
169
|
+ locationData.value = itemLocationRes?.value?.data || []
|
|
172
|
170
|
|
|
173
|
171
|
setOption2(pieOption(
|
|
174
|
172
|
missCheckReasonRes?.value?.data?.map(item => ({
|
|
|
@@ -313,6 +311,27 @@ const rankData3 = reactive([
|
|
313
|
311
|
|
|
314
|
312
|
])
|
|
315
|
313
|
|
|
|
314
|
+const locationData = ref([])
|
|
|
315
|
+
|
|
|
316
|
+const gridPositions = computed(() => {
|
|
|
317
|
+ const positionOrder = ['左上', '中上', '右上', '左中', '中间', '右中', '左下', '中下', '右下']
|
|
|
318
|
+ const dataMap = {}
|
|
|
319
|
+ let maxCount = 0
|
|
|
320
|
+ locationData.value.forEach(item => {
|
|
|
321
|
+ dataMap[item.itemLocation] = item.count || 0
|
|
|
322
|
+ if (item.count > maxCount) maxCount = item.count
|
|
|
323
|
+ })
|
|
|
324
|
+ const total = locationData.value.reduce((sum, item) => sum + (item.count || 0), 0)
|
|
|
325
|
+
|
|
|
326
|
+ return positionOrder.map(position => {
|
|
|
327
|
+ const count = dataMap[position] || 0
|
|
|
328
|
+ const percent = total > 0 ? ((count / total) * 100).toFixed(1) : '0.0'
|
|
|
329
|
+ const ratio = maxCount > 0 ? count / maxCount : 0
|
|
|
330
|
+ const bgColor = `rgba(255, 193, 7, ${0.1 + ratio * 0.7})`
|
|
|
331
|
+ return { position, count, percent, bgColor }
|
|
|
332
|
+ })
|
|
|
333
|
+})
|
|
|
334
|
+
|
|
316
|
335
|
const pieOption = (data, colors, isRing = false) => ({
|
|
317
|
336
|
color: colors,
|
|
318
|
337
|
legend: {
|
|
|
@@ -454,4 +473,34 @@ onMounted(() => {
|
|
454
|
473
|
width: 100%;
|
|
455
|
474
|
min-height: 250px;
|
|
456
|
475
|
}
|
|
|
476
|
+
|
|
|
477
|
+.grid-nine {
|
|
|
478
|
+ display: grid;
|
|
|
479
|
+ grid-template-columns: repeat(3, 1fr);
|
|
|
480
|
+ gap: 4px;
|
|
|
481
|
+ flex: 1;
|
|
|
482
|
+ padding: 4px;
|
|
|
483
|
+}
|
|
|
484
|
+
|
|
|
485
|
+.grid-cell {
|
|
|
486
|
+ display: flex;
|
|
|
487
|
+ flex-direction: column;
|
|
|
488
|
+ align-items: center;
|
|
|
489
|
+ justify-content: center;
|
|
|
490
|
+ border-radius: 6px;
|
|
|
491
|
+ padding: 8px;
|
|
|
492
|
+ color: #000;
|
|
|
493
|
+}
|
|
|
494
|
+
|
|
|
495
|
+.cell-position {
|
|
|
496
|
+ font-size: 14px;
|
|
|
497
|
+ font-weight: bold;
|
|
|
498
|
+ margin-bottom: 4px;
|
|
|
499
|
+}
|
|
|
500
|
+
|
|
|
501
|
+.cell-count,
|
|
|
502
|
+.cell-percent {
|
|
|
503
|
+ font-size: 12px;
|
|
|
504
|
+ line-height: 1.5;
|
|
|
505
|
+}
|
|
457
|
506
|
</style>
|