widget.vue 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. <template>
  2. <div style="width: 100%; height: 100%">
  3. <el-button-group class="buttonGroupClass" style="position: abs">
  4. <!-- <el-button type="primary" size="small" @click="craftShow=true">一厂</el-button> -->
  5. <!-- <el-button type="primary" size="small" @click="craftShow = false"
  6. >二厂</el-button
  7. > -->
  8. <el-button type="primary" size="small">二厂</el-button>
  9. <video
  10. ref="videoMsg"
  11. src="../../../../assets/alarm/14184.mp3"
  12. loop="loop"
  13. style="display: none"
  14. />
  15. </el-button-group>
  16. <div
  17. style="
  18. position: absolute;
  19. top: 15px;
  20. left: 195px;
  21. z-index: 10;
  22. background: #fffb;
  23. padding: 10px;
  24. border-radius: 5px;
  25. "
  26. >
  27. <el-switch v-model="isOpenFlow" inactive-text="开启动画" />
  28. </div>
  29. <div
  30. style="
  31. position: absolute;
  32. top: 15px;
  33. left: 330px;
  34. z-index: 10;
  35. background: #fffb;
  36. padding: 10px;
  37. border-radius: 5px;
  38. "
  39. >
  40. <el-switch v-model="isOpenAlarm" inactive-text="开启报警" />
  41. </div>
  42. <div
  43. v-show="craftShow"
  44. id="graphContainer"
  45. ref="graphContainer"
  46. v-loading="loading"
  47. class="graph"
  48. style="width: 100%; height: 100%; background: rgb(5, 37, 58)"
  49. />
  50. <div
  51. v-show="!craftShow"
  52. id="graphContainer2"
  53. ref="graphContainer2"
  54. v-loading="loading"
  55. class="graph"
  56. style="width: 100%; height: 100%; background: rgb(5, 37, 58)"
  57. />
  58. <el-dialog
  59. :title="siteTitle"
  60. :visible.sync="siteVisible"
  61. width="1400px"
  62. top="calc(50vh - 350px)"
  63. >
  64. <el-row style="margin-top: 8px">
  65. <span class="title2">时间</span>
  66. <!-- <el-time-select
  67. v-model="startTime"
  68. placeholder="起始时间"
  69. :picker-options="{
  70. start: '00:00:00',
  71. step: '01:00:00',
  72. end: '23:00:00'
  73. }"
  74. />~ -->
  75. <el-time-picker
  76. v-model="startTime"
  77. format="HH:mm:ss"
  78. value-format="HH:mm:ss"
  79. size="small"
  80. :picker-options="{
  81. selectableRange: `00:00:00 - 23:59:00`,
  82. }"
  83. />
  84. <el-time-picker
  85. v-model="endTime"
  86. format="HH:mm:ss"
  87. value-format="HH:mm:ss"
  88. size="small"
  89. :picker-options="{
  90. selectableRange: `${startTime ? startTime : '00:00:00'}-23:59:59`,
  91. }"
  92. />
  93. <!-- <el-time-select
  94. v-model="endTime"
  95. placeholder="结束时间"
  96. :picker-options="{
  97. start: '00:59:59',
  98. step: '01:00:00',
  99. end: '23:59:59',
  100. minTime: startTime
  101. }"
  102. /> -->
  103. <el-button size="small" type="primary" @click="showResult"
  104. >查询</el-button
  105. >
  106. <el-checkbox v-model="dontShow">去除特殊值(-9999)</el-checkbox>
  107. </el-row>
  108. <div
  109. v-loading="infoLoading"
  110. style="width: 100%; height: 500px; margin-top: 8px; display: flex"
  111. >
  112. <div style="width: 25%; height: 100%">
  113. <el-table
  114. :data="siteDatas"
  115. border
  116. height="calc(100% - 43px)"
  117. style="width: 100%"
  118. >
  119. <el-table-column prop="scadaTime" label="时间" />
  120. <el-table-column prop="value" label="测量值" />
  121. </el-table>
  122. <el-row style="margin-top: 8px">
  123. <el-col :span="20">
  124. <el-pagination
  125. ref="pagination2"
  126. small
  127. background
  128. layout="total, sizes, prev, next"
  129. :page-sizes="[10, 20, 50, 100, 1000]"
  130. :total="total2"
  131. @current-change="pagRefersh"
  132. @size-change="pagRefersh"
  133. />
  134. </el-col>
  135. <el-col :span="4">
  136. <span
  137. ref="pageLength2"
  138. style="font-size: 13px"
  139. class="el-pagination__total"
  140. >1/30 页</span
  141. >
  142. </el-col>
  143. </el-row>
  144. </div>
  145. <div ref="chart" style="width: 75%; height: 100%" />
  146. </div>
  147. </el-dialog>
  148. </div>
  149. </template>
  150. <script>
  151. import { allConfig2, allConfig } from "./craftConfig";
  152. import siteIndex from "./siteIndex";
  153. import mxgraph from "mxgraph";
  154. import request from "@/utils/request"; // 请求
  155. import { parseTime } from "@/utils/index";
  156. import Echarts from "echarts";
  157. import { getScadaAlarmDataPage } from "@/api/mbsys/scada";
  158. export default {
  159. name: "CraftMap2",
  160. components: { Echarts },
  161. data() {
  162. return {
  163. craftShow: true, // 默认显示一二期的工艺图
  164. activeName: "first",
  165. loading: false,
  166. infoLoading: false,
  167. elements: {},
  168. siteTitle: "",
  169. siteVisible: false,
  170. timss: ["", ""],
  171. startTime: "00:00:00",
  172. endTime: "23:59:59",
  173. total2: 0,
  174. siteDatas: [],
  175. isOpenFlow: true,
  176. isOpenFlow2: true,
  177. isOpenAlarm: true,
  178. isAlarm: false,
  179. dontShow: true,
  180. twinkle: null,
  181. indexCodes: [],
  182. };
  183. },
  184. watch: {
  185. isOpenFlow(e) {
  186. var flows = this.flowLines;
  187. var flows2 = this.flowLines2;
  188. var text = e ? "flow" : "flowN";
  189. for (let i = 0, ii = flows.length; i < ii; i++) {
  190. flows[i].classList.value = text;
  191. }
  192. for (let i = 0, ii = flows2.length; i < ii; i++) {
  193. flows2[i].classList.value = text;
  194. }
  195. },
  196. isOpenAlarm(e) {
  197. this.speckVideo(e);
  198. },
  199. },
  200. created() {
  201. this.indexCodes = []; //存储配置的指标编码
  202. for (var i = 0; i < siteIndex.deviceValue.length; i++) {
  203. const deviceValue = siteIndex.deviceValue[i];
  204. if (deviceValue) {
  205. deviceValue.value.map((item) => {
  206. if (item.itnm && item.itnm !== "") this.indexCodes.push(item.itnm);
  207. });
  208. }
  209. }
  210. },
  211. mounted() {
  212. this.ready = 0;
  213. this.loadCraft();
  214. this.loadCraft2();
  215. this.getSide();
  216. var date = new Date();
  217. var year = date.getFullYear();
  218. var month = date.getMonth() + 1;
  219. var day = date.getDate();
  220. if (month < 10) month = "0" + month;
  221. if (day < 10) day = "0" + day;
  222. this.timss = [
  223. year + "-" + month + "-" + day,
  224. year + "-" + month + "-" + day,
  225. ];
  226. },
  227. destroyed() {
  228. if (this.nextDo) clearTimeout(this.nextDo);
  229. if (this.twinkle) this.twinkle = null;
  230. },
  231. methods: {
  232. init(div) {
  233. var mx = mxgraph();
  234. var mxGraphHandler = mx.mxGraphHandler;
  235. var mxConstants = mx.mxConstants;
  236. var mxEvent = mx.mxEvent;
  237. mxEvent.disableContextMenu(div);
  238. const graph = new mx.mxGraph(div);
  239. graph.setConnectable(true); // 是否允许Cells通过其中部的连接点新建连接,false则通过连接线连接
  240. graph.setTooltips(false); // 是否显示提示,默认显示Cell的名称
  241. graph.setEnabled(false); // 设置启用,就是允不允许你改变CELL的形状内容。
  242. graph.setCellsResizable(true); // 节点不可改变大小
  243. graph.connectionHandler.setCreateTarget(false); // 是否创建目标
  244. graph.foldingEnabled = false;
  245. mxGraphHandler.prototype.setMoveEnabled(false); // 是否可以移动
  246. mxGraphHandler.prototype.guidesEnabled = true; // 显示细胞位置标尺
  247. const p = graph.getDefaultParent();
  248. const styleE = graph.getStylesheet().getDefaultEdgeStyle();
  249. styleE[mxConstants.STYLE_EDGE] = "orthogonalEdgeStyle"; // 设置折线
  250. styleE[mxConstants.STYLE_ENDARROW] = "none"; // 设置箭头末尾
  251. styleE[mxConstants.STYLE_STROKECOLOR] = "#029ac9"; // 设置颜色
  252. if (!this.test) {
  253. styleE[mxConstants.STYLE_STROKEWIDTH] = 5; // 设置颜色
  254. }
  255. const styleV = graph.getStylesheet().getDefaultVertexStyle();
  256. if (!this.test) {
  257. styleV[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = "bottom"; // 设置文本底部
  258. styleV[mxConstants.STYLE_VERTICAL_ALIGN] = "top"; // 设置文本底部
  259. styleV[mxConstants.STYLE_FILLCOLOR] = "none"; // 设置背景颜色
  260. styleV[mxConstants.STYLE_TEXT_OPACITY] = 0; // 设置文本透明度
  261. styleV[mxConstants.STYLE_STROKECOLOR] = "none"; // 设置边框
  262. }
  263. return [graph, p];
  264. },
  265. /**
  266. * 二水厂工艺图
  267. */
  268. loadCraft() {
  269. this.test = false;
  270. var test = this.test;
  271. var div = this.$refs.graphContainer;
  272. var flowLines = (this.flowLines = []);
  273. const cache = {};
  274. const modulesFiles = require.context("./images", true, /\.(png|gif)$/);
  275. modulesFiles.keys().forEach((key) => (cache[key] = modulesFiles(key)));
  276. var mxPoint = mxgraph().mxPoint;
  277. var width = div.offsetWidth;
  278. var height = div.offsetHeight;
  279. div.innerHTML +=
  280. '<div class="underSvg"></div><div class="onSvg"><div class="text"></div><div></div></div>';
  281. var children = div.children;
  282. var backgroundDiv = children[children.length - 2];
  283. var backgroundstr = "";
  284. var showNodeDiv = children[children.length - 1];
  285. var textDiv = showNodeDiv.children[0];
  286. var textStr = "";
  287. var imageDiv = showNodeDiv.children[1];
  288. var imagestr = "";
  289. const [graph, p] = this.init(div);
  290. var nodeMx = [];
  291. var nodes = [];
  292. var nodesIndex = {};
  293. var imagesUrl = "./";
  294. var that = this;
  295. setTimeout(() => {
  296. thenDo().then(() => {
  297. //that.loading = false;
  298. div.parentElement.style.overflow = "auto";
  299. });
  300. }, 500);
  301. async function thenDo() {
  302. //allConfig.push(...siteIndex.deviceValue)
  303. let config = allConfig.filter((p) => 1 == 1);
  304. config.push(...siteIndex.deviceValue);
  305. for (var i = 0, ii = config.length; i < ii; i++) {
  306. var node = config[i];
  307. if (nodesIndex.hasOwnProperty(node.id)) alert("重复ID" + node.id);
  308. switch (node.type) {
  309. case "point":
  310. var x, y;
  311. if (node.from) {
  312. var fromNode = nodesIndex[node.from];
  313. var margin = node.margin;
  314. var dx = margin.x[0] * width + margin.x[1];
  315. var dy = margin.y[0] * height + margin.y[1];
  316. x = fromNode.x + dx;
  317. y = fromNode.y + dy;
  318. } else if (node.locationFrom) {
  319. var fromInfo = node.locationFrom;
  320. var fromNodeX = nodesIndex[fromInfo.xFrom];
  321. var fromNodeY = nodesIndex[fromInfo.yFrom];
  322. var margin = node.margin;
  323. x = fromNodeX.x + width * margin.x[0] + margin.x[1];
  324. y = fromNodeY.y + height * margin.y[0] + margin.y[1];
  325. } else {
  326. x = width * node.x[0] - 1 + node.x[1];
  327. y = height * node.y[0] - 1 + node.y[1];
  328. }
  329. var nodeGraph = graph.insertVertex(
  330. p,
  331. node.id,
  332. node.id,
  333. x,
  334. y,
  335. 2,
  336. 2
  337. );
  338. nodeMx.push(nodeGraph);
  339. nodes.push(
  340. (nodesIndex[node.id] = {
  341. type: "point",
  342. x: x,
  343. y: y,
  344. width: 2,
  345. height: 2,
  346. graph: nodeGraph,
  347. })
  348. );
  349. break;
  350. case "image":
  351. if (node.from) {
  352. var fromNode = nodesIndex[node.from];
  353. var margin = node.margin;
  354. var x = fromNode.x + margin.x[0] * width + margin.x[1];
  355. var y = fromNode.y + margin.y[0] * height + margin.y[1];
  356. var str =
  357. '<div class="img" style="transform: translate(-' +
  358. node.point[0] * 100 +
  359. "%,-" +
  360. node.point[1] * 100 +
  361. "%); top: " +
  362. y.toFixed(2) +
  363. "px; left: " +
  364. x.toFixed(2) +
  365. "px; width: " +
  366. node.width +
  367. "px; height: " +
  368. node.height +
  369. "px; " +
  370. (test
  371. ? "opacity: 0.5;border: 1px solid #0ff;"
  372. : "background-image: url(" +
  373. cache[imagesUrl + node.src] +
  374. ");") +
  375. '">'; //
  376. // str += '<img src=' + cache[imagesUrl + node.src] + '>'
  377. if (node.text) {
  378. str +=
  379. '<span class="' +
  380. (node.class || "unText") +
  381. '">' +
  382. (test ? node.id : node.text) +
  383. "</span>";
  384. } //
  385. str += "</div>";
  386. imagestr += str;
  387. nodes.push(
  388. (nodesIndex[node.id] = {
  389. type: "image",
  390. x: x,
  391. y: y,
  392. width: node.width,
  393. height: node.height,
  394. })
  395. );
  396. }
  397. break;
  398. case "text":
  399. var x;
  400. var y;
  401. if (node.from) {
  402. var fromNode = nodesIndex[node.from];
  403. var margin = node.margin;
  404. x = (fromNode.x + margin.x[0] * width + margin.x[1]).toFixed(2);
  405. y = (fromNode.y + margin.y[0] * height + margin.y[1]).toFixed(
  406. 2
  407. );
  408. }
  409. var str;
  410. if (node.text) {
  411. str =
  412. '<div class="inPic" style="transform: translate(-' +
  413. node.point[0] * 100 +
  414. "%,-" +
  415. node.point[1] * 100 +
  416. "%); top: " +
  417. y +
  418. "px; left: " +
  419. x +
  420. 'px"><span>' +
  421. node.text +
  422. "</span></div>";
  423. } else {
  424. str =
  425. '<ul style="transform: translate(-' +
  426. node.point[0] * 100 +
  427. "%,-" +
  428. node.point[1] * 100 +
  429. "%); top: " +
  430. y +
  431. "px; left: " +
  432. x +
  433. "px;" +
  434. (node.style || "") +
  435. '">';
  436. var textIndex = {};
  437. for (let j = 0, jl = node.value, jj = jl.length; j < jj; j++) {
  438. var text = jl[j];
  439. let value = text.value;
  440. if (text.isType == "1") {
  441. let types = text.type;
  442. value = types[text.value] ? types[text.value] : text.value;
  443. }
  444. if (text.isType == "2" && text.hasOwnProperty("toFixed")) {
  445. value = parseFloat(value).toFixed(parseInt(text.toFixed));
  446. }
  447. str +=
  448. '<li class="tf-li" data="' +
  449. (text.itnm || "") +
  450. '"><div class="' +
  451. (node.class || "title") +
  452. " tfStyleTitle" +
  453. '"><span>' +
  454. text.name +
  455. '</span></div><span class="value tfStyle">' +
  456. value +
  457. '</span><span class="unit tfStyle">' +
  458. text.unit +
  459. "</span></li>";
  460. }
  461. str += "</ul>";
  462. }
  463. textStr += str;
  464. break;
  465. case "arrow":
  466. var arrowGraph = graph.insertEdge(
  467. p,
  468. null,
  469. null,
  470. nodesIndex[node.from].graph,
  471. nodesIndex[node.to].graph,
  472. node.style
  473. );
  474. var jl = node.road;
  475. if (jl && jl.length > 0) {
  476. var arrowGeomentry = arrowGraph.geometry;
  477. arrowGeomentry.relative = true;
  478. var points = [];
  479. for (let j = 0, jj = jl.length; j < jj; j++) {
  480. var arrowNode = jl[j];
  481. var id = arrowNode.id;
  482. if (id) {
  483. var nodeF = nodesIndex[id];
  484. var offer = [1, 1];
  485. if (nodeF.type == "image") offer = [0, 0];
  486. points.push(
  487. new mxPoint(
  488. nodeF.x +
  489. offer[0] +
  490. arrowNode.x[0] * width +
  491. arrowNode.x[1],
  492. nodeF.y +
  493. offer[1] +
  494. arrowNode.y[0] * height +
  495. arrowNode.y[1]
  496. )
  497. );
  498. } else {
  499. points.push(
  500. new mxPoint(
  501. arrowNode.x[0] * width + arrowNode.x[1],
  502. arrowNode.y[0] * height + arrowNode.y[1]
  503. )
  504. );
  505. }
  506. }
  507. arrowGeomentry.points = points;
  508. }
  509. graph.refresh(arrowGraph);
  510. if (node.flow && !test) {
  511. var state = graph.view
  512. .getState(arrowGraph)
  513. .shape.node.getElementsByTagName("path");
  514. var [backGroundLine, flowLine] = state;
  515. backGroundLine.removeAttribute("visibility");
  516. backGroundLine.setAttribute("class", "flowBack");
  517. backGroundLine.setAttribute("stroke-width", "12");
  518. backGroundLine.setAttribute("stroke", "#72a8d4");
  519. flowLine.setAttribute("class", "flow");
  520. flowLines.push(flowLine);
  521. }
  522. break;
  523. case "background":
  524. if (node.from) {
  525. var fromNode = nodesIndex[node.from];
  526. var margin = node.margin;
  527. var x = fromNode.x + margin.x[0] * width + margin.x[1];
  528. var y = fromNode.y + margin.y[0] * height + margin.y[1];
  529. var str =
  530. '<div style="transform: translate(-' +
  531. node.point[0] * 100 +
  532. "%,-" +
  533. node.point[1] * 100 +
  534. "%); top: " +
  535. y.toFixed(2) +
  536. "px; left: " +
  537. x.toFixed(2) +
  538. "px; width: " +
  539. node.width +
  540. "px; height: " +
  541. node.height +
  542. 'px;">';
  543. if (node.text) {
  544. str +=
  545. '<span class="' +
  546. (node.class || "onText") +
  547. '">' +
  548. (test ? node.id : node.text) +
  549. "</span>";
  550. } // node.id
  551. str += "</div>";
  552. backgroundstr += str;
  553. nodes.push(
  554. (nodesIndex[node.id] = {
  555. type: "background",
  556. x: x,
  557. y: y,
  558. width: node.width,
  559. height: node.height,
  560. })
  561. );
  562. }
  563. break;
  564. }
  565. }
  566. textDiv.innerHTML = textStr;
  567. backgroundDiv.innerHTML = backgroundstr;
  568. imageDiv.innerHTML = imagestr;
  569. that.setSide();
  570. }
  571. },
  572. loadCraft2() {
  573. this.test = false;
  574. var test = this.test;
  575. var div = this.$refs.graphContainer;
  576. var div2 = this.$refs.graphContainer;
  577. var flowLines = (this.flowLines2 = []);
  578. const cache = {};
  579. const modulesFiles = require.context("./images", true, /\.(png|gif)$/);
  580. modulesFiles.keys().forEach((key) => (cache[key] = modulesFiles(key)));
  581. var mxPoint = mxgraph().mxPoint;
  582. var width = div.offsetWidth || div2.offsetWidth;
  583. var height = div.offsetHeight || div2.offsetHeight;
  584. div.innerHTML +=
  585. '<div class="underSvg"></div><div class="onSvg"><div class="text"></div><div></div></div>';
  586. var children = div.children;
  587. var backgroundDiv = children[children.length - 2];
  588. var backgroundstr = "";
  589. var showNodeDiv = children[children.length - 1];
  590. var textDiv = showNodeDiv.children[0];
  591. var textStr = "";
  592. var imageDiv = showNodeDiv.children[1];
  593. var imagestr = "";
  594. const [graph, p] = this.init(div);
  595. var nodeMx = [];
  596. var nodes = [];
  597. var nodesIndex = {};
  598. var imagesUrl = "./";
  599. var that = this;
  600. setTimeout(() => {
  601. thenDo().then(() => {
  602. //that.loading = false;
  603. div.parentElement.style.overflow = "auto";
  604. });
  605. }, 200);
  606. async function thenDo() {
  607. let config = allConfig.filter((p) => 1 == 1);
  608. config.push(...siteIndex.deviceValue);
  609. for (var i = 0, ii = config.length; i < ii; i++) {
  610. var node = config[i];
  611. if (nodesIndex.hasOwnProperty(node.id)) alert("重复ID" + node.id);
  612. switch (node.type) {
  613. case "point":
  614. var x, y;
  615. if (node.from) {
  616. var fromNode = nodesIndex[node.from];
  617. var margin = node.margin;
  618. var dx = margin.x[0] * width + margin.x[1];
  619. var dy = margin.y[0] * height + margin.y[1];
  620. x = fromNode.x + dx;
  621. y = fromNode.y + dy;
  622. } else if (node.locationFrom) {
  623. var fromInfo = node.locationFrom;
  624. var fromNodeX = nodesIndex[fromInfo.xFrom];
  625. var fromNodeY = nodesIndex[fromInfo.yFrom];
  626. var margin = node.margin;
  627. x = fromNodeX.x + width * margin.x[0] + margin.x[1];
  628. y = fromNodeY.y + height * margin.y[0] + margin.y[1];
  629. } else {
  630. x = width * node.x[0] - 1 + node.x[1];
  631. y = height * node.y[0] - 1 + node.y[1];
  632. }
  633. var nodeGraph = graph.insertVertex(
  634. p,
  635. node.id,
  636. node.id,
  637. x,
  638. y,
  639. 2,
  640. 2
  641. );
  642. nodeMx.push(nodeGraph);
  643. nodes.push(
  644. (nodesIndex[node.id] = {
  645. type: "point",
  646. x: x,
  647. y: y,
  648. width: 2,
  649. height: 2,
  650. graph: nodeGraph,
  651. })
  652. );
  653. break;
  654. case "image":
  655. if (node.from) {
  656. var fromNode = nodesIndex[node.from];
  657. var margin = node.margin;
  658. var x = fromNode.x + margin.x[0] * width + margin.x[1];
  659. var y = fromNode.y + margin.y[0] * height + margin.y[1];
  660. var str =
  661. '<div class="img" style="transform: translate(-' +
  662. node.point[0] * 100 +
  663. "%,-" +
  664. node.point[1] * 100 +
  665. "%); top: " +
  666. y.toFixed(2) +
  667. "px; left: " +
  668. x.toFixed(2) +
  669. "px; width: " +
  670. node.width +
  671. "px; height: " +
  672. node.height +
  673. "px; " +
  674. (test
  675. ? "opacity: 0.5;border: 1px solid #0ff;"
  676. : "background-image: url(" +
  677. cache[imagesUrl + node.src] +
  678. ");") +
  679. '">'; //
  680. // str += '<img src=' + cache[imagesUrl + node.src] + '>'
  681. if (node.text) {
  682. str +=
  683. '<span class="' +
  684. (node.class || "unText") +
  685. '">' +
  686. (test ? node.id : node.text) +
  687. "</span>";
  688. } //
  689. str += "</div>";
  690. imagestr += str;
  691. nodes.push(
  692. (nodesIndex[node.id] = {
  693. type: "image",
  694. x: x,
  695. y: y,
  696. width: node.width,
  697. height: node.height,
  698. })
  699. );
  700. }
  701. break;
  702. case "text":
  703. var x;
  704. var y;
  705. if (node.from) {
  706. var fromNode = nodesIndex[node.from];
  707. var margin = node.margin;
  708. x = (fromNode.x + margin.x[0] * width + margin.x[1]).toFixed(2);
  709. y = (fromNode.y + margin.y[0] * height + margin.y[1]).toFixed(
  710. 2
  711. );
  712. }
  713. var str;
  714. if (node.text) {
  715. str =
  716. '<div class="inPic" style="transform: translate(-' +
  717. node.point[0] * 100 +
  718. "%,-" +
  719. node.point[1] * 100 +
  720. "%); top: " +
  721. y +
  722. "px; left: " +
  723. x +
  724. 'px"><span>' +
  725. node.text +
  726. "</span></div>";
  727. } else {
  728. const className =
  729. node.id == "m1t6" || node.id == "m1t7" ? true : false;
  730. str =
  731. '<ul style="' +
  732. (className ? "color:#fff;" : "") +
  733. "transform: translate(-" +
  734. node.point[0] * 100 +
  735. "%,-" +
  736. node.point[1] * 100 +
  737. "%); top: " +
  738. y +
  739. "px; left: " +
  740. x +
  741. "px;" +
  742. (node.style || "") +
  743. '">';
  744. var textIndex = {};
  745. for (let j = 0, jl = node.value, jj = jl.length; j < jj; j++) {
  746. var text = jl[j];
  747. let value = text.value;
  748. if (text.isType == "1") {
  749. let types = text.type;
  750. value = types[text.value] ? types[text.value] : text.value;
  751. }
  752. if (text.isType == "2" && text.hasOwnProperty("toFixed")) {
  753. value = parseFloat(value).toFixed(parseInt(text.toFixed));
  754. }
  755. str +=
  756. '<li class="tf-li" data="' +
  757. (text.itnm || "") +
  758. '"><div class="' +
  759. (node.class || "title") +
  760. " tfStyleTitle" +
  761. '"><span>' +
  762. text.name +
  763. '</span></div><span class="value tfStyle">' +
  764. value +
  765. '</span><span class="unit tfStyle">' +
  766. text.unit +
  767. "</span></li>";
  768. }
  769. str += "</ul>";
  770. }
  771. textStr += str;
  772. break;
  773. case "arrow":
  774. var arrowGraph = graph.insertEdge(
  775. p,
  776. null,
  777. null,
  778. nodesIndex[node.from].graph,
  779. nodesIndex[node.to].graph,
  780. node.style
  781. );
  782. var jl = node.road;
  783. if (jl && jl.length > 0) {
  784. var arrowGeomentry = arrowGraph.geometry;
  785. arrowGeomentry.relative = true;
  786. var points = [];
  787. for (let j = 0, jj = jl.length; j < jj; j++) {
  788. var arrowNode = jl[j];
  789. var id = arrowNode.id;
  790. if (id) {
  791. var nodeF = nodesIndex[id];
  792. var offer = [1, 1];
  793. if (nodeF.type == "image") offer = [0, 0];
  794. points.push(
  795. new mxPoint(
  796. nodeF.x +
  797. offer[0] +
  798. arrowNode.x[0] * width +
  799. arrowNode.x[1],
  800. nodeF.y +
  801. offer[1] +
  802. arrowNode.y[0] * height +
  803. arrowNode.y[1]
  804. )
  805. );
  806. } else {
  807. points.push(
  808. new mxPoint(
  809. arrowNode.x[0] * width + arrowNode.x[1],
  810. arrowNode.y[0] * height + arrowNode.y[1]
  811. )
  812. );
  813. }
  814. }
  815. arrowGeomentry.points = points;
  816. }
  817. graph.refresh(arrowGraph);
  818. if (node.flow && !test) {
  819. var state = graph.view
  820. .getState(arrowGraph)
  821. .shape.node.getElementsByTagName("path");
  822. var [backGroundLine, flowLine] = state;
  823. backGroundLine.removeAttribute("visibility");
  824. backGroundLine.setAttribute("class", "flowBack");
  825. backGroundLine.setAttribute("stroke-width", "12");
  826. backGroundLine.setAttribute("stroke", "#72a8d4");
  827. flowLine.setAttribute("class", "flow");
  828. flowLines.push(flowLine);
  829. }
  830. break;
  831. case "background":
  832. if (node.from) {
  833. var fromNode = nodesIndex[node.from];
  834. var margin = node.margin;
  835. var x = fromNode.x + margin.x[0] * width + margin.x[1];
  836. var y = fromNode.y + margin.y[0] * height + margin.y[1];
  837. var str =
  838. '<div style="transform: translate(-' +
  839. node.point[0] * 100 +
  840. "%,-" +
  841. node.point[1] * 100 +
  842. "%); top: " +
  843. y.toFixed(2) +
  844. "px; left: " +
  845. x.toFixed(2) +
  846. "px; width: " +
  847. node.width +
  848. "px; height: " +
  849. node.height +
  850. 'px;">';
  851. if (node.text) {
  852. str +=
  853. '<span class="' +
  854. (node.class || "onText") +
  855. '">' +
  856. (test ? node.id : node.text) +
  857. "</span>";
  858. } // node.id
  859. str += "</div>";
  860. backgroundstr += str;
  861. nodes.push(
  862. (nodesIndex[node.id] = {
  863. type: "background",
  864. x: x,
  865. y: y,
  866. width: node.width,
  867. height: node.height,
  868. })
  869. );
  870. }
  871. break;
  872. }
  873. }
  874. textDiv.innerHTML = textStr;
  875. backgroundDiv.innerHTML = backgroundstr;
  876. imageDiv.innerHTML = imagestr;
  877. that.setSide();
  878. }
  879. },
  880. getSide() {
  881. request({
  882. url: "/tofly-scada/scada/app/data",
  883. method: "post",
  884. data: {
  885. type: 1,
  886. },
  887. }).then((res) => {
  888. if (res && res.code == 1) {
  889. var scada = (this.scada = {});
  890. res.result.map((e) => {
  891. if (e.allocations) {
  892. for (const i in e.allocations) {
  893. scada[e.allocations[i].variableCode] = e.allocations[i];
  894. }
  895. }
  896. });
  897. this.setSide();
  898. } else {
  899. this.$message.error("获取指标失败:" + res.message);
  900. //this.loading = false;
  901. }
  902. });
  903. this.getAlarmData();
  904. },
  905. getAlarmData() {
  906. if (this.indexCodes.length < 1) return;
  907. const frontHelfTime = parseTime(
  908. new Date(new Date().getTime() - 24 * 60 * 30 * 1000),
  909. "{y}-{m}-{d} {h}:{i}:{s}"
  910. );
  911. const nowTime = parseTime(new Date(), "{y}-{m}-{d} {h}:{i}:{s}");
  912. const params = {
  913. codes: this.indexCodes.toString(), //指标编码
  914. status: 0, //处理状态未处理
  915. start: frontHelfTime,
  916. end: nowTime,
  917. current: 1,
  918. size: 20,
  919. };
  920. // getScadaAlarmDataPage(params)
  921. // .then((res) => {})
  922. // .catch((ex) => {});
  923. },
  924. setSide() {
  925. this.ready += 1;
  926. if (this.ready == 3) {
  927. var scada = this.scada;
  928. var allLis = [];
  929. var lis = this.$refs.graphContainer.querySelectorAll("li");
  930. //var lis2 = this.$refs.graphContainer2.querySelectorAll('li')
  931. allLis.push.apply(allLis, lis);
  932. //allLis.push.apply(allLis, lis2)
  933. // Object.assign(lis, lis2)
  934. var infos = {};
  935. var loadSite = () => {
  936. for (var i = 0, ii = allLis.length; i < ii; i++) {
  937. var dl = allLis[i];
  938. var att = dl.getAttribute("data");
  939. if (att && scada.hasOwnProperty(att)) {
  940. dl.onclick = this.showHistoty;
  941. dl = dl.children;
  942. var datt = scada[att];
  943. // dl[0].innerHTML = "<span>" + datt.itnm + "</span>"
  944. dl[1].innerHTML = "-"; // datt.description
  945. dl[2].innerHTML = datt.unit;
  946. infos[datt.variableCode] = dl[1]; // value值
  947. }
  948. }
  949. //this.loading = false;
  950. this.$nextTick(loadInfo);
  951. };
  952. var loadInfo = () => {
  953. try {
  954. //this.loading = true;
  955. request({
  956. url: "/tofly-scada/scada/app/data",
  957. method: "post",
  958. data: {
  959. type: 1,
  960. },
  961. })
  962. .then((res) => {
  963. if (res && res.code && res.code == 1) {
  964. res = res.result;
  965. for (var item in res) {
  966. var di = res[item];
  967. if (di.allocations) {
  968. for (const i in di.allocations) {
  969. var t = di.allocations[i].variableCode;
  970. if (infos.hasOwnProperty(t)) {
  971. let n = di.allocations[i]
  972. ? di.allocations[i].scada.value
  973. : "null";
  974. if (n == "null") n = "-";
  975. if (t == "S7.300.1#F_POWER_FAULT")
  976. n = n == "1" ? "开" : "关";
  977. if (t == "S7.300.1#F_OPEN")
  978. n = n == "1" ? "开" : "关";
  979. if (t == "S7.300.2#F_OPEN")
  980. n = n == "1" ? "开" : "关";
  981. if (t == "S7.300.2#F_POWER_FAULT")
  982. n = n == "1" ? "开" : "关";
  983. if (t == "S7.300.CHU_SS")
  984. n = parseFloat(n).toFixed(3);
  985. if (t == "S7.300.CHU_CL")
  986. n = parseFloat(n).toFixed(3);
  987. if (t == "S7.300.CHU_FT")
  988. n = parseFloat(n).toFixed(3);
  989. if (t == "S7.300.1#QSYW")
  990. n = parseFloat(n).toFixed(3);
  991. if (t == "S7.300.2#QSYW")
  992. n = parseFloat(n).toFixed(3);
  993. infos[t].innerHTML = n;
  994. }
  995. }
  996. }
  997. }
  998. this.nextDo = setTimeout(loadInfo, 1000 * 10); //1分钟一次
  999. this.setAlarm(res, infos);
  1000. } else {
  1001. this.$message.error("获取指标失败:" + res.message);
  1002. this.nextDo = setTimeout(loadInfo, 1000 * 10); //1分钟一次
  1003. }
  1004. //this.loading = false;
  1005. })
  1006. .catch((ex) => {
  1007. this.$message.error("连接异常:" + ex);
  1008. this.nextDo = setTimeout(loadInfo, 1000 * 10); //1分钟一次
  1009. });
  1010. } catch (ex) {
  1011. this.nextDo = setTimeout(loadInfo, 1000 * 10); //1分钟一次
  1012. }
  1013. };
  1014. this.$nextTick(loadSite);
  1015. }
  1016. },
  1017. showHistoty(e) {
  1018. var att = e.currentTarget.getAttribute("data");
  1019. var scada = this.scada;
  1020. if (att && scada.hasOwnProperty(att)) {
  1021. this.siteVisible = true;
  1022. this.$nextTick(() => {
  1023. var ec = this.$refs.chart;
  1024. this.chart = Echarts.init(ec);
  1025. var datt = scada[att];
  1026. this.siteTitle = datt.displayName;
  1027. this.selectSite = att;
  1028. this.showResult();
  1029. });
  1030. }
  1031. },
  1032. showResult() {
  1033. if (this.selectSite) {
  1034. //this.infoLoading = true;
  1035. var datt = this.scada[this.selectSite];
  1036. this.getAllDate(datt.variableCode, datt.displayName);
  1037. this.pagRefersh(false);
  1038. }
  1039. },
  1040. getAllDate(stid, zbx) {
  1041. var times = [
  1042. this.timss[0] + " " + this.startTime,
  1043. this.timss[1] + " " + this.endTime,
  1044. ];
  1045. // times[0] + ' ' + this.startTime
  1046. // times[1] + ' ' + this.endTime
  1047. var datt = this.scada[this.selectSite];
  1048. request({
  1049. url:
  1050. "/tofly-scada/scada/page?code=" +
  1051. stid +
  1052. "&start=" +
  1053. times[0] +
  1054. "&end=" +
  1055. times[1] +
  1056. "&size=" +
  1057. 10000 +
  1058. "&statisticsType=" +
  1059. 0,
  1060. method: "get",
  1061. }).then((res) => {
  1062. var chart = this.chart;
  1063. chart.clear();
  1064. if (res.code == 1) {
  1065. res = res.result.records;
  1066. var dataX = [];
  1067. var dataY = [];
  1068. var dontShow = this.dontShow;
  1069. var max = -Infinity;
  1070. var min = Infinity;
  1071. var Xmax = -Infinity;
  1072. var Xmin = Infinity;
  1073. var d;
  1074. var symbol = "none";
  1075. for (var i = 0, il = res, ii = il.length; i < ii; i++) {
  1076. var v = parseFloat(il[i].value);
  1077. if (dontShow && v == -9999) continue;
  1078. var x = il[i].startTime
  1079. ? il[i].startTime.split(" ")[1]
  1080. : il[i].scadaTime
  1081. ? il[i].scadaTime.split(" ")[1]
  1082. : "";
  1083. dataX.push(x);
  1084. dataY.push(v);
  1085. }
  1086. var unit = datt.unit;
  1087. var type = zbx;
  1088. chart.setOption({
  1089. title: {
  1090. text: zbx,
  1091. left: "center",
  1092. subtext: times[0] + "至" + times[1],
  1093. },
  1094. color: "rgb(45, 116, 231)",
  1095. grid: { left: "50px", right: "50px", bottom: "80px" },
  1096. // dataZoom: [
  1097. // {
  1098. // minSpan: 1,
  1099. // type: 'slider',
  1100. // labelFormatter: (i) => {
  1101. // var date = new Date(i)
  1102. // var time = [date.getHours(), date.getMinutes()]
  1103. // if (time[0] < 10) time[0] = '0' + time[0]
  1104. // if (time[1] < 10) time[1] = '0' + time[1]
  1105. // return (
  1106. // [
  1107. // date.getFullYear(),
  1108. // date.getMonth() + 1,
  1109. // date.getDate()
  1110. // ].join('-') +
  1111. // '\n' +
  1112. // time.join(':')
  1113. // )
  1114. // }
  1115. // }
  1116. // ],
  1117. toolbox: { feature: { saveAsImage: {} } },
  1118. tooltip: {
  1119. trigger: "axis",
  1120. formatter(a) {
  1121. return (
  1122. "记录时间:" +
  1123. a[0].axisValue +
  1124. "<br>" +
  1125. type +
  1126. " " +
  1127. a[0].data +
  1128. " " +
  1129. unit
  1130. );
  1131. },
  1132. },
  1133. xAxis: [
  1134. {
  1135. name: "日期",
  1136. type: "category",
  1137. data: dataX,
  1138. axisTick: {
  1139. show: false,
  1140. },
  1141. axisLine: {
  1142. show: false,
  1143. },
  1144. },
  1145. ],
  1146. yAxis: [{ name: unit, type: "value" }],
  1147. series: [{ type: "line", smooth: false, data: dataY }],
  1148. });
  1149. } else this.$message(res.message);
  1150. //this.infoLoading = false;
  1151. });
  1152. },
  1153. /**
  1154. * 判断报警情况
  1155. */
  1156. setAlarm(data, infos) {
  1157. if (data.length > 0) {
  1158. const alarmData = data[0].allocations.filter(
  1159. (item) => item.scadaReports != null
  1160. );
  1161. let alarmArr = [];
  1162. let openAlarm = false;
  1163. this.isAlarm = false;
  1164. alarmData.forEach((alarm) => {
  1165. const value = parseFloat(alarm.scada.value);
  1166. const scadaReports = alarm.scadaReports;
  1167. const variableCode = alarm.variableCode;
  1168. if (scadaReports) {
  1169. scadaReports.forEach((p) => {
  1170. const max = parseFloat(p.reportUpper);
  1171. const min = parseFloat(p.reportLower);
  1172. if (value > max || value < min) {
  1173. openAlarm = true; //存在报警
  1174. this.isAlarm = true;
  1175. const obj = Object.assign(
  1176. { variableCode: variableCode },
  1177. parseFloat
  1178. );
  1179. alarmArr.push(obj);
  1180. }
  1181. });
  1182. }
  1183. });
  1184. //报警
  1185. if (this.isOpenAlarm) {
  1186. this.speckVideo(openAlarm);
  1187. this.twinkle = setInterval(() => {
  1188. alarmArr.forEach((op) => {
  1189. const color = infos[op.variableCode].style.color;
  1190. let clr = "red";
  1191. if (
  1192. ["S7.300.1#QSYW", "S7.300.2#QSYW"].includes(op.variableCode)
  1193. ) {
  1194. clr = color == "red" ? "#fff" : "red";
  1195. } else {
  1196. clr = color == "red" ? "#fff" : "red";
  1197. }
  1198. infos[op.variableCode].style.color = clr;
  1199. });
  1200. }, 500);
  1201. } else {
  1202. for (key in infos) {
  1203. if (["S7.300.1#QSYW", "S7.300.2#QSYW"].includes(key)) {
  1204. infos[key].style.color = "#ffffff";
  1205. } else {
  1206. infos[key].style.color = "#ffffff";
  1207. }
  1208. }
  1209. if (this.twinkle) this.twinkle = null;
  1210. }
  1211. }
  1212. },
  1213. /**
  1214. * @description 消息播放
  1215. * @isAlarm 是否报警
  1216. */
  1217. speckVideo(alarm) {
  1218. this.$nextTick(() => {
  1219. const _videoMsg = this.$refs.videoMsg;
  1220. alarm && this.isAlarm ? _videoMsg.play() : _videoMsg.pause();
  1221. });
  1222. },
  1223. pagRefersh(bool) {
  1224. var datt = this.scada[this.selectSite];
  1225. var pages = this.$refs.pagination2;
  1226. var times = [
  1227. this.timss[0] + " " + this.startTime,
  1228. this.timss[1] + " " + this.endTime,
  1229. ];
  1230. //if (bool) this.infoLoading = true;
  1231. request({
  1232. url:
  1233. "/tofly-scada/scada/page?code=" +
  1234. datt.variableCode +
  1235. "&start=" +
  1236. times[0] +
  1237. "&end=" +
  1238. times[1] +
  1239. "&statisticsType=" +
  1240. 0 +
  1241. "&current=" +
  1242. pages.internalCurrentPage +
  1243. "&size=" +
  1244. pages.internalPageSize,
  1245. method: "get",
  1246. }).then((res) => {
  1247. if (res.code == 1) {
  1248. res = res.result;
  1249. this.siteDatas = res.records;
  1250. this.$refs.pageLength2.innerHTML =
  1251. pages.internalCurrentPage +
  1252. "/" +
  1253. Math.ceil((this.total2 = res.total) / pages.internalPageSize) +
  1254. " 页";
  1255. } else {
  1256. this.$message.error(res.message);
  1257. this.siteDatas = [];
  1258. this.$refs.pageLength2.innerHTML = "1/1 页";
  1259. }
  1260. //if (bool) this.infoLoading = false;
  1261. });
  1262. },
  1263. },
  1264. };
  1265. </script>
  1266. <style lang='scss' scoped>
  1267. .buttonGroupClass {
  1268. border-radius: unset;
  1269. border-right: none;
  1270. position: absolute;
  1271. top: 20px;
  1272. left: 50px;
  1273. z-index: 999;
  1274. }
  1275. .onWhiteText {
  1276. color: #8ac9fb !important;
  1277. }
  1278. .inPic {
  1279. color: #8ac9fb !important;
  1280. font-size: 17px;
  1281. }
  1282. >>> .tfStyleTitle {
  1283. font-size: 24px !important;
  1284. margin-bottom: 10px !important;
  1285. }
  1286. >>> .tfStyle {
  1287. font-size: 24px !important;
  1288. margin-bottom: 10px !important;
  1289. }
  1290. >>> .tf-li {
  1291. margin-bottom: 16px !important;
  1292. }
  1293. </style>