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