running.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <template>
  2. <div class="_running">
  3. <HeadlineTag type="right" value="运行统计"></HeadlineTag>
  4. <div class="_running_mains">
  5. <div class="flex_person">
  6. <div ref="chartAccessLeft" style="width: 100%;height: 100%;"></div>
  7. </div>
  8. </div>
  9. </div>
  10. </template>
  11. <script setup>
  12. import { ref } from "vue";
  13. import HeadlineTag from '@/components/HeadlineTag'
  14. import * as echarts from 'echarts'
  15. const props = defineProps({
  16. resultData: {
  17. type: Object,
  18. default: {}
  19. }
  20. })
  21. const chartAccessLeft = ref(null);
  22. let chartLeft = null;
  23. let chartRight = null;
  24. const initAccess = () => {
  25. let data = [
  26. {
  27. name: '设备总数',
  28. value: 0,
  29. },
  30. {
  31. name: '网关数量',
  32. value: 0,
  33. },
  34. {
  35. name: '策略总量',
  36. value: 0,
  37. },
  38. {
  39. name: '报警数量',
  40. value: 0,
  41. },
  42. ];
  43. let arrName = getArrayValue(data, 'name');
  44. let arrValue = getArrayValue(data, 'value');
  45. let sumValue = eval(arrValue.join('+'));
  46. let objData = array2obj(data, 'name');
  47. let optionData = getData(data);
  48. function getArrayValue(array, key) {
  49. var key = key || 'value';
  50. var res = [];
  51. if (array) {
  52. array.forEach(function (t) {
  53. res.push(t[key]);
  54. });
  55. }
  56. return res;
  57. }
  58. function array2obj(array, key) {
  59. var resObj = {};
  60. for (var i = 0; i < array.length; i++) {
  61. resObj[array[i][key]] = array[i];
  62. }
  63. return resObj;
  64. }
  65. function getData(data) {
  66. var res = {
  67. series: [],
  68. yAxis: [],
  69. };
  70. for (let i = 0; i < data.length; i++) {
  71. res.series.push({
  72. // name: '职员1',
  73. type: 'pie',
  74. clockwise: true, //顺时加载
  75. emphasis: {
  76. scale: false
  77. },
  78. //鼠标移入变大
  79. radius: [65 - i * 15 + '%', 57 - i * 15 + '%'],
  80. center: ['30%', '55%'],
  81. label: {
  82. show: false,
  83. },
  84. itemStyle: {
  85. label: {
  86. show: false,
  87. },
  88. labelLine: {
  89. show: false,
  90. },
  91. borderWidth: 5,
  92. },
  93. data: [
  94. {
  95. value: data[i].value,
  96. name: data[i].name,
  97. },
  98. {
  99. value: sumValue - data[i].value,
  100. name: '',
  101. itemStyle: {
  102. color: 'rgba(0,0,0,0)',
  103. borderWidth: 0,
  104. },
  105. tooltip: {
  106. show: false,
  107. },
  108. emphasis: {
  109. scale: false
  110. },
  111. },
  112. ],
  113. });
  114. res.series.push({
  115. name: '',
  116. type: 'pie',
  117. silent: true,
  118. z: 1,
  119. clockwise: true, //顺时加载
  120. emphasis: {
  121. scale: false
  122. },
  123. //鼠标移入变大
  124. radius: [65 - i * 15 + '%', 57 - i * 15 + '%'],
  125. center: ['30%', '55%'],
  126. label: {
  127. show: false,
  128. },
  129. itemStyle: {
  130. label: {
  131. show: false,
  132. },
  133. labelLine: {
  134. show: false,
  135. },
  136. borderWidth: 5,
  137. },
  138. data: [
  139. {
  140. value: 7.5,
  141. itemStyle: {
  142. color: '#E3F0FF',
  143. borderWidth: 0,
  144. },
  145. tooltip: {
  146. show: false,
  147. },
  148. emphasis: {
  149. scale: false
  150. },
  151. },
  152. {
  153. value: 2.5,
  154. name: '',
  155. itemStyle: {
  156. color: 'rgba(0,0,0,0)',
  157. borderWidth: 0,
  158. },
  159. tooltip: {
  160. show: false,
  161. },
  162. emphasis: {
  163. scale: false
  164. },
  165. },
  166. ],
  167. });
  168. res.yAxis.push(((data[i].value / sumValue) * 100).toFixed(2) + '%');
  169. }
  170. return res;
  171. }
  172. chartLeft = echarts.init(chartAccessLeft.value);
  173. let option = {
  174. // backgroundColor: '#fff',
  175. legend: {//图例设置
  176. show: true,
  177. top: '35%',
  178. left: '60%',
  179. data: arrName,
  180. itemWidth: 15,
  181. itemHeight: 15,
  182. width: 70,
  183. padding: [0, 5],
  184. itemGap: 20,
  185. formatter: function (name) {
  186. return '{title|' + name + '}-{value|' + objData[name].value + '}';
  187. },
  188. textStyle: {
  189. rich: {
  190. title: {
  191. fontSize: 12,
  192. lineHeight: 10,
  193. color: '#fff',
  194. },
  195. value: {
  196. fontSize: 12,
  197. lineHeight: 10,
  198. color: '#fff',
  199. },
  200. },
  201. },
  202. },
  203. tooltip: {
  204. show: true,
  205. trigger: 'item',
  206. formatter: '{a}<br>{b}:{c}({d}%)',
  207. textStyle: {
  208. color: '#fafafa',
  209. },
  210. borderColor: 'transparent',
  211. backgroundColor: 'rgba(0, 0, 0, 0.5)',
  212. extraCssText: 'backdrop-filter: blur(6px);',
  213. },
  214. color: ['#409eff', '#15acaa', '#FFC107', 'rgb(244, 67, 54)'],
  215. grid: {
  216. top: '20%',
  217. bottom: '48%',
  218. left: '20%',
  219. containLabel: false,
  220. },
  221. yAxis: [
  222. {
  223. type: 'category',
  224. inverse: true,
  225. axisLine: {
  226. show: false,
  227. },
  228. axisTick: {
  229. show: false,
  230. },
  231. axisLabel: {
  232. interval: 0,
  233. inside: true,
  234. textStyle: {
  235. color: '#fff',
  236. fontSize: 10,
  237. },
  238. show: true,
  239. },
  240. data: optionData.yAxis,
  241. },
  242. ],
  243. xAxis: [
  244. {
  245. show: true,
  246. },
  247. ],
  248. series: optionData.series,
  249. };
  250. chartLeft.setOption(option)
  251. };
  252. watch(() => props.resultData, (newVal) => {
  253. if (chartLeft && newVal && Object.keys(newVal).length != 0) {
  254. let data = [
  255. {
  256. name: '设备总数',
  257. value: newVal.DeviceCount,
  258. },
  259. {
  260. name: '网关数量',
  261. value: newVal.GatewayCount,
  262. },
  263. {
  264. name: '策略总量',
  265. value: newVal.OffCount,
  266. },
  267. {
  268. name: '报警数量',
  269. value: newVal.AlarmCount,
  270. },
  271. ];
  272. let arrName = getArrayValue(data, 'name');
  273. let arrValue = getArrayValue(data, 'value');
  274. let sumValue = eval(arrValue.join('+'));
  275. let objData = array2obj(data, 'name');
  276. let optionData = getData(data);
  277. function getArrayValue(array, key) {
  278. var key = key || 'value';
  279. var res = [];
  280. if (array) {
  281. array.forEach(function (t) {
  282. res.push(t[key]);
  283. });
  284. }
  285. return res;
  286. }
  287. function array2obj(array, key) {
  288. var resObj = {};
  289. for (var i = 0; i < array.length; i++) {
  290. resObj[array[i][key]] = array[i];
  291. }
  292. return resObj;
  293. }
  294. function getData(data) {
  295. var res = {
  296. series: [],
  297. yAxis: [],
  298. };
  299. for (let i = 0; i < data.length; i++) {
  300. res.series.push({
  301. // name: '职员1',
  302. type: 'pie',
  303. clockwise: true, //顺时加载
  304. emphasis: {
  305. scale: false
  306. },
  307. //鼠标移入变大
  308. radius: [65 - i * 15 + '%', 57 - i * 15 + '%'],
  309. center: ['30%', '55%'],
  310. label: {
  311. show: false,
  312. },
  313. itemStyle: {
  314. label: {
  315. show: false,
  316. },
  317. labelLine: {
  318. show: false,
  319. },
  320. borderWidth: 5,
  321. },
  322. data: [
  323. {
  324. value: data[i].value,
  325. name: data[i].name,
  326. },
  327. {
  328. value: sumValue - data[i].value,
  329. name: '',
  330. itemStyle: {
  331. color: 'rgba(0,0,0,0)',
  332. borderWidth: 0,
  333. },
  334. tooltip: {
  335. show: false,
  336. },
  337. emphasis: {
  338. scale: false
  339. },
  340. },
  341. ],
  342. });
  343. res.series.push({
  344. name: '',
  345. type: 'pie',
  346. silent: true,
  347. z: 1,
  348. clockwise: true, //顺时加载
  349. emphasis: {
  350. scale: false
  351. },
  352. //鼠标移入变大
  353. radius: [65 - i * 15 + '%', 57 - i * 15 + '%'],
  354. center: ['30%', '55%'],
  355. label: {
  356. show: false,
  357. },
  358. itemStyle: {
  359. label: {
  360. show: false,
  361. },
  362. labelLine: {
  363. show: false,
  364. },
  365. borderWidth: 5,
  366. },
  367. data: [
  368. {
  369. value: 7.5,
  370. itemStyle: {
  371. color: '#E3F0FF',
  372. borderWidth: 0,
  373. },
  374. tooltip: {
  375. show: false,
  376. },
  377. emphasis: {
  378. scale: false
  379. },
  380. },
  381. {
  382. value: 2.5,
  383. name: '',
  384. itemStyle: {
  385. color: 'rgba(0,0,0,0)',
  386. borderWidth: 0,
  387. },
  388. tooltip: {
  389. show: false,
  390. },
  391. emphasis: {
  392. scale: false
  393. },
  394. },
  395. ],
  396. });
  397. res.yAxis.push(((data[i].value / sumValue) * 100).toFixed(2) + '%');
  398. }
  399. return res;
  400. }
  401. chartLeft.setOption({
  402. legend: {
  403. data: arrName,
  404. formatter: function (name) {
  405. return '{title|' + name + '}-{value|' + objData[name].value + '}';
  406. },
  407. },
  408. xAxis: [
  409. {
  410. show: true,
  411. },
  412. ],
  413. yAxis: [{
  414. type: 'category',
  415. data: optionData.yAxis,
  416. }],
  417. series: optionData.series,
  418. })
  419. }
  420. }, { deep: true, immediate: true } // 开启深度监听
  421. )
  422. // 生命周期
  423. onMounted(() => {
  424. initAccess()
  425. });
  426. // 窗口自适应
  427. window.addEventListener('resize', () => {
  428. chartLeft?.resize();
  429. chartRight?.resize();
  430. });
  431. </script>
  432. <style lang="scss" scoped>
  433. ._running {
  434. display: flex;
  435. flex-direction: column;
  436. &_mains {
  437. flex: 1;
  438. display: flex;
  439. &_left {
  440. width: 150px;
  441. height: 150px;
  442. position: relative;
  443. flex-shrink: 0;
  444. &_tuan {
  445. width: 100%;
  446. height: 100%;
  447. background: url("@/assets/images/content_circle.png");
  448. background-size: 100% 100%;
  449. background-position: center;
  450. background-repeat: no-repeat;
  451. animation: scanning 4s linear infinite;
  452. }
  453. &_conter {
  454. position: absolute;
  455. left: 0;
  456. top: 0;
  457. flex-shrink: 0;
  458. width: 100%;
  459. height: 100%;
  460. display: flex;
  461. flex-direction: column;
  462. align-items: center;
  463. justify-content: center;
  464. color: #fff;
  465. &_num {
  466. font-size: 18px;
  467. }
  468. &_text {
  469. font-size: 12px;
  470. }
  471. }
  472. }
  473. &_right {
  474. margin-left: 10px;
  475. flex: 1;
  476. color: #fff;
  477. &_item {
  478. display: flex;
  479. align-items: center;
  480. gap: 40px;
  481. padding: 5px 0;
  482. &_tuan {
  483. display: flex;
  484. align-items: center;
  485. &_flag {
  486. display: block;
  487. width: 7px;
  488. height: 7px;
  489. border-radius: 50%;
  490. margin-right: 10px;
  491. }
  492. }
  493. &__txt {
  494. font-size: 24px;
  495. }
  496. }
  497. }
  498. }
  499. }
  500. .flex_person {
  501. flex: 1;
  502. width: 100%;
  503. height: 100%;
  504. }
  505. @keyframes scanning {
  506. to {
  507. transform: rotate(1turn);
  508. }
  509. }
  510. </style>