|
1
|
<template>
|
|
2
|
<div class="map-module">
|
|
3
|
<div class="tool-style">
|
|
4
5
6
7
8
9
|
<span style="font-size: 14px; color: #409eff"
>{{ $t("main.monitor.legend") }}:</span
>
<el-tag type="success" effect="dark">{{
$t("main.monitor.standby")
}}</el-tag>
|
|
10
|
<el-divider direction="vertical"></el-divider>
|
|
11
|
<el-tag effect="dark">{{ $t("main.monitor.normalRunning") }}</el-tag>
|
|
12
|
<el-divider direction="vertical"></el-divider>
|
|
13
14
15
|
<el-tag type="warning" effect="dark">{{
$t("main.monitor.nonAutomatic")
}}</el-tag>
|
|
16
|
<el-divider direction="vertical"></el-divider>
|
|
17
18
19
|
<el-tag type="danger" effect="dark">{{
$t("main.monitor.abnormal")
}}</el-tag>
|
|
20
|
<el-divider direction="vertical"></el-divider>
|
|
21
22
23
24
25
|
<el-button
type="primary"
size="mini"
icon="el-icon-refresh"
@click="reset"
|
|
26
|
>{{ $t("main.monitor.reset") }}</el-button
|
|
27
|
>
|
|
28
|
<el-divider direction="vertical"></el-divider>
|
|
29
30
31
|
<div style="width: 350px">
{{ $t("main.monitor.currentScalingFactor") }}:{{ scale.sx }}
</div>
|
|
32
33
|
<!-- <el-divider direction="vertical"></el-divider> -->
<!-- <span>当前偏移量:1</span> -->
|
|
34
35
|
</div>
<div id="flow" class="canvas-style">
|
|
36
37
38
39
|
<div id="container" @wheel.prevent="onWheel"></div>
<!-- @mousedown="onMouseDown"
@mousemove="onMouseMove"
@mouseup="onMouseUp" -->
|
|
40
41
42
43
44
|
</div>
</div>
</template>
<script>
|
|
45
46
|
import FlowGraph from "./flow/graph";
import graphData from "./flow/graph/data/test-data";
|
|
47
|
// import graphData from './flow/graph/data/data-custom-3';
|
|
48
49
50
51
52
53
54
55
|
import { getGUID } from "@/utils/index.js";
import {
conveyor,
conveyor_center,
conveyor_left,
conveyor_right,
} from "./flow/graph/images";
import { $, getContainerSize } from "./flow/index.js";
|
|
56
57
|
export default {
|
|
58
|
name: "MapModule",
|
|
59
60
61
62
63
64
|
data() {
return {
canvas: null,
graph: null,
initialTranslate: { x: 0, y: 0 },
initialScale: 1,
|
|
65
66
|
dataJson: graphData,
srmPath: {},
|
|
67
68
69
70
71
72
73
74
|
scale: {
sx: 1,
sy: 1,
},
isDragging: false, // 标记是否正在拖动
lastPointer: null, // 记录上次鼠标位置
canvasTop: 0, // 画布的顶部偏移
canvasLeft: 0, // 画布的左部偏移
|
|
75
76
77
78
79
|
};
},
props: {
isActive: {
type: Boolean,
|
|
80
81
|
default: false,
},
|
|
82
83
|
},
mounted() {
|
|
84
|
this.getFlowJson();
|
|
85
86
|
},
destroyed() {
|
|
87
|
const { graph } = FlowGraph;
|
|
88
|
// 销毁画布,资源回收
|
|
89
|
if (graph) graph.dispose();
|
|
90
|
// 移除监听
|
|
91
|
window.removeEventListener("resize", this.resizeFn);
|
|
92
93
|
},
methods: {
|
|
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
onWheel(event) {
const { graph } = FlowGraph;
if (graph) {
this.scale.sx = parseFloat(graph.scale().sx.toFixed(2));
}
},
onMouseDown(event) {
this.isDragging = true;
// this.lastPointer = this.canvas.getPointer(event);
// 获取相对于视口的坐标
const clientX = event.clientX;
const clientY = event.clientY;
// 获取相对于页面的坐标
const pageX = event.pageX;
const pageY = event.pageY;
// 获取相对于目标元素的坐标
const rect = event.target.getBoundingClientRect();
const offsetX = event.clientX - rect.left;
const offsetY = event.clientY - rect.top;
console.log("相对于视口的坐标:", clientX, clientY);
console.log("相对于页面的坐标:", pageX, pageY);
console.log("相对于 div 的坐标:", offsetX, offsetY);
},
onMouseMove(event) {
if (this.isDragging) {
// const currentPointer = this.canvas.getPointer(event);
// const deltaX = currentPointer.x - this.lastPointer.x;
// const deltaY = currentPointer.y - this.lastPointer.y;
// // 更新 canvasTop 和 canvasLeft
// this.canvasTop += deltaY;
// this.canvasLeft += deltaX;
// this.lastPointer = currentPointer;
}
},
onMouseUp() {
this.isDragging = false;
},
|
|
134
135
136
|
// 去后台拿json
getFlowJson() {
setTimeout(() => {
|
|
137
|
const graphJson = this.dataJson; //JSON.parse(window.localStorage.getItem('graphJson'))
|
|
138
|
// console.log(graphJson)
|
|
139
|
if (graphJson) {
|
|
140
|
this.srmPath = {};
|
|
141
142
143
144
145
146
147
148
149
|
for (let i = 0; i < 8; i++) {
var x = 150;
var y = 150;
switch (i) {
case 1:
y = 180;
break;
case 2:
y = 270;
|
|
150
|
break;
|
|
151
152
|
case 3:
y = 300;
|
|
153
|
break;
|
|
154
155
|
case 4:
y = 360;
|
|
156
|
break;
|
|
157
158
|
case 5:
y = 390;
|
|
159
|
break;
|
|
160
161
|
case 6:
y = 480;
|
|
162
|
break;
|
|
163
164
|
case 7:
y = 510;
|
|
165
|
break;
|
|
166
167
|
}
for (let j = 0; j < 28; j++) {
|
|
168
|
const isDuplicate = this.srmPath["A" + (j + 1)];
|
|
169
|
if (isDuplicate == undefined) {
|
|
170
|
this.srmPath["A" + (j + 1)] = x;
|
|
171
|
}
|
|
172
173
174
|
graphJson.cells.push({
position: {
x: x,
|
|
175
|
y: y,
|
|
176
177
178
|
},
attrs: {
text: {
|
|
179
180
|
text: j + 1,
},
|
|
181
182
183
|
},
size: {
width: 30,
|
|
184
|
height: 30,
|
|
185
|
},
|
|
186
|
shape: "Storage",
|
|
187
|
id: getGUID(),
|
|
188
189
|
zIndex: 1,
});
|
|
190
191
192
|
x += 30;
}
}
|
|
193
194
195
196
|
this.initFlowImage(graphJson);
}
}, 300);
|
|
197
198
199
200
|
},
// 根据json渲染
initFlowImage(graphJson) {
// 初始化画板
|
|
201
202
203
204
205
206
|
const graph = FlowGraph.init(
$("#container"),
$("#container").getBoundingClientRect().width,
$("#container").getBoundingClientRect().height,
false
);
|
|
207
|
// 渲染操作
|
|
208
|
graph.fromJSON(graphJson);
|
|
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
// // 定义新节点的数据
// const newNode = {
// position: { x: 500, y: 500 },
// size: { width: 80, height: 42 },
// attrs: {
// text: { text: '新节点' },
// body: { rx: 24, ry: 24 }
// },
// visible: true,
// shape: 'flow-chart-rect',
// id: 'new-node-id',
// zIndex: 24,
// data: { status: 0, pointCode: '53', fieldName: 'newFieldName' }
// };
// // 添加新节点到图中
// graph.addNode(newNode);
// 监听数据改变事件
|
|
228
229
|
graph.getNodes().forEach((node) => {
if (node.getData()) {
|
|
230
|
var data = node.getData();
|
|
231
|
if (node.shape.startsWith("Station") && data.type != undefined) {
|
|
232
|
if (data.type == "left") {
|
|
233
|
node.attr("image/xlink:href", conveyor_left);
|
|
234
|
// node.attr('body/class','flash-shrink-animation')
|
|
235
|
} else if (data.type == "right") {
|
|
236
|
node.attr("image/xlink:href", conveyor_right);
|
|
237
|
// node.attr('body/class','flash-shrink-animation')
|
|
238
239
240
|
// node.attr('body/fill','green')
// node.attr('text/fill', '#080808')
} else if (data.type == "center") {
|
|
241
|
node.attr("image/xlink:href", conveyor_center);
|
|
242
|
// node.attr('body/class','flash-shrink-animation')
|
|
243
244
|
// node.attr('body/fill','green')
// node.attr('text/fill', '#080808')
|
|
245
|
} else {
|
|
246
|
node.attr("image/xlink:href", conveyor);
|
|
247
248
249
|
}
}
node.on("change:data", ({ cell, current }) => {
|
|
250
251
|
if (current.status == "0") {
cell.attr("body/class", "flash-shrink-animation-close");
|
|
252
|
} else {
|
|
253
|
cell.attr("body/class", "flash-shrink-animation");
|
|
254
|
}
|
|
255
256
|
if (current.pallet == "0") {
cell.attr("imagePallet/class", "hide-pallet");
|
|
257
|
} else {
|
|
258
|
cell.attr("imagePallet/class", "show-pallet");
|
|
259
|
}
|
|
260
|
});
|
|
261
|
}
|
|
262
|
});
|
|
263
|
|
|
264
265
|
window.addEventListener("resize", this.resizeFn);
},
|
|
266
267
268
269
|
resizeFn() {
setTimeout(() => {
const { graph } = FlowGraph;
|
|
270
|
const { width, height } = getContainerSize($("#flow"));
|
|
271
272
273
274
|
graph.resize(width, height);
}, 100);
},
|
|
275
|
reset() {
|
|
276
277
|
const { graph } = FlowGraph;
if (graph) {
|
|
278
279
|
// console.log(this.initialScale);
// console.log(this.initialTranslate);
|
|
280
281
282
283
|
// 恢复初始缩放比例
graph.scale(1, 1);
// 恢复初始位置
graph.translate(0, 0);
|
|
284
|
}
|
|
285
|
},
|
|
286
287
288
289
|
//更新数据
updateData(srmList, rgvList, stationList) {
const { graph } = FlowGraph;
|
|
290
|
if (graph) {
|
|
291
|
// 监听数据改变事件
|
|
292
293
|
graph.getNodes().forEach((node) => {
if (node.getData()) {
|
|
294
|
var data = node.getData();
|
|
295
|
var isExist = false;
|
|
296
|
if (node.shape == "SRM") {
|
|
297
|
srmList.forEach((item) => {
|
|
298
299
|
// console.log(item)
if (item.code == data.code) {
|
|
300
|
isExist = true;
|
|
301
|
data.status = item.totalError == "True" ? "1" : "0";
|
|
302
303
304
305
306
|
data.pallet =
item.fork1HasPallet == "True" ||
item.fork2HasPallet == "True"
? "1"
: "0";
|
|
307
|
data.auto = item.operationModel == "5" ? "1" : "0";
|
|
308
|
data.text = item.fork1GoodsBarcode;
|
|
309
310
|
// 定义要过渡的属性路径
|
|
311
|
const path = "position/x";
|
|
312
313
|
// 定义目标值
var target = 0;
|
|
314
315
316
317
318
|
if (
item.fork1XPosition != null &&
item.fork1XPosition != ""
) {
if (item.fork1XPosition < 500) {
|
|
319
320
321
322
|
target = this.srmPath["A" + item.fork1XPosition];
} else {
target = 1000;
}
|
|
323
324
325
|
} else {
target = -999;
}
|
|
326
|
if (target != -999) {
|
|
327
328
329
|
// 定义过渡动画的配置选项
const options = {
duration: 1000, // 过渡效果持续 1 秒
|
|
330
331
|
easing: "ease-out", // 缓动函数为 ease-out
callback: function () {},
|
|
332
333
|
};
node.transition(path, target, options);
|
|
334
335
|
}
}
|
|
336
337
338
|
});
} else if (node.shape == "RGV") {
rgvList.forEach((item) => {
|
|
339
|
if (item.code == data.code) {
|
|
340
|
isExist = true;
|
|
341
|
data.status = item.totalError == "True" ? "1" : "0";
|
|
342
343
344
345
346
|
data.pallet =
item.fork1HasPallet == "True" ||
item.fork2HasPallet == "True"
? "1"
: "0";
|
|
347
|
data.auto = item.operationModel == "5" ? "1" : "0";
|
|
348
|
data.text = item.fork1GoodsBarcode;
|
|
349
|
}
|
|
350
351
352
|
});
} else if (node.shape.startsWith("Station")) {
stationList.forEach((item) => {
|
|
353
|
if (item.code.replace("StationMonitor", "") == data.code) {
|
|
354
|
isExist = true;
|
|
355
356
|
data.status =
item.stationError == "" ? "0" : item.stationError;
|
|
357
358
|
data.pallet = item.stationMonitorOccupied;
data.auto = item.stationMonitorAutomation;
|
|
359
|
data.text = item.stationMonitorBarcode;
|
|
360
|
}
|
|
361
|
});
|
|
362
|
}
|
|
363
364
|
if (isExist) {
//状态
|
|
365
366
|
if (data.status == "0" && data.auto == "1") {
node.attr("body/class", "flash-shrink-animation-close");
|
|
367
|
} else {
|
|
368
369
|
node.attr("body/width", node.getSize().width);
node.attr("body/height", node.getSize().height);
|
|
370
|
if (data.status != "0") {
|
|
371
|
node.attr("body/stroke", "#FF0000");
|
|
372
373
|
// node.attr('body/stroke',"#f56c6c")
} else {
|
|
374
|
node.attr("body/stroke", "#FFFF00");
|
|
375
376
|
// node.attr('body/stroke',"#e6a23c")
}
|
|
377
|
node.attr("body/class", "flash-shrink-animation");
|
|
378
379
|
}
//托盘
|
|
380
381
|
if (data.pallet == "0") {
node.attr("imagePallet/class", "hide-pallet");
|
|
382
|
} else {
|
|
383
|
node.attr("imagePallet/class", "show-pallet");
|
|
384
385
|
//个性化设置
if (node.shape == "SRM") {
|
|
386
387
|
node.attr("imagePallet/x", -5);
node.attr("imagePallet/y", 0);
|
|
388
|
} else if (node.shape == "Station") {
|
|
389
|
node.attr("imagePallet/x", 10);
|
|
390
|
}
|
|
391
|
//托盘
|
|
392
393
|
if (data.text != "") {
node.attr("textCode/text", data.text);
|
|
394
|
}
|
|
395
396
|
}
node.setData(data);
|
|
397
|
} else {
|
|
398
399
400
401
|
node.attr("body/width", node.getSize().width);
node.attr("body/height", node.getSize().height);
node.attr("body/stroke", "#FFFF00");
node.attr("body/class", "flash-shrink-animation");
|
|
402
403
|
}
}
|
|
404
|
});
|
|
405
|
}
|
|
406
407
408
|
},
},
};
|
|
409
410
411
|
</script>
<style scoped>
|
|
412
|
.tool-style {
|
|
413
414
415
|
position: absolute;
/* left: 0px;
top: 0px; */
|
|
416
417
|
display: flex;
align-items: center;
|
|
418
419
420
|
margin: 10px;
z-index: 99999;
}
|
|
421
422
|
.canvas-style {
border: 1px solid #ebeef5;
|
|
423
|
width: 100vw;
|
|
424
|
height: 100vh;
|
|
425
426
427
|
}
</style>
<style>
|
|
428
429
430
431
|
.map-module {
.el-main {
padding-top: 0px;
}
|
|
432
433
|
}
</style>
|