AlgoDataPanel copy.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <div class="algo-data">
  3. <span class="algo-tit">算法数据分析</span>
  4. <CensusTabs @check-tab="onCheckTab" />
  5. <v-chart class="chart" :option="option" />
  6. <div class="stat-show">
  7. <ViolationStatItem :data="getVioStatData(0)" />
  8. <div class="stat-divider"></div>
  9. <ViolationStatItem :data="getVioStatData(1)" />
  10. <div class="stat-divider"></div>
  11. <ViolationStatItem :data="getVioStatData(2)" />
  12. <div class="stat-divider"></div>
  13. <ViolationStatItem :data="getVioStatData(3)" />
  14. </div>
  15. </div>
  16. </template>
  17. <script setup lang="ts">
  18. import { computed, ref } from 'vue';
  19. import CensusTabs from './AlgoCensusTabs.vue';
  20. import ViolationStatItem from './ViolationStatItem.vue';
  21. import { TimeTabEnum, violationHandleCounts } from '../types';
  22. import { use } from 'echarts/core';
  23. import { CanvasRenderer } from 'echarts/renderers';
  24. import { PieChart } from 'echarts/charts';
  25. import { TooltipComponent, LegendComponent } from 'echarts/components';
  26. import { ViolationCount } from '@/api/home/home.ts';
  27. import VChart from 'vue-echarts';
  28. const props = defineProps<{
  29. data: ViolationCount;
  30. getViolations: (range: string[]) => void;
  31. }>();
  32. use([CanvasRenderer, PieChart, TooltipComponent, LegendComponent]);
  33. const algoData = computed(() => {
  34. let newData: any[] = [];
  35. const vioList = props.data.violationAlgoList;
  36. if (vioList && vioList.length) {
  37. newData = vioList.map((item) => {
  38. return {
  39. value: item.proportion,
  40. name: item.name,
  41. };
  42. });
  43. }
  44. console.log(newData);
  45. return newData;
  46. });
  47. // [
  48. // { value: 335, name: "人员闯入" },
  49. // { value: 310, name: "未穿反光背心" },
  50. // { value: 2, name: "明火烟雾" },
  51. // { value: 135, name: "机翼保护垫" },
  52. // { value: 148, name: "工装未归位" },
  53. // { value: 335, name: "人员闯入1" },
  54. // { value: 310, name: "未穿反光背心1" },
  55. // { value: 2, name: "明火烟雾1" },
  56. // { value: 135, name: "机翼保护垫1" },
  57. // { value: 148, name: "工装未归位1" },
  58. // ];
  59. const statData = computed(() => props.data.statusCountList);
  60. const getVioStatData = (index) => {
  61. let count = 0;
  62. if (statData.value && statData.value.length) {
  63. const matchItem = statData.value.find(
  64. (item) => item.name === violationHandleCounts[index].value,
  65. );
  66. if (matchItem) {
  67. count = matchItem.value;
  68. }
  69. }
  70. return { ...violationHandleCounts[index], count };
  71. };
  72. const option = computed(() => {
  73. return {
  74. tooltip: {
  75. trigger: 'item',
  76. formatter: '{a} <br/>{b} : {c} ({d}%)',
  77. },
  78. legend: {
  79. orient: 'horizontial',
  80. x: 'center',
  81. y: 'bottom',
  82. icon: 'circle',
  83. width: '80%',
  84. height: '28%',
  85. type: 'scroll',
  86. data: algoData.value.map((item) => item.name),
  87. formatter: function (name) {
  88. let total = 0;
  89. let target;
  90. for (let i = 0; i < algoData.value.length; i++) {
  91. total += algoData.value[i].value;
  92. if (algoData.value[i].name === name) {
  93. target = algoData.value[i].value;
  94. }
  95. }
  96. var arr = [
  97. '{a|' + name + '}',
  98. '{b|' + ' | ' + ((target / total) * 100).toFixed(0) + '%}\n',
  99. ];
  100. return arr.join(' ');
  101. },
  102. textStyle: {
  103. padding: [8, 0, 0, 0],
  104. fontSize: 14,
  105. rich: {
  106. a: {
  107. fontSize: 15,
  108. },
  109. b: {
  110. fontSize: 15,
  111. color: '#c1c1c1',
  112. },
  113. },
  114. },
  115. },
  116. series: [
  117. {
  118. name: '违规统计',
  119. type: 'pie',
  120. radius: ['40%', '65%'],
  121. center: ['50%', '40%'],
  122. labelLine: {
  123. show: false,
  124. },
  125. label: {
  126. show: false,
  127. position: 'center',
  128. },
  129. data: algoData.value,
  130. itemStyle: {
  131. borderColor: '#fff',
  132. borderWidth: 5,
  133. },
  134. emphasis: {
  135. label: {
  136. show: true,
  137. fontSize: 20,
  138. fontWeight: 'bold',
  139. },
  140. itemStyle: {
  141. shadowBlur: 10,
  142. shadowOffsetX: 0,
  143. shadowColor: 'rgba(0, 0, 0, 0.5)',
  144. },
  145. },
  146. },
  147. ],
  148. };
  149. });
  150. const timeTab = ref<TimeTabEnum>(TimeTabEnum.DAY);
  151. const onCheckTab = (info: { tab: TimeTabEnum; data: string[] }) => {
  152. timeTab.value = info.tab;
  153. props.getViolations(info.data);
  154. };
  155. </script>
  156. <style scoped>
  157. .algo-data {
  158. width: 484px;
  159. padding: 12px 27px;
  160. border-left: 2px solid #e8e8e8;
  161. display: flex;
  162. flex-direction: column;
  163. align-items: flex-start;
  164. }
  165. .chart {
  166. width: 100%;
  167. height: 450px;
  168. }
  169. .algo-tit {
  170. font-size: 16px;
  171. font-weight: 500;
  172. margin-bottom: 10px;
  173. line-height: 44px;
  174. color: #2e2e2e;
  175. }
  176. .stat-show {
  177. width: 100%;
  178. margin-top: 32px;
  179. display: flex;
  180. justify-content: space-between;
  181. align-items: center;
  182. }
  183. .stat-divider {
  184. width: 1px;
  185. height: 40px;
  186. background: #e9e9e9;
  187. }
  188. </style>