squarified 0.3.7 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -41
- package/dist/dom-event-BPqG0KO2.js +1712 -0
- package/dist/dom-event-DQ8OFrZa.mjs +1471 -0
- package/dist/index.d.mts +613 -345
- package/dist/index.d.ts +613 -345
- package/dist/index.js +103 -1987
- package/dist/index.mjs +72 -1974
- package/dist/plugin.d.mts +431 -0
- package/dist/plugin.d.ts +431 -0
- package/dist/plugin.js +399 -0
- package/dist/plugin.mjs +394 -0
- package/package.json +23 -9
|
@@ -0,0 +1,1712 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
//#region src/etoile/native/matrix.ts
|
|
4
|
+
const DEG_TO_RAD = Math.PI / 180;
|
|
5
|
+
const PI_2 = Math.PI * 2;
|
|
6
|
+
const DEFAULT_MATRIX_LOC = {
|
|
7
|
+
a: 1,
|
|
8
|
+
b: 0,
|
|
9
|
+
c: 0,
|
|
10
|
+
d: 1,
|
|
11
|
+
e: 0,
|
|
12
|
+
f: 0
|
|
13
|
+
};
|
|
14
|
+
var Matrix2D = class {
|
|
15
|
+
a;
|
|
16
|
+
b;
|
|
17
|
+
c;
|
|
18
|
+
d;
|
|
19
|
+
e;
|
|
20
|
+
f;
|
|
21
|
+
constructor(loc = {}) {
|
|
22
|
+
this.a = loc.a || 1;
|
|
23
|
+
this.b = loc.b || 0;
|
|
24
|
+
this.c = loc.c || 0;
|
|
25
|
+
this.d = loc.d || 1;
|
|
26
|
+
this.e = loc.e || 0;
|
|
27
|
+
this.f = loc.f || 0;
|
|
28
|
+
}
|
|
29
|
+
create(loc) {
|
|
30
|
+
Object.assign(this, loc);
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
transform(x, y, scaleX, scaleY, rotation, skewX, skewY) {
|
|
34
|
+
this.scale(scaleX, scaleY).translation(x, y);
|
|
35
|
+
if (skewX || skewY) this.skew(skewX, skewY);
|
|
36
|
+
else this.roate(rotation);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
translation(x, y) {
|
|
40
|
+
this.e += x;
|
|
41
|
+
this.f += y;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
scale(a, d) {
|
|
45
|
+
this.a *= a;
|
|
46
|
+
this.d *= d;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
skew(x, y) {
|
|
50
|
+
const tanX = Math.tan(x * DEG_TO_RAD);
|
|
51
|
+
const tanY = Math.tan(y * DEG_TO_RAD);
|
|
52
|
+
const a = this.a + this.b * tanX;
|
|
53
|
+
const b = this.b + this.a * tanY;
|
|
54
|
+
const c = this.c + this.d * tanX;
|
|
55
|
+
const d = this.d + this.c * tanY;
|
|
56
|
+
this.a = a;
|
|
57
|
+
this.b = b;
|
|
58
|
+
this.c = c;
|
|
59
|
+
this.d = d;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
roate(rotation) {
|
|
63
|
+
if (rotation > 0) {
|
|
64
|
+
const rad = rotation * DEG_TO_RAD;
|
|
65
|
+
const cosTheta = Math.cos(rad);
|
|
66
|
+
const sinTheta = Math.sin(rad);
|
|
67
|
+
const a = this.a * cosTheta - this.b * sinTheta;
|
|
68
|
+
const b = this.a * sinTheta + this.b * cosTheta;
|
|
69
|
+
const c = this.c * cosTheta - this.d * sinTheta;
|
|
70
|
+
const d = this.c * sinTheta + this.d * cosTheta;
|
|
71
|
+
this.a = a;
|
|
72
|
+
this.b = b;
|
|
73
|
+
this.c = c;
|
|
74
|
+
this.d = d;
|
|
75
|
+
}
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/etoile/graph/display.ts
|
|
82
|
+
const SELF_ID = {
|
|
83
|
+
id: 0,
|
|
84
|
+
get() {
|
|
85
|
+
return this.id++;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
let DisplayType = /* @__PURE__ */ function(DisplayType$1) {
|
|
89
|
+
DisplayType$1["Graph"] = "Graph";
|
|
90
|
+
DisplayType$1["Box"] = "Box";
|
|
91
|
+
DisplayType$1["Text"] = "Text";
|
|
92
|
+
DisplayType$1["RoundRect"] = "RoundRect";
|
|
93
|
+
DisplayType$1["Bitmap"] = "Bitmap";
|
|
94
|
+
return DisplayType$1;
|
|
95
|
+
}({});
|
|
96
|
+
var Display = class {
|
|
97
|
+
parent;
|
|
98
|
+
id;
|
|
99
|
+
matrix;
|
|
100
|
+
constructor() {
|
|
101
|
+
this.parent = null;
|
|
102
|
+
this.id = SELF_ID.get();
|
|
103
|
+
this.matrix = new Matrix2D();
|
|
104
|
+
}
|
|
105
|
+
destory() {}
|
|
106
|
+
};
|
|
107
|
+
const ASSIGN_MAPPINGS = {
|
|
108
|
+
fillStyle: 1,
|
|
109
|
+
strokeStyle: 2,
|
|
110
|
+
font: 4,
|
|
111
|
+
lineWidth: 8,
|
|
112
|
+
textAlign: 16,
|
|
113
|
+
textBaseline: 32
|
|
114
|
+
};
|
|
115
|
+
const ASSIGN_MAPPINGS_MODE = ASSIGN_MAPPINGS.fillStyle | ASSIGN_MAPPINGS.strokeStyle | ASSIGN_MAPPINGS.font | ASSIGN_MAPPINGS.lineWidth | ASSIGN_MAPPINGS.textAlign | ASSIGN_MAPPINGS.textBaseline;
|
|
116
|
+
const CALL_MAPPINGS_MODE = 0;
|
|
117
|
+
function createInstruction() {
|
|
118
|
+
return {
|
|
119
|
+
mods: [],
|
|
120
|
+
fillStyle(...args) {
|
|
121
|
+
this.mods.push({
|
|
122
|
+
mod: ["fillStyle", args],
|
|
123
|
+
type: ASSIGN_MAPPINGS.fillStyle
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
fillRect(...args) {
|
|
127
|
+
this.mods.push({
|
|
128
|
+
mod: ["fillRect", args],
|
|
129
|
+
type: CALL_MAPPINGS_MODE
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
strokeStyle(...args) {
|
|
133
|
+
this.mods.push({
|
|
134
|
+
mod: ["strokeStyle", args],
|
|
135
|
+
type: ASSIGN_MAPPINGS.strokeStyle
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
lineWidth(...args) {
|
|
139
|
+
this.mods.push({
|
|
140
|
+
mod: ["lineWidth", args],
|
|
141
|
+
type: ASSIGN_MAPPINGS.lineWidth
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
strokeRect(...args) {
|
|
145
|
+
this.mods.push({
|
|
146
|
+
mod: ["strokeRect", args],
|
|
147
|
+
type: CALL_MAPPINGS_MODE
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
fillText(...args) {
|
|
151
|
+
this.mods.push({
|
|
152
|
+
mod: ["fillText", args],
|
|
153
|
+
type: CALL_MAPPINGS_MODE
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
font(...args) {
|
|
157
|
+
this.mods.push({
|
|
158
|
+
mod: ["font", args],
|
|
159
|
+
type: ASSIGN_MAPPINGS.font
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
textBaseline(...args) {
|
|
163
|
+
this.mods.push({
|
|
164
|
+
mod: ["textBaseline", args],
|
|
165
|
+
type: ASSIGN_MAPPINGS.textBaseline
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
textAlign(...args) {
|
|
169
|
+
this.mods.push({
|
|
170
|
+
mod: ["textAlign", args],
|
|
171
|
+
type: ASSIGN_MAPPINGS.textAlign
|
|
172
|
+
});
|
|
173
|
+
},
|
|
174
|
+
beginPath() {
|
|
175
|
+
this.mods.push({
|
|
176
|
+
mod: ["beginPath", []],
|
|
177
|
+
type: CALL_MAPPINGS_MODE
|
|
178
|
+
});
|
|
179
|
+
},
|
|
180
|
+
moveTo(...args) {
|
|
181
|
+
this.mods.push({
|
|
182
|
+
mod: ["moveTo", args],
|
|
183
|
+
type: CALL_MAPPINGS_MODE
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
arcTo(...args) {
|
|
187
|
+
this.mods.push({
|
|
188
|
+
mod: ["arcTo", args],
|
|
189
|
+
type: CALL_MAPPINGS_MODE
|
|
190
|
+
});
|
|
191
|
+
},
|
|
192
|
+
closePath() {
|
|
193
|
+
this.mods.push({
|
|
194
|
+
mod: ["closePath", []],
|
|
195
|
+
type: CALL_MAPPINGS_MODE
|
|
196
|
+
});
|
|
197
|
+
},
|
|
198
|
+
fill() {
|
|
199
|
+
this.mods.push({
|
|
200
|
+
mod: ["fill", []],
|
|
201
|
+
type: CALL_MAPPINGS_MODE
|
|
202
|
+
});
|
|
203
|
+
},
|
|
204
|
+
stroke() {
|
|
205
|
+
this.mods.push({
|
|
206
|
+
mod: ["stroke", []],
|
|
207
|
+
type: CALL_MAPPINGS_MODE
|
|
208
|
+
});
|
|
209
|
+
},
|
|
210
|
+
drawImage(...args) {
|
|
211
|
+
this.mods.push({
|
|
212
|
+
mod: ["drawImage", args],
|
|
213
|
+
type: CALL_MAPPINGS_MODE
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
var S = class extends Display {
|
|
219
|
+
width;
|
|
220
|
+
height;
|
|
221
|
+
x;
|
|
222
|
+
y;
|
|
223
|
+
scaleX;
|
|
224
|
+
scaleY;
|
|
225
|
+
rotation;
|
|
226
|
+
skewX;
|
|
227
|
+
skewY;
|
|
228
|
+
constructor(options = {}) {
|
|
229
|
+
super();
|
|
230
|
+
this.width = options.width || 0;
|
|
231
|
+
this.height = options.height || 0;
|
|
232
|
+
this.x = options.x || 0;
|
|
233
|
+
this.y = options.y || 0;
|
|
234
|
+
this.scaleX = options.scaleX || 1;
|
|
235
|
+
this.scaleY = options.scaleY || 1;
|
|
236
|
+
this.rotation = options.rotation || 0;
|
|
237
|
+
this.skewX = options.skewX || 0;
|
|
238
|
+
this.skewY = options.skewY || 0;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
var Graph = class extends S {
|
|
242
|
+
instruction;
|
|
243
|
+
__options__;
|
|
244
|
+
__widget__;
|
|
245
|
+
constructor(options = {}) {
|
|
246
|
+
super(options);
|
|
247
|
+
this.instruction = createInstruction();
|
|
248
|
+
this.__options__ = options;
|
|
249
|
+
this.__widget__ = null;
|
|
250
|
+
}
|
|
251
|
+
render(ctx) {
|
|
252
|
+
this.create();
|
|
253
|
+
const cap = this.instruction.mods.length;
|
|
254
|
+
for (let i = 0; i < cap; i++) {
|
|
255
|
+
const { mod, type } = this.instruction.mods[i];
|
|
256
|
+
const [direct, ...args] = mod;
|
|
257
|
+
if (type & ASSIGN_MAPPINGS_MODE) {
|
|
258
|
+
ctx[direct] = args[0];
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
ctx[direct].apply(ctx, ...args);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
get __instanceOf__() {
|
|
265
|
+
return DisplayType.Graph;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/etoile/graph/types.ts
|
|
271
|
+
function isGraph(display) {
|
|
272
|
+
return display.__instanceOf__ === DisplayType.Graph;
|
|
273
|
+
}
|
|
274
|
+
function isBox(display) {
|
|
275
|
+
return display.__instanceOf__ === DisplayType.Box;
|
|
276
|
+
}
|
|
277
|
+
function isRoundRect(display) {
|
|
278
|
+
return isGraph(display) && display.__shape__ === DisplayType.RoundRect;
|
|
279
|
+
}
|
|
280
|
+
function isText(display) {
|
|
281
|
+
return isGraph(display) && display.__shape__ === DisplayType.Text;
|
|
282
|
+
}
|
|
283
|
+
function isBitmap(display) {
|
|
284
|
+
return isGraph(display) && display.__shape__ === DisplayType.Bitmap;
|
|
285
|
+
}
|
|
286
|
+
const asserts = {
|
|
287
|
+
isGraph,
|
|
288
|
+
isBox,
|
|
289
|
+
isText,
|
|
290
|
+
isRoundRect,
|
|
291
|
+
isBitmap
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region src/etoile/graph/box.ts
|
|
296
|
+
var C = class extends Display {
|
|
297
|
+
elements;
|
|
298
|
+
constructor() {
|
|
299
|
+
super();
|
|
300
|
+
this.elements = [];
|
|
301
|
+
}
|
|
302
|
+
add(...elements) {
|
|
303
|
+
const cap = elements.length;
|
|
304
|
+
for (let i = 0; i < cap; i++) {
|
|
305
|
+
const element = elements[i];
|
|
306
|
+
if (element.parent) {}
|
|
307
|
+
this.elements.push(element);
|
|
308
|
+
element.parent = this;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
remove(...elements) {
|
|
312
|
+
const cap = elements.length;
|
|
313
|
+
for (let i = 0; i < cap; i++) for (let j = this.elements.length - 1; j >= 0; j--) {
|
|
314
|
+
const element = this.elements[j];
|
|
315
|
+
if (element.id === elements[i].id) {
|
|
316
|
+
this.elements.splice(j, 1);
|
|
317
|
+
element.parent = null;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
destory() {
|
|
322
|
+
this.elements.forEach((element) => element.parent = null);
|
|
323
|
+
this.elements.length = 0;
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
var Box = class Box extends C {
|
|
327
|
+
elements;
|
|
328
|
+
constructor() {
|
|
329
|
+
super();
|
|
330
|
+
this.elements = [];
|
|
331
|
+
}
|
|
332
|
+
add(...elements) {
|
|
333
|
+
const cap = elements.length;
|
|
334
|
+
for (let i = 0; i < cap; i++) {
|
|
335
|
+
const element = elements[i];
|
|
336
|
+
if (element.parent) {}
|
|
337
|
+
this.elements.push(element);
|
|
338
|
+
element.parent = this;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
remove(...elements) {
|
|
342
|
+
const cap = elements.length;
|
|
343
|
+
for (let i = 0; i < cap; i++) for (let j = this.elements.length - 1; j >= 0; j--) {
|
|
344
|
+
const element = this.elements[j];
|
|
345
|
+
if (element.id === elements[i].id) {
|
|
346
|
+
this.elements.splice(j, 1);
|
|
347
|
+
element.parent = null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
destory() {
|
|
352
|
+
this.elements.forEach((element) => element.parent = null);
|
|
353
|
+
this.elements.length = 0;
|
|
354
|
+
}
|
|
355
|
+
get __instanceOf__() {
|
|
356
|
+
return DisplayType.Box;
|
|
357
|
+
}
|
|
358
|
+
clone() {
|
|
359
|
+
const box = new Box();
|
|
360
|
+
if (this.elements.length) {
|
|
361
|
+
const stack = [{
|
|
362
|
+
elements: this.elements,
|
|
363
|
+
parent: box
|
|
364
|
+
}];
|
|
365
|
+
while (stack.length > 0) {
|
|
366
|
+
const { elements, parent } = stack.pop();
|
|
367
|
+
const cap = elements.length;
|
|
368
|
+
for (let i = 0; i < cap; i++) {
|
|
369
|
+
const element = elements[i];
|
|
370
|
+
if (asserts.isBox(element)) {
|
|
371
|
+
const newBox = new Box();
|
|
372
|
+
newBox.parent = parent;
|
|
373
|
+
parent.add(newBox);
|
|
374
|
+
stack.push({
|
|
375
|
+
elements: element.elements,
|
|
376
|
+
parent: newBox
|
|
377
|
+
});
|
|
378
|
+
} else if (asserts.isGraph(element)) {
|
|
379
|
+
const el = element.clone();
|
|
380
|
+
el.parent = parent;
|
|
381
|
+
parent.add(el);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return box;
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/etoile/native/runtime.ts
|
|
392
|
+
function decodeHLS(meta) {
|
|
393
|
+
const { h, l, s, a } = meta;
|
|
394
|
+
if ("a" in meta) return `hsla(${h}deg, ${s}%, ${l}%, ${a})`;
|
|
395
|
+
return `hsl(${h}deg, ${s}%, ${l}%)`;
|
|
396
|
+
}
|
|
397
|
+
function decodeRGB(meta) {
|
|
398
|
+
const { r, g, b, a } = meta;
|
|
399
|
+
if ("a" in meta) return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
400
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
401
|
+
}
|
|
402
|
+
function decodeColor(meta) {
|
|
403
|
+
return meta.mode === "rgb" ? decodeRGB(meta.desc) : decodeHLS(meta.desc);
|
|
404
|
+
}
|
|
405
|
+
function evaluateFillStyle(primitive, opacity = 1) {
|
|
406
|
+
const descibe = {
|
|
407
|
+
mode: primitive.mode,
|
|
408
|
+
desc: {
|
|
409
|
+
...primitive.desc,
|
|
410
|
+
a: opacity
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
return decodeColor(descibe);
|
|
414
|
+
}
|
|
415
|
+
const runtime = { evaluateFillStyle };
|
|
416
|
+
|
|
417
|
+
//#endregion
|
|
418
|
+
//#region src/etoile/graph/rect.ts
|
|
419
|
+
var RoundRect = class RoundRect extends Graph {
|
|
420
|
+
style;
|
|
421
|
+
constructor(options = {}) {
|
|
422
|
+
super(options);
|
|
423
|
+
this.style = options.style || Object.create(null);
|
|
424
|
+
}
|
|
425
|
+
get __shape__() {
|
|
426
|
+
return DisplayType.RoundRect;
|
|
427
|
+
}
|
|
428
|
+
create() {
|
|
429
|
+
const padding = this.style.padding;
|
|
430
|
+
const x = 0;
|
|
431
|
+
const y = 0;
|
|
432
|
+
const width = this.width - padding * 2;
|
|
433
|
+
const height = this.height - padding * 2;
|
|
434
|
+
const radius = this.style.radius || 0;
|
|
435
|
+
this.instruction.beginPath();
|
|
436
|
+
this.instruction.moveTo(x + radius, y);
|
|
437
|
+
this.instruction.arcTo(x + width, y, x + width, y + height, radius);
|
|
438
|
+
this.instruction.arcTo(x + width, y + height, x, y + height, radius);
|
|
439
|
+
this.instruction.arcTo(x, y + height, x, y, radius);
|
|
440
|
+
this.instruction.arcTo(x, y, x + width, y, radius);
|
|
441
|
+
this.instruction.closePath();
|
|
442
|
+
if (this.style.fill) {
|
|
443
|
+
this.instruction.closePath();
|
|
444
|
+
this.instruction.fillStyle(runtime.evaluateFillStyle(this.style.fill, this.style.opacity));
|
|
445
|
+
this.instruction.fill();
|
|
446
|
+
}
|
|
447
|
+
if (this.style.stroke) {
|
|
448
|
+
if (typeof this.style.lineWidth === "number") this.instruction.lineWidth(this.style.lineWidth);
|
|
449
|
+
this.instruction.strokeStyle(this.style.stroke);
|
|
450
|
+
this.instruction.stroke();
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
clone() {
|
|
454
|
+
return new RoundRect({
|
|
455
|
+
...this.style,
|
|
456
|
+
...this.__options__
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
//#endregion
|
|
462
|
+
//#region src/etoile/graph/text.ts
|
|
463
|
+
var Text = class Text extends Graph {
|
|
464
|
+
text;
|
|
465
|
+
style;
|
|
466
|
+
constructor(options = {}) {
|
|
467
|
+
super(options);
|
|
468
|
+
this.text = options.text || "";
|
|
469
|
+
this.style = options.style || Object.create(null);
|
|
470
|
+
}
|
|
471
|
+
create() {
|
|
472
|
+
if (this.style.fill) {
|
|
473
|
+
this.instruction.font(this.style.font);
|
|
474
|
+
this.instruction.lineWidth(this.style.lineWidth);
|
|
475
|
+
this.instruction.textBaseline(this.style.baseline);
|
|
476
|
+
this.instruction.textAlign(this.style.textAlign);
|
|
477
|
+
this.instruction.fillStyle(this.style.fill);
|
|
478
|
+
this.instruction.fillText(this.text, 0, 0);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
clone() {
|
|
482
|
+
return new Text({
|
|
483
|
+
...this.style,
|
|
484
|
+
...this.__options__
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
get __shape__() {
|
|
488
|
+
return DisplayType.Text;
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
//#endregion
|
|
493
|
+
//#region src/etoile/etoile.ts
|
|
494
|
+
function traverse(graphs, handler) {
|
|
495
|
+
const len = graphs.length;
|
|
496
|
+
for (let i = 0; i < len; i++) {
|
|
497
|
+
const graph = graphs[i];
|
|
498
|
+
if (asserts.isGraph(graph)) handler(graph);
|
|
499
|
+
else if (asserts.isBox(graph)) traverse(graph.elements, handler);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
//#endregion
|
|
504
|
+
//#region src/etoile/native/easing.ts
|
|
505
|
+
const easing = {
|
|
506
|
+
linear: (k) => k,
|
|
507
|
+
quadraticIn: (k) => k * k,
|
|
508
|
+
quadraticOut: (k) => k * (2 - k),
|
|
509
|
+
quadraticInOut: (k) => {
|
|
510
|
+
if ((k *= 2) < 1) return .5 * k * k;
|
|
511
|
+
return -.5 * (--k * (k - 2) - 1);
|
|
512
|
+
},
|
|
513
|
+
cubicIn: (k) => k * k * k,
|
|
514
|
+
cubicOut: (k) => {
|
|
515
|
+
if ((k *= 2) < 1) return .5 * k * k * k;
|
|
516
|
+
return .5 * ((k -= 2) * k * k + 2);
|
|
517
|
+
},
|
|
518
|
+
cubicInOut: (k) => {
|
|
519
|
+
if ((k *= 2) < 1) return .5 * k * k * k;
|
|
520
|
+
return .5 * ((k -= 2) * k * k + 2);
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
//#endregion
|
|
525
|
+
//#region src/etoile/native/event.ts
|
|
526
|
+
var Event = class {
|
|
527
|
+
eventCollections;
|
|
528
|
+
constructor() {
|
|
529
|
+
this.eventCollections = Object.create(null);
|
|
530
|
+
}
|
|
531
|
+
on(evt, handler, c) {
|
|
532
|
+
if (!(evt in this.eventCollections)) this.eventCollections[evt] = [];
|
|
533
|
+
const data = {
|
|
534
|
+
name: evt,
|
|
535
|
+
handler,
|
|
536
|
+
ctx: c || this,
|
|
537
|
+
silent: false
|
|
538
|
+
};
|
|
539
|
+
this.eventCollections[evt].push(data);
|
|
540
|
+
}
|
|
541
|
+
off(evt, handler) {
|
|
542
|
+
if (evt in this.eventCollections) {
|
|
543
|
+
if (!handler) {
|
|
544
|
+
this.eventCollections[evt] = [];
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
this.eventCollections[evt] = this.eventCollections[evt].filter((d) => d.handler !== handler);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
silent(evt, handler) {
|
|
551
|
+
if (!(evt in this.eventCollections)) return;
|
|
552
|
+
this.eventCollections[evt].forEach((d) => {
|
|
553
|
+
if (!handler || d.handler === handler) d.silent = true;
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
active(evt, handler) {
|
|
557
|
+
if (!(evt in this.eventCollections)) return;
|
|
558
|
+
this.eventCollections[evt].forEach((d) => {
|
|
559
|
+
if (!handler || d.handler === handler) d.silent = false;
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
emit(evt, ...args) {
|
|
563
|
+
if (!this.eventCollections[evt]) return;
|
|
564
|
+
const handlers = this.eventCollections[evt];
|
|
565
|
+
if (handlers.length) handlers.forEach((d) => {
|
|
566
|
+
if (d.silent) return;
|
|
567
|
+
d.handler.call(d.ctx, ...args);
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
bindWithContext(c) {
|
|
571
|
+
return (evt, handler) => this.on(evt, handler, c);
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
//#endregion
|
|
576
|
+
//#region src/etoile/native/dom.ts
|
|
577
|
+
function getOffset(el) {
|
|
578
|
+
let e = 0;
|
|
579
|
+
let f = 0;
|
|
580
|
+
if (document.documentElement.getBoundingClientRect && el.getBoundingClientRect) {
|
|
581
|
+
const { top, left } = el.getBoundingClientRect();
|
|
582
|
+
e = top;
|
|
583
|
+
f = left;
|
|
584
|
+
} else for (let elt = el; elt; elt = el.offsetParent) {
|
|
585
|
+
e += el.offsetLeft;
|
|
586
|
+
f += el.offsetTop;
|
|
587
|
+
}
|
|
588
|
+
return [e + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft), f + Math.max(document.documentElement.scrollTop, document.body.scrollTop)];
|
|
589
|
+
}
|
|
590
|
+
function captureBoxXY(c, evt, a, d, translateX, translateY) {
|
|
591
|
+
const boundingClientRect = c.getBoundingClientRect();
|
|
592
|
+
if (evt instanceof MouseEvent) {
|
|
593
|
+
const [e, f] = getOffset(c);
|
|
594
|
+
return {
|
|
595
|
+
x: (evt.clientX - boundingClientRect.left - e - translateX) / a,
|
|
596
|
+
y: (evt.clientY - boundingClientRect.top - f - translateY) / d
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
return {
|
|
600
|
+
x: 0,
|
|
601
|
+
y: 0
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
function createEffectRun(c) {
|
|
605
|
+
return (fn) => {
|
|
606
|
+
const effect = () => {
|
|
607
|
+
const done = fn();
|
|
608
|
+
if (!done) c.animationFrameID = raf(effect);
|
|
609
|
+
};
|
|
610
|
+
if (!c.animationFrameID) c.animationFrameID = raf(effect);
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
function createEffectStop(c) {
|
|
614
|
+
return () => {
|
|
615
|
+
if (c.animationFrameID) {
|
|
616
|
+
window.cancelAnimationFrame(c.animationFrameID);
|
|
617
|
+
c.animationFrameID = null;
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
function createSmoothFrame() {
|
|
622
|
+
const c = { animationFrameID: null };
|
|
623
|
+
const run = createEffectRun(c);
|
|
624
|
+
const stop = createEffectStop(c);
|
|
625
|
+
return {
|
|
626
|
+
run,
|
|
627
|
+
stop
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
//#endregion
|
|
632
|
+
//#region src/shared/index.ts
|
|
633
|
+
function hashCode(str) {
|
|
634
|
+
let hash = 0;
|
|
635
|
+
for (let i = 0; i < str.length; i++) {
|
|
636
|
+
const code = str.charCodeAt(i);
|
|
637
|
+
hash = (hash << 5) - hash + code;
|
|
638
|
+
hash = hash & hash;
|
|
639
|
+
}
|
|
640
|
+
return hash;
|
|
641
|
+
}
|
|
642
|
+
function perferNumeric(s) {
|
|
643
|
+
if (typeof s === "number") return true;
|
|
644
|
+
return s.charCodeAt(0) >= 48 && s.charCodeAt(0) <= 57;
|
|
645
|
+
}
|
|
646
|
+
function noop() {}
|
|
647
|
+
function createRoundBlock(x, y, width, height, style) {
|
|
648
|
+
return new RoundRect({
|
|
649
|
+
width,
|
|
650
|
+
height,
|
|
651
|
+
x,
|
|
652
|
+
y,
|
|
653
|
+
style: { ...style }
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
function createTitleText(text, x, y, font, color) {
|
|
657
|
+
return new Text({
|
|
658
|
+
text,
|
|
659
|
+
x,
|
|
660
|
+
y,
|
|
661
|
+
style: {
|
|
662
|
+
fill: color,
|
|
663
|
+
textAlign: "center",
|
|
664
|
+
baseline: "middle",
|
|
665
|
+
font,
|
|
666
|
+
lineWidth: 1
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
const raf = window.requestAnimationFrame;
|
|
671
|
+
function createCanvasElement() {
|
|
672
|
+
return document.createElement("canvas");
|
|
673
|
+
}
|
|
674
|
+
function applyCanvasTransform(ctx, matrix, dpr) {
|
|
675
|
+
ctx.setTransform(matrix.a * dpr, matrix.b * dpr, matrix.c * dpr, matrix.d * dpr, matrix.e * dpr, matrix.f * dpr);
|
|
676
|
+
}
|
|
677
|
+
function mixin(app, methods) {
|
|
678
|
+
methods.forEach(({ name, fn }) => {
|
|
679
|
+
Object.defineProperty(app, name, {
|
|
680
|
+
value: fn(app),
|
|
681
|
+
writable: false
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
return app;
|
|
685
|
+
}
|
|
686
|
+
function mixinWithParams(app, methods) {
|
|
687
|
+
methods.forEach(({ name, fn }) => {
|
|
688
|
+
Object.defineProperty(app, name, {
|
|
689
|
+
value: fn(app),
|
|
690
|
+
writable: false,
|
|
691
|
+
enumerable: true
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
return app;
|
|
695
|
+
}
|
|
696
|
+
function prettyStrJoin(...s) {
|
|
697
|
+
return s.join("");
|
|
698
|
+
}
|
|
699
|
+
function isMacOS() {
|
|
700
|
+
return /Mac OS X/.test(navigator.userAgent);
|
|
701
|
+
}
|
|
702
|
+
function typedForIn(obj, callback) {
|
|
703
|
+
for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) callback(key, obj[key]);
|
|
704
|
+
}
|
|
705
|
+
function stackMatrixTransform(graph, e, f, scale) {
|
|
706
|
+
graph.x = graph.x * scale + e;
|
|
707
|
+
graph.y = graph.y * scale + f;
|
|
708
|
+
graph.scaleX = scale;
|
|
709
|
+
graph.scaleY = scale;
|
|
710
|
+
}
|
|
711
|
+
function stackMatrixTransformWithGraphAndLayer(graphs, e, f, scale) {
|
|
712
|
+
traverse(graphs, (graph) => stackMatrixTransform(graph, e, f, scale));
|
|
713
|
+
}
|
|
714
|
+
function smoothFrame(callback, opts) {
|
|
715
|
+
const frame = createSmoothFrame();
|
|
716
|
+
const startTime = Date.now();
|
|
717
|
+
const condtion = (process) => {
|
|
718
|
+
if (Array.isArray(opts.deps)) return opts.deps.some((dep) => dep());
|
|
719
|
+
return process >= 1;
|
|
720
|
+
};
|
|
721
|
+
frame.run(() => {
|
|
722
|
+
const elapsed = Date.now() - startTime;
|
|
723
|
+
const progress = Math.min(elapsed / opts.duration, 1);
|
|
724
|
+
if (condtion(progress)) {
|
|
725
|
+
frame.stop();
|
|
726
|
+
if (opts.onStop) opts.onStop();
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
return callback(progress, frame.stop);
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
function isScrollWheelOrRightButtonOnMouseupAndDown(e) {
|
|
733
|
+
return e.which === 2 || e.which === 3;
|
|
734
|
+
}
|
|
735
|
+
var DefaultMap = class extends Map {
|
|
736
|
+
defaultFactory;
|
|
737
|
+
constructor(defaultFactory, entries) {
|
|
738
|
+
super(entries);
|
|
739
|
+
this.defaultFactory = defaultFactory;
|
|
740
|
+
}
|
|
741
|
+
get(key) {
|
|
742
|
+
if (!super.has(key)) return this.defaultFactory();
|
|
743
|
+
return super.get(key);
|
|
744
|
+
}
|
|
745
|
+
getOrInsert(key, value) {
|
|
746
|
+
if (!super.has(key)) {
|
|
747
|
+
const defaultValue = value || this.defaultFactory();
|
|
748
|
+
super.set(key, defaultValue);
|
|
749
|
+
return defaultValue;
|
|
750
|
+
}
|
|
751
|
+
return super.get(key);
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
//#endregion
|
|
756
|
+
//#region src/shared/logger.ts
|
|
757
|
+
const createLogger = (namespace) => {
|
|
758
|
+
return {
|
|
759
|
+
error: (message) => {
|
|
760
|
+
return console.error(`[${namespace}] ${message}`);
|
|
761
|
+
},
|
|
762
|
+
panic: (message) => {
|
|
763
|
+
throw new Error(`[${namespace}] ${message}`);
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
};
|
|
767
|
+
function assertExists(value, logger$1, message) {
|
|
768
|
+
if (value === null || value === void 0) logger$1.panic(message);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
//#endregion
|
|
772
|
+
//#region src/etoile/native/log.ts
|
|
773
|
+
const NAME_SPACE = "etoile";
|
|
774
|
+
const log = createLogger(NAME_SPACE);
|
|
775
|
+
|
|
776
|
+
//#endregion
|
|
777
|
+
//#region src/etoile/schedule/render.ts
|
|
778
|
+
function writeBoundingRectForCanvas(c, w, h, dpr) {
|
|
779
|
+
c.width = w * dpr;
|
|
780
|
+
c.height = h * dpr;
|
|
781
|
+
c.style.cssText = `width: ${w}px; height: ${h}px`;
|
|
782
|
+
}
|
|
783
|
+
var Canvas = class {
|
|
784
|
+
canvas;
|
|
785
|
+
ctx;
|
|
786
|
+
constructor(options) {
|
|
787
|
+
this.canvas = createCanvasElement();
|
|
788
|
+
this.setOptions(options);
|
|
789
|
+
this.ctx = this.canvas.getContext("2d");
|
|
790
|
+
}
|
|
791
|
+
setOptions(options) {
|
|
792
|
+
writeBoundingRectForCanvas(this.canvas, options.width, options.height, options.devicePixelRatio);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
var Render = class {
|
|
796
|
+
options;
|
|
797
|
+
container;
|
|
798
|
+
constructor(to, options) {
|
|
799
|
+
this.container = new Canvas(options);
|
|
800
|
+
this.options = options;
|
|
801
|
+
this.initOptions(options);
|
|
802
|
+
if (!options.shaow) to.appendChild(this.container.canvas);
|
|
803
|
+
}
|
|
804
|
+
clear(width, height) {
|
|
805
|
+
this.ctx.clearRect(0, 0, width, height);
|
|
806
|
+
}
|
|
807
|
+
get canvas() {
|
|
808
|
+
return this.container.canvas;
|
|
809
|
+
}
|
|
810
|
+
get ctx() {
|
|
811
|
+
return this.container.ctx;
|
|
812
|
+
}
|
|
813
|
+
initOptions(userOptions = {}) {
|
|
814
|
+
Object.assign(this.options, userOptions);
|
|
815
|
+
this.container.setOptions(this.options);
|
|
816
|
+
}
|
|
817
|
+
destory() {}
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
//#endregion
|
|
821
|
+
//#region src/etoile/schedule/index.ts
|
|
822
|
+
function drawGraphIntoCanvas(graph, opts) {
|
|
823
|
+
const { ctx, dpr } = opts;
|
|
824
|
+
ctx.save();
|
|
825
|
+
if (asserts.isBox(graph)) {
|
|
826
|
+
const elements = graph.elements;
|
|
827
|
+
const cap = elements.length;
|
|
828
|
+
for (let i = 0; i < cap; i++) {
|
|
829
|
+
const element = elements[i];
|
|
830
|
+
drawGraphIntoCanvas(element, opts);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
if (asserts.isGraph(graph)) {
|
|
834
|
+
const matrix = graph.matrix.create({
|
|
835
|
+
a: 1,
|
|
836
|
+
b: 0,
|
|
837
|
+
c: 0,
|
|
838
|
+
d: 1,
|
|
839
|
+
e: 0,
|
|
840
|
+
f: 0
|
|
841
|
+
});
|
|
842
|
+
matrix.transform(graph.x, graph.y, graph.scaleX, graph.scaleY, graph.rotation, graph.skewX, graph.skewY);
|
|
843
|
+
applyCanvasTransform(ctx, matrix, dpr);
|
|
844
|
+
graph.render(ctx);
|
|
845
|
+
}
|
|
846
|
+
ctx.restore();
|
|
847
|
+
}
|
|
848
|
+
var Schedule = class extends Box {
|
|
849
|
+
render;
|
|
850
|
+
to;
|
|
851
|
+
event;
|
|
852
|
+
constructor(to, renderOptions = {}) {
|
|
853
|
+
super();
|
|
854
|
+
this.to = typeof to === "string" ? document.querySelector(to) : to;
|
|
855
|
+
if (!this.to) log.panic("The element to bind is not found.");
|
|
856
|
+
const { width, height } = this.to.getBoundingClientRect();
|
|
857
|
+
Object.assign(renderOptions, {
|
|
858
|
+
width,
|
|
859
|
+
height
|
|
860
|
+
}, { devicePixelRatio: window.devicePixelRatio || 1 });
|
|
861
|
+
this.event = new Event();
|
|
862
|
+
this.render = new Render(this.to, renderOptions);
|
|
863
|
+
}
|
|
864
|
+
update() {
|
|
865
|
+
this.render.clear(this.render.options.width, this.render.options.height);
|
|
866
|
+
this.execute(this.render, this);
|
|
867
|
+
const matrix = this.matrix.create({
|
|
868
|
+
a: 1,
|
|
869
|
+
b: 0,
|
|
870
|
+
c: 0,
|
|
871
|
+
d: 1,
|
|
872
|
+
e: 0,
|
|
873
|
+
f: 0
|
|
874
|
+
});
|
|
875
|
+
applyCanvasTransform(this.render.ctx, matrix, this.render.options.devicePixelRatio);
|
|
876
|
+
}
|
|
877
|
+
execute(render, graph = this) {
|
|
878
|
+
drawGraphIntoCanvas(graph, {
|
|
879
|
+
c: render.canvas,
|
|
880
|
+
ctx: render.ctx,
|
|
881
|
+
dpr: render.options.devicePixelRatio
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
//#endregion
|
|
887
|
+
//#region src/primitives/struct.ts
|
|
888
|
+
function sortChildrenByKey(data, ...keys) {
|
|
889
|
+
return data.sort((a, b) => {
|
|
890
|
+
for (const key of keys) {
|
|
891
|
+
const v = a[key];
|
|
892
|
+
const v2 = b[key];
|
|
893
|
+
if (perferNumeric(v) && perferNumeric(v2)) {
|
|
894
|
+
if (v2 > v) return 1;
|
|
895
|
+
if (v2 < v) return -1;
|
|
896
|
+
continue;
|
|
897
|
+
}
|
|
898
|
+
const comparison = ("" + v).localeCompare("" + v2);
|
|
899
|
+
if (comparison !== 0) return comparison;
|
|
900
|
+
}
|
|
901
|
+
return 0;
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
function c2m(data, key, modifier) {
|
|
905
|
+
if (Array.isArray(data.groups)) data.groups = sortChildrenByKey(data.groups.map((d) => c2m(d, key, modifier)), "weight");
|
|
906
|
+
const obj = {
|
|
907
|
+
...data,
|
|
908
|
+
weight: data[key]
|
|
909
|
+
};
|
|
910
|
+
if (modifier) Object.assign(obj, modifier(obj));
|
|
911
|
+
return obj;
|
|
912
|
+
}
|
|
913
|
+
function flatten(data) {
|
|
914
|
+
const result = [];
|
|
915
|
+
for (let i = 0; i < data.length; i++) {
|
|
916
|
+
const { groups,...rest } = data[i];
|
|
917
|
+
result.push(rest);
|
|
918
|
+
if (groups) result.push(...flatten(groups));
|
|
919
|
+
}
|
|
920
|
+
return result;
|
|
921
|
+
}
|
|
922
|
+
function bindParentForModule(modules, parent) {
|
|
923
|
+
return modules.map((module$1) => {
|
|
924
|
+
const next = { ...module$1 };
|
|
925
|
+
next.parent = parent;
|
|
926
|
+
if (next.groups && Array.isArray(next.groups)) next.groups = bindParentForModule(next.groups, next);
|
|
927
|
+
return next;
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
function getNodeDepth(node) {
|
|
931
|
+
let depth = 0;
|
|
932
|
+
while (node.parent) {
|
|
933
|
+
node = node.parent;
|
|
934
|
+
depth++;
|
|
935
|
+
}
|
|
936
|
+
return depth;
|
|
937
|
+
}
|
|
938
|
+
function visit(data, fn) {
|
|
939
|
+
if (!data) return null;
|
|
940
|
+
for (const d of data) {
|
|
941
|
+
if (d.children) {
|
|
942
|
+
const result = visit(d.children, fn);
|
|
943
|
+
if (result) return result;
|
|
944
|
+
}
|
|
945
|
+
const stop = fn(d);
|
|
946
|
+
if (stop) return d;
|
|
947
|
+
}
|
|
948
|
+
return null;
|
|
949
|
+
}
|
|
950
|
+
function findRelativeNode(p, layoutNodes) {
|
|
951
|
+
return visit(layoutNodes, (node) => {
|
|
952
|
+
const [x, y, w, h] = node.layout;
|
|
953
|
+
if (p.x >= x && p.y >= y && p.x < x + w && p.y < y + h) return true;
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
function findRelativeNodeById(id, layoutNodes) {
|
|
957
|
+
return visit(layoutNodes, (node) => {
|
|
958
|
+
if (node.node.id === id) return true;
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
//#endregion
|
|
963
|
+
//#region src/primitives/squarify.ts
|
|
964
|
+
function generateStableCombinedNodeId(weight, nodes) {
|
|
965
|
+
const name = nodes.map((node) => node.id).sort().join("-");
|
|
966
|
+
return Math.abs(hashCode(name)) + "-" + weight;
|
|
967
|
+
}
|
|
968
|
+
function processSquarifyData(data, totalArea, minNodeSize, minNodeArea) {
|
|
969
|
+
if (!data || !data.length) return [];
|
|
970
|
+
const totalWeight = data.reduce((sum, node) => sum + node.weight, 0);
|
|
971
|
+
if (totalWeight <= 0) return [];
|
|
972
|
+
const processedNodes = [];
|
|
973
|
+
const tooSmallNodes = [];
|
|
974
|
+
data.forEach((node) => {
|
|
975
|
+
const nodeArea = node.weight / totalWeight * totalArea;
|
|
976
|
+
const estimatedSize = Math.sqrt(nodeArea);
|
|
977
|
+
if (estimatedSize < minNodeSize || nodeArea < minNodeArea) tooSmallNodes.push({ ...node });
|
|
978
|
+
else processedNodes.push({ ...node });
|
|
979
|
+
});
|
|
980
|
+
if (tooSmallNodes.length > 0) {
|
|
981
|
+
const combinedWeight = tooSmallNodes.reduce((sum, node) => sum + node.weight, 0);
|
|
982
|
+
if (combinedWeight > 0 && combinedWeight / totalWeight * totalArea >= minNodeArea) {
|
|
983
|
+
const combinedNode = {
|
|
984
|
+
id: `combined-node-${generateStableCombinedNodeId(combinedWeight, tooSmallNodes)}`,
|
|
985
|
+
weight: combinedWeight,
|
|
986
|
+
isCombinedNode: true,
|
|
987
|
+
originalNodeCount: tooSmallNodes.length,
|
|
988
|
+
parent: null,
|
|
989
|
+
groups: [],
|
|
990
|
+
originalNodes: tooSmallNodes
|
|
991
|
+
};
|
|
992
|
+
processedNodes.push(combinedNode);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
return processedNodes;
|
|
996
|
+
}
|
|
997
|
+
function squarify(data, rect, config, scale = 1) {
|
|
998
|
+
const result = [];
|
|
999
|
+
if (!data.length) return result;
|
|
1000
|
+
const totalArea = rect.w * rect.h;
|
|
1001
|
+
const containerSize = Math.min(rect.w, rect.h);
|
|
1002
|
+
const scaleFactor = Math.max(.5, Math.min(1, containerSize / 800));
|
|
1003
|
+
const minRenderableSize = Math.max(20, containerSize * .05) / scale;
|
|
1004
|
+
const minRenderableArea = minRenderableSize * minRenderableSize;
|
|
1005
|
+
const scaledGap = config.rectGap * scaleFactor;
|
|
1006
|
+
const scaledRadius = config.rectRadius * scaleFactor;
|
|
1007
|
+
const processedData = processSquarifyData(data, totalArea, minRenderableSize, minRenderableArea);
|
|
1008
|
+
if (!processedData.length) return result;
|
|
1009
|
+
rect = {
|
|
1010
|
+
x: rect.x + scaledGap / 2,
|
|
1011
|
+
y: rect.y + scaledGap / 2,
|
|
1012
|
+
w: rect.w - scaledGap,
|
|
1013
|
+
h: rect.h - scaledGap
|
|
1014
|
+
};
|
|
1015
|
+
const worst = (start, end, shortestSide, totalWeight, aspectRatio) => {
|
|
1016
|
+
const max = processedData[start].weight * aspectRatio;
|
|
1017
|
+
const min = processedData[end].weight * aspectRatio;
|
|
1018
|
+
return Math.max(shortestSide * shortestSide * max / (totalWeight * totalWeight), totalWeight * totalWeight / (shortestSide * shortestSide * min));
|
|
1019
|
+
};
|
|
1020
|
+
const recursion = (start, rect$1, depth = 0) => {
|
|
1021
|
+
const depthFactor = Math.max(.4, 1 - depth * .15);
|
|
1022
|
+
const currentGap = scaledGap * depthFactor;
|
|
1023
|
+
const currentRadius = scaledRadius * depthFactor;
|
|
1024
|
+
while (start < processedData.length) {
|
|
1025
|
+
let totalWeight = 0;
|
|
1026
|
+
for (let i = start; i < processedData.length; i++) totalWeight += processedData[i].weight;
|
|
1027
|
+
const shortestSide = Math.min(rect$1.w, rect$1.h);
|
|
1028
|
+
const aspectRatio = rect$1.w * rect$1.h / totalWeight;
|
|
1029
|
+
let end = start;
|
|
1030
|
+
let areaInRun = 0;
|
|
1031
|
+
let oldWorst = 0;
|
|
1032
|
+
while (end < processedData.length) {
|
|
1033
|
+
const area = processedData[end].weight * aspectRatio || 0;
|
|
1034
|
+
const newWorst = worst(start, end, shortestSide, areaInRun + area, aspectRatio);
|
|
1035
|
+
if (end > start && oldWorst < newWorst) break;
|
|
1036
|
+
areaInRun += area;
|
|
1037
|
+
oldWorst = newWorst;
|
|
1038
|
+
end++;
|
|
1039
|
+
}
|
|
1040
|
+
const splited = Math.round(areaInRun / shortestSide);
|
|
1041
|
+
let areaInLayout = 0;
|
|
1042
|
+
const isHorizontalLayout = rect$1.w >= rect$1.h;
|
|
1043
|
+
for (let i = start; i < end; i++) {
|
|
1044
|
+
const isFirst = i === start;
|
|
1045
|
+
const isLast = i === end - 1;
|
|
1046
|
+
const children = processedData[i];
|
|
1047
|
+
const area = children.weight * aspectRatio;
|
|
1048
|
+
const lower = Math.round(shortestSide * areaInLayout / areaInRun);
|
|
1049
|
+
const upper = Math.round(shortestSide * (areaInLayout + area) / areaInRun);
|
|
1050
|
+
let x, y, w, h;
|
|
1051
|
+
if (isHorizontalLayout) {
|
|
1052
|
+
x = rect$1.x;
|
|
1053
|
+
y = rect$1.y + lower;
|
|
1054
|
+
w = splited;
|
|
1055
|
+
h = upper - lower;
|
|
1056
|
+
} else {
|
|
1057
|
+
x = rect$1.x + lower;
|
|
1058
|
+
y = rect$1.y;
|
|
1059
|
+
w = upper - lower;
|
|
1060
|
+
h = splited;
|
|
1061
|
+
}
|
|
1062
|
+
const edgeGap = currentGap / 2;
|
|
1063
|
+
if (!isFirst) if (isHorizontalLayout) {
|
|
1064
|
+
y += edgeGap;
|
|
1065
|
+
h -= edgeGap;
|
|
1066
|
+
} else {
|
|
1067
|
+
x += edgeGap;
|
|
1068
|
+
w -= edgeGap;
|
|
1069
|
+
}
|
|
1070
|
+
if (!isLast) if (isHorizontalLayout) h -= edgeGap;
|
|
1071
|
+
else w -= edgeGap;
|
|
1072
|
+
const nodeDepth = getNodeDepth(children) || 1;
|
|
1073
|
+
const { titleAreaHeight } = config;
|
|
1074
|
+
const diff = titleAreaHeight.max / nodeDepth;
|
|
1075
|
+
const titleHeight = diff < titleAreaHeight.min ? titleAreaHeight.min : diff;
|
|
1076
|
+
w = Math.max(2, w);
|
|
1077
|
+
h = Math.max(2, h);
|
|
1078
|
+
let childrenLayout = [];
|
|
1079
|
+
const hasValidChildren = children.groups && children.groups.length > 0;
|
|
1080
|
+
if (hasValidChildren) {
|
|
1081
|
+
const childRect = {
|
|
1082
|
+
x: x + currentGap,
|
|
1083
|
+
y: y + titleHeight,
|
|
1084
|
+
w: Math.max(0, w - currentGap * 2),
|
|
1085
|
+
h: Math.max(0, h - titleHeight - currentGap)
|
|
1086
|
+
};
|
|
1087
|
+
if (childRect.w > currentRadius * 2 && childRect.h > currentRadius * 2) childrenLayout = squarify(children.groups || [], childRect, {
|
|
1088
|
+
...config,
|
|
1089
|
+
rectGap: currentGap,
|
|
1090
|
+
rectRadius: currentRadius
|
|
1091
|
+
}, scale);
|
|
1092
|
+
}
|
|
1093
|
+
result.push({
|
|
1094
|
+
layout: [
|
|
1095
|
+
x,
|
|
1096
|
+
y,
|
|
1097
|
+
w,
|
|
1098
|
+
h
|
|
1099
|
+
],
|
|
1100
|
+
node: children,
|
|
1101
|
+
children: childrenLayout,
|
|
1102
|
+
config: {
|
|
1103
|
+
titleAreaHeight: titleHeight,
|
|
1104
|
+
rectGap: currentGap,
|
|
1105
|
+
rectRadius: currentRadius
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
areaInLayout += area;
|
|
1109
|
+
}
|
|
1110
|
+
start = end;
|
|
1111
|
+
if (isHorizontalLayout) {
|
|
1112
|
+
rect$1.x += splited + currentGap;
|
|
1113
|
+
rect$1.w -= splited + currentGap;
|
|
1114
|
+
} else {
|
|
1115
|
+
rect$1.y += splited + currentGap;
|
|
1116
|
+
rect$1.h -= splited + currentGap;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
1120
|
+
recursion(0, rect);
|
|
1121
|
+
return result;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
//#endregion
|
|
1125
|
+
//#region src/shared/plugin-driver.ts
|
|
1126
|
+
function definePlugin(plugin) {
|
|
1127
|
+
return plugin;
|
|
1128
|
+
}
|
|
1129
|
+
var PluginDriver = class {
|
|
1130
|
+
plugins = new Map();
|
|
1131
|
+
pluginContext;
|
|
1132
|
+
constructor(component) {
|
|
1133
|
+
this.pluginContext = {
|
|
1134
|
+
resolveModuleById(id) {
|
|
1135
|
+
return findRelativeNodeById(id, component.layoutNodes);
|
|
1136
|
+
},
|
|
1137
|
+
getPluginMetadata: (pluginName) => {
|
|
1138
|
+
return this.getPluginMetadata(pluginName);
|
|
1139
|
+
},
|
|
1140
|
+
get instance() {
|
|
1141
|
+
return component;
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
use(plugin) {
|
|
1146
|
+
if (!plugin.name) {
|
|
1147
|
+
logger.error("Plugin name is required");
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
if (this.plugins.has(plugin.name)) logger.panic(`Plugin ${plugin.name} is already registered`);
|
|
1151
|
+
this.plugins.set(plugin.name, plugin);
|
|
1152
|
+
}
|
|
1153
|
+
runHook(hookName, ...args) {
|
|
1154
|
+
this.plugins.forEach((plugin) => {
|
|
1155
|
+
const hook = plugin[hookName];
|
|
1156
|
+
if (hook) hook.apply(this.pluginContext, args);
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
cascadeHook(hookName, ...args) {
|
|
1160
|
+
const finalResult = {};
|
|
1161
|
+
this.plugins.forEach((plugin) => {
|
|
1162
|
+
const hook = plugin[hookName];
|
|
1163
|
+
if (hook) {
|
|
1164
|
+
const hookResult = hook.call(this.pluginContext, ...args);
|
|
1165
|
+
if (hookResult) Object.assign(finalResult, hookResult);
|
|
1166
|
+
}
|
|
1167
|
+
});
|
|
1168
|
+
return finalResult;
|
|
1169
|
+
}
|
|
1170
|
+
getPluginMetadata(pluginName) {
|
|
1171
|
+
const plugin = this.plugins.get(pluginName);
|
|
1172
|
+
return plugin?.meta || null;
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
//#endregion
|
|
1177
|
+
//#region src/component.ts
|
|
1178
|
+
const logger = createLogger("Treemap");
|
|
1179
|
+
const DEFAULT_RECT_FILL_DESC = {
|
|
1180
|
+
mode: "rgb",
|
|
1181
|
+
desc: {
|
|
1182
|
+
r: 0,
|
|
1183
|
+
g: 0,
|
|
1184
|
+
b: 0
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
const DEFAULT_TITLE_AREA_HEIGHT = {
|
|
1188
|
+
min: 30,
|
|
1189
|
+
max: 60
|
|
1190
|
+
};
|
|
1191
|
+
const DEFAULT_RECT_GAP = 4;
|
|
1192
|
+
const DEFAULT_RECT_BORDER_RADIUS = 4;
|
|
1193
|
+
const DEFAULT_FONT_SIZE = {
|
|
1194
|
+
max: 70,
|
|
1195
|
+
min: 12
|
|
1196
|
+
};
|
|
1197
|
+
const DEFAULT_FONT_FAMILY = "sans-serif";
|
|
1198
|
+
const DEFAULT_FONT_COLOR = "#000";
|
|
1199
|
+
var Component = class extends Schedule {
|
|
1200
|
+
pluginDriver;
|
|
1201
|
+
data;
|
|
1202
|
+
colorMappings;
|
|
1203
|
+
rectLayer;
|
|
1204
|
+
textLayer;
|
|
1205
|
+
layoutNodes;
|
|
1206
|
+
config;
|
|
1207
|
+
caches;
|
|
1208
|
+
constructor(config, ...args) {
|
|
1209
|
+
super(...args);
|
|
1210
|
+
this.data = [];
|
|
1211
|
+
this.config = config;
|
|
1212
|
+
this.colorMappings = {};
|
|
1213
|
+
this.pluginDriver = new PluginDriver(this);
|
|
1214
|
+
this.rectLayer = new Box();
|
|
1215
|
+
this.textLayer = new Box();
|
|
1216
|
+
this.caches = new DefaultMap(() => 14);
|
|
1217
|
+
this.layoutNodes = [];
|
|
1218
|
+
}
|
|
1219
|
+
drawBroundRect(node) {
|
|
1220
|
+
const [x, y, w, h] = node.layout;
|
|
1221
|
+
const { rectRadius } = node.config;
|
|
1222
|
+
const effectiveRadius = Math.min(rectRadius, w / 4, h / 4);
|
|
1223
|
+
const fill = this.colorMappings[node.node.id] || DEFAULT_RECT_FILL_DESC;
|
|
1224
|
+
const rect = createRoundBlock(x, y, w, h, {
|
|
1225
|
+
fill,
|
|
1226
|
+
padding: 0,
|
|
1227
|
+
radius: effectiveRadius
|
|
1228
|
+
});
|
|
1229
|
+
rect.__widget__ = node;
|
|
1230
|
+
this.rectLayer.add(rect);
|
|
1231
|
+
for (const child of node.children) this.drawBroundRect(child);
|
|
1232
|
+
}
|
|
1233
|
+
drawText(node) {
|
|
1234
|
+
if (!node.node.label && !node.node.isCombinedNode) return;
|
|
1235
|
+
const [x, y, w, h] = node.layout;
|
|
1236
|
+
const { titleAreaHeight } = node.config;
|
|
1237
|
+
const content = node.node.isCombinedNode ? `+ ${node.node.originalNodeCount} Modules` : node.node.label;
|
|
1238
|
+
const availableHeight = node.children && node.children.length > 0 ? titleAreaHeight - DEFAULT_RECT_GAP * 2 : h - DEFAULT_RECT_GAP * 2;
|
|
1239
|
+
const availableWidth = w - DEFAULT_RECT_GAP * 2;
|
|
1240
|
+
if (availableWidth <= 0 || availableHeight <= 0) return;
|
|
1241
|
+
const config = {
|
|
1242
|
+
fontSize: this.config.font?.fontSize || DEFAULT_FONT_SIZE,
|
|
1243
|
+
family: this.config.font?.family || DEFAULT_FONT_FAMILY,
|
|
1244
|
+
color: this.config.font?.color || DEFAULT_FONT_COLOR
|
|
1245
|
+
};
|
|
1246
|
+
const optimalFontSize = this.caches.getOrInsert(node.node.id, evaluateOptimalFontSize(this.render.ctx, content, config, availableWidth, availableHeight));
|
|
1247
|
+
const font = `${optimalFontSize}px ${config.family}`;
|
|
1248
|
+
this.render.ctx.font = font;
|
|
1249
|
+
const result = getTextLayout(this.render.ctx, content, availableWidth, availableHeight);
|
|
1250
|
+
if (!result.valid) return;
|
|
1251
|
+
const { text } = result;
|
|
1252
|
+
const textX = x + Math.round(w / 2);
|
|
1253
|
+
const textY = y + (node.children && node.children.length > 0 ? Math.round(titleAreaHeight / 2) : Math.round(h / 2));
|
|
1254
|
+
const textComponent = createTitleText(text, textX, textY, font, config.color);
|
|
1255
|
+
this.textLayer.add(textComponent);
|
|
1256
|
+
for (const child of node.children) this.drawText(child);
|
|
1257
|
+
}
|
|
1258
|
+
draw(flush = true, update = true) {
|
|
1259
|
+
const { width, height } = this.render.options;
|
|
1260
|
+
if (update) this.layoutNodes = this.calculateLayoutNodes(this.data, {
|
|
1261
|
+
w: width,
|
|
1262
|
+
h: height,
|
|
1263
|
+
x: 0,
|
|
1264
|
+
y: 0
|
|
1265
|
+
});
|
|
1266
|
+
if (flush) {
|
|
1267
|
+
const result = this.pluginDriver.cascadeHook("onModuleInit", this.layoutNodes);
|
|
1268
|
+
if (result) this.colorMappings = result.colorMappings || {};
|
|
1269
|
+
}
|
|
1270
|
+
for (const node of this.layoutNodes) this.drawBroundRect(node);
|
|
1271
|
+
for (const node of this.layoutNodes) this.drawText(node);
|
|
1272
|
+
this.add(this.rectLayer, this.textLayer);
|
|
1273
|
+
if (update) this.update();
|
|
1274
|
+
}
|
|
1275
|
+
cleanup() {
|
|
1276
|
+
this.remove(this.rectLayer, this.textLayer);
|
|
1277
|
+
this.rectLayer.destory();
|
|
1278
|
+
this.textLayer.destory();
|
|
1279
|
+
}
|
|
1280
|
+
calculateLayoutNodes(data, rect, scale = 1) {
|
|
1281
|
+
const config = {
|
|
1282
|
+
titleAreaHeight: this.config.layout?.titleAreaHeight || DEFAULT_TITLE_AREA_HEIGHT,
|
|
1283
|
+
rectRadius: this.config.layout?.rectRadius || DEFAULT_RECT_BORDER_RADIUS,
|
|
1284
|
+
rectGap: this.config.layout?.rectGap || DEFAULT_RECT_GAP
|
|
1285
|
+
};
|
|
1286
|
+
return squarify(data, rect, config, scale);
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
function evaluateOptimalFontSize(c, text, config, desiredW, desiredH) {
|
|
1290
|
+
desiredW = Math.floor(desiredW);
|
|
1291
|
+
desiredH = Math.floor(desiredH);
|
|
1292
|
+
const { fontSize, family } = config;
|
|
1293
|
+
let min = fontSize.min;
|
|
1294
|
+
let max = fontSize.max;
|
|
1295
|
+
const cache = new Map();
|
|
1296
|
+
while (max - min >= 1) {
|
|
1297
|
+
const current = min + (max - min) / 2;
|
|
1298
|
+
if (!cache.has(current)) {
|
|
1299
|
+
c.font = `${current}px ${family}`;
|
|
1300
|
+
const metrics = c.measureText(text);
|
|
1301
|
+
const width$1 = metrics.width;
|
|
1302
|
+
const height$1 = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
|
|
1303
|
+
cache.set(current, {
|
|
1304
|
+
width: width$1,
|
|
1305
|
+
height: height$1
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
const { width, height } = cache.get(current);
|
|
1309
|
+
if (width > desiredW || height > desiredH) max = current;
|
|
1310
|
+
else min = current;
|
|
1311
|
+
}
|
|
1312
|
+
return Math.floor(min);
|
|
1313
|
+
}
|
|
1314
|
+
function getTextLayout(c, text, width, height) {
|
|
1315
|
+
const ellipsisWidth = measureTextWidth(c, "...");
|
|
1316
|
+
if (width < ellipsisWidth) {
|
|
1317
|
+
if (height > ellipsisWidth) return {
|
|
1318
|
+
valid: true,
|
|
1319
|
+
text: "...",
|
|
1320
|
+
direction: "vertical",
|
|
1321
|
+
width: ellipsisWidth / 3
|
|
1322
|
+
};
|
|
1323
|
+
return {
|
|
1324
|
+
valid: false,
|
|
1325
|
+
text: "",
|
|
1326
|
+
direction: "horizontal",
|
|
1327
|
+
width: 0
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
const textWidth = measureTextWidth(c, text);
|
|
1331
|
+
if (textWidth < width) return {
|
|
1332
|
+
valid: true,
|
|
1333
|
+
text,
|
|
1334
|
+
direction: "horizontal",
|
|
1335
|
+
width: textWidth
|
|
1336
|
+
};
|
|
1337
|
+
return {
|
|
1338
|
+
valid: true,
|
|
1339
|
+
text: "...",
|
|
1340
|
+
direction: "horizontal",
|
|
1341
|
+
width: ellipsisWidth
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
function measureTextWidth(c, text) {
|
|
1345
|
+
return c.measureText(text).width;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
//#endregion
|
|
1349
|
+
//#region src/dom-event.ts
|
|
1350
|
+
const DOM_EVENTS = [
|
|
1351
|
+
"click",
|
|
1352
|
+
"mousedown",
|
|
1353
|
+
"mousemove",
|
|
1354
|
+
"mouseup",
|
|
1355
|
+
"mouseover",
|
|
1356
|
+
"mouseout",
|
|
1357
|
+
"wheel",
|
|
1358
|
+
"contextmenu"
|
|
1359
|
+
];
|
|
1360
|
+
const STATE_TRANSITION = {
|
|
1361
|
+
IDLE: "IDLE",
|
|
1362
|
+
PRESSED: "PRESSED",
|
|
1363
|
+
DRAGGING: "DRAGGING",
|
|
1364
|
+
CLICK_POTENTIAL: "CLICK_POTENTIAL",
|
|
1365
|
+
ZOOMING: "ZOOMING",
|
|
1366
|
+
MOVE: "MOVE",
|
|
1367
|
+
SCALING: "SCALING"
|
|
1368
|
+
};
|
|
1369
|
+
var StateManager = class {
|
|
1370
|
+
current;
|
|
1371
|
+
constructor() {
|
|
1372
|
+
this.current = STATE_TRANSITION.IDLE;
|
|
1373
|
+
}
|
|
1374
|
+
canTransition(to) {
|
|
1375
|
+
switch (this.current) {
|
|
1376
|
+
case "IDLE": return to === "PRESSED" || to === "MOVE" || to === "SCALING" || to === "ZOOMING";
|
|
1377
|
+
case "PRESSED": return to === "DRAGGING" || to === "IDLE";
|
|
1378
|
+
case "DRAGGING": return to === "IDLE";
|
|
1379
|
+
case "MOVE": return to === "PRESSED" || to === "IDLE";
|
|
1380
|
+
case "SCALING": return to === "IDLE";
|
|
1381
|
+
case "ZOOMING": return to === "IDLE";
|
|
1382
|
+
default: return false;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
transition(to) {
|
|
1386
|
+
const valid = this.canTransition(to);
|
|
1387
|
+
if (valid) this.current = to;
|
|
1388
|
+
return valid;
|
|
1389
|
+
}
|
|
1390
|
+
reset() {
|
|
1391
|
+
this.current = STATE_TRANSITION.IDLE;
|
|
1392
|
+
}
|
|
1393
|
+
isInState(state) {
|
|
1394
|
+
return this.current === state;
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
function isWheelEvent(metadata) {
|
|
1398
|
+
return metadata.kind === "wheel";
|
|
1399
|
+
}
|
|
1400
|
+
function isMouseEvent(metadata) {
|
|
1401
|
+
return [
|
|
1402
|
+
"mousedown",
|
|
1403
|
+
"mouseup",
|
|
1404
|
+
"mousemove"
|
|
1405
|
+
].includes(metadata.kind);
|
|
1406
|
+
}
|
|
1407
|
+
function isClickEvent(metadata) {
|
|
1408
|
+
return metadata.kind === "click";
|
|
1409
|
+
}
|
|
1410
|
+
function isContextMenuEvent(metadata) {
|
|
1411
|
+
return metadata.kind === "contextmenu";
|
|
1412
|
+
}
|
|
1413
|
+
function bindDOMEvent(el, evt, dom) {
|
|
1414
|
+
const handler = (e) => {
|
|
1415
|
+
const data = { native: e };
|
|
1416
|
+
Object.defineProperty(data, "kind", {
|
|
1417
|
+
value: evt,
|
|
1418
|
+
enumerable: true,
|
|
1419
|
+
configurable: false,
|
|
1420
|
+
writable: false
|
|
1421
|
+
});
|
|
1422
|
+
dom.emit(evt, data);
|
|
1423
|
+
};
|
|
1424
|
+
el.addEventListener(evt, handler);
|
|
1425
|
+
return {
|
|
1426
|
+
evt,
|
|
1427
|
+
handler
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1430
|
+
var DOMEvent = class extends Event {
|
|
1431
|
+
domEvents;
|
|
1432
|
+
el;
|
|
1433
|
+
currentModule;
|
|
1434
|
+
component;
|
|
1435
|
+
matrix;
|
|
1436
|
+
stateManager;
|
|
1437
|
+
constructor(component) {
|
|
1438
|
+
super();
|
|
1439
|
+
this.component = component;
|
|
1440
|
+
this.el = component.render.canvas;
|
|
1441
|
+
this.matrix = new Matrix2D();
|
|
1442
|
+
this.currentModule = null;
|
|
1443
|
+
this.stateManager = new StateManager();
|
|
1444
|
+
this.domEvents = DOM_EVENTS.map((evt) => bindDOMEvent(this.el, evt, this));
|
|
1445
|
+
DOM_EVENTS.forEach((evt) => {
|
|
1446
|
+
this.on(evt, (e) => {
|
|
1447
|
+
this.dispatch(evt, e);
|
|
1448
|
+
});
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
destory() {
|
|
1452
|
+
if (this.el) {
|
|
1453
|
+
this.domEvents.forEach(({ evt, handler }) => this.el?.removeEventListener(evt, handler));
|
|
1454
|
+
this.domEvents = [];
|
|
1455
|
+
for (const evt in this.eventCollections) this.off(evt);
|
|
1456
|
+
this.matrix.create(DEFAULT_MATRIX_LOC);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
dispatch(kind, e) {
|
|
1460
|
+
const node = this.findRelativeNode(e);
|
|
1461
|
+
this.component.pluginDriver.runHook("onDOMEventTriggered", kind, e, node, this);
|
|
1462
|
+
this.emit("__exposed__", kind, {
|
|
1463
|
+
native: e.native,
|
|
1464
|
+
module: node
|
|
1465
|
+
});
|
|
1466
|
+
}
|
|
1467
|
+
findRelativeNode(e) {
|
|
1468
|
+
return findRelativeNode(captureBoxXY(this.el, e.native, this.matrix.a, this.matrix.d, this.matrix.e, this.matrix.f), this.component.layoutNodes);
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
|
|
1472
|
+
//#endregion
|
|
1473
|
+
Object.defineProperty(exports, 'Component', {
|
|
1474
|
+
enumerable: true,
|
|
1475
|
+
get: function () {
|
|
1476
|
+
return Component;
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
Object.defineProperty(exports, 'DEFAULT_MATRIX_LOC', {
|
|
1480
|
+
enumerable: true,
|
|
1481
|
+
get: function () {
|
|
1482
|
+
return DEFAULT_MATRIX_LOC;
|
|
1483
|
+
}
|
|
1484
|
+
});
|
|
1485
|
+
Object.defineProperty(exports, 'DOMEvent', {
|
|
1486
|
+
enumerable: true,
|
|
1487
|
+
get: function () {
|
|
1488
|
+
return DOMEvent;
|
|
1489
|
+
}
|
|
1490
|
+
});
|
|
1491
|
+
Object.defineProperty(exports, 'DefaultMap', {
|
|
1492
|
+
enumerable: true,
|
|
1493
|
+
get: function () {
|
|
1494
|
+
return DefaultMap;
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
Object.defineProperty(exports, 'Event', {
|
|
1498
|
+
enumerable: true,
|
|
1499
|
+
get: function () {
|
|
1500
|
+
return Event;
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
Object.defineProperty(exports, 'PI_2', {
|
|
1504
|
+
enumerable: true,
|
|
1505
|
+
get: function () {
|
|
1506
|
+
return PI_2;
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
Object.defineProperty(exports, 'Schedule', {
|
|
1510
|
+
enumerable: true,
|
|
1511
|
+
get: function () {
|
|
1512
|
+
return Schedule;
|
|
1513
|
+
}
|
|
1514
|
+
});
|
|
1515
|
+
Object.defineProperty(exports, 'applyCanvasTransform', {
|
|
1516
|
+
enumerable: true,
|
|
1517
|
+
get: function () {
|
|
1518
|
+
return applyCanvasTransform;
|
|
1519
|
+
}
|
|
1520
|
+
});
|
|
1521
|
+
Object.defineProperty(exports, 'assertExists', {
|
|
1522
|
+
enumerable: true,
|
|
1523
|
+
get: function () {
|
|
1524
|
+
return assertExists;
|
|
1525
|
+
}
|
|
1526
|
+
});
|
|
1527
|
+
Object.defineProperty(exports, 'bindParentForModule', {
|
|
1528
|
+
enumerable: true,
|
|
1529
|
+
get: function () {
|
|
1530
|
+
return bindParentForModule;
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
Object.defineProperty(exports, 'c2m', {
|
|
1534
|
+
enumerable: true,
|
|
1535
|
+
get: function () {
|
|
1536
|
+
return c2m;
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
Object.defineProperty(exports, 'createCanvasElement', {
|
|
1540
|
+
enumerable: true,
|
|
1541
|
+
get: function () {
|
|
1542
|
+
return createCanvasElement;
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
Object.defineProperty(exports, 'createRoundBlock', {
|
|
1546
|
+
enumerable: true,
|
|
1547
|
+
get: function () {
|
|
1548
|
+
return createRoundBlock;
|
|
1549
|
+
}
|
|
1550
|
+
});
|
|
1551
|
+
Object.defineProperty(exports, 'createTitleText', {
|
|
1552
|
+
enumerable: true,
|
|
1553
|
+
get: function () {
|
|
1554
|
+
return createTitleText;
|
|
1555
|
+
}
|
|
1556
|
+
});
|
|
1557
|
+
Object.defineProperty(exports, 'definePlugin', {
|
|
1558
|
+
enumerable: true,
|
|
1559
|
+
get: function () {
|
|
1560
|
+
return definePlugin;
|
|
1561
|
+
}
|
|
1562
|
+
});
|
|
1563
|
+
Object.defineProperty(exports, 'easing', {
|
|
1564
|
+
enumerable: true,
|
|
1565
|
+
get: function () {
|
|
1566
|
+
return easing;
|
|
1567
|
+
}
|
|
1568
|
+
});
|
|
1569
|
+
Object.defineProperty(exports, 'findRelativeNode', {
|
|
1570
|
+
enumerable: true,
|
|
1571
|
+
get: function () {
|
|
1572
|
+
return findRelativeNode;
|
|
1573
|
+
}
|
|
1574
|
+
});
|
|
1575
|
+
Object.defineProperty(exports, 'findRelativeNodeById', {
|
|
1576
|
+
enumerable: true,
|
|
1577
|
+
get: function () {
|
|
1578
|
+
return findRelativeNodeById;
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
Object.defineProperty(exports, 'flatten', {
|
|
1582
|
+
enumerable: true,
|
|
1583
|
+
get: function () {
|
|
1584
|
+
return flatten;
|
|
1585
|
+
}
|
|
1586
|
+
});
|
|
1587
|
+
Object.defineProperty(exports, 'getNodeDepth', {
|
|
1588
|
+
enumerable: true,
|
|
1589
|
+
get: function () {
|
|
1590
|
+
return getNodeDepth;
|
|
1591
|
+
}
|
|
1592
|
+
});
|
|
1593
|
+
Object.defineProperty(exports, 'hashCode', {
|
|
1594
|
+
enumerable: true,
|
|
1595
|
+
get: function () {
|
|
1596
|
+
return hashCode;
|
|
1597
|
+
}
|
|
1598
|
+
});
|
|
1599
|
+
Object.defineProperty(exports, 'isClickEvent', {
|
|
1600
|
+
enumerable: true,
|
|
1601
|
+
get: function () {
|
|
1602
|
+
return isClickEvent;
|
|
1603
|
+
}
|
|
1604
|
+
});
|
|
1605
|
+
Object.defineProperty(exports, 'isContextMenuEvent', {
|
|
1606
|
+
enumerable: true,
|
|
1607
|
+
get: function () {
|
|
1608
|
+
return isContextMenuEvent;
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1611
|
+
Object.defineProperty(exports, 'isMacOS', {
|
|
1612
|
+
enumerable: true,
|
|
1613
|
+
get: function () {
|
|
1614
|
+
return isMacOS;
|
|
1615
|
+
}
|
|
1616
|
+
});
|
|
1617
|
+
Object.defineProperty(exports, 'isMouseEvent', {
|
|
1618
|
+
enumerable: true,
|
|
1619
|
+
get: function () {
|
|
1620
|
+
return isMouseEvent;
|
|
1621
|
+
}
|
|
1622
|
+
});
|
|
1623
|
+
Object.defineProperty(exports, 'isScrollWheelOrRightButtonOnMouseupAndDown', {
|
|
1624
|
+
enumerable: true,
|
|
1625
|
+
get: function () {
|
|
1626
|
+
return isScrollWheelOrRightButtonOnMouseupAndDown;
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
Object.defineProperty(exports, 'isWheelEvent', {
|
|
1630
|
+
enumerable: true,
|
|
1631
|
+
get: function () {
|
|
1632
|
+
return isWheelEvent;
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1635
|
+
Object.defineProperty(exports, 'logger', {
|
|
1636
|
+
enumerable: true,
|
|
1637
|
+
get: function () {
|
|
1638
|
+
return logger;
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
Object.defineProperty(exports, 'mixin', {
|
|
1642
|
+
enumerable: true,
|
|
1643
|
+
get: function () {
|
|
1644
|
+
return mixin;
|
|
1645
|
+
}
|
|
1646
|
+
});
|
|
1647
|
+
Object.defineProperty(exports, 'mixinWithParams', {
|
|
1648
|
+
enumerable: true,
|
|
1649
|
+
get: function () {
|
|
1650
|
+
return mixinWithParams;
|
|
1651
|
+
}
|
|
1652
|
+
});
|
|
1653
|
+
Object.defineProperty(exports, 'noop', {
|
|
1654
|
+
enumerable: true,
|
|
1655
|
+
get: function () {
|
|
1656
|
+
return noop;
|
|
1657
|
+
}
|
|
1658
|
+
});
|
|
1659
|
+
Object.defineProperty(exports, 'perferNumeric', {
|
|
1660
|
+
enumerable: true,
|
|
1661
|
+
get: function () {
|
|
1662
|
+
return perferNumeric;
|
|
1663
|
+
}
|
|
1664
|
+
});
|
|
1665
|
+
Object.defineProperty(exports, 'prettyStrJoin', {
|
|
1666
|
+
enumerable: true,
|
|
1667
|
+
get: function () {
|
|
1668
|
+
return prettyStrJoin;
|
|
1669
|
+
}
|
|
1670
|
+
});
|
|
1671
|
+
Object.defineProperty(exports, 'raf', {
|
|
1672
|
+
enumerable: true,
|
|
1673
|
+
get: function () {
|
|
1674
|
+
return raf;
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
Object.defineProperty(exports, 'smoothFrame', {
|
|
1678
|
+
enumerable: true,
|
|
1679
|
+
get: function () {
|
|
1680
|
+
return smoothFrame;
|
|
1681
|
+
}
|
|
1682
|
+
});
|
|
1683
|
+
Object.defineProperty(exports, 'sortChildrenByKey', {
|
|
1684
|
+
enumerable: true,
|
|
1685
|
+
get: function () {
|
|
1686
|
+
return sortChildrenByKey;
|
|
1687
|
+
}
|
|
1688
|
+
});
|
|
1689
|
+
Object.defineProperty(exports, 'stackMatrixTransform', {
|
|
1690
|
+
enumerable: true,
|
|
1691
|
+
get: function () {
|
|
1692
|
+
return stackMatrixTransform;
|
|
1693
|
+
}
|
|
1694
|
+
});
|
|
1695
|
+
Object.defineProperty(exports, 'stackMatrixTransformWithGraphAndLayer', {
|
|
1696
|
+
enumerable: true,
|
|
1697
|
+
get: function () {
|
|
1698
|
+
return stackMatrixTransformWithGraphAndLayer;
|
|
1699
|
+
}
|
|
1700
|
+
});
|
|
1701
|
+
Object.defineProperty(exports, 'typedForIn', {
|
|
1702
|
+
enumerable: true,
|
|
1703
|
+
get: function () {
|
|
1704
|
+
return typedForIn;
|
|
1705
|
+
}
|
|
1706
|
+
});
|
|
1707
|
+
Object.defineProperty(exports, 'visit', {
|
|
1708
|
+
enumerable: true,
|
|
1709
|
+
get: function () {
|
|
1710
|
+
return visit;
|
|
1711
|
+
}
|
|
1712
|
+
});
|