measurePoint.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <template>
  2. <div class="content">
  3. <div class="title">
  4. <div class="text">{{ title }}</div>
  5. <!-- <a-radio-group v-model:value="shown" button-style="solid">
  6. <a-radio-button value="default">测点信息</a-radio-button>
  7. <a-radio-button value="chart">预测曲线</a-radio-button>
  8. </a-radio-group> -->
  9. <BaseTab
  10. style="width: 200px"
  11. :tabs="[
  12. { name: '测点信息', id: 'default' },
  13. { name: '预测曲线', id: 'chart' },
  14. ]"
  15. v-model:id="shown"
  16. />
  17. </div>
  18. <div v-if="shown === 'default'" class="content-item">
  19. <div class="card-content" v-for="(item, index) in cards" :key="`vmac${index}`">
  20. <div class="item-l">
  21. <div class="label-l">{{ item.label }}</div>
  22. <div class="value-l">{{ item.value }}</div>
  23. </div>
  24. <div class="item-r">
  25. <div class="content-r" v-for="el in item.listR" :key="el.id">
  26. <span>{{ `${el.label} : ` }}</span>
  27. <span
  28. :class="{
  29. 'status-f': el.value == 1,
  30. 'status-l': el.value == 0,
  31. }"
  32. >
  33. {{ el.value == 1 ? '异常' : el.value == 0 ? '正常' : el.value }}
  34. </span>
  35. </div>
  36. </div>
  37. </div>
  38. </div>
  39. <div v-if="shown === 'chart'" class="chart-item">
  40. <div v-for="(item, index) in charts" :key="`acmt${index}`">
  41. <PredictionCurve style="height: 300px; width: 400px; margin: 0 5px" :chart="item" :timeout="timeout" />
  42. <div class="text-center">
  43. {{ item.label }}
  44. </div>
  45. </div>
  46. </div>
  47. </div>
  48. </template>
  49. <script setup lang="ts">
  50. import { ref } from 'vue';
  51. import BaseTab from '../../../gas/components/tab/baseTab.vue';
  52. import PredictionCurve from './predictionCurve.vue';
  53. // well i know this is trash but the time is reaching
  54. defineProps<{
  55. cards: { label: string; value: any; listR: { id: number; label: string; dw: string; value: any }[] }[];
  56. charts: { id: string; label: string; time: []; data: [number, number, number, number]; monitorData: number[] }[];
  57. title: string;
  58. timeout?: number;
  59. }>();
  60. const shown = ref('default');
  61. // const chartsConfig = ref<
  62. // {
  63. // label: string;
  64. // /** 下一项数据更新后应该替换配置中的哪项数据的标志 */
  65. // indexMark: number;
  66. // x: string[];
  67. // y1: number[];
  68. // y2: number[];
  69. // y3: number[];
  70. // y4: number[];
  71. // }[]
  72. // >([]);
  73. // watch(
  74. // () => props.charts,
  75. // () => {
  76. // const arr = new Array(20).fill(0);
  77. // props.charts.forEach((el, i) => {
  78. // if (chartsConfig.value[i]) {
  79. // // 由于上面这些数据都是 20 项组成的,当指针移动到 20 时说明上次更新了最后一项
  80. // // 那么应该按先进后出的队列模式更新数据了
  81. // const val = chartsConfig.value[i];
  82. // if (val.indexMark === 20) {
  83. // val.x.shift();
  84. // val.y1.shift();
  85. // val.y2.shift();
  86. // val.y3.shift();
  87. // val.y4.shift();
  88. // val.indexMark = 19;
  89. // }
  90. // val.x[val.indexMark] = moment(el.time).format('HH:mm:ss');
  91. // val.y1[val.indexMark] = el.data[0];
  92. // val.y2[val.indexMark] = el.data[1];
  93. // val.y3[val.indexMark] = el.data[2];
  94. // val.y4[val.indexMark] = el.data[3];
  95. // // 指针向后移动1
  96. // val.indexMark += 1;
  97. // } else {
  98. // // 更新配置
  99. // // 初始化配置数据,按照一项数据,生成一个由 20 项数据组成的数组,该数组由此项数据衍生
  100. // const startFrom = moment(el.time);
  101. // chartsConfig.value[i] = {
  102. // label: el.label,
  103. // indexMark: 1,
  104. // x: arr.map(() => {
  105. // const str = startFrom.format('HH:mm:ss');
  106. // startFrom.add(props.timeout || 3000);
  107. // return str;
  108. // }),
  109. // y1: arr.map(() => {
  110. // return el.data[0];
  111. // }),
  112. // y2: arr.map(() => {
  113. // return el.data[1];
  114. // }),
  115. // y3: arr.map(() => {
  116. // return el.data[2];
  117. // }),
  118. // y4: arr.map(() => {
  119. // return el.data[3];
  120. // }),
  121. // };
  122. // }
  123. // });
  124. // },
  125. // { immediate: true, deep: true }
  126. // );
  127. </script>
  128. <style lang="less">
  129. @import '/@/design/theme.less';
  130. @{theme-deepblue} {
  131. .content {
  132. --image-bot-area: url('/@/assets/images/themify/deepblue/fire/bot-area.png');
  133. --image-bot-area1: url('/@/assets/images/themify/deepblue/fire/bot-area1.png');
  134. }
  135. }
  136. .content {
  137. --image-bot-area: url('/@/assets/images/fire/bot-area.png');
  138. --image-bot-area1: url('/@/assets/images/fire/bot-area1.png');
  139. height: 100%;
  140. color: var(--vent-font-color);
  141. .title {
  142. height: 30px;
  143. margin-bottom: 10px;
  144. display: flex;
  145. justify-content: space-between;
  146. align-items: center;
  147. .text {
  148. font-family: 'douyuFont';
  149. font-size: 14px;
  150. }
  151. }
  152. .content-item {
  153. display: flex;
  154. justify-content: flex-start;
  155. align-items: flex-start;
  156. flex-wrap: wrap;
  157. height: calc(100% - 50px);
  158. overflow-y: auto;
  159. .card-content {
  160. position: relative;
  161. width: 30%;
  162. height: 128px;
  163. margin: 0px 15px 15px 15px;
  164. background: var(--image-bot-area) no-repeat center;
  165. background-size: 100% 100%;
  166. .item-l {
  167. position: absolute;
  168. left: 32px;
  169. top: 50%;
  170. transform: translate(0, -50%);
  171. width: 89px;
  172. height: 98px;
  173. background: var(--image-bot-area1) no-repeat center;
  174. .label-l {
  175. position: absolute;
  176. left: 50%;
  177. top: 7px;
  178. color: var(--vent-font-color);
  179. font-size: 14px;
  180. transform: translate(-50%, 0);
  181. }
  182. .value-l {
  183. position: absolute;
  184. left: 50%;
  185. top: 50px;
  186. transform: translate(-50%, 0);
  187. font-family: 'douyuFont';
  188. font-size: 14px;
  189. color: var(--vent-table-action-link);
  190. }
  191. }
  192. .item-r {
  193. position: absolute;
  194. left: 132px;
  195. top: 50%;
  196. transform: translate(0, -50%);
  197. height: 128px;
  198. padding: 5px 0px;
  199. display: flex;
  200. flex-direction: column;
  201. justify-content: space-around;
  202. box-sizing: border-box;
  203. .content-r {
  204. display: flex;
  205. span {
  206. font-size: 14px;
  207. color: var(--vent-font-color);
  208. &:first-child {
  209. display: inline-block;
  210. width: 68px;
  211. }
  212. &:last-child {
  213. display: inline-block;
  214. width: calc(100% - 68px);
  215. }
  216. }
  217. .status-f {
  218. color: #ff0000;
  219. }
  220. .status-l {
  221. color: var(--vent-table-action-link);
  222. }
  223. }
  224. }
  225. }
  226. }
  227. .chart-item {
  228. display: flex;
  229. justify-content: flex-start;
  230. align-items: flex-start;
  231. flex-wrap: wrap;
  232. height: calc(100% - 50px);
  233. overflow-y: auto;
  234. }
  235. }
  236. </style>