-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVisualTree.js
executable file
·129 lines (95 loc) · 4.12 KB
/
VisualTree.js
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
function printTitle(title) {
let p = document.createElement("p");
p.innerText = title;
let area = document.querySelector("#Steps");
area.appendChild(p);
}
function paintTree(tree, brief="") {
const level = tree.root ? tree.root.height + 1 : 0;
const canvas_margin = 10;
const node_width = 30;
const node_split_space = 10;
function calcCanvasWidth(tree) {
if (level == 0) return 60;
return canvas_margin + (2 ** (level - 1)) * (node_width + node_split_space) + canvas_margin;
}
const canvas_width = calcCanvasWidth(tree);
const canvas_height = level * (12 + 30);
let canvas = document.createElement("canvas");
canvas.width = canvas_width;
canvas.height = canvas_height;
let ctx = canvas.getContext("2d");
ctx.font = "12px Arial";
if (tree.root) {
const array = tree.array();
const tree_height = tree.root.height;
let height = 0;
let rootIndex = 0;
let maxIndex = 1;
while (height <= tree_height) {
const level_margin = (canvas_width - canvas_margin * 2) / (maxIndex); // be careful
const next_level_margin = (canvas_width - canvas_margin * 2) / (maxIndex * 2);
const draw_text_y = height * (12 + 30) + 20;
const next_draw_line_end_y = (height + 1) * (12 + 30) + 5;
for (var index = 0; index < maxIndex; index++) {
const value = array[rootIndex + index];
if (value == null) continue; // detect undefined or null
const draw_text_x = canvas_margin +
index * (level_margin) +
level_margin / 2 -
ctx.measureText(value).width / 2;
function nodeDrawLine(p, d) {
const loc = 2 * p + d;
if (array.length > loc && array[loc] != null) {
const draw_line_start_x = canvas_margin +
index * (level_margin) +
level_margin / 2;
const draw_line_end_x = canvas_margin +
(index * 2 + d - 1) * (next_level_margin) +
next_level_margin / 2;
ctx.beginPath();
ctx.moveTo(draw_line_start_x, draw_text_y + 5);
ctx.lineTo(draw_line_end_x, next_draw_line_end_y);
ctx.stroke();
}
}
ctx.fillText(value + "", draw_text_x, draw_text_y);
nodeDrawLine(rootIndex + index, 1); // left
nodeDrawLine(rootIndex + index, 2); // right
}
height++;
rootIndex = 2 ** height - 1;
maxIndex *= 2;
}
}
var span = document.createElement("span");
span.innerText = brief;
var area = document.querySelector("#Steps")
area.appendChild(span);
area.appendChild(canvas);
updateInfomation(tree);
}
function updateInfomation(tree) {
var preOrder = document.querySelector("#Information #PreOrder");
var inOrder = document.querySelector("#Information #InOrder");
var postOrder = document.querySelector("#Information #PostOrder");
var treeArray = document.querySelector("#TreeArray");
preOrder.innerText = tree.traversePreOrder().join(", ");
inOrder.innerText = tree.traverseInOrder().join(", ");
postOrder.innerText = tree.traversePostOrder().join(", ");
//treeArray.innerText = tree.array().join(", ");
let rtn = tree.array();
let idx_tr = document.querySelector("#TreeArray #IdxTr");
idx_tr.innerHTML = ""; // remove all children
let content_tr = document.querySelector("#TreeArray #ContentTr");
content_tr.innerHTML = ""; // remove all children
for (let i = 0; i < rtn.length; i++) {
let idx_td = document.createElement("td");
idx_td.innerText = i + "";
let content_td = document.createElement("td");
let value = rtn[i];
content_td.innerText = value == null ? "" : value + "";
idx_tr.appendChild(idx_td);
content_tr.appendChild(content_td);
}
}