squarified 0.1.2 → 0.2.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 +6 -11
- package/dist/index.d.mts +61 -63
- package/dist/index.d.ts +61 -63
- package/dist/index.js +440 -232
- package/dist/index.mjs +440 -232
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -20,11 +20,7 @@ class Matrix2D {
|
|
|
20
20
|
this.f = loc.f || 0;
|
|
21
21
|
}
|
|
22
22
|
create(loc) {
|
|
23
|
-
|
|
24
|
-
if (Object.hasOwnProperty.call(this, key)) {
|
|
25
|
-
this[key] = value;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
23
|
+
Object.assign(this, loc);
|
|
28
24
|
return this;
|
|
29
25
|
}
|
|
30
26
|
transform(x, y, scaleX, scaleY, rotation, skewX, skewY) {
|
|
@@ -91,6 +87,7 @@ var DisplayType = /* @__PURE__ */ ((DisplayType2) => {
|
|
|
91
87
|
DisplayType2["Box"] = "Box";
|
|
92
88
|
DisplayType2["Rect"] = "Rect";
|
|
93
89
|
DisplayType2["Text"] = "Text";
|
|
90
|
+
DisplayType2["Layer"] = "Layer";
|
|
94
91
|
return DisplayType2;
|
|
95
92
|
})(DisplayType || {});
|
|
96
93
|
class Display {
|
|
@@ -172,10 +169,8 @@ class Graph extends S {
|
|
|
172
169
|
constructor(options = {}) {
|
|
173
170
|
super(options);
|
|
174
171
|
__publicField$9(this, "instruction");
|
|
175
|
-
__publicField$9(this, "__refresh__");
|
|
176
172
|
__publicField$9(this, "__options__");
|
|
177
173
|
this.instruction = createInstruction();
|
|
178
|
-
this.__refresh__ = true;
|
|
179
174
|
this.__options__ = options;
|
|
180
175
|
}
|
|
181
176
|
render(ctx) {
|
|
@@ -208,17 +203,53 @@ function isRect(display) {
|
|
|
208
203
|
function isText(display) {
|
|
209
204
|
return isGraph(display) && display.__shape__ === DisplayType.Text;
|
|
210
205
|
}
|
|
206
|
+
function isLayer(display) {
|
|
207
|
+
return display.__instanceOf__ === DisplayType.Layer;
|
|
208
|
+
}
|
|
211
209
|
const asserts = {
|
|
212
210
|
isGraph,
|
|
213
211
|
isBox,
|
|
214
212
|
isRect,
|
|
215
|
-
isText
|
|
213
|
+
isText,
|
|
214
|
+
isLayer
|
|
216
215
|
};
|
|
217
216
|
|
|
218
217
|
var __defProp$8 = Object.defineProperty;
|
|
219
218
|
var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
220
219
|
var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, key + "" , value);
|
|
221
|
-
class
|
|
220
|
+
class C extends Display {
|
|
221
|
+
constructor() {
|
|
222
|
+
super();
|
|
223
|
+
__publicField$8(this, "elements");
|
|
224
|
+
this.elements = [];
|
|
225
|
+
}
|
|
226
|
+
add(...elements) {
|
|
227
|
+
const cap = elements.length;
|
|
228
|
+
for (let i = 0; i < cap; i++) {
|
|
229
|
+
const element = elements[i];
|
|
230
|
+
if (element.parent) ;
|
|
231
|
+
this.elements.push(element);
|
|
232
|
+
element.parent = this;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
remove(...elements) {
|
|
236
|
+
const cap = elements.length;
|
|
237
|
+
for (let i = 0; i < cap; i++) {
|
|
238
|
+
for (let j = this.elements.length - 1; j >= 0; j--) {
|
|
239
|
+
const element = this.elements[j];
|
|
240
|
+
if (element.id === elements[i].id) {
|
|
241
|
+
this.elements.splice(j, 1);
|
|
242
|
+
element.parent = null;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
destory() {
|
|
248
|
+
this.elements.forEach((element) => element.parent = null);
|
|
249
|
+
this.elements.length = 0;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
class Box extends C {
|
|
222
253
|
constructor() {
|
|
223
254
|
super();
|
|
224
255
|
__publicField$8(this, "elements");
|
|
@@ -279,6 +310,126 @@ class Box extends Display {
|
|
|
279
310
|
}
|
|
280
311
|
}
|
|
281
312
|
|
|
313
|
+
var __defProp$7 = Object.defineProperty;
|
|
314
|
+
var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
315
|
+
var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
316
|
+
function writeBoundingRectForCanvas(c, w, h, dpr) {
|
|
317
|
+
c.width = w * dpr;
|
|
318
|
+
c.height = h * dpr;
|
|
319
|
+
c.style.cssText = `width: ${w}px; height: ${h}px`;
|
|
320
|
+
}
|
|
321
|
+
class Canvas {
|
|
322
|
+
constructor(options) {
|
|
323
|
+
__publicField$7(this, "canvas");
|
|
324
|
+
__publicField$7(this, "ctx");
|
|
325
|
+
this.canvas = createCanvasElement();
|
|
326
|
+
writeBoundingRectForCanvas(this.canvas, options.width, options.height, options.devicePixelRatio);
|
|
327
|
+
this.ctx = this.canvas.getContext("2d");
|
|
328
|
+
}
|
|
329
|
+
get c() {
|
|
330
|
+
return { canvas: this.canvas, ctx: this.ctx };
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
class Render {
|
|
334
|
+
constructor(to, options) {
|
|
335
|
+
__publicField$7(this, "c");
|
|
336
|
+
__publicField$7(this, "options");
|
|
337
|
+
this.c = new Canvas(options);
|
|
338
|
+
this.options = options;
|
|
339
|
+
this.initOptions(options);
|
|
340
|
+
!options.shaow && to.appendChild(this.canvas);
|
|
341
|
+
}
|
|
342
|
+
clear(width, height) {
|
|
343
|
+
this.ctx.clearRect(0, 0, width, height);
|
|
344
|
+
}
|
|
345
|
+
get canvas() {
|
|
346
|
+
return this.c.c.canvas;
|
|
347
|
+
}
|
|
348
|
+
get ctx() {
|
|
349
|
+
return this.c.c.ctx;
|
|
350
|
+
}
|
|
351
|
+
initOptions(userOptions = {}) {
|
|
352
|
+
Object.assign(this.options, userOptions);
|
|
353
|
+
writeBoundingRectForCanvas(this.canvas, this.options.width, this.options.height, this.options.devicePixelRatio);
|
|
354
|
+
}
|
|
355
|
+
update(schedule) {
|
|
356
|
+
this.clear(this.options.width, this.options.height);
|
|
357
|
+
schedule.execute(this);
|
|
358
|
+
}
|
|
359
|
+
destory() {
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
var __defProp$6 = Object.defineProperty;
|
|
364
|
+
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
365
|
+
var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
366
|
+
class Layer extends C {
|
|
367
|
+
constructor(options = {}) {
|
|
368
|
+
super();
|
|
369
|
+
__publicField$6(this, "c");
|
|
370
|
+
__publicField$6(this, "__refresh__");
|
|
371
|
+
__publicField$6(this, "options");
|
|
372
|
+
__publicField$6(this, "width");
|
|
373
|
+
__publicField$6(this, "height");
|
|
374
|
+
__publicField$6(this, "x");
|
|
375
|
+
__publicField$6(this, "y");
|
|
376
|
+
__publicField$6(this, "scaleX");
|
|
377
|
+
__publicField$6(this, "scaleY");
|
|
378
|
+
__publicField$6(this, "rotation");
|
|
379
|
+
__publicField$6(this, "skewX");
|
|
380
|
+
__publicField$6(this, "skewY");
|
|
381
|
+
this.c = new Canvas({ width: 0, height: 0, devicePixelRatio: 1 });
|
|
382
|
+
this.__refresh__ = false;
|
|
383
|
+
this.options = /* @__PURE__ */ Object.create(null);
|
|
384
|
+
this.width = options.width || 0;
|
|
385
|
+
this.height = options.height || 0;
|
|
386
|
+
this.x = options.x || 0;
|
|
387
|
+
this.y = options.y || 0;
|
|
388
|
+
this.scaleX = options.scaleX || 1;
|
|
389
|
+
this.scaleY = options.scaleY || 1;
|
|
390
|
+
this.rotation = options.rotation || 0;
|
|
391
|
+
this.skewX = options.skewX || 0;
|
|
392
|
+
this.skewY = options.skewY || 0;
|
|
393
|
+
}
|
|
394
|
+
get __instanceOf__() {
|
|
395
|
+
return DisplayType.Layer;
|
|
396
|
+
}
|
|
397
|
+
setCanvasOptions(options = {}) {
|
|
398
|
+
Object.assign(this.options, options);
|
|
399
|
+
writeBoundingRectForCanvas(this.c.c.canvas, options.width || 0, options.height || 0, options.devicePixelRatio || 1);
|
|
400
|
+
}
|
|
401
|
+
setCacheSnapshot(c) {
|
|
402
|
+
const dpr = this.options.devicePixelRatio || 1;
|
|
403
|
+
const matrix = this.matrix.create({ a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 });
|
|
404
|
+
this.ctx.clearRect(0, 0, this.options.width, this.options.height);
|
|
405
|
+
matrix.transform(this.x, this.y, this.scaleX, this.scaleY, this.rotation, this.skewX, this.skewY);
|
|
406
|
+
applyCanvasTransform(this.ctx, matrix, dpr);
|
|
407
|
+
this.ctx.drawImage(c, 0, 0, this.options.width / dpr, this.options.height / dpr);
|
|
408
|
+
this.__refresh__ = true;
|
|
409
|
+
}
|
|
410
|
+
initLoc(options = {}) {
|
|
411
|
+
this.x = options.x || 0;
|
|
412
|
+
this.y = options.y || 0;
|
|
413
|
+
this.scaleX = options.scaleX || 1;
|
|
414
|
+
this.scaleY = options.scaleY || 1;
|
|
415
|
+
this.rotation = options.rotation || 0;
|
|
416
|
+
this.skewX = options.skewX || 0;
|
|
417
|
+
this.skewY = options.skewY || 0;
|
|
418
|
+
}
|
|
419
|
+
draw(ctx) {
|
|
420
|
+
const matrix = this.matrix.create({ a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 });
|
|
421
|
+
matrix.transform(this.x, this.y, this.scaleX, this.scaleY, this.rotation, this.skewX, this.skewY);
|
|
422
|
+
applyCanvasTransform(ctx, matrix, this.options.devicePixelRatio || 1);
|
|
423
|
+
ctx.drawImage(this.canvas, 0, 0);
|
|
424
|
+
}
|
|
425
|
+
get canvas() {
|
|
426
|
+
return this.c.c.canvas;
|
|
427
|
+
}
|
|
428
|
+
get ctx() {
|
|
429
|
+
return this.c.c.ctx;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
282
433
|
function decodeHLS(meta) {
|
|
283
434
|
const { h, l, s, a } = meta;
|
|
284
435
|
if ("a" in meta) {
|
|
@@ -304,13 +455,13 @@ const runtime = {
|
|
|
304
455
|
evaluateFillStyle
|
|
305
456
|
};
|
|
306
457
|
|
|
307
|
-
var __defProp$
|
|
308
|
-
var __defNormalProp$
|
|
309
|
-
var __publicField$
|
|
458
|
+
var __defProp$5 = Object.defineProperty;
|
|
459
|
+
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
460
|
+
var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, key + "" , value);
|
|
310
461
|
class Rect extends Graph {
|
|
311
462
|
constructor(options = {}) {
|
|
312
463
|
super(options);
|
|
313
|
-
__publicField$
|
|
464
|
+
__publicField$5(this, "style");
|
|
314
465
|
this.style = options.style || /* @__PURE__ */ Object.create(null);
|
|
315
466
|
}
|
|
316
467
|
get __shape__() {
|
|
@@ -334,14 +485,14 @@ class Rect extends Graph {
|
|
|
334
485
|
}
|
|
335
486
|
}
|
|
336
487
|
|
|
337
|
-
var __defProp$
|
|
338
|
-
var __defNormalProp$
|
|
339
|
-
var __publicField$
|
|
488
|
+
var __defProp$4 = Object.defineProperty;
|
|
489
|
+
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
490
|
+
var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
340
491
|
class Text extends Graph {
|
|
341
492
|
constructor(options = {}) {
|
|
342
493
|
super(options);
|
|
343
|
-
__publicField$
|
|
344
|
-
__publicField$
|
|
494
|
+
__publicField$4(this, "text");
|
|
495
|
+
__publicField$4(this, "style");
|
|
345
496
|
this.text = options.text || "";
|
|
346
497
|
this.style = options.style || /* @__PURE__ */ Object.create(null);
|
|
347
498
|
}
|
|
@@ -362,12 +513,12 @@ class Text extends Graph {
|
|
|
362
513
|
}
|
|
363
514
|
}
|
|
364
515
|
|
|
365
|
-
var __defProp$
|
|
366
|
-
var __defNormalProp$
|
|
367
|
-
var __publicField$
|
|
516
|
+
var __defProp$3 = Object.defineProperty;
|
|
517
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
518
|
+
var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, key + "" , value);
|
|
368
519
|
class Event {
|
|
369
520
|
constructor() {
|
|
370
|
-
__publicField$
|
|
521
|
+
__publicField$3(this, "eventCollections");
|
|
371
522
|
this.eventCollections = /* @__PURE__ */ Object.create(null);
|
|
372
523
|
}
|
|
373
524
|
on(evt, handler, c) {
|
|
@@ -411,47 +562,39 @@ const log = {
|
|
|
411
562
|
}
|
|
412
563
|
};
|
|
413
564
|
|
|
414
|
-
var __defProp$
|
|
415
|
-
var __defNormalProp$
|
|
416
|
-
var __publicField$
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
Object.assign(this.options, userOptions);
|
|
433
|
-
const { options } = this;
|
|
434
|
-
this.canvas.width = options.width * options.devicePixelRatio;
|
|
435
|
-
this.canvas.height = options.height * options.devicePixelRatio;
|
|
436
|
-
this.canvas.style.cssText = `width: ${options.width}px; height: ${options.height}px`;
|
|
437
|
-
}
|
|
438
|
-
update(schedule) {
|
|
439
|
-
this.clear(this.options.width, this.options.height);
|
|
440
|
-
schedule.execute(this);
|
|
565
|
+
var __defProp$2 = Object.defineProperty;
|
|
566
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
567
|
+
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
568
|
+
function drawGraphIntoCanvas(graph, opts, callback) {
|
|
569
|
+
const { ctx, dpr } = opts;
|
|
570
|
+
ctx.save();
|
|
571
|
+
if (asserts.isLayer(graph) && graph.__refresh__) {
|
|
572
|
+
callback(opts, graph);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (asserts.isLayer(graph) || asserts.isBox(graph)) {
|
|
576
|
+
const elements = graph.elements;
|
|
577
|
+
const cap = elements.length;
|
|
578
|
+
for (let i = 0; i < cap; i++) {
|
|
579
|
+
const element = elements[i];
|
|
580
|
+
drawGraphIntoCanvas(element, opts, callback);
|
|
581
|
+
}
|
|
582
|
+
callback(opts, graph);
|
|
441
583
|
}
|
|
442
|
-
|
|
584
|
+
if (asserts.isGraph(graph)) {
|
|
585
|
+
const matrix = graph.matrix.create({ a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 });
|
|
586
|
+
matrix.transform(graph.x, graph.y, graph.scaleX, graph.scaleY, graph.rotation, graph.skewX, graph.skewY);
|
|
587
|
+
applyCanvasTransform(ctx, matrix, dpr);
|
|
588
|
+
graph.render(ctx);
|
|
443
589
|
}
|
|
590
|
+
ctx.restore();
|
|
444
591
|
}
|
|
445
|
-
|
|
446
|
-
var __defProp$3 = Object.defineProperty;
|
|
447
|
-
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
448
|
-
var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
449
|
-
let Schedule$1 = class Schedule extends Box {
|
|
592
|
+
class Schedule extends Box {
|
|
450
593
|
constructor(to, renderOptions = {}) {
|
|
451
594
|
super();
|
|
452
|
-
__publicField$
|
|
453
|
-
__publicField$
|
|
454
|
-
__publicField$
|
|
595
|
+
__publicField$2(this, "render");
|
|
596
|
+
__publicField$2(this, "to");
|
|
597
|
+
__publicField$2(this, "event");
|
|
455
598
|
this.to = typeof to === "string" ? document.querySelector(to) : to;
|
|
456
599
|
if (!this.to) {
|
|
457
600
|
throw new Error(log.error("The element to bind is not found."));
|
|
@@ -461,63 +604,42 @@ let Schedule$1 = class Schedule extends Box {
|
|
|
461
604
|
this.event = new Event();
|
|
462
605
|
this.render = new Render(this.to, renderOptions);
|
|
463
606
|
}
|
|
464
|
-
applyTransform(matrix) {
|
|
465
|
-
const pixel = this.render.options.devicePixelRatio;
|
|
466
|
-
this.render.ctx.setTransform(
|
|
467
|
-
matrix.a * pixel,
|
|
468
|
-
matrix.b * pixel,
|
|
469
|
-
matrix.c * pixel,
|
|
470
|
-
matrix.d * pixel,
|
|
471
|
-
matrix.e * pixel,
|
|
472
|
-
matrix.f * pixel
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
607
|
update() {
|
|
476
608
|
this.render.update(this);
|
|
477
609
|
const matrix = this.matrix.create({ a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 });
|
|
478
|
-
this.
|
|
610
|
+
applyCanvasTransform(this.render.ctx, matrix, this.render.options.devicePixelRatio);
|
|
479
611
|
}
|
|
480
612
|
// execute all graph elements
|
|
481
613
|
execute(render, graph = this) {
|
|
482
|
-
render.ctx.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
const element = elements[i];
|
|
489
|
-
if (asserts.isGraph(element)) {
|
|
490
|
-
matrices[i] = element.matrix.create({ a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 });
|
|
491
|
-
matrices[i].transform(element.x, element.y, element.scaleX, element.scaleY, element.rotation, element.skewX, element.skewY);
|
|
614
|
+
drawGraphIntoCanvas(graph, { c: render.canvas, ctx: render.ctx, dpr: render.options.devicePixelRatio }, (opts, graph2) => {
|
|
615
|
+
if (asserts.isLayer(graph2)) {
|
|
616
|
+
if (graph2.__refresh__) {
|
|
617
|
+
graph2.draw(opts.ctx);
|
|
618
|
+
} else {
|
|
619
|
+
graph2.setCacheSnapshot(opts.c);
|
|
492
620
|
}
|
|
493
621
|
}
|
|
494
|
-
|
|
495
|
-
const element = elements[i];
|
|
496
|
-
this.execute(render, element);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
if (asserts.isGraph(graph)) {
|
|
500
|
-
const matrix = graph.matrix;
|
|
501
|
-
this.applyTransform(matrix);
|
|
502
|
-
graph.render(render.ctx);
|
|
503
|
-
}
|
|
504
|
-
render.ctx.restore();
|
|
622
|
+
});
|
|
505
623
|
}
|
|
506
|
-
}
|
|
624
|
+
}
|
|
507
625
|
|
|
508
626
|
function traverse(graphs, handler) {
|
|
509
627
|
const len = graphs.length;
|
|
510
628
|
for (let i = 0; i < len; i++) {
|
|
511
629
|
const graph = graphs[i];
|
|
512
|
-
if (asserts.
|
|
513
|
-
traverse(graph.elements, handler);
|
|
514
|
-
} else if (asserts.isGraph(graph)) {
|
|
630
|
+
if (asserts.isLayer(graph) && graph.__refresh__) {
|
|
515
631
|
handler(graph);
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
if (asserts.isGraph(graph)) {
|
|
635
|
+
handler(graph);
|
|
636
|
+
} else if (asserts.isBox(graph) || asserts.isLayer(graph)) {
|
|
637
|
+
traverse(graph.elements, handler);
|
|
516
638
|
}
|
|
517
639
|
}
|
|
518
640
|
}
|
|
519
641
|
const etoile = {
|
|
520
|
-
Schedule
|
|
642
|
+
Schedule,
|
|
521
643
|
traverse
|
|
522
644
|
};
|
|
523
645
|
|
|
@@ -546,27 +668,14 @@ const easing = {
|
|
|
546
668
|
}
|
|
547
669
|
};
|
|
548
670
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
this.keys = Object.keys(data);
|
|
558
|
-
}
|
|
559
|
-
// dprint-ignore
|
|
560
|
-
*[Symbol.iterator]() {
|
|
561
|
-
for (let i = 0; i < this.keys.length; i++) {
|
|
562
|
-
yield {
|
|
563
|
-
key: this.keys[i],
|
|
564
|
-
value: this.data[this.keys[i]],
|
|
565
|
-
index: i,
|
|
566
|
-
peek: () => this.keys[i + 1]
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
}
|
|
671
|
+
function hashCode(str) {
|
|
672
|
+
let hash = 0;
|
|
673
|
+
for (let i = 0; i < str.length; i++) {
|
|
674
|
+
const code = str.charCodeAt(i);
|
|
675
|
+
hash = (hash << 5) - hash + code;
|
|
676
|
+
hash = hash & hash;
|
|
677
|
+
}
|
|
678
|
+
return hash;
|
|
570
679
|
}
|
|
571
680
|
function perferNumeric(s) {
|
|
572
681
|
if (typeof s === "number") return true;
|
|
@@ -584,6 +693,20 @@ function createTitleText(text, x, y, font, color) {
|
|
|
584
693
|
});
|
|
585
694
|
}
|
|
586
695
|
const raf = window.requestAnimationFrame;
|
|
696
|
+
function createCanvasElement() {
|
|
697
|
+
return document.createElement("canvas");
|
|
698
|
+
}
|
|
699
|
+
function applyCanvasTransform(ctx, matrix, dpr) {
|
|
700
|
+
ctx.setTransform(matrix.a * dpr, matrix.b * dpr, matrix.c * dpr, matrix.d * dpr, matrix.e * dpr, matrix.f * dpr);
|
|
701
|
+
}
|
|
702
|
+
function mixin(app, methods) {
|
|
703
|
+
methods.forEach(({ name, fn }) => {
|
|
704
|
+
Object.defineProperty(app, name, {
|
|
705
|
+
value: fn(app),
|
|
706
|
+
writable: false
|
|
707
|
+
});
|
|
708
|
+
});
|
|
709
|
+
}
|
|
587
710
|
|
|
588
711
|
function sortChildrenByKey(data, ...keys) {
|
|
589
712
|
return data.sort((a, b) => {
|
|
@@ -748,9 +871,7 @@ function createEffectRun(c) {
|
|
|
748
871
|
return (fn) => {
|
|
749
872
|
const effect = () => {
|
|
750
873
|
const done = fn();
|
|
751
|
-
if (done) {
|
|
752
|
-
c.animationFrameID = null;
|
|
753
|
-
} else {
|
|
874
|
+
if (!done) {
|
|
754
875
|
c.animationFrameID = raf(effect);
|
|
755
876
|
}
|
|
756
877
|
};
|
|
@@ -777,14 +898,6 @@ function createEffectScope() {
|
|
|
777
898
|
}
|
|
778
899
|
|
|
779
900
|
class RegisterModule {
|
|
780
|
-
static mixin(app, methods) {
|
|
781
|
-
methods.forEach(({ name, fn }) => {
|
|
782
|
-
Object.defineProperty(app, name, {
|
|
783
|
-
value: fn(app),
|
|
784
|
-
writable: false
|
|
785
|
-
});
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
901
|
}
|
|
789
902
|
function registerModuleForSchedule(mod) {
|
|
790
903
|
if (mod instanceof RegisterModule) {
|
|
@@ -799,33 +912,34 @@ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !==
|
|
|
799
912
|
const primitiveEvents = ["click", "mousedown", "mousemove", "mouseup", "mouseover", "mouseout"];
|
|
800
913
|
const fill = { desc: { r: 255, g: 255, b: 255 }, mode: "rgb" };
|
|
801
914
|
function smoothDrawing(c) {
|
|
802
|
-
const { self
|
|
915
|
+
const { self } = c;
|
|
803
916
|
const currentNode = self.currentNode;
|
|
804
917
|
if (currentNode) {
|
|
805
|
-
const
|
|
918
|
+
const effect = createEffectScope();
|
|
806
919
|
const startTime = Date.now();
|
|
807
920
|
const animationDuration = 300;
|
|
808
921
|
const [x, y, w, h] = currentNode.layout;
|
|
809
|
-
run(() => {
|
|
810
|
-
if (self.forceDestroy) {
|
|
811
|
-
stop();
|
|
812
|
-
return true;
|
|
813
|
-
}
|
|
922
|
+
effect.run(() => {
|
|
814
923
|
const elapsed = Date.now() - startTime;
|
|
815
924
|
const progress = Math.min(elapsed / animationDuration, 1);
|
|
925
|
+
if (self.forceDestroy || progress >= 1) {
|
|
926
|
+
effect.stop();
|
|
927
|
+
self.highlight.reset();
|
|
928
|
+
self.highlight.setDisplayLayerForHighlight();
|
|
929
|
+
return true;
|
|
930
|
+
}
|
|
816
931
|
const easedProgress = easing.cubicInOut(progress);
|
|
932
|
+
self.highlight.reset();
|
|
817
933
|
const mask = createFillBlock(x, y, w, h, { fill, opacity: 0.4 });
|
|
818
|
-
|
|
934
|
+
self.highlight.highlight.add(mask);
|
|
935
|
+
self.highlight.setDisplayLayerForHighlight("1");
|
|
819
936
|
applyForOpacity(mask, 0.4, 0.4, easedProgress);
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
treemap.update();
|
|
823
|
-
return progress >= 1;
|
|
937
|
+
stackMatrixTransform(mask, self.translateX, self.translateY, self.scaleRatio);
|
|
938
|
+
self.highlight.highlight.update();
|
|
824
939
|
});
|
|
825
940
|
} else {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
treemap.update();
|
|
941
|
+
self.highlight.reset();
|
|
942
|
+
self.highlight.setDisplayLayerForHighlight();
|
|
829
943
|
}
|
|
830
944
|
}
|
|
831
945
|
function applyZoomEvent(ctx) {
|
|
@@ -864,9 +978,8 @@ function captureBoxXY(c, evt, a, d, translateX, translateY) {
|
|
|
864
978
|
}
|
|
865
979
|
return { x: 0, y: 0 };
|
|
866
980
|
}
|
|
867
|
-
function bindPrimitiveEvent(ctx, evt, bus) {
|
|
981
|
+
function bindPrimitiveEvent(c, ctx, evt, bus) {
|
|
868
982
|
const { treemap, self } = ctx;
|
|
869
|
-
const c = treemap.render.canvas;
|
|
870
983
|
const handler = (e) => {
|
|
871
984
|
const { x, y } = captureBoxXY(
|
|
872
985
|
c,
|
|
@@ -898,6 +1011,9 @@ class SelfEvent extends RegisterModule {
|
|
|
898
1011
|
__publicField$1(this, "isDragging");
|
|
899
1012
|
__publicField$1(this, "draggingState");
|
|
900
1013
|
__publicField$1(this, "event");
|
|
1014
|
+
__publicField$1(this, "triggerZoom");
|
|
1015
|
+
// eslint-disable-next-line no-use-before-define
|
|
1016
|
+
__publicField$1(this, "highlight");
|
|
901
1017
|
this.currentNode = null;
|
|
902
1018
|
this.forceDestroy = false;
|
|
903
1019
|
this.isDragging = false;
|
|
@@ -908,6 +1024,8 @@ class SelfEvent extends RegisterModule {
|
|
|
908
1024
|
this.layoutHeight = 0;
|
|
909
1025
|
this.draggingState = { x: 0, y: 0 };
|
|
910
1026
|
this.event = new Event();
|
|
1027
|
+
this.triggerZoom = false;
|
|
1028
|
+
this.highlight = createHighlight();
|
|
911
1029
|
}
|
|
912
1030
|
ondragstart(metadata) {
|
|
913
1031
|
const { native } = metadata;
|
|
@@ -929,6 +1047,8 @@ class SelfEvent extends RegisterModule {
|
|
|
929
1047
|
}
|
|
930
1048
|
return;
|
|
931
1049
|
}
|
|
1050
|
+
this.self.highlight.reset();
|
|
1051
|
+
this.self.highlight.setDisplayLayerForHighlight();
|
|
932
1052
|
this.self.event.off("mousemove", this.self.onmousemove);
|
|
933
1053
|
this.treemap.event.off("zoom");
|
|
934
1054
|
this.self.forceDestroy = true;
|
|
@@ -941,23 +1061,26 @@ class SelfEvent extends RegisterModule {
|
|
|
941
1061
|
this.self.translateX += drawX;
|
|
942
1062
|
this.self.translateY += drawY;
|
|
943
1063
|
this.self.draggingState = { x, y };
|
|
1064
|
+
if (this.self.triggerZoom) {
|
|
1065
|
+
refreshBackgroundLayer(this);
|
|
1066
|
+
}
|
|
944
1067
|
this.treemap.reset();
|
|
945
|
-
|
|
1068
|
+
stackMatrixTransform(this.treemap.backgroundLayer, 0, 0, 0);
|
|
1069
|
+
stackMatrixTransformWithGraphAndLayer(this.treemap.elements, this.self.translateX, this.self.translateY, this.self.scaleRatio);
|
|
946
1070
|
this.treemap.update();
|
|
947
1071
|
}
|
|
948
|
-
ondragend(
|
|
1072
|
+
ondragend() {
|
|
949
1073
|
if (!this.self.isDragging) {
|
|
950
1074
|
return;
|
|
951
1075
|
}
|
|
952
1076
|
this.self.isDragging = false;
|
|
953
1077
|
this.self.draggingState = { x: 0, y: 0 };
|
|
1078
|
+
this.self.highlight.reset();
|
|
1079
|
+
this.self.highlight.setDisplayLayerForHighlight();
|
|
954
1080
|
this.self.event.bindWithContext(this)("mousemove", this.self.onmousemove);
|
|
955
1081
|
}
|
|
956
1082
|
onmousemove(metadata) {
|
|
957
1083
|
const { self } = this;
|
|
958
|
-
if (self.isDragging) {
|
|
959
|
-
return;
|
|
960
|
-
}
|
|
961
1084
|
const { module: node } = metadata;
|
|
962
1085
|
self.forceDestroy = false;
|
|
963
1086
|
if (self.currentNode !== node) {
|
|
@@ -969,7 +1092,6 @@ class SelfEvent extends RegisterModule {
|
|
|
969
1092
|
const { self } = this;
|
|
970
1093
|
self.currentNode = null;
|
|
971
1094
|
self.forceDestroy = true;
|
|
972
|
-
self.isDragging = false;
|
|
973
1095
|
smoothDrawing(this);
|
|
974
1096
|
}
|
|
975
1097
|
onwheel(metadata) {
|
|
@@ -982,7 +1104,13 @@ class SelfEvent extends RegisterModule {
|
|
|
982
1104
|
return;
|
|
983
1105
|
}
|
|
984
1106
|
self.forceDestroy = true;
|
|
1107
|
+
if (self.triggerZoom) {
|
|
1108
|
+
refreshBackgroundLayer(this);
|
|
1109
|
+
}
|
|
985
1110
|
treemap.reset();
|
|
1111
|
+
this.self.highlight.reset();
|
|
1112
|
+
this.self.highlight.setDisplayLayerForHighlight();
|
|
1113
|
+
stackMatrixTransform(this.treemap.backgroundLayer, 0, 0, 0);
|
|
986
1114
|
const factor = absWheelDelta > 3 ? 1.4 : absWheelDelta > 1 ? 1.2 : 1.1;
|
|
987
1115
|
const delta = wheelDelta > 0 ? factor : 1 / factor;
|
|
988
1116
|
self.scaleRatio *= delta;
|
|
@@ -990,11 +1118,11 @@ class SelfEvent extends RegisterModule {
|
|
|
990
1118
|
const translateY = offsetY - (offsetY - self.translateY) * delta;
|
|
991
1119
|
self.translateX = translateX;
|
|
992
1120
|
self.translateY = translateY;
|
|
993
|
-
|
|
1121
|
+
stackMatrixTransformWithGraphAndLayer(this.treemap.elements, this.self.translateX, this.self.translateY, this.self.scaleRatio);
|
|
994
1122
|
treemap.update();
|
|
995
1123
|
self.forceDestroy = false;
|
|
996
1124
|
}
|
|
997
|
-
init(app, treemap
|
|
1125
|
+
init(app, treemap) {
|
|
998
1126
|
const event = this.event;
|
|
999
1127
|
const nativeEvents = [];
|
|
1000
1128
|
const methods = [
|
|
@@ -1011,19 +1139,30 @@ class SelfEvent extends RegisterModule {
|
|
|
1011
1139
|
fn: () => event.emit.bind(event)
|
|
1012
1140
|
}
|
|
1013
1141
|
];
|
|
1014
|
-
|
|
1142
|
+
mixin(app, methods);
|
|
1015
1143
|
const selfEvents = [...primitiveEvents, "wheel"];
|
|
1016
1144
|
selfEvents.forEach((evt) => {
|
|
1017
|
-
nativeEvents.push(bindPrimitiveEvent({ treemap, self: this }, evt, event));
|
|
1145
|
+
nativeEvents.push(bindPrimitiveEvent(treemap.render.canvas, { treemap, self: this }, evt, event));
|
|
1018
1146
|
});
|
|
1019
1147
|
const selfEvt = event.bindWithContext({ treemap, self: this });
|
|
1020
1148
|
selfEvt("mousedown", this.ondragstart);
|
|
1021
1149
|
selfEvt("mousemove", this.ondragmove);
|
|
1022
1150
|
selfEvt("mouseup", this.ondragend);
|
|
1023
|
-
selfEvt("mousemove", this.onmousemove);
|
|
1024
|
-
selfEvt("mouseout", this.onmouseout);
|
|
1025
1151
|
selfEvt("wheel", this.onwheel);
|
|
1026
1152
|
applyZoomEvent({ treemap, self: this });
|
|
1153
|
+
let installHightlightEvent = false;
|
|
1154
|
+
treemap.event.on("onload:selfevent", ({ width, height, root }) => {
|
|
1155
|
+
this.highlight.init(width, height, root);
|
|
1156
|
+
if (!installHightlightEvent) {
|
|
1157
|
+
bindPrimitiveEvent(this.highlight.highlight.render.canvas, { treemap, self: this }, "mousemove", event);
|
|
1158
|
+
bindPrimitiveEvent(this.highlight.highlight.render.canvas, { treemap, self: this }, "mouseout", event);
|
|
1159
|
+
selfEvt("mousemove", this.onmousemove);
|
|
1160
|
+
selfEvt("mouseout", this.onmouseout);
|
|
1161
|
+
installHightlightEvent = true;
|
|
1162
|
+
this.highlight.setDisplayLayerForHighlight();
|
|
1163
|
+
}
|
|
1164
|
+
this.highlight.reset();
|
|
1165
|
+
});
|
|
1027
1166
|
treemap.event.on("cleanup:selfevent", () => {
|
|
1028
1167
|
this.currentNode = null;
|
|
1029
1168
|
this.scaleRatio = 1;
|
|
@@ -1032,6 +1171,7 @@ class SelfEvent extends RegisterModule {
|
|
|
1032
1171
|
this.layoutWidth = treemap.render.canvas.width;
|
|
1033
1172
|
this.layoutHeight = treemap.render.canvas.height;
|
|
1034
1173
|
this.isDragging = false;
|
|
1174
|
+
this.triggerZoom = false;
|
|
1035
1175
|
this.draggingState = { x: 0, y: 0 };
|
|
1036
1176
|
});
|
|
1037
1177
|
}
|
|
@@ -1060,17 +1200,19 @@ function estimateZoomingArea(node, root, w, h) {
|
|
|
1060
1200
|
const scaleFactor = Math.max(minScaleFactor, Math.min(maxScaleFactor, Math.sqrt(area / viewArea)));
|
|
1061
1201
|
return [w * scaleFactor, h * scaleFactor];
|
|
1062
1202
|
}
|
|
1063
|
-
function
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1203
|
+
function stackMatrixTransform(graph, e, f, scale) {
|
|
1204
|
+
graph.x = graph.x * scale + e;
|
|
1205
|
+
graph.y = graph.y * scale + f;
|
|
1206
|
+
graph.scaleX = scale;
|
|
1207
|
+
graph.scaleY = scale;
|
|
1208
|
+
}
|
|
1209
|
+
function stackMatrixTransformWithGraphAndLayer(graphs, e, f, scale) {
|
|
1210
|
+
etoile.traverse(graphs, (graph) => stackMatrixTransform(graph, e, f, scale));
|
|
1070
1211
|
}
|
|
1071
1212
|
function onZoom(ctx, node, root) {
|
|
1072
1213
|
if (!node) return;
|
|
1073
1214
|
const { treemap, self } = ctx;
|
|
1215
|
+
self.forceDestroy = true;
|
|
1074
1216
|
const c = treemap.render.canvas;
|
|
1075
1217
|
const boundingClientRect = c.getBoundingClientRect();
|
|
1076
1218
|
const [w, h] = estimateZoomingArea(node, root, boundingClientRect.width, boundingClientRect.height);
|
|
@@ -1094,10 +1236,14 @@ function onZoom(ctx, node, root) {
|
|
|
1094
1236
|
run(() => {
|
|
1095
1237
|
const elapsed = Date.now() - startTime;
|
|
1096
1238
|
const progress = Math.min(elapsed / animationDuration, 1);
|
|
1239
|
+
treemap.backgroundLayer.__refresh__ = false;
|
|
1097
1240
|
if (progress >= 1) {
|
|
1098
1241
|
stop();
|
|
1099
1242
|
self.layoutWidth = w;
|
|
1100
1243
|
self.layoutHeight = h;
|
|
1244
|
+
self.forceDestroy = false;
|
|
1245
|
+
self.triggerZoom = true;
|
|
1246
|
+
return true;
|
|
1101
1247
|
}
|
|
1102
1248
|
const easedProgress = easing.cubicInOut(progress);
|
|
1103
1249
|
const scaleRatio = initialScale + (scale - initialScale) * easedProgress;
|
|
@@ -1105,9 +1251,8 @@ function onZoom(ctx, node, root) {
|
|
|
1105
1251
|
self.translateY = initialTranslateY + (translateY - initialTranslateY) * easedProgress;
|
|
1106
1252
|
self.scaleRatio = scaleRatio;
|
|
1107
1253
|
treemap.reset();
|
|
1108
|
-
|
|
1254
|
+
stackMatrixTransformWithGraphAndLayer(treemap.elements, self.translateX, self.translateY, scaleRatio);
|
|
1109
1255
|
treemap.update();
|
|
1110
|
-
return progress >= 1;
|
|
1111
1256
|
});
|
|
1112
1257
|
}
|
|
1113
1258
|
root = node;
|
|
@@ -1115,6 +1260,40 @@ function onZoom(ctx, node, root) {
|
|
|
1115
1260
|
function isScrollWheelOrRightButtonOnMouseupAndDown(e) {
|
|
1116
1261
|
return e.which === 2 || e.which === 3;
|
|
1117
1262
|
}
|
|
1263
|
+
function createHighlight() {
|
|
1264
|
+
let s = null;
|
|
1265
|
+
const setDisplayLayerForHighlight = (layer = "-1") => {
|
|
1266
|
+
if (!s) return;
|
|
1267
|
+
const c = s.render.canvas;
|
|
1268
|
+
c.style.zIndex = layer;
|
|
1269
|
+
};
|
|
1270
|
+
const init = (w, h, root) => {
|
|
1271
|
+
if (!s) {
|
|
1272
|
+
s = new Schedule(root, { width: w, height: h });
|
|
1273
|
+
}
|
|
1274
|
+
setDisplayLayerForHighlight();
|
|
1275
|
+
s.render.canvas.style.position = "absolute";
|
|
1276
|
+
s.render.canvas.style.pointerEvents = "none";
|
|
1277
|
+
};
|
|
1278
|
+
const reset = () => {
|
|
1279
|
+
if (!s) return;
|
|
1280
|
+
s.destory();
|
|
1281
|
+
s.update();
|
|
1282
|
+
};
|
|
1283
|
+
return {
|
|
1284
|
+
init,
|
|
1285
|
+
reset,
|
|
1286
|
+
setDisplayLayerForHighlight,
|
|
1287
|
+
get highlight() {
|
|
1288
|
+
return s;
|
|
1289
|
+
}
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
function refreshBackgroundLayer(c) {
|
|
1293
|
+
const { treemap } = c;
|
|
1294
|
+
const { backgroundLayer } = treemap;
|
|
1295
|
+
backgroundLayer.__refresh__ = false;
|
|
1296
|
+
}
|
|
1118
1297
|
|
|
1119
1298
|
var __defProp = Object.defineProperty;
|
|
1120
1299
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -1169,33 +1348,32 @@ function getSafeText(c, text, width, cache) {
|
|
|
1169
1348
|
}
|
|
1170
1349
|
function resetLayout(treemap, w, h) {
|
|
1171
1350
|
treemap.layoutNodes = squarify(treemap.data, { w, h, x: 0, y: 0 }, treemap.decorator.layout);
|
|
1172
|
-
treemap.reset();
|
|
1351
|
+
treemap.reset(true);
|
|
1173
1352
|
}
|
|
1174
|
-
class
|
|
1175
|
-
}
|
|
1176
|
-
class TreemapLayout extends Schedule {
|
|
1353
|
+
class TreemapLayout extends etoile.Schedule {
|
|
1177
1354
|
constructor(...args) {
|
|
1178
1355
|
super(...args);
|
|
1179
1356
|
__publicField(this, "data");
|
|
1180
1357
|
__publicField(this, "layoutNodes");
|
|
1181
1358
|
__publicField(this, "decorator");
|
|
1182
|
-
__publicField(this, "
|
|
1359
|
+
__publicField(this, "bgLayer");
|
|
1183
1360
|
__publicField(this, "fgBox");
|
|
1184
1361
|
__publicField(this, "fontsCaches");
|
|
1185
1362
|
__publicField(this, "ellispsisWidthCache");
|
|
1186
1363
|
this.data = [];
|
|
1187
1364
|
this.layoutNodes = [];
|
|
1188
|
-
this.
|
|
1365
|
+
this.bgLayer = new Layer();
|
|
1189
1366
|
this.fgBox = new Box();
|
|
1190
1367
|
this.decorator = /* @__PURE__ */ Object.create(null);
|
|
1191
1368
|
this.fontsCaches = /* @__PURE__ */ Object.create(null);
|
|
1192
1369
|
this.ellispsisWidthCache = /* @__PURE__ */ Object.create(null);
|
|
1370
|
+
this.bgLayer.setCanvasOptions(this.render.options);
|
|
1193
1371
|
}
|
|
1194
1372
|
drawBackgroundNode(node) {
|
|
1195
1373
|
const [x, y, w, h] = node.layout;
|
|
1196
1374
|
const fill = this.decorator.color.mappings[node.node.id];
|
|
1197
1375
|
const s = createFillBlock(x, y, w, h, { fill });
|
|
1198
|
-
this.
|
|
1376
|
+
this.bgLayer.add(s);
|
|
1199
1377
|
for (const child of node.children) {
|
|
1200
1378
|
this.drawBackgroundNode(child);
|
|
1201
1379
|
}
|
|
@@ -1212,7 +1390,7 @@ class TreemapLayout extends Schedule {
|
|
|
1212
1390
|
} else {
|
|
1213
1391
|
optimalFontSize = evaluateOptimalFontSize(
|
|
1214
1392
|
this.render.ctx,
|
|
1215
|
-
node.node.
|
|
1393
|
+
node.node.label,
|
|
1216
1394
|
{
|
|
1217
1395
|
range: fontSize,
|
|
1218
1396
|
family: fontFamily
|
|
@@ -1223,7 +1401,7 @@ class TreemapLayout extends Schedule {
|
|
|
1223
1401
|
this.fontsCaches[node.node.id] = optimalFontSize;
|
|
1224
1402
|
}
|
|
1225
1403
|
this.render.ctx.font = `${optimalFontSize}px ${fontFamily}`;
|
|
1226
|
-
const result = getSafeText(this.render.ctx, node.node.
|
|
1404
|
+
const result = getSafeText(this.render.ctx, node.node.label, w - rectGap * 2, this.ellispsisWidthCache);
|
|
1227
1405
|
if (!result) return;
|
|
1228
1406
|
if (result.width >= w || optimalFontSize >= h) return;
|
|
1229
1407
|
const { text, width } = result;
|
|
@@ -1234,16 +1412,24 @@ class TreemapLayout extends Schedule {
|
|
|
1234
1412
|
this.drawForegroundNode(child);
|
|
1235
1413
|
}
|
|
1236
1414
|
}
|
|
1237
|
-
reset() {
|
|
1238
|
-
this.
|
|
1239
|
-
this.
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1415
|
+
reset(refresh = false) {
|
|
1416
|
+
this.remove(this.bgLayer, this.fgBox);
|
|
1417
|
+
if (!this.bgLayer.__refresh__) {
|
|
1418
|
+
this.bgLayer.destory();
|
|
1419
|
+
for (const node of this.layoutNodes) {
|
|
1420
|
+
this.drawBackgroundNode(node);
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
if (!this.fgBox.elements.length || refresh) {
|
|
1424
|
+
this.render.ctx.textBaseline = "middle";
|
|
1425
|
+
this.fgBox.destory();
|
|
1426
|
+
for (const node of this.layoutNodes) {
|
|
1427
|
+
this.drawForegroundNode(node);
|
|
1428
|
+
}
|
|
1429
|
+
} else {
|
|
1430
|
+
this.fgBox = this.fgBox.clone();
|
|
1245
1431
|
}
|
|
1246
|
-
this.add(this.
|
|
1432
|
+
this.add(this.bgLayer, this.fgBox);
|
|
1247
1433
|
}
|
|
1248
1434
|
get api() {
|
|
1249
1435
|
return {
|
|
@@ -1252,6 +1438,9 @@ class TreemapLayout extends Schedule {
|
|
|
1252
1438
|
}
|
|
1253
1439
|
};
|
|
1254
1440
|
}
|
|
1441
|
+
get backgroundLayer() {
|
|
1442
|
+
return this.bgLayer;
|
|
1443
|
+
}
|
|
1255
1444
|
}
|
|
1256
1445
|
function createTreemap() {
|
|
1257
1446
|
let treemap = null;
|
|
@@ -1269,6 +1458,13 @@ function createTreemap() {
|
|
|
1269
1458
|
function init(el) {
|
|
1270
1459
|
treemap = new TreemapLayout(el);
|
|
1271
1460
|
root = el;
|
|
1461
|
+
root.style.position = "relative";
|
|
1462
|
+
if (!installed) {
|
|
1463
|
+
for (const registry of defaultRegistries) {
|
|
1464
|
+
registry(context, treemap, treemap.render);
|
|
1465
|
+
}
|
|
1466
|
+
installed = true;
|
|
1467
|
+
}
|
|
1272
1468
|
}
|
|
1273
1469
|
function dispose() {
|
|
1274
1470
|
if (root && treemap) {
|
|
@@ -1281,9 +1477,15 @@ function createTreemap() {
|
|
|
1281
1477
|
function resize() {
|
|
1282
1478
|
if (!treemap || !root) return;
|
|
1283
1479
|
const { width, height } = root.getBoundingClientRect();
|
|
1480
|
+
treemap.backgroundLayer.__refresh__ = false;
|
|
1284
1481
|
treemap.render.initOptions({ height, width, devicePixelRatio: window.devicePixelRatio });
|
|
1482
|
+
treemap.render.canvas.style.position = "absolute";
|
|
1483
|
+
treemap.backgroundLayer.setCanvasOptions(treemap.render.options);
|
|
1484
|
+
treemap.backgroundLayer.initLoc();
|
|
1485
|
+
treemap.backgroundLayer.matrix = treemap.backgroundLayer.matrix.create({ a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 });
|
|
1285
1486
|
treemap.fontsCaches = /* @__PURE__ */ Object.create(null);
|
|
1286
1487
|
treemap.event.emit("cleanup:selfevent");
|
|
1488
|
+
treemap.event.emit("onload:selfevent", { width, height, root });
|
|
1287
1489
|
resetLayout(treemap, width, height);
|
|
1288
1490
|
treemap.update();
|
|
1289
1491
|
}
|
|
@@ -1292,12 +1494,6 @@ function createTreemap() {
|
|
|
1292
1494
|
throw new Error("Treemap not initialized");
|
|
1293
1495
|
}
|
|
1294
1496
|
treemap.data = bindParentForModule(options.data || []);
|
|
1295
|
-
if (!installed) {
|
|
1296
|
-
for (const registry of defaultRegistries) {
|
|
1297
|
-
registry(context, treemap, treemap.render);
|
|
1298
|
-
}
|
|
1299
|
-
installed = true;
|
|
1300
|
-
}
|
|
1301
1497
|
for (const use2 of uses) {
|
|
1302
1498
|
use2(treemap);
|
|
1303
1499
|
}
|
|
@@ -1341,54 +1537,66 @@ function presetDecorator(app) {
|
|
|
1341
1537
|
Object.assign(app.decorator, {
|
|
1342
1538
|
layout: defaultLayoutOptions,
|
|
1343
1539
|
font: defaultFontOptions,
|
|
1344
|
-
color:
|
|
1540
|
+
color: { mappings: evaluateColorMappings(app.data) }
|
|
1345
1541
|
});
|
|
1346
1542
|
}
|
|
1347
|
-
function
|
|
1348
|
-
const
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
if (node.parent) {
|
|
1353
|
-
sweepAngle = node.weight / node.parent.weight * sweepAngle;
|
|
1354
|
-
baseHue = state.hue + sweepAngle / Math.PI * 180;
|
|
1355
|
-
}
|
|
1356
|
-
baseHue += sweepAngle;
|
|
1357
|
-
const depthHueOffset = depth + totalHueRange / 10;
|
|
1358
|
-
const finalHue = baseHue + depthHueOffset / 2;
|
|
1359
|
-
const saturation = 0.6 + 0.4 * Math.max(0, Math.cos(finalHue));
|
|
1360
|
-
const lightness = 0.5 + 0.2 * Math.max(0, Math.cos(finalHue + Math.PI * 2 / 3));
|
|
1361
|
-
state.hue = baseHue;
|
|
1362
|
-
return {
|
|
1363
|
-
mode: "hsl",
|
|
1364
|
-
desc: {
|
|
1365
|
-
h: finalHue,
|
|
1366
|
-
s: Math.round(saturation * 100),
|
|
1367
|
-
l: Math.round(lightness * 100)
|
|
1368
|
-
}
|
|
1543
|
+
function evaluateColorMappings(data) {
|
|
1544
|
+
const colorMappings = {};
|
|
1545
|
+
const hashToHue = (id) => {
|
|
1546
|
+
const hash = Math.abs(hashCode(id));
|
|
1547
|
+
return hash % 360;
|
|
1369
1548
|
};
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1549
|
+
const lightScale = (depth) => 70 - depth * 5;
|
|
1550
|
+
const baseSaturation = 40;
|
|
1551
|
+
const siblingHueShift = 20;
|
|
1552
|
+
const rc = 0.2126;
|
|
1553
|
+
const gc = 0.7152;
|
|
1554
|
+
const bc = 0.0722;
|
|
1555
|
+
const hslToRgb = (h, s, l) => {
|
|
1556
|
+
const a = s * Math.min(l, 1 - l);
|
|
1557
|
+
const f = (n) => {
|
|
1558
|
+
const k = (n + h / 30) % 12;
|
|
1559
|
+
return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
1560
|
+
};
|
|
1561
|
+
return { r: f(0), g: f(8), b: f(4) };
|
|
1562
|
+
};
|
|
1563
|
+
const calculateLuminance = (r, g, b) => {
|
|
1564
|
+
return rc * r + gc * g + bc * b;
|
|
1565
|
+
};
|
|
1566
|
+
const calculateColor = (module, depth, parentHue, siblingIndex, totalSiblings) => {
|
|
1567
|
+
const nodeHue = hashToHue(module.id);
|
|
1568
|
+
const hue = parentHue !== null ? (parentHue + siblingHueShift * siblingIndex / totalSiblings) % 360 : nodeHue;
|
|
1569
|
+
const lightness = lightScale(depth);
|
|
1570
|
+
const hslColor = {
|
|
1571
|
+
h: hue,
|
|
1572
|
+
s: baseSaturation,
|
|
1573
|
+
l: lightness / 100
|
|
1574
|
+
};
|
|
1575
|
+
const { r, g, b } = hslToRgb(hslColor.h, hslColor.s / 100, hslColor.l);
|
|
1576
|
+
const luminance = calculateLuminance(r, g, b);
|
|
1577
|
+
if (luminance < 0.6) {
|
|
1578
|
+
hslColor.l += 0.2;
|
|
1579
|
+
} else if (luminance > 0.8) {
|
|
1580
|
+
hslColor.l -= 0.1;
|
|
1581
|
+
}
|
|
1582
|
+
hslColor.l *= 100;
|
|
1583
|
+
colorMappings[module.id] = {
|
|
1584
|
+
mode: "hsl",
|
|
1585
|
+
desc: hslColor
|
|
1586
|
+
};
|
|
1587
|
+
if (module.groups && Array.isArray(module.groups)) {
|
|
1588
|
+
const totalChildren = module.groups.length;
|
|
1589
|
+
for (let i = 0; i < totalChildren; i++) {
|
|
1590
|
+
const child = module.groups[i];
|
|
1591
|
+
calculateColor(child, depth + 1, hue, i, totalChildren);
|
|
1592
|
+
}
|
|
1376
1593
|
}
|
|
1377
|
-
}
|
|
1378
|
-
if (node.id) {
|
|
1379
|
-
colorMappings2[node.id] = colorDecorator(node, state);
|
|
1380
|
-
}
|
|
1381
|
-
return colorMappings2;
|
|
1382
|
-
}
|
|
1383
|
-
function colorMappings(app) {
|
|
1384
|
-
const colorMappings2 = {};
|
|
1385
|
-
const state = {
|
|
1386
|
-
hue: 0
|
|
1387
1594
|
};
|
|
1388
|
-
for (
|
|
1389
|
-
|
|
1595
|
+
for (let i = 0; i < data.length; i++) {
|
|
1596
|
+
const module = data[i];
|
|
1597
|
+
calculateColor(module, 0, null, i, data.length);
|
|
1390
1598
|
}
|
|
1391
|
-
return
|
|
1599
|
+
return colorMappings;
|
|
1392
1600
|
}
|
|
1393
1601
|
|
|
1394
1602
|
exports.TreemapLayout = TreemapLayout;
|