-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcanvas.html
423 lines (373 loc) · 9.49 KB
/
canvas.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
<html>
<script src="./savepage.js"></script>
<body>
<div id="graph">
</div>
<div id="drawing" style="position: relative;">
</div>
<canvas id="processCanvas"></canvas>
<div style="position: relative;">
</div>
<div style="position: relative;">
<canvas id="myCanvas"></canvas>
</div>
</html>
</body>
<script>
var lines = [
{
beginNodeId:"1",
beginNode:"测试节点1",
endNodeId:"2",
endNode:"测试节点2"
},
{
beginNodeId:"2",
beginNode:"测试节点2",
endNodeId:"3",
endNode:"测试节点3"
},
{
beginNodeId:"3",
beginNode:"测试节点3",
endNodeId:"4",
endNode:"测试节点4"
},
{
beginNodeId:"4",
beginNode:"测试节点4",
endNodeId:"5",
endNode:"测试节点5"
},
{
beginNodeId:"5",
beginNode:"测试节点5",
endNodeId:"6",
endNode:"测试节点6"
},
{
beginNodeId:"5",
beginNode:"测试节点5",
endNodeId:"1",
endNode:"测试节点1"
},
{
beginNodeId:"7",
beginNode:"测试节点7",
endNodeId:"8",
endNode:"测试节点8"
}
];
var allNodesArr = [];
var allStartNodes = [];
var allEndNodes = [];
var onlyStartNodes=[];//只是起始节点
var onlyEndNodes = [];//只是结束节点
//获取起点
function getStartEndNodes(allnodes){
for(var i in allnodes){
var node = allnodes[i];
var beginNode = {
id:node.beginNodeId,
name:node.beginNode
};
var endNode = {
id:node.endNodeId,
name:node.endNode
};
allNodesArr.push(beginNode);
allNodesArr.push(endNode);
allStartNodes.push(beginNode);
allEndNodes.push(endNode);
}
allNodesArr = unique(allNodesArr);//去重
allStartNodes = unique(allStartNodes);
allEndNodes = unique(allEndNodes);
//仅是开始节点
onlyStartNodes = allStartNodes.filter(function(node){
var flag = true;
for(var i in lines){
if(lines[i].endNodeId == node.id){
flag = false;
}
}
return flag;
});
console.log(onlyStartNodes);
}
// 对象数组去重
function unique(inputArr){
var obj = {};
var outputArr = [];
for(var i in inputArr){
if(!obj[inputArr[i].id]){
outputArr.push(inputArr[i]);
obj[inputArr[i].id] = true;
}
}
return outputArr;
}
//运行
getStartEndNodes(lines);
//有向图邻接表
// var targetNodesHtml = "";
// for(var i in allNodesArr){
// var node = allNodesArr[i]
// targetNodesHtml = targetNodesHtml + "<div class='graph-block target-node'>"+node.name+"</div>";
// }
// var firstLineHtml = "<div class='graph-line '><div class='graph-block source-node target-node'></div>"+targetNodesHtml+"</div>";
// var allEdgeHtml = ""
// for(var i in allNodesArr){
// var edgeArr = [];//线数组
// var sourceNode = allNodesArr[i];//源节点
// var edgeHtml = "<div class='graph-line'><div class='graph-block source-node'>"+sourceNode.name+"</div>";
// for(var j in allNodesArr){
// var targetNode = allNodesArr[j];//目的节点
// var inFlag = false;
// for(var k in lines){
// var line = lines[k];
// if(line.beginNodeId==sourceNode.id && line.endNodeId==targetNode.id){
// inFlag = true;
// }
// }
// if(inFlag){
// edgeArr.push(1)
// }else{
// edgeArr.push(0);
// }
// }
// for(var m in edgeArr){
// if(edgeArr[m]==1){//着色
// edgeHtml = edgeHtml + "<div class='graph-block' style='font-weight: bold;background-color:#4ff181;'>"+edgeArr[m]+"</div>";
// }else{
// edgeHtml = edgeHtml + "<div class='graph-block'>"+edgeArr[m]+"</div>";
// }
// }
// edgeHtml = edgeHtml + "</div>";
// allEdgeHtml = allEdgeHtml + edgeHtml
// }
// var graph = document.getElementById("graph");
// graph.innerHTML = firstLineHtml + allEdgeHtml;
//canvas画图-----开始
var processCanvas = document.getElementById('processCanvas');
var canvasHeight = allNodesArr.length * 60
processCanvas.height = canvasHeight;
processCanvas.width = canvasHeight;
var ctx = processCanvas.getContext("2d");
var num = allNodesArr.length;//有多少个点
var angle = Math.PI * 2 / num;//分角
var x = processCanvas.width/2;//大圆心x坐标
var y = processCanvas.height/2;//大圆心y坐标
var r = x>y ? (y-40) : (x-40);//大圆半径
var xTemp=x-r;//小圆心x坐标
var yTemp=y;//小圆心y坐标
var rTemp=40;//小圆半径
//画小圆
for(var i in allNodesArr){
var nodeId = allNodesArr[i].id;//点的id
var nodeName = allNodesArr[i].name;//
//点中心的坐标
xTemp = x + r*Math.sin(i*angle);
yTemp = y + r*Math.cos(i*angle);
ctx.beginPath();
ctx.arc(xTemp, yTemp, rTemp, Math.PI * 2, false);
ctx.closePath();
if(onlyStartNodes.includes(nodeId)){//开始节点涂色
ctx.fillStyle = 'green';
}else if(onlyEndNodes.includes(nodeId)){//结束节点涂色
ctx.fillStyle = 'red';
}else{
ctx.fillStyle = 'rgb(79,241,129,1)';
}
ctx.fill();
// 设置字体
ctx.font = "12px bold 黑体";
// 设置颜色
ctx.fillStyle = 'rgb(0,0,0,1)';
// 设置水平对齐方式
ctx.textAlign = "center";
// 设置垂直对齐方式
ctx.textBaseline = "middle";
ctx.fillText(nodeName, xTemp, yTemp);
allNodesArr[i].x = xTemp;
allNodesArr[i].y = yTemp;
}
//画线
for(var i in lines){
var startNode = allNodesArr.find(function(node){
return node.id == lines[i].beginNodeId;
})
var endNode = allNodesArr.find(function(node){
return node.id == lines[i].endNodeId;
});
ctx.strokeStyle="gray";
ctx.fillStyle="blue";
ctx.lineWidth=1;
// 开始画线
ctx.beginPath();
var lineLength = distance(startNode,endNode);
//重新计算线的起点
var x1 = rTemp/lineLength*(endNode.x-startNode.x)+startNode.x;//交点的x值
var y1 = rTemp/lineLength*(endNode.y-startNode.y)+startNode.y;//交点的y值
var lineStart = {x:x1,y:y1};
ctx.moveTo(x1,y1);
//重新计算线的终点
var x2 = (lineLength-rTemp)/lineLength*(endNode.x-startNode.x)+startNode.x;//交点的x值
var y2 = (lineLength-rTemp)/lineLength*(endNode.y-startNode.y)+startNode.y;//交点的y值
var lineEnd = {x:x2,y:y2};
ctx.lineTo(x2,y2);
ctx.stroke();
ctx.closePath();
//绘制箭头
var angleLength = 15;//设置角的长度
var theta = 20*Math.PI/180;//设置角的角度
var lineK=(lineStart.x-lineEnd.x)/(lineStart.y-lineEnd.y);//直线斜率
//直线与水平线夹角(-90 ~ 90)
var lineTheta = Math.atan(lineK);
//极坐标系转换为平面坐标系
var leftTheta = lineTheta+theta;
var rightTheta = lineTheta-theta;
var x4=0,y4=0;//箭头左侧坐标
var x5=0,y5=0;//箭头右侧坐标
if(endNode.y - startNode.y > 0){//向量夹角在0-180度之间(0--PI)
x4 = x2 - angleLength*Math.sin(leftTheta);
y4 = y2 - angleLength*Math.cos(leftTheta);
x5 = x2 - angleLength*Math.sin(rightTheta);
y5 = y2 - angleLength*Math.cos(rightTheta);
}else{//向量夹角在180度-360度之间(PI--2*PI)
x4 = x2 + angleLength*Math.sin(leftTheta);
y4 = y2 + angleLength*Math.cos(leftTheta);
x5 = x2 + angleLength*Math.sin(rightTheta);
y5 = y2 + angleLength*Math.cos(rightTheta);
}
/**
var x3 = (lineLength-rTemp-angleLength)/lineLength*(endNode.x-startNode.x)+startNode.x;//交点的x值
var y3 = (lineLength-rTemp-angleLength)/lineLength*(endNode.y-startNode.y)+startNode.y;//交点的y值
var intersection = {x:x3,y:y3};//垂线与直线交点
var k = 1/lineK;//正交线斜率 垂线y=kx+b
var b = y3-k*x3;//求出直线偏移
*/
//以x2 和y2为起点,左右各成一定角度画箭头
ctx.save();//入栈
ctx.beginPath();
ctx.strokeStyle="gray";
ctx.moveTo(x2,y2);
ctx.lineTo(x4,y4);
ctx.moveTo(x2,y2);
ctx.lineTo(x5,y5);
ctx.closePath();
ctx.stroke();
ctx.restore();//出栈
}
//求两个点之间的距离
function distance(start,end){
return Math.sqrt(Math.pow((start.x - end.x),2)+Math.pow((start.y - end.y),2));
}
processCanvas.οnmοusedοwn=function (e) {
console.log("οnmοusedοwn");
processCanvas.onmousemove = function(e){
console.log("onmousemove");
var x = e.clientX;
var y = e.clientY;
console.log("x="+x);
};
processCanvas.onmouseup = function(){
//canva.onmousemove = null;
//canva.onmouseup = null;
};
}
getMaxPath();
function getMaxPath(){
var pathArr = [];
for(var i in onlyStartNodes){
var startNode = onlyStartNodes[i];
var pathTemp = [];
var result = []
getPath(startNode,pathTemp,result);
console.log(result);
}
}
function getPath(startNode,prePath,result){
for(var i in lines){
if(lines[i].beginNodeId == startNode.id){
prePath.push(startNode);
result.push(prePath);
startNode = allNodesArr.find(function(node){
return node.id == lines[i].endNodeId;
})
getPath(startNode,prePath,result);
}
}
}
</script>
<style>
.front-arrow{
position:absolute;
right: -5px;
bottom:0px;
width: 10px;
height: 10px;
border: 1px solid black;
border-top: none;
border-right: none;
transform: rotate(-45deg);
}
.back-arrow{
position:absolute;
top: 0px;
left:-5px;
width: 10px;
height: 10px;
border: 1px solid black;
border-top: none;
border-right: none;
transform: rotate(135deg);
}
.edge-front{
position:absolute;
border-top:1px solid;
border-left:1px solid;
border-right:1px solid;
}
.edge-back{
position:absolute;
border-bottom:1px solid;
border-left:1px solid;
border-right:1px solid;
}
.drawing-line{
display:flex;
position:absolute;
}
.drawing-block{
width:60px;
height:60px;
border:1px solid #CCC;
border-radius: 30px;
line-height: 60px;
text-align: center;
margin: 9px;
background-color:#4ff181;
}
.graph-line{
display:flex;
}
.graph-block{
width:60px;
text-align: center;
border-bottom: 1px solid #CCC;
border-right: 1px solid #CCC;
height: 40px;
line-height: 40px;
}
.target-node{
background-color:red;
height: 200px;
line-height: 20px;
}
.source-node{
background-color:green;
width: 240px;
font-size: 12px;
}
</style>