passable.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. <template>
  2. <div class="person_box">
  3. <dv-border-box-1>
  4. <div class="box_monitoring">
  5. <div class="flex_spection box_tion_zx">
  6. <div class="line_blue">
  7. <div class="blue_dot"></div>
  8. </div>
  9. <div class="monit_title">应到岗</div>
  10. <span class="monit_num">{{ resultData.Fault || 0 }}人</span>
  11. </div>
  12. <div class="camera">
  13. <div class="entry-box">
  14. <div class="entry-box-item">
  15. <div class="item-center-line"></div>
  16. <div class="item-center-pie"></div>
  17. </div>
  18. </div>
  19. <div class="img_camera">
  20. <div ref="chartDistrict" style="width: 100%;height: 100%;"></div>
  21. </div>
  22. </div>
  23. <div class="flex_spection box_tion_lx">
  24. <div class="line_green">
  25. <div class="green_dot"></div>
  26. </div>
  27. <div class="monit_title">实际到岗</div>
  28. <span class="monit_num">{{ resultData.Offline || 0 }}人</span>
  29. </div>
  30. </div>
  31. </dv-border-box-1>
  32. </div>
  33. </template>
  34. <script setup>
  35. import * as echarts from 'echarts'
  36. const props = defineProps({
  37. resultData: {
  38. type: Object,
  39. default: {}
  40. }
  41. })
  42. const chartDistrict = ref(null);
  43. let chartDom = null;
  44. const initAccess = (valueNum) => {
  45. if (!chartDom) {
  46. chartDom = echarts.init(chartDistrict.value);
  47. }
  48. let attendanceRate = valueNum
  49. let option = {
  50. graphic: {
  51. elements: [
  52. {
  53. zlevel: 101,
  54. type: 'rect',
  55. left: 'center',
  56. top: 396,
  57. shape: {
  58. x: 0, // 矩形的 x 坐标
  59. y: 0, // 矩形的 y 坐标
  60. width: 22, // 矩形的宽度
  61. height: 3, // 矩形的高度
  62. },
  63. style: {
  64. fill: '#005AFF', // 设置背景颜色为半透明白色
  65. stroke: 'none',
  66. },
  67. },
  68. {
  69. zlevel: 101,
  70. type: 'text',
  71. left: 'center',
  72. top: 110,
  73. style: {
  74. text: '出勤率',
  75. textAlign: 'center',
  76. fill: '#75AFFC',
  77. fontSize: 12,
  78. },
  79. },
  80. ],
  81. },
  82. series: [
  83. {
  84. title: {
  85. show: false,
  86. offsetCenter: [0, '10%'],
  87. padding: [0, 0],
  88. fontSize: 12,
  89. color: '#E9F7FF',
  90. },
  91. zlevel: 100,
  92. name: '外部',
  93. type: 'gauge',
  94. radius: '95%',
  95. center: ['50%', '50%'],
  96. itemStyle: {
  97. color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
  98. {
  99. offset: 0,
  100. color: '#030C1D',
  101. },
  102. {
  103. offset: 0.5,
  104. color: '#005AFF',
  105. },
  106. {
  107. offset: 1,
  108. color: '#005AFF',
  109. },
  110. ]),
  111. },
  112. progress: {
  113. show: true,
  114. width: 5,
  115. roundCap: false,
  116. },
  117. axisLine: {
  118. lineStyle: {
  119. width: 2,
  120. type: 'dashed',
  121. color: [[1, '#a3b3d0']],
  122. },
  123. },
  124. sartAngle: 225,
  125. endAngle: -45,
  126. clockwise: true,
  127. min: 0,
  128. max: 100,
  129. splitNumber: 10,
  130. axisLabel: {
  131. textStyle: {
  132. color: '#75AFFC',
  133. fontSize: 12,
  134. },
  135. },
  136. pointer: {
  137. show: false,
  138. icon: 'triangle',
  139. width: '40%', //指针的宽度
  140. length: '170%', //指针长度,按照半圆半径的百分比
  141. },
  142. detail: {
  143. valueAnimation: true,
  144. offsetCenter: [0, '-3%'],
  145. fontSize: 20,
  146. color: '#E9F7FF',
  147. textStyle: {
  148. fontFamily: 'MyFont2',
  149. },
  150. formatter: function (val) {
  151. let str = val + '{a|%}'
  152. return str
  153. },
  154. rich: {
  155. a: {
  156. color: '#E9F7FF',
  157. fontSize: 10,
  158. padding: [10, 0, 0, 0],
  159. },
  160. },
  161. },
  162. markPoint: {
  163. symbol: 'circle',
  164. symbolSize: 0,
  165. data: [
  166. {
  167. x: 'center',
  168. y: '50%',
  169. itemStyle: {
  170. color: ' rgba(23,39,90,0.54)', // 指针颜色,默认(auto)取数值所在的区间的颜色
  171. borderWidth: 1, // 描边线宽,默认 0。为 0 时无描边。
  172. borderType: 'solid', // 柱条的描边类型,默认为实线,支持 'solid', 'dashed', 'dotted'。
  173. borderColor: '#3375E8', // 图形的描边颜色,默认 "#000"。支持的颜色格式同 color,不支持回调函数。
  174. shadowBlur: 5, // (发光效果)图形阴影的模糊大小。该属性配合 shadowColor,shadowOffsetX, shadowOffsetY 一起设置图形的阴影效果。
  175. shadowColor: '#08398b',
  176. opacity: 1,
  177. },
  178. },
  179. ],
  180. },
  181. data: [
  182. {
  183. name: '完成率',
  184. value: attendanceRate,
  185. },
  186. ],
  187. },
  188. {
  189. name: '内部刻度',
  190. type: 'gauge',
  191. backgroundColor: '#071d3f',
  192. center: ['50%', '50%'],
  193. itemStyle: {
  194. shadowBlur: 10, // (发光效果)图形阴影的模糊大小。该属性配合 shadowColor,shadowOffsetX, shadowOffsetY 一起设置图形的阴影效果。
  195. shadowColor: '#08398b',
  196. color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
  197. {
  198. offset: 0,
  199. color: '#0548c3',
  200. },
  201. {
  202. offset: 1,
  203. color: '#005afe',
  204. },
  205. ]),
  206. },
  207. progress: {
  208. show: true,
  209. width: 2,
  210. },
  211. radius: '70%',
  212. axisTick: {
  213. //一个一个的小刻度
  214. show: false,
  215. },
  216. axisLabel: {
  217. //周围刻度线的数字
  218. show: false,
  219. },
  220. splitLine: {
  221. show: false,
  222. },
  223. detail: {
  224. show: false,
  225. },
  226. axisLine: {
  227. show: false,
  228. },
  229. // 指针
  230. pointer: {
  231. icon: 'triangle',
  232. width: '90%', //指针的宽度
  233. length: '66%', //指针长度,按照半圆半径的百分比
  234. },
  235. data: [
  236. {
  237. name: '',
  238. value: attendanceRate,
  239. },
  240. ],
  241. },
  242. {
  243. name: '内部圆圈',
  244. type: 'gauge',
  245. center: ['50%', '50%'],
  246. itemStyle: {
  247. shadowBlur: 10, // (发光效果)图形阴影的模糊大小。该属性配合 shadowColor,shadowOffsetX, shadowOffsetY 一起设置图形的阴影效果。
  248. shadowColor: '#08398b',
  249. color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
  250. {
  251. offset: 0,
  252. color: '#061d3e',
  253. },
  254. {
  255. offset: 0.5,
  256. color: '#073b97',
  257. },
  258. ]),
  259. },
  260. progress: {
  261. show: true,
  262. width: 2,
  263. },
  264. // 指针圆
  265. radius: '36%',
  266. axisTick: {
  267. //一个一个的小刻度
  268. show: false,
  269. },
  270. axisLabel: {
  271. //周围刻度线的数字
  272. show: false,
  273. },
  274. splitLine: {
  275. show: false,
  276. },
  277. detail: {
  278. show: false,
  279. },
  280. pointer: {
  281. show: false,
  282. },
  283. axisLine: {
  284. show: false,
  285. },
  286. data: [
  287. {
  288. name: '',
  289. value: 100,
  290. },
  291. ],
  292. },
  293. {
  294. name: '遮罩',
  295. tooltip: {
  296. show: false,
  297. },
  298. type: 'pie',
  299. radius: '36%',
  300. center: ['50%', '50%'], // 默认全局居中
  301. hoverAnimation: false,
  302. itemStyle: {
  303. normal: {
  304. color: '#071d3f',
  305. },
  306. emphasis: {
  307. color: '#071d3f',
  308. },
  309. },
  310. labelLine: {
  311. normal: {
  312. show: false,
  313. },
  314. },
  315. animation: false,
  316. data: [1.9],
  317. },
  318. ],
  319. };
  320. chartDom.setOption(option)
  321. };
  322. watch(() => props.resultData, (newVal) => {
  323. if (chartDom) {
  324. initAccess(newVal.Abnormal)
  325. }
  326. }, { deep: true, immediate: true } // 开启深度监听
  327. )
  328. // 生命周期
  329. onMounted(() => {
  330. initAccess(0)
  331. });
  332. // 窗口自适应
  333. window.addEventListener('resize', () => {
  334. chartDom?.resize();
  335. });
  336. </script>
  337. <style scoped lang="scss">
  338. .person_box {
  339. width: 100%;
  340. height: 100%;
  341. // padding: 0px;
  342. display: flex;
  343. align-items: center;
  344. padding-top: 10px;
  345. padding-right: 10px;
  346. }
  347. .box_monitoring {
  348. display: flex;
  349. align-items: center;
  350. height: 100%;
  351. padding: 20px;
  352. }
  353. .line_blue {
  354. position: relative;
  355. height: 5px;
  356. width: 70%;
  357. background-color: rgba(5, 125, 230, .5);
  358. margin-bottom: 10px;
  359. }
  360. .blue_dot {
  361. position: absolute;
  362. left: 5px;
  363. top: 0;
  364. bottom: 0;
  365. width: 20px;
  366. border-left: 5px solid #000;
  367. border-right: 5px solid #000;
  368. background-color: rgba(5, 125, 230, 1);
  369. }
  370. .line_green {
  371. position: relative;
  372. height: 5px;
  373. width: 70%;
  374. background-color: rgba(5, 227, 227, .5);
  375. margin-bottom: 10px;
  376. }
  377. .green_dot {
  378. position: absolute;
  379. left: 5px;
  380. top: 0;
  381. bottom: 0;
  382. width: 20px;
  383. border-left: 5px solid #000;
  384. border-right: 5px solid #000;
  385. background-color: rgba(5, 227, 227, 1);
  386. }
  387. .img_camera {
  388. position: absolute;
  389. width: 200px;
  390. height: 200px;
  391. top: calc(50% - 100px);
  392. left: calc(50% - 100px);
  393. border-radius: 50%;
  394. border: 1px solid rgb(15, 39, 66);
  395. // box-shadow: inset 0px 0px 20px 2px rgb(78, 207, 220);
  396. }
  397. .flex_spection {
  398. flex: 1;
  399. }
  400. .box_tion_zx {
  401. display: flex;
  402. flex-direction: column;
  403. align-items: center;
  404. }
  405. .box_tion_lx {
  406. display: flex;
  407. flex-direction: column;
  408. align-items: center;
  409. }
  410. .camera {
  411. width: 240px;
  412. height: 100%;
  413. display: flex;
  414. position: relative;
  415. .entry-box {
  416. width: 100%;
  417. height: 100%;
  418. object-fit: fill;
  419. position: absolute;
  420. top: 0;
  421. left: 0;
  422. display: flex;
  423. align-items: center;
  424. justify-content: center;
  425. }
  426. .entry-box-item {
  427. width: 100%;
  428. height: 100%;
  429. color: #fff;
  430. display: flex;
  431. justify-content: center;
  432. align-items: center;
  433. position: relative;
  434. background: radial-gradient(circle,
  435. rgba(51, 149, 233, 0) 100px,
  436. rgba(51, 149, 233, 0) 100px);
  437. .item-center-line {
  438. width: 240px;
  439. height: 240px;
  440. background-color: transparent;
  441. border-top: 3px solid rgb(22, 110, 191);
  442. border-bottom: 3px solid rgb(22, 110, 191);
  443. border-radius: 50%;
  444. box-sizing: border-box;
  445. position: absolute;
  446. top: calc(50% - 120px);
  447. left: calc(50% - 120px);
  448. animation: rotate 8s infinite linear;
  449. }
  450. .item-center-pie {
  451. width: 210px;
  452. height: 210px;
  453. background-color: transparent;
  454. border-top: 2px solid rgb(22, 110, 191);
  455. border-bottom: 2px solid rgb(22, 110, 191);
  456. border-radius: 50%;
  457. box-sizing: border-box;
  458. position: absolute;
  459. top: calc(50% - 105px);
  460. left: calc(50% - 105px);
  461. animation: rotate1 8s infinite linear;
  462. }
  463. }
  464. }
  465. /* 定义中间球体顺时针转动 */
  466. @keyframes rotate {
  467. from {
  468. transform: rotate(0deg);
  469. }
  470. to {
  471. transform: rotate(360deg);
  472. }
  473. }
  474. /* 定义中间圆逆时针转动 */
  475. @keyframes rotate1 {
  476. from {
  477. transform: rotate(0deg);
  478. }
  479. to {
  480. transform: rotate(-360deg);
  481. }
  482. }
  483. .monit_title {
  484. font-size: 16px;
  485. background-image: -webkit-linear-gradient(bottom, rgb(120, 173, 221), rgb(229, 232, 236));
  486. -webkit-background-clip: text;
  487. -webkit-text-fill-color: transparent;
  488. padding: 6px 0px;
  489. }
  490. .monit_num {
  491. font-size: 30px;
  492. font-weight: bold;
  493. }
  494. </style>