chartjs-chart-treemap 1.0.0 → 2.0.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/LICENSE +1 -1
- package/README.md +3 -2
- package/dist/chartjs-chart-treemap.esm.js +139 -51
- package/dist/chartjs-chart-treemap.js +141 -52
- package/dist/chartjs-chart-treemap.min.js +2 -2
- package/package.json +14 -14
- package/types/index.esm.d.ts +143 -0
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# chartjs-chart-treemap
|
|
2
2
|
|
|
3
|
-
[Chart.js](https://www.chartjs.org/) **v3.
|
|
3
|
+
[Chart.js](https://www.chartjs.org/) **v3.6.0** module for creating treemap charts. Implementation for Chart.js v2 is in [2.x branch](https://github.com/kurkle/chartjs-chart-treemap/tree/2.x)
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/chartjs-chart-
|
|
5
|
+
[](https://www.npmjs.com/package/chartjs-chart-treemap)
|
|
6
6
|
[](https://github.com/kurkle/chartjs-chart-treemap/releases/latest)
|
|
7
7
|

|
|
8
8
|
[](https://chartjs-chart-treemap.pages.dev)
|
|
9
9
|

|
|
10
|
+
[](https://coveralls.io/github/kurkle/chartjs-chart-treemap)
|
|
10
11
|
|
|
11
12
|

|
|
12
13
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap
|
|
2
|
+
* chartjs-chart-treemap v2.0.0
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2021 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import { toFont, valueOrDefault } from 'chart.js/helpers';
|
|
7
|
+
import { Chart, registry, DatasetController, Element } from 'chart.js';
|
|
8
|
+
import { toFont, valueOrDefault, isArray } from 'chart.js/helpers';
|
|
9
9
|
|
|
10
10
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
|
|
11
11
|
function flatten(input) {
|
|
@@ -108,6 +108,13 @@ function sum(values, key) {
|
|
|
108
108
|
return s;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
function requireVersion(min, ver) {
|
|
112
|
+
const parts = ver.split('.');
|
|
113
|
+
if (!min.split('.').reduce((a, c, i) => a && c <= parts[i], true)) {
|
|
114
|
+
throw new Error(`Chart.js v${ver} is not supported. v${min} or newer is required.`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
111
118
|
function round(v, n) {
|
|
112
119
|
// @ts-ignore
|
|
113
120
|
return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
|
|
@@ -346,7 +353,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
|
|
|
346
353
|
return flatten(rows);
|
|
347
354
|
}
|
|
348
355
|
|
|
349
|
-
var version = "
|
|
356
|
+
var version = "2.0.0";
|
|
350
357
|
|
|
351
358
|
function rectNotEqual(r1, r2) {
|
|
352
359
|
return !r1 || !r2
|
|
@@ -383,35 +390,47 @@ function shouldDrawCaption(rect, font) {
|
|
|
383
390
|
|
|
384
391
|
function drawCaption(ctx, rect, item, opts, levels) {
|
|
385
392
|
ctx.save();
|
|
386
|
-
ctx.fillStyle = opts.color;
|
|
387
|
-
ctx.font = opts.font.string;
|
|
388
393
|
ctx.beginPath();
|
|
389
394
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
390
395
|
ctx.clip();
|
|
391
396
|
if (!('l' in item) || item.l === levels) {
|
|
392
|
-
ctx.textAlign = 'center';
|
|
393
|
-
ctx.textBaseline = 'middle';
|
|
394
397
|
drawLabels(ctx, item, rect);
|
|
395
|
-
} else if (opts.
|
|
396
|
-
ctx
|
|
397
|
-
ctx.textBaseline = 'top';
|
|
398
|
-
const x = opts.rtl ? rect.x + rect.width - opts.borderWidth - 3 : rect.x + opts.borderWidth + 3;
|
|
399
|
-
ctx.fillText(item.g, x, rect.y + opts.borderWidth + 3);
|
|
398
|
+
} else if (opts.captions && opts.captions.display) {
|
|
399
|
+
drawCaptionLabel(ctx, item, rect);
|
|
400
400
|
}
|
|
401
401
|
ctx.restore();
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
+
function drawCaptionLabel(ctx, item, rect) {
|
|
405
|
+
const opts = rect.options;
|
|
406
|
+
const captionsOpts = opts.captions || {};
|
|
407
|
+
const borderWidth = opts.borderWidth || 0;
|
|
408
|
+
const spacing = valueOrDefault(opts.spacing, 0) + borderWidth;
|
|
409
|
+
const color = (rect.active ? captionsOpts.hoverColor : captionsOpts.color) || captionsOpts.color;
|
|
410
|
+
const padding = captionsOpts.padding;
|
|
411
|
+
const align = captionsOpts.align || (opts.rtl ? 'right' : 'left');
|
|
412
|
+
const optFont = (rect.active ? captionsOpts.hoverFont : captionsOpts.font) || captionsOpts.font;
|
|
413
|
+
const font = toFont(optFont);
|
|
414
|
+
const x = calculateX(rect, align, padding, borderWidth);
|
|
415
|
+
ctx.fillStyle = color;
|
|
416
|
+
ctx.font = font.string;
|
|
417
|
+
ctx.textAlign = align;
|
|
418
|
+
ctx.textBaseline = 'middle';
|
|
419
|
+
ctx.fillText(captionsOpts.formatter || item.g, x, rect.y + padding + spacing + (font.lineHeight / 2));
|
|
420
|
+
}
|
|
421
|
+
|
|
404
422
|
function drawDivider(ctx, rect) {
|
|
405
423
|
const opts = rect.options;
|
|
424
|
+
const dividersOpts = opts.dividers || {};
|
|
406
425
|
const w = rect.width || rect.w;
|
|
407
426
|
const h = rect.height || rect.h;
|
|
408
427
|
|
|
409
428
|
ctx.save();
|
|
410
|
-
ctx.strokeStyle =
|
|
411
|
-
ctx.lineCap =
|
|
412
|
-
ctx.setLineDash(
|
|
413
|
-
ctx.lineDashOffset =
|
|
414
|
-
ctx.lineWidth =
|
|
429
|
+
ctx.strokeStyle = dividersOpts.lineColor || 'black';
|
|
430
|
+
ctx.lineCap = dividersOpts.lineCapStyle;
|
|
431
|
+
ctx.setLineDash(dividersOpts.lineDash || []);
|
|
432
|
+
ctx.lineDashOffset = dividersOpts.lineDashOffset;
|
|
433
|
+
ctx.lineWidth = dividersOpts.lineWidth;
|
|
415
434
|
ctx.beginPath();
|
|
416
435
|
if (w > h) {
|
|
417
436
|
const w2 = w / 2;
|
|
@@ -426,12 +445,15 @@ function drawDivider(ctx, rect) {
|
|
|
426
445
|
ctx.restore();
|
|
427
446
|
}
|
|
428
447
|
|
|
429
|
-
function buildData(dataset, mainRect,
|
|
448
|
+
function buildData(dataset, mainRect, captions) {
|
|
430
449
|
const key = dataset.key || '';
|
|
431
450
|
let tree = dataset.tree || [];
|
|
432
451
|
const groups = dataset.groups || [];
|
|
433
452
|
const glen = groups.length;
|
|
434
|
-
const sp = (dataset.spacing
|
|
453
|
+
const sp = valueOrDefault(dataset.spacing, 0) + valueOrDefault(dataset.borderWidth, 0);
|
|
454
|
+
const captionsFont = captions.font || {};
|
|
455
|
+
const font = toFont(captionsFont);
|
|
456
|
+
const padding = valueOrDefault(captions.padding, 3);
|
|
435
457
|
|
|
436
458
|
function recur(gidx, rect, parent, gs) {
|
|
437
459
|
const g = groups[gidx];
|
|
@@ -443,10 +465,9 @@ function buildData(dataset, mainRect, font) {
|
|
|
443
465
|
if (gidx < glen - 1) {
|
|
444
466
|
gsq.forEach((sq) => {
|
|
445
467
|
subRect = {x: sq.x + sp, y: sq.y + sp, w: sq.w - 2 * sp, h: sq.h - 2 * sp};
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
subRect.
|
|
449
|
-
subRect.h -= font.lineHeight;
|
|
468
|
+
if (valueOrDefault(captions.display, true) && shouldDrawCaption(sq, font)) {
|
|
469
|
+
subRect.y += font.lineHeight + padding * 2;
|
|
470
|
+
subRect.h -= font.lineHeight + padding * 2;
|
|
450
471
|
}
|
|
451
472
|
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
|
|
452
473
|
});
|
|
@@ -465,10 +486,49 @@ function buildData(dataset, mainRect, font) {
|
|
|
465
486
|
|
|
466
487
|
function drawLabels(ctx, item, rect) {
|
|
467
488
|
const opts = rect.options;
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
489
|
+
const labelsOpts = opts.labels;
|
|
490
|
+
if (!labelsOpts || !labelsOpts.display) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const optColor = (rect.active ? labelsOpts.hoverColor : labelsOpts.color) || labelsOpts.color;
|
|
494
|
+
const optFont = (rect.active ? labelsOpts.hoverFont : labelsOpts.font) || labelsOpts.font;
|
|
495
|
+
const font = toFont(optFont);
|
|
496
|
+
const lh = font.lineHeight;
|
|
497
|
+
const label = labelsOpts.formatter;
|
|
498
|
+
if (label) {
|
|
499
|
+
const labels = isArray(label) ? label : [label];
|
|
500
|
+
const xyPoint = calculateXYLabel(opts, rect, labels, lh);
|
|
501
|
+
ctx.font = font.string;
|
|
502
|
+
ctx.textAlign = labelsOpts.align;
|
|
503
|
+
ctx.textBaseline = labelsOpts.position;
|
|
504
|
+
ctx.fillStyle = optColor;
|
|
505
|
+
labels.forEach((l, i) => ctx.fillText(l, xyPoint.x, xyPoint.y + i * lh));
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function calculateXYLabel(options, rect, labels, lineHeight) {
|
|
510
|
+
const labelsOpts = options.labels;
|
|
511
|
+
const borderWidth = options.borderWidth || 0;
|
|
512
|
+
const {align, position, padding} = labelsOpts;
|
|
513
|
+
let x, y;
|
|
514
|
+
x = calculateX(rect, align, padding, borderWidth);
|
|
515
|
+
if (position === 'top') {
|
|
516
|
+
y = rect.y + padding + borderWidth;
|
|
517
|
+
} else if (position === 'bottom') {
|
|
518
|
+
y = rect.y + rect.height - padding - borderWidth - (labels.length - 1) * lineHeight;
|
|
519
|
+
} else {
|
|
520
|
+
y = rect.y + rect.height / 2 - labels.length * lineHeight / 4;
|
|
521
|
+
}
|
|
522
|
+
return {x, y};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function calculateX(rect, align, padding, borderWidth) {
|
|
526
|
+
if (align === 'left') {
|
|
527
|
+
return rect.x + padding + borderWidth;
|
|
528
|
+
} else if (align === 'right') {
|
|
529
|
+
return rect.x + rect.width - padding - borderWidth;
|
|
530
|
+
}
|
|
531
|
+
return rect.x + rect.width / 2;
|
|
472
532
|
}
|
|
473
533
|
|
|
474
534
|
class TreemapController extends DatasetController {
|
|
@@ -490,7 +550,7 @@ class TreemapController extends DatasetController {
|
|
|
490
550
|
const meta = me.getMeta();
|
|
491
551
|
const dataset = me.getDataset();
|
|
492
552
|
const groups = dataset.groups || (dataset.groups = []);
|
|
493
|
-
const
|
|
553
|
+
const captions = dataset.captions ? dataset.captions : {};
|
|
494
554
|
const area = me.chart.chartArea;
|
|
495
555
|
const key = dataset.key || '';
|
|
496
556
|
const rtl = !!dataset.rtl;
|
|
@@ -501,7 +561,8 @@ class TreemapController extends DatasetController {
|
|
|
501
561
|
me._rect = mainRect;
|
|
502
562
|
me._groups = groups.slice();
|
|
503
563
|
me._key = key;
|
|
504
|
-
|
|
564
|
+
|
|
565
|
+
dataset.data = buildData(dataset, mainRect, captions);
|
|
505
566
|
// @ts-ignore using private stuff
|
|
506
567
|
me._dataCheck();
|
|
507
568
|
// @ts-ignore using private stuff
|
|
@@ -514,7 +575,7 @@ class TreemapController extends DatasetController {
|
|
|
514
575
|
resolveDataElementOptions(index, mode) {
|
|
515
576
|
const options = super.resolveDataElementOptions(index, mode);
|
|
516
577
|
const result = Object.isFrozen(options) ? Object.assign({}, options) : options;
|
|
517
|
-
result.font = toFont(options.font);
|
|
578
|
+
result.font = toFont(options.captions.font);
|
|
518
579
|
return result;
|
|
519
580
|
}
|
|
520
581
|
|
|
@@ -553,13 +614,11 @@ class TreemapController extends DatasetController {
|
|
|
553
614
|
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
|
|
554
615
|
const rect = metadata[i];
|
|
555
616
|
const item = data[i];
|
|
556
|
-
|
|
617
|
+
const dividersOpts = rect.options.dividers || {};
|
|
618
|
+
if (dividersOpts.display && item._data.children.length > 1) {
|
|
557
619
|
drawDivider(ctx, rect);
|
|
558
620
|
}
|
|
559
621
|
}
|
|
560
|
-
if (this.getDataset().groupDividers) {
|
|
561
|
-
drawDivider(ctx, this._rect);
|
|
562
|
-
}
|
|
563
622
|
}
|
|
564
623
|
|
|
565
624
|
_drawRects(ctx, data, metadata, levels) {
|
|
@@ -569,7 +628,7 @@ class TreemapController extends DatasetController {
|
|
|
569
628
|
if (!rect.hidden) {
|
|
570
629
|
rect.draw(ctx);
|
|
571
630
|
const opts = rect.options;
|
|
572
|
-
if (shouldDrawCaption(rect, opts.font)
|
|
631
|
+
if (shouldDrawCaption(rect, opts.captions.font)) {
|
|
573
632
|
drawCaption(ctx, rect, item, opts, levels);
|
|
574
633
|
}
|
|
575
634
|
}
|
|
@@ -596,14 +655,20 @@ TreemapController.version = version;
|
|
|
596
655
|
TreemapController.defaults = {
|
|
597
656
|
dataElementType: 'treemap',
|
|
598
657
|
|
|
599
|
-
groupLabels: true,
|
|
600
658
|
borderWidth: 0,
|
|
601
659
|
spacing: 0.5,
|
|
602
|
-
|
|
603
|
-
|
|
660
|
+
dividers: {
|
|
661
|
+
display: false,
|
|
662
|
+
lineWidth: 1,
|
|
663
|
+
}
|
|
604
664
|
|
|
605
665
|
};
|
|
606
666
|
|
|
667
|
+
TreemapController.descriptors = {
|
|
668
|
+
_scriptable: true,
|
|
669
|
+
_indexable: false
|
|
670
|
+
};
|
|
671
|
+
|
|
607
672
|
TreemapController.overrides = {
|
|
608
673
|
interaction: {
|
|
609
674
|
mode: 'point',
|
|
@@ -645,6 +710,10 @@ TreemapController.overrides = {
|
|
|
645
710
|
},
|
|
646
711
|
};
|
|
647
712
|
|
|
713
|
+
TreemapController.beforeRegister = function() {
|
|
714
|
+
requireVersion('3.6', Chart.version);
|
|
715
|
+
};
|
|
716
|
+
|
|
648
717
|
TreemapController.afterRegister = function() {
|
|
649
718
|
const tooltipPlugin = registry.plugins.get('tooltip');
|
|
650
719
|
if (tooltipPlugin) {
|
|
@@ -769,7 +838,6 @@ class TreemapElement extends Element {
|
|
|
769
838
|
ctx.fillStyle = options.backgroundColor;
|
|
770
839
|
ctx.fillRect(inner.x, inner.y, inner.w, inner.h);
|
|
771
840
|
}
|
|
772
|
-
|
|
773
841
|
ctx.restore();
|
|
774
842
|
}
|
|
775
843
|
|
|
@@ -805,20 +873,40 @@ class TreemapElement extends Element {
|
|
|
805
873
|
TreemapElement.id = 'treemap';
|
|
806
874
|
|
|
807
875
|
TreemapElement.defaults = {
|
|
808
|
-
borderSkipped: undefined,
|
|
809
876
|
borderWidth: undefined,
|
|
810
|
-
color: undefined,
|
|
811
|
-
dividerCapStyle: 'butt',
|
|
812
|
-
dividerColor: 'black',
|
|
813
|
-
dividerDash: undefined,
|
|
814
|
-
dividerDashOffset: 0,
|
|
815
|
-
dividerWidth: 0,
|
|
816
|
-
font: {},
|
|
817
|
-
groupDividers: false,
|
|
818
|
-
groupLabels: undefined,
|
|
819
877
|
spacing: undefined,
|
|
820
878
|
label: undefined,
|
|
821
|
-
rtl: undefined
|
|
879
|
+
rtl: undefined,
|
|
880
|
+
dividers: {
|
|
881
|
+
display: false,
|
|
882
|
+
lineCapStyle: 'butt',
|
|
883
|
+
lineColor: 'black',
|
|
884
|
+
lineDash: undefined,
|
|
885
|
+
lineDashOffset: 0,
|
|
886
|
+
lineWidth: 0,
|
|
887
|
+
},
|
|
888
|
+
captions: {
|
|
889
|
+
align: undefined,
|
|
890
|
+
color: undefined,
|
|
891
|
+
display: true,
|
|
892
|
+
formatter: (ctx) => ctx.raw.g || '',
|
|
893
|
+
font: {},
|
|
894
|
+
padding: 3
|
|
895
|
+
},
|
|
896
|
+
labels: {
|
|
897
|
+
align: 'center',
|
|
898
|
+
color: undefined,
|
|
899
|
+
display: false,
|
|
900
|
+
formatter: (ctx) => ctx.raw.g ? [ctx.raw.g, ctx.raw.v] : ctx.raw.v,
|
|
901
|
+
font: {},
|
|
902
|
+
position: 'middle',
|
|
903
|
+
padding: 3
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
TreemapElement.descriptors = {
|
|
908
|
+
_scriptable: true,
|
|
909
|
+
_indexable: false
|
|
822
910
|
};
|
|
823
911
|
|
|
824
912
|
TreemapElement.defaultRoutes = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap
|
|
2
|
+
* chartjs-chart-treemap v2.0.0
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2021 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
(function (global, factory) {
|
|
8
8
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('chart.js'), require('chart.js/helpers')) :
|
|
9
9
|
typeof define === 'function' && define.amd ? define(['exports', 'chart.js', 'chart.js/helpers'], factory) :
|
|
10
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global[
|
|
11
|
-
}(this, (function (exports, chart_js, helpers) { 'use strict';
|
|
10
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["chartjs-chart-treemap"] = {}, global.Chart, global.Chart.helpers));
|
|
11
|
+
})(this, (function (exports, chart_js, helpers) { 'use strict';
|
|
12
12
|
|
|
13
13
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
|
|
14
14
|
function flatten(input) {
|
|
@@ -111,6 +111,13 @@ function sum(values, key) {
|
|
|
111
111
|
return s;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
function requireVersion(min, ver) {
|
|
115
|
+
const parts = ver.split('.');
|
|
116
|
+
if (!min.split('.').reduce((a, c, i) => a && c <= parts[i], true)) {
|
|
117
|
+
throw new Error(`Chart.js v${ver} is not supported. v${min} or newer is required.`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
114
121
|
function round(v, n) {
|
|
115
122
|
// @ts-ignore
|
|
116
123
|
return (+(Math.round(v + 'e+' + n) + 'e-' + n)) || 0;
|
|
@@ -349,7 +356,7 @@ function squarify(values, rectangle, key, grp, lvl, gsum) {
|
|
|
349
356
|
return flatten(rows);
|
|
350
357
|
}
|
|
351
358
|
|
|
352
|
-
var version = "
|
|
359
|
+
var version = "2.0.0";
|
|
353
360
|
|
|
354
361
|
function rectNotEqual(r1, r2) {
|
|
355
362
|
return !r1 || !r2
|
|
@@ -386,35 +393,47 @@ function shouldDrawCaption(rect, font) {
|
|
|
386
393
|
|
|
387
394
|
function drawCaption(ctx, rect, item, opts, levels) {
|
|
388
395
|
ctx.save();
|
|
389
|
-
ctx.fillStyle = opts.color;
|
|
390
|
-
ctx.font = opts.font.string;
|
|
391
396
|
ctx.beginPath();
|
|
392
397
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
393
398
|
ctx.clip();
|
|
394
399
|
if (!('l' in item) || item.l === levels) {
|
|
395
|
-
ctx.textAlign = 'center';
|
|
396
|
-
ctx.textBaseline = 'middle';
|
|
397
400
|
drawLabels(ctx, item, rect);
|
|
398
|
-
} else if (opts.
|
|
399
|
-
ctx
|
|
400
|
-
ctx.textBaseline = 'top';
|
|
401
|
-
const x = opts.rtl ? rect.x + rect.width - opts.borderWidth - 3 : rect.x + opts.borderWidth + 3;
|
|
402
|
-
ctx.fillText(item.g, x, rect.y + opts.borderWidth + 3);
|
|
401
|
+
} else if (opts.captions && opts.captions.display) {
|
|
402
|
+
drawCaptionLabel(ctx, item, rect);
|
|
403
403
|
}
|
|
404
404
|
ctx.restore();
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
+
function drawCaptionLabel(ctx, item, rect) {
|
|
408
|
+
const opts = rect.options;
|
|
409
|
+
const captionsOpts = opts.captions || {};
|
|
410
|
+
const borderWidth = opts.borderWidth || 0;
|
|
411
|
+
const spacing = helpers.valueOrDefault(opts.spacing, 0) + borderWidth;
|
|
412
|
+
const color = (rect.active ? captionsOpts.hoverColor : captionsOpts.color) || captionsOpts.color;
|
|
413
|
+
const padding = captionsOpts.padding;
|
|
414
|
+
const align = captionsOpts.align || (opts.rtl ? 'right' : 'left');
|
|
415
|
+
const optFont = (rect.active ? captionsOpts.hoverFont : captionsOpts.font) || captionsOpts.font;
|
|
416
|
+
const font = helpers.toFont(optFont);
|
|
417
|
+
const x = calculateX(rect, align, padding, borderWidth);
|
|
418
|
+
ctx.fillStyle = color;
|
|
419
|
+
ctx.font = font.string;
|
|
420
|
+
ctx.textAlign = align;
|
|
421
|
+
ctx.textBaseline = 'middle';
|
|
422
|
+
ctx.fillText(captionsOpts.formatter || item.g, x, rect.y + padding + spacing + (font.lineHeight / 2));
|
|
423
|
+
}
|
|
424
|
+
|
|
407
425
|
function drawDivider(ctx, rect) {
|
|
408
426
|
const opts = rect.options;
|
|
427
|
+
const dividersOpts = opts.dividers || {};
|
|
409
428
|
const w = rect.width || rect.w;
|
|
410
429
|
const h = rect.height || rect.h;
|
|
411
430
|
|
|
412
431
|
ctx.save();
|
|
413
|
-
ctx.strokeStyle =
|
|
414
|
-
ctx.lineCap =
|
|
415
|
-
ctx.setLineDash(
|
|
416
|
-
ctx.lineDashOffset =
|
|
417
|
-
ctx.lineWidth =
|
|
432
|
+
ctx.strokeStyle = dividersOpts.lineColor || 'black';
|
|
433
|
+
ctx.lineCap = dividersOpts.lineCapStyle;
|
|
434
|
+
ctx.setLineDash(dividersOpts.lineDash || []);
|
|
435
|
+
ctx.lineDashOffset = dividersOpts.lineDashOffset;
|
|
436
|
+
ctx.lineWidth = dividersOpts.lineWidth;
|
|
418
437
|
ctx.beginPath();
|
|
419
438
|
if (w > h) {
|
|
420
439
|
const w2 = w / 2;
|
|
@@ -429,12 +448,15 @@ function drawDivider(ctx, rect) {
|
|
|
429
448
|
ctx.restore();
|
|
430
449
|
}
|
|
431
450
|
|
|
432
|
-
function buildData(dataset, mainRect,
|
|
451
|
+
function buildData(dataset, mainRect, captions) {
|
|
433
452
|
const key = dataset.key || '';
|
|
434
453
|
let tree = dataset.tree || [];
|
|
435
454
|
const groups = dataset.groups || [];
|
|
436
455
|
const glen = groups.length;
|
|
437
|
-
const sp = (dataset.spacing
|
|
456
|
+
const sp = helpers.valueOrDefault(dataset.spacing, 0) + helpers.valueOrDefault(dataset.borderWidth, 0);
|
|
457
|
+
const captionsFont = captions.font || {};
|
|
458
|
+
const font = helpers.toFont(captionsFont);
|
|
459
|
+
const padding = helpers.valueOrDefault(captions.padding, 3);
|
|
438
460
|
|
|
439
461
|
function recur(gidx, rect, parent, gs) {
|
|
440
462
|
const g = groups[gidx];
|
|
@@ -446,10 +468,9 @@ function buildData(dataset, mainRect, font) {
|
|
|
446
468
|
if (gidx < glen - 1) {
|
|
447
469
|
gsq.forEach((sq) => {
|
|
448
470
|
subRect = {x: sq.x + sp, y: sq.y + sp, w: sq.w - 2 * sp, h: sq.h - 2 * sp};
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
subRect.
|
|
452
|
-
subRect.h -= font.lineHeight;
|
|
471
|
+
if (helpers.valueOrDefault(captions.display, true) && shouldDrawCaption(sq, font)) {
|
|
472
|
+
subRect.y += font.lineHeight + padding * 2;
|
|
473
|
+
subRect.h -= font.lineHeight + padding * 2;
|
|
453
474
|
}
|
|
454
475
|
ret.push(...recur(gidx + 1, subRect, sq.g, sq.s));
|
|
455
476
|
});
|
|
@@ -468,10 +489,49 @@ function buildData(dataset, mainRect, font) {
|
|
|
468
489
|
|
|
469
490
|
function drawLabels(ctx, item, rect) {
|
|
470
491
|
const opts = rect.options;
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
492
|
+
const labelsOpts = opts.labels;
|
|
493
|
+
if (!labelsOpts || !labelsOpts.display) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const optColor = (rect.active ? labelsOpts.hoverColor : labelsOpts.color) || labelsOpts.color;
|
|
497
|
+
const optFont = (rect.active ? labelsOpts.hoverFont : labelsOpts.font) || labelsOpts.font;
|
|
498
|
+
const font = helpers.toFont(optFont);
|
|
499
|
+
const lh = font.lineHeight;
|
|
500
|
+
const label = labelsOpts.formatter;
|
|
501
|
+
if (label) {
|
|
502
|
+
const labels = helpers.isArray(label) ? label : [label];
|
|
503
|
+
const xyPoint = calculateXYLabel(opts, rect, labels, lh);
|
|
504
|
+
ctx.font = font.string;
|
|
505
|
+
ctx.textAlign = labelsOpts.align;
|
|
506
|
+
ctx.textBaseline = labelsOpts.position;
|
|
507
|
+
ctx.fillStyle = optColor;
|
|
508
|
+
labels.forEach((l, i) => ctx.fillText(l, xyPoint.x, xyPoint.y + i * lh));
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function calculateXYLabel(options, rect, labels, lineHeight) {
|
|
513
|
+
const labelsOpts = options.labels;
|
|
514
|
+
const borderWidth = options.borderWidth || 0;
|
|
515
|
+
const {align, position, padding} = labelsOpts;
|
|
516
|
+
let x, y;
|
|
517
|
+
x = calculateX(rect, align, padding, borderWidth);
|
|
518
|
+
if (position === 'top') {
|
|
519
|
+
y = rect.y + padding + borderWidth;
|
|
520
|
+
} else if (position === 'bottom') {
|
|
521
|
+
y = rect.y + rect.height - padding - borderWidth - (labels.length - 1) * lineHeight;
|
|
522
|
+
} else {
|
|
523
|
+
y = rect.y + rect.height / 2 - labels.length * lineHeight / 4;
|
|
524
|
+
}
|
|
525
|
+
return {x, y};
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function calculateX(rect, align, padding, borderWidth) {
|
|
529
|
+
if (align === 'left') {
|
|
530
|
+
return rect.x + padding + borderWidth;
|
|
531
|
+
} else if (align === 'right') {
|
|
532
|
+
return rect.x + rect.width - padding - borderWidth;
|
|
533
|
+
}
|
|
534
|
+
return rect.x + rect.width / 2;
|
|
475
535
|
}
|
|
476
536
|
|
|
477
537
|
class TreemapController extends chart_js.DatasetController {
|
|
@@ -493,7 +553,7 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
493
553
|
const meta = me.getMeta();
|
|
494
554
|
const dataset = me.getDataset();
|
|
495
555
|
const groups = dataset.groups || (dataset.groups = []);
|
|
496
|
-
const
|
|
556
|
+
const captions = dataset.captions ? dataset.captions : {};
|
|
497
557
|
const area = me.chart.chartArea;
|
|
498
558
|
const key = dataset.key || '';
|
|
499
559
|
const rtl = !!dataset.rtl;
|
|
@@ -504,7 +564,8 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
504
564
|
me._rect = mainRect;
|
|
505
565
|
me._groups = groups.slice();
|
|
506
566
|
me._key = key;
|
|
507
|
-
|
|
567
|
+
|
|
568
|
+
dataset.data = buildData(dataset, mainRect, captions);
|
|
508
569
|
// @ts-ignore using private stuff
|
|
509
570
|
me._dataCheck();
|
|
510
571
|
// @ts-ignore using private stuff
|
|
@@ -517,7 +578,7 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
517
578
|
resolveDataElementOptions(index, mode) {
|
|
518
579
|
const options = super.resolveDataElementOptions(index, mode);
|
|
519
580
|
const result = Object.isFrozen(options) ? Object.assign({}, options) : options;
|
|
520
|
-
result.font = helpers.toFont(options.font);
|
|
581
|
+
result.font = helpers.toFont(options.captions.font);
|
|
521
582
|
return result;
|
|
522
583
|
}
|
|
523
584
|
|
|
@@ -556,13 +617,11 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
556
617
|
for (let i = 0, ilen = metadata.length; i < ilen; ++i) {
|
|
557
618
|
const rect = metadata[i];
|
|
558
619
|
const item = data[i];
|
|
559
|
-
|
|
620
|
+
const dividersOpts = rect.options.dividers || {};
|
|
621
|
+
if (dividersOpts.display && item._data.children.length > 1) {
|
|
560
622
|
drawDivider(ctx, rect);
|
|
561
623
|
}
|
|
562
624
|
}
|
|
563
|
-
if (this.getDataset().groupDividers) {
|
|
564
|
-
drawDivider(ctx, this._rect);
|
|
565
|
-
}
|
|
566
625
|
}
|
|
567
626
|
|
|
568
627
|
_drawRects(ctx, data, metadata, levels) {
|
|
@@ -572,7 +631,7 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
572
631
|
if (!rect.hidden) {
|
|
573
632
|
rect.draw(ctx);
|
|
574
633
|
const opts = rect.options;
|
|
575
|
-
if (shouldDrawCaption(rect, opts.font)
|
|
634
|
+
if (shouldDrawCaption(rect, opts.captions.font)) {
|
|
576
635
|
drawCaption(ctx, rect, item, opts, levels);
|
|
577
636
|
}
|
|
578
637
|
}
|
|
@@ -599,14 +658,20 @@ TreemapController.version = version;
|
|
|
599
658
|
TreemapController.defaults = {
|
|
600
659
|
dataElementType: 'treemap',
|
|
601
660
|
|
|
602
|
-
groupLabels: true,
|
|
603
661
|
borderWidth: 0,
|
|
604
662
|
spacing: 0.5,
|
|
605
|
-
|
|
606
|
-
|
|
663
|
+
dividers: {
|
|
664
|
+
display: false,
|
|
665
|
+
lineWidth: 1,
|
|
666
|
+
}
|
|
607
667
|
|
|
608
668
|
};
|
|
609
669
|
|
|
670
|
+
TreemapController.descriptors = {
|
|
671
|
+
_scriptable: true,
|
|
672
|
+
_indexable: false
|
|
673
|
+
};
|
|
674
|
+
|
|
610
675
|
TreemapController.overrides = {
|
|
611
676
|
interaction: {
|
|
612
677
|
mode: 'point',
|
|
@@ -648,6 +713,10 @@ TreemapController.overrides = {
|
|
|
648
713
|
},
|
|
649
714
|
};
|
|
650
715
|
|
|
716
|
+
TreemapController.beforeRegister = function() {
|
|
717
|
+
requireVersion('3.6', chart_js.Chart.version);
|
|
718
|
+
};
|
|
719
|
+
|
|
651
720
|
TreemapController.afterRegister = function() {
|
|
652
721
|
const tooltipPlugin = chart_js.registry.plugins.get('tooltip');
|
|
653
722
|
if (tooltipPlugin) {
|
|
@@ -772,7 +841,6 @@ class TreemapElement extends chart_js.Element {
|
|
|
772
841
|
ctx.fillStyle = options.backgroundColor;
|
|
773
842
|
ctx.fillRect(inner.x, inner.y, inner.w, inner.h);
|
|
774
843
|
}
|
|
775
|
-
|
|
776
844
|
ctx.restore();
|
|
777
845
|
}
|
|
778
846
|
|
|
@@ -808,20 +876,40 @@ class TreemapElement extends chart_js.Element {
|
|
|
808
876
|
TreemapElement.id = 'treemap';
|
|
809
877
|
|
|
810
878
|
TreemapElement.defaults = {
|
|
811
|
-
borderSkipped: undefined,
|
|
812
879
|
borderWidth: undefined,
|
|
813
|
-
color: undefined,
|
|
814
|
-
dividerCapStyle: 'butt',
|
|
815
|
-
dividerColor: 'black',
|
|
816
|
-
dividerDash: undefined,
|
|
817
|
-
dividerDashOffset: 0,
|
|
818
|
-
dividerWidth: 0,
|
|
819
|
-
font: {},
|
|
820
|
-
groupDividers: false,
|
|
821
|
-
groupLabels: undefined,
|
|
822
880
|
spacing: undefined,
|
|
823
881
|
label: undefined,
|
|
824
|
-
rtl: undefined
|
|
882
|
+
rtl: undefined,
|
|
883
|
+
dividers: {
|
|
884
|
+
display: false,
|
|
885
|
+
lineCapStyle: 'butt',
|
|
886
|
+
lineColor: 'black',
|
|
887
|
+
lineDash: undefined,
|
|
888
|
+
lineDashOffset: 0,
|
|
889
|
+
lineWidth: 0,
|
|
890
|
+
},
|
|
891
|
+
captions: {
|
|
892
|
+
align: undefined,
|
|
893
|
+
color: undefined,
|
|
894
|
+
display: true,
|
|
895
|
+
formatter: (ctx) => ctx.raw.g || '',
|
|
896
|
+
font: {},
|
|
897
|
+
padding: 3
|
|
898
|
+
},
|
|
899
|
+
labels: {
|
|
900
|
+
align: 'center',
|
|
901
|
+
color: undefined,
|
|
902
|
+
display: false,
|
|
903
|
+
formatter: (ctx) => ctx.raw.g ? [ctx.raw.g, ctx.raw.v] : ctx.raw.v,
|
|
904
|
+
font: {},
|
|
905
|
+
position: 'middle',
|
|
906
|
+
padding: 3
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
TreemapElement.descriptors = {
|
|
911
|
+
_scriptable: true,
|
|
912
|
+
_indexable: false
|
|
825
913
|
};
|
|
826
914
|
|
|
827
915
|
TreemapElement.defaultRoutes = {
|
|
@@ -835,9 +923,10 @@ exports.flatten = flatten;
|
|
|
835
923
|
exports.group = group;
|
|
836
924
|
exports.index = index;
|
|
837
925
|
exports.isObject = isObject;
|
|
926
|
+
exports.requireVersion = requireVersion;
|
|
838
927
|
exports.sort = sort;
|
|
839
928
|
exports.sum = sum;
|
|
840
929
|
|
|
841
930
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
842
931
|
|
|
843
|
-
}))
|
|
932
|
+
}));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap
|
|
2
|
+
* chartjs-chart-treemap v2.0.0
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2021 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
6
6
|
*/
|
|
7
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["exports","chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["chartjs-chart-treemap"]={},t.Chart,t.Chart.helpers)}(this,(function(t,e,i){"use strict";function n(t){const e=[...t],i=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):i.push(t)}return i.reverse()}function r(t,e,i,n,r){const o=Object.create(null),s=Object.create(null),a=[];let l,h,u,d;for(h=0,u=t.length;h<u;++h)d=t[h],n&&d[n]!==r||(l=d[e]||"",l in o||(o[l]=0,s[l]=[]),o[l]+=+d[i],s[l].push(d));return Object.keys(o).forEach((t=>{d={children:s[t]},d[i]=+o[t],d[e]=t,n&&(d[n]=r),a.push(d)})),a}function o(t){const e=typeof t;return"function"===e||"object"===e&&!!t}function s(t,e){let i,n=t.length;if(!n)return e;const r=o(t[0]);for(e=r?e:"v",i=0,n=t.length;i<n;++i)r?t[i]._idx=i:t[i]={v:t[i],_idx:i};return e}function a(t,e){e?t.sort(((t,i)=>+i[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function l(t,e){let i,n,r;for(i=0,n=0,r=t.length;n<r;++n)i+=e?+t[n][e]:+t[n];return i}function h(t,e){return+(Math.round(t+"e+"+e)+"e-"+e)||0}function u(t,e,i,n){const r=t._normalized,o=e*r/i,s=Math.sqrt(r*o),a=r/s;return{d1:s,d2:a,w:"_ix"===n?s:a,h:"_ix"===n?a:s}}const d=(t,e)=>h(t.rtl?t.x+t.w-t._ix-e:t.x+t._ix,4);function c(t,e,i,n){const r={x:d(t,i.w),y:h(t.y+t._iy,4),w:h(i.w,4),h:h(i.h,4),a:h(e._normalized,4),v:e.value,s:n,_data:e._data};return e.group&&(r.g=e.group,r.l=e.level,r.gs=e.groupSum),r}class g{constructor(t){const e=this;t=t||{w:1,h:1},e.rtl=!!t.rtl,e.x=t.x||t.left||0,e.y=t.y||t.top||0,e._ix=0,e._iy=0,e.w=t.w||t.width||t.right-t.left,e.h=t.h||t.height||t.bottom-t.top}get area(){return this.w*this.h}get iw(){return this.w-this._ix}get ih(){return this.h-this._iy}get dir(){const t=this.ih;return t<=this.iw&&t>0?"y":"x"}get side(){return"x"===this.dir?this.iw:this.ih}map(t){const e=this,i=[],n=t.nsum,r=t.get(),o=e.dir,s=e.side,a=s*s,l="x"===o?"_ix":"_iy",h=n*n;let d=0,g=0;for(const n of r){const r=u(n,a,h,l);g+=r.d1,d=Math.max(d,r.d2),i.push(c(e,n,r,t.sum)),e[l]+=r.d1}return e["y"===o?"_ix":"_iy"]+=d,e[l]-=g,i}}const p=Math.min,f=Math.max;function m(t,e){const i=+e[t.key],n=i*t.ratio;return e._normalized=n,{min:p(t.min,i),max:f(t.max,i),sum:t.sum+i,nmin:p(t.nmin,n),nmax:f(t.nmax,n),nsum:t.nsum+n}}function x(t,e,i){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,i)}class y{constructor(t,e){const i=this;i.key=t,i.ratio=e,i.reset()}get length(){return this._arr.length}reset(){const t=this;t._arr=[],t._hist=[],t.sum=0,t.nsum=0,t.min=1/0,t.max=-1/0,t.nmin=1/0,t.nmax=-1/0}push(t){x(this,t,m(this,t))}pushIf(t,e,...i){const n=m(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),n,i))return t;var r;x(this,t,n)}get(){return this._arr}}function v(t,e,i){if(0===t.sum)return!0;const[n]=i,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=n*n,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function b(t,e,i,r,o,h){t=t||[];const u=[],d=new g(e),c=new y("value",d.area/l(t,i));let p=d.side;const f=t.length;let m,x;if(!f)return u;const b=t.slice();i=s(b,i),a(b,i);const w=t=>r&&b[t][r];for(m=0;m<f;++m)x={value:(_=m,i?+b[_][i]:+b[_]),groupSum:h,_data:t[b[m]._idx],level:void 0,group:void 0},r&&(x.level=o,x.group=w(m)),x=c.pushIf(x,v,p),x&&(u.push(d.map(c)),p=d.side,c.reset(),c.push(x));var _;return c.length&&u.push(d.map(c)),n(u)}function w(t,e){if(!e)return!1;const i=t.width||t.w,n=t.height||t.h,r=2*e.lineHeight;return i>r&&n>r}function _(t,e,i,n,r){if(t.save(),t.fillStyle=n.color,t.font=n.font.string,t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.clip(),"l"in i&&i.l!==r){if(n.groupLabels){t.textAlign=n.rtl?"end":"start",t.textBaseline="top";const r=n.rtl?e.x+e.width-n.borderWidth-3:e.x+n.borderWidth+3;t.fillText(i.g,r,e.y+n.borderWidth+3)}}else t.textAlign="center",t.textBaseline="middle",function(t,e,i){const n=i.options,r=n.font.lineHeight,o=(n.label||e.g+"\n"+e.v).split("\n"),s=i.y+i.height/2-o.length*r/4;o.forEach(((e,n)=>t.fillText(e,i.x+i.width/2,s+n*r)))}(t,i,e);t.restore()}function D(t,e){const i=e.options,n=e.width||e.w,r=e.height||e.h;if(t.save(),t.strokeStyle=i.dividerColor||"black",t.lineCap=i.dividerCapStyle,t.setLineDash(i.dividerDash||[]),t.lineDashOffset=i.dividerDashOffset,t.lineWidth=i.dividerWidth,t.beginPath(),n>r){const i=n/2;t.moveTo(e.x+i,e.y),t.lineTo(e.x+i,e.y+r)}else{const i=r/2;t.moveTo(e.x,e.y+i),t.lineTo(e.x+n,e.y+i)}t.stroke(),t.restore()}class O extends e.DatasetController{constructor(t,e){super(t,e),this._rect=void 0,this._key=void 0,this._groups=void 0}initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this,n=e.getMeta(),o=e.getDataset(),s=o.groups||(o.groups=[]),a=i.toFont(o.font),l=e.chart.chartArea,h=o.key||"",u=!!o.rtl,d={x:l.left,y:l.top,w:l.right-l.left,h:l.bottom-l.top,rtl:u};var c,g;"reset"!==t&&(c=e._rect,g=d,c&&g&&c.x===g.x&&c.y===g.y&&c.w===g.w&&c.h===g.h)&&e._key===h&&!function(t,e){let i,n;if(t.lenght!==e.length)return!0;for(i=0,n=t.length;i<n;++i)if(t[i]!==e[i])return!0;return!1}(e._groups,s)||(e._rect=d,e._groups=s.slice(),e._key=h,o.data=function(t,e,n){const o=t.key||"";let s=t.tree||[];const a=t.groups||[],l=a.length,h=(t.spacing||0)+(t.borderWidth||0);return!s.length&&t.data.length&&(s=t.tree=t.data),l?function e(u,d,c,g){const p=a[u],f=u>0&&a[u-1],m=b(r(s,p,o,f,c),d,o,p,u,g),x=m.slice();let y;return u<l-1&&m.forEach((r=>{y={x:r.x+h,y:r.y+h,w:r.w-2*h,h:r.h-2*h},i.valueOrDefault(t.groupLabels,!0)&&w(r,n)&&(y.y+=n.lineHeight,y.h-=n.lineHeight),x.push(...e(u+1,y,r.g,r.s))})),x}(0,e):b(s,e,o)}(o,d,a),e._dataCheck(),e._resyncElements()),e.updateElements(n.data,0,n.data.length,t)}resolveDataElementOptions(t,e){const n=super.resolveDataElementOptions(t,e),r=Object.isFrozen(n)?Object.assign({},n):n;return r.font=i.toFont(n.font),r}updateElements(t,e,i,n){const r=this,o="reset"===n,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,n),l=r.getSharedOptions(a),h=r.includeOptions(n,l);for(let a=e;a<e+i;a++){const e=s.data[a],i=l||r.resolveDataElementOptions(a,n),u=o?0:e.h-2*i.spacing,d=o?0:e.w-2*i.spacing,c={x:e.x+i.spacing,y:e.y+i.spacing,width:d,height:u};h&&(c.options=i),r.updateElement(t[a],a,c,n)}r.updateSharedOptions(l,n,a)}_drawDividers(t,e,i){for(let n=0,r=i.length;n<r;++n){const r=i[n],o=e[n];r.options.groupDividers&&o._data.children.length>1&&D(t,r)}this.getDataset().groupDividers&&D(t,this._rect)}_drawRects(t,e,i,n){for(let r=0,o=i.length;r<o;++r){const o=i[r],s=e[r];if(!o.hidden){o.draw(t);const e=o.options;w(o,e.font)&&s.g&&_(t,o,s,e,n)}}}draw(){const t=this,e=t.chart.ctx,i=t.getMeta().data||[],n=t.getDataset(),r=(n.groups||[]).length-1,o=n.data||[];t._drawRects(e,o,i,r),t._drawDividers(e,o,i)}}function k(t,e){const{x:i,y:n,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:i,top:n,right:i+r,bottom:n+o}}function C(t,e,i){return Math.max(Math.min(t,i),e)}function j(t){const e=k(t),i=e.right-e.left,n=e.bottom-e.top,r=function(t,e,i){let n,r,s,a;return o(t)?(n=+t.top||0,r=+t.right||0,s=+t.bottom||0,a=+t.left||0):n=r=s=a=+t||0,{t:C(n,0,i),r:C(r,0,e),b:C(s,0,i),l:C(a,0,e)}}(t.options.borderWidth,i/2,n/2);return{outer:{x:e.left,y:e.top,w:i,h:n},inner:{x:e.left+r.l,y:e.top+r.t,w:i-r.l-r.r,h:n-r.t-r.b}}}function E(t,e,i,n){const r=null===e,o=null===i,s=!(!t||r&&o)&&k(t,n);return s&&(r||e>=s.left&&e<=s.right)&&(o||i>=s.top&&i<=s.bottom)}O.id="treemap",O.version="1.0.0",O.defaults={dataElementType:"treemap",groupLabels:!0,borderWidth:0,spacing:.5,groupDividers:!1,dividerWidth:1},O.overrides={interaction:{mode:"point",intersect:!0},hover:{},plugins:{tooltip:{position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,i=e.data[t.dataIndex],n=i.g||e.label;return(n?n+": ":"")+i.v}}}},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}},O.afterRegister=function(){const t=e.registry.plugins.get("tooltip");t&&(t.positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()})},O.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap};class S extends e.Element{constructor(t){super(),this.options=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t){const e=this.options,{inner:i,outer:n}=j(this);t.save(),n.w!==i.w||n.h!==i.h?(t.beginPath(),t.rect(n.x,n.y,n.w,n.h),t.clip(),t.rect(i.x,i.y,i.w,i.h),t.fillStyle=e.backgroundColor,t.fill(),t.fillStyle=e.borderColor,t.fill("evenodd")):(t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h)),t.restore()}inRange(t,e,i){return E(this,t,e,i)}inXRange(t,e){return E(this,t,null,e)}inYRange(t,e){return E(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,width:n,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+n/2,y:i+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}S.id="treemap",S.defaults={borderSkipped:void 0,borderWidth:void 0,color:void 0,dividerCapStyle:"butt",dividerColor:"black",dividerDash:void 0,dividerDashOffset:0,dividerWidth:0,font:{},groupDividers:!1,groupLabels:void 0,spacing:void 0,label:void 0,rtl:void 0},S.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},e.Chart.register(O,S),t.flatten=n,t.group=r,t.index=s,t.isObject=o,t.sort=a,t.sum=l,Object.defineProperty(t,"__esModule",{value:!0})}));
|
|
7
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["exports","chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["chartjs-chart-treemap"]={},t.Chart,t.Chart.helpers)}(this,(function(t,e,n){"use strict";function i(t){const e=[...t],n=[];for(;e.length;){const t=e.pop();Array.isArray(t)?e.push(...t):n.push(t)}return n.reverse()}function r(t,e,n,i,r){const o=Object.create(null),s=Object.create(null),a=[];let l,h,u,c;for(h=0,u=t.length;h<u;++h)c=t[h],i&&c[i]!==r||(l=c[e]||"",l in o||(o[l]=0,s[l]=[]),o[l]+=+c[n],s[l].push(c));return Object.keys(o).forEach((t=>{c={children:s[t]},c[n]=+o[t],c[e]=t,i&&(c[i]=r),a.push(c)})),a}function o(t){const e=typeof t;return"function"===e||"object"===e&&!!t}function s(t,e){let n,i=t.length;if(!i)return e;const r=o(t[0]);for(e=r?e:"v",n=0,i=t.length;n<i;++n)r?t[n]._idx=n:t[n]={v:t[n],_idx:n};return e}function a(t,e){e?t.sort(((t,n)=>+n[e]-+t[e])):t.sort(((t,e)=>+e-+t))}function l(t,e){let n,i,r;for(n=0,i=0,r=t.length;i<r;++i)n+=e?+t[i][e]:+t[i];return n}function h(t,e){const n=e.split(".");if(!t.split(".").reduce(((t,e,i)=>t&&e<=n[i]),!0))throw new Error(`Chart.js v${e} is not supported. v${t} or newer is required.`)}function u(t,e){return+(Math.round(t+"e+"+e)+"e-"+e)||0}function c(t,e,n,i){const r=t._normalized,o=e*r/n,s=Math.sqrt(r*o),a=r/s;return{d1:s,d2:a,w:"_ix"===i?s:a,h:"_ix"===i?a:s}}const d=(t,e)=>u(t.rtl?t.x+t.w-t._ix-e:t.x+t._ix,4);function p(t,e,n,i){const r={x:d(t,n.w),y:u(t.y+t._iy,4),w:u(n.w,4),h:u(n.h,4),a:u(e._normalized,4),v:e.value,s:i,_data:e._data};return e.group&&(r.g=e.group,r.l=e.level,r.gs=e.groupSum),r}class g{constructor(t){const e=this;t=t||{w:1,h:1},e.rtl=!!t.rtl,e.x=t.x||t.left||0,e.y=t.y||t.top||0,e._ix=0,e._iy=0,e.w=t.w||t.width||t.right-t.left,e.h=t.h||t.height||t.bottom-t.top}get area(){return this.w*this.h}get iw(){return this.w-this._ix}get ih(){return this.h-this._iy}get dir(){const t=this.ih;return t<=this.iw&&t>0?"y":"x"}get side(){return"x"===this.dir?this.iw:this.ih}map(t){const e=this,n=[],i=t.nsum,r=t.get(),o=e.dir,s=e.side,a=s*s,l="x"===o?"_ix":"_iy",h=i*i;let u=0,d=0;for(const i of r){const r=c(i,a,h,l);d+=r.d1,u=Math.max(u,r.d2),n.push(p(e,i,r,t.sum)),e[l]+=r.d1}return e["y"===o?"_ix":"_iy"]+=u,e[l]-=d,n}}const f=Math.min,m=Math.max;function y(t,e){const n=+e[t.key],i=n*t.ratio;return e._normalized=i,{min:f(t.min,n),max:m(t.max,n),sum:t.sum+n,nmin:f(t.nmin,i),nmax:m(t.nmax,i),nsum:t.nsum+i}}function x(t,e,n){t._arr.push(e),function(t,e){Object.assign(t,e)}(t,n)}class v{constructor(t,e){const n=this;n.key=t,n.ratio=e,n.reset()}get length(){return this._arr.length}reset(){const t=this;t._arr=[],t._hist=[],t.sum=0,t.nsum=0,t.min=1/0,t.max=-1/0,t.nmin=1/0,t.nmax=-1/0}push(t){x(this,t,y(this,t))}pushIf(t,e,...n){const i=y(this,t);if(!e((r=this,{min:r.min,max:r.max,sum:r.sum,nmin:r.nmin,nmax:r.nmax,nsum:r.nsum}),i,n))return t;var r;x(this,t,i)}get(){return this._arr}}function w(t,e,n){if(0===t.sum)return!0;const[i]=n,r=t.nsum*t.nsum,o=e.nsum*e.nsum,s=i*i,a=Math.max(s*t.nmax/r,r/(s*t.nmin));return Math.max(s*e.nmax/o,o/(s*e.nmin))<=a}function b(t,e,n,r,o,h){t=t||[];const u=[],c=new g(e),d=new v("value",c.area/l(t,n));let p=c.side;const f=t.length;let m,y;if(!f)return u;const x=t.slice();n=s(x,n),a(x,n);const b=t=>r&&x[t][r];for(m=0;m<f;++m)y={value:(_=m,n?+x[_][n]:+x[_]),groupSum:h,_data:t[x[m]._idx],level:void 0,group:void 0},r&&(y.level=o,y.group=b(m)),y=d.pushIf(y,w,p),y&&(u.push(c.map(d)),p=c.side,d.reset(),d.push(y));var _;return d.length&&u.push(c.map(d)),i(u)}function _(t,e){if(!e)return!1;const n=t.width||t.w,i=t.height||t.h,r=2*e.lineHeight;return n>r&&i>r}function O(t,e,i,r,o){t.save(),t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.clip(),"l"in i&&i.l!==o?r.captions&&r.captions.display&&function(t,e,i){const r=i.options,o=r.captions||{},s=r.borderWidth||0,a=n.valueOrDefault(r.spacing,0)+s,l=(i.active?o.hoverColor:o.color)||o.color,h=o.padding,u=o.align||(r.rtl?"right":"left"),c=(i.active?o.hoverFont:o.font)||o.font,d=n.toFont(c),p=D(i,u,h,s);t.fillStyle=l,t.font=d.string,t.textAlign=u,t.textBaseline="middle",t.fillText(o.formatter||e.g,p,i.y+h+a+d.lineHeight/2)}(t,i,e):function(t,e,i){const r=i.options,o=r.labels;if(!o||!o.display)return;const s=(i.active?o.hoverColor:o.color)||o.color,a=(i.active?o.hoverFont:o.font)||o.font,l=n.toFont(a),h=l.lineHeight,u=o.formatter;if(u){const e=n.isArray(u)?u:[u],a=function(t,e,n,i){const r=t.labels,o=t.borderWidth||0,{align:s,position:a,padding:l}=r;let h,u;h=D(e,s,l,o),u="top"===a?e.y+l+o:"bottom"===a?e.y+e.height-l-o-(n.length-1)*i:e.y+e.height/2-n.length*i/4;return{x:h,y:u}}(r,i,e,h);t.font=l.string,t.textAlign=o.align,t.textBaseline=o.position,t.fillStyle=s,e.forEach(((e,n)=>t.fillText(e,a.x,a.y+n*h)))}}(t,0,e),t.restore()}function C(t,e){const n=e.options.dividers||{},i=e.width||e.w,r=e.height||e.h;if(t.save(),t.strokeStyle=n.lineColor||"black",t.lineCap=n.lineCapStyle,t.setLineDash(n.lineDash||[]),t.lineDashOffset=n.lineDashOffset,t.lineWidth=n.lineWidth,t.beginPath(),i>r){const n=i/2;t.moveTo(e.x+n,e.y),t.lineTo(e.x+n,e.y+r)}else{const n=r/2;t.moveTo(e.x,e.y+n),t.lineTo(e.x+i,e.y+n)}t.stroke(),t.restore()}function D(t,e,n,i){return"left"===e?t.x+n+i:"right"===e?t.x+t.width-n-i:t.x+t.width/2}class k extends e.DatasetController{constructor(t,e){super(t,e),this._rect=void 0,this._key=void 0,this._groups=void 0}initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this,i=e.getMeta(),o=e.getDataset(),s=o.groups||(o.groups=[]),a=o.captions?o.captions:{},l=e.chart.chartArea,h=o.key||"",u=!!o.rtl,c={x:l.left,y:l.top,w:l.right-l.left,h:l.bottom-l.top,rtl:u};var d,p;"reset"!==t&&(d=e._rect,p=c,d&&p&&d.x===p.x&&d.y===p.y&&d.w===p.w&&d.h===p.h)&&e._key===h&&!function(t,e){let n,i;if(t.lenght!==e.length)return!0;for(n=0,i=t.length;n<i;++n)if(t[n]!==e[n])return!0;return!1}(e._groups,s)||(e._rect=c,e._groups=s.slice(),e._key=h,o.data=function(t,e,i){const o=t.key||"";let s=t.tree||[];const a=t.groups||[],l=a.length,h=n.valueOrDefault(t.spacing,0)+n.valueOrDefault(t.borderWidth,0),u=i.font||{},c=n.toFont(u),d=n.valueOrDefault(i.padding,3);return!s.length&&t.data.length&&(s=t.tree=t.data),l?function t(e,u,p,g){const f=a[e],m=e>0&&a[e-1],y=b(r(s,f,o,m,p),u,o,f,e,g),x=y.slice();let v;return e<l-1&&y.forEach((r=>{v={x:r.x+h,y:r.y+h,w:r.w-2*h,h:r.h-2*h},n.valueOrDefault(i.display,!0)&&_(r,c)&&(v.y+=c.lineHeight+2*d,v.h-=c.lineHeight+2*d),x.push(...t(e+1,v,r.g,r.s))})),x}(0,e):b(s,e,o)}(o,c,a),e._dataCheck(),e._resyncElements()),e.updateElements(i.data,0,i.data.length,t)}resolveDataElementOptions(t,e){const i=super.resolveDataElementOptions(t,e),r=Object.isFrozen(i)?Object.assign({},i):i;return r.font=n.toFont(i.captions.font),r}updateElements(t,e,n,i){const r=this,o="reset"===i,s=r.getDataset(),a=r._rect.options=r.resolveDataElementOptions(e,i),l=r.getSharedOptions(a),h=r.includeOptions(i,l);for(let a=e;a<e+n;a++){const e=s.data[a],n=l||r.resolveDataElementOptions(a,i),u=o?0:e.h-2*n.spacing,c=o?0:e.w-2*n.spacing,d={x:e.x+n.spacing,y:e.y+n.spacing,width:c,height:u};h&&(d.options=n),r.updateElement(t[a],a,d,i)}r.updateSharedOptions(l,i,a)}_drawDividers(t,e,n){for(let i=0,r=n.length;i<r;++i){const r=n[i],o=e[i];(r.options.dividers||{}).display&&o._data.children.length>1&&C(t,r)}}_drawRects(t,e,n,i){for(let r=0,o=n.length;r<o;++r){const o=n[r],s=e[r];if(!o.hidden){o.draw(t);const e=o.options;_(o,e.captions.font)&&O(t,o,s,e,i)}}}draw(){const t=this,e=t.chart.ctx,n=t.getMeta().data||[],i=t.getDataset(),r=(i.groups||[]).length-1,o=i.data||[];t._drawRects(e,o,n,r),t._drawDividers(e,o,n)}}function j(t,e){const{x:n,y:i,width:r,height:o}=t.getProps(["x","y","width","height"],e);return{left:n,top:i,right:n+r,bottom:i+o}}function E(t,e,n){return Math.max(Math.min(t,n),e)}function S(t){const e=j(t),n=e.right-e.left,i=e.bottom-e.top,r=function(t,e,n){let i,r,s,a;return o(t)?(i=+t.top||0,r=+t.right||0,s=+t.bottom||0,a=+t.left||0):i=r=s=a=+t||0,{t:E(i,0,n),r:E(r,0,e),b:E(s,0,n),l:E(a,0,e)}}(t.options.borderWidth,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+r.l,y:e.top+r.t,w:n-r.l-r.r,h:i-r.t-r.b}}}function M(t,e,n,i){const r=null===e,o=null===n,s=!(!t||r&&o)&&j(t,i);return s&&(r||e>=s.left&&e<=s.right)&&(o||n>=s.top&&n<=s.bottom)}k.id="treemap",k.version="2.0.0",k.defaults={dataElementType:"treemap",borderWidth:0,spacing:.5,dividers:{display:!1,lineWidth:1}},k.descriptors={_scriptable:!0,_indexable:!1},k.overrides={interaction:{mode:"point",intersect:!0},hover:{},plugins:{tooltip:{position:"treemap",intersect:!0,callbacks:{title(t){if(t.length){return t[0].dataset.key||""}return""},label(t){const e=t.dataset,n=e.data[t.dataIndex],i=n.g||e.label;return(i?i+": ":"")+n.v}}}},scales:{x:{type:"linear",display:!1},y:{type:"linear",display:!1}}},k.beforeRegister=function(){h("3.6",e.Chart.version)},k.afterRegister=function(){const t=e.registry.plugins.get("tooltip");t&&(t.positioners.treemap=function(t){if(!t.length)return!1;return t[t.length-1].element.tooltipPosition()})},k.afterUnregister=function(){const t=e.registry.plugins.get("tooltip");t&&delete t.positioners.treemap};class P extends e.Element{constructor(t){super(),this.options=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t){const e=this.options,{inner:n,outer:i}=S(this);t.save(),i.w!==n.w||i.h!==n.h?(t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.rect(n.x,n.y,n.w,n.h),t.fillStyle=e.backgroundColor,t.fill(),t.fillStyle=e.borderColor,t.fill("evenodd")):(t.fillStyle=e.backgroundColor,t.fillRect(n.x,n.y,n.w,n.h)),t.restore()}inRange(t,e,n){return M(this,t,e,n)}inXRange(t,e){return M(this,t,null,e)}inYRange(t,e){return M(this,null,t,e)}getCenterPoint(t){const{x:e,y:n,width:i,height:r}=this.getProps(["x","y","width","height"],t);return{x:e+i/2,y:n+r/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}P.id="treemap",P.defaults={borderWidth:void 0,spacing:void 0,label:void 0,rtl:void 0,dividers:{display:!1,lineCapStyle:"butt",lineColor:"black",lineDash:void 0,lineDashOffset:0,lineWidth:0},captions:{align:void 0,color:void 0,display:!0,formatter:t=>t.raw.g||"",font:{},padding:3},labels:{align:"center",color:void 0,display:!1,formatter:t=>t.raw.g?[t.raw.g,t.raw.v]:t.raw.v,font:{},position:"middle",padding:3}},P.descriptors={_scriptable:!0,_indexable:!1},P.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},e.Chart.register(k,P),t.flatten=i,t.group=r,t.index=s,t.isObject=o,t.requireVersion=h,t.sort=a,t.sum=l,Object.defineProperty(t,"__esModule",{value:!0})}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chartjs-chart-treemap",
|
|
3
3
|
"homepage": "https://chartjs-chart-treemap.pages.dev/",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"description": "Chart.js module for creating treemap charts",
|
|
6
6
|
"main": "dist/chartjs-chart-treemap.js",
|
|
7
7
|
"module": "dist/chartjs-chart-treemap.esm.js",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"treemap"
|
|
31
31
|
],
|
|
32
32
|
"files": [
|
|
33
|
-
"dist/*.js"
|
|
33
|
+
"dist/*.js",
|
|
34
|
+
"types/index.esm.d.ts"
|
|
34
35
|
],
|
|
35
36
|
"author": "Jukka Kurkela",
|
|
36
37
|
"license": "MIT",
|
|
@@ -38,18 +39,18 @@
|
|
|
38
39
|
"url": "https://github.com/kurkle/chartjs-chart-treemap/issues"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@rollup/plugin-commonjs": "^
|
|
42
|
+
"@rollup/plugin-commonjs": "^21.0.1",
|
|
42
43
|
"@rollup/plugin-json": "^4.1.0",
|
|
43
|
-
"@rollup/plugin-node-resolve": "^
|
|
44
|
-
"@typescript-eslint/eslint-plugin": "^4.
|
|
45
|
-
"@typescript-eslint/parser": "^4.
|
|
46
|
-
"chart.js": "^3.
|
|
44
|
+
"@rollup/plugin-node-resolve": "^13.0.0",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
|
46
|
+
"@typescript-eslint/parser": "^5.4.0",
|
|
47
|
+
"chart.js": "^3.6.0",
|
|
47
48
|
"chartjs-adapter-date-fns": "^2.0.0",
|
|
48
|
-
"chartjs-test-utils": "^0.
|
|
49
|
+
"chartjs-test-utils": "^0.3.0",
|
|
49
50
|
"concurrently": "^6.0.1",
|
|
50
51
|
"cross-env": "^7.0.3",
|
|
51
52
|
"date-fns": "^2.20.2",
|
|
52
|
-
"eslint": "^
|
|
53
|
+
"eslint": "^8.3.0",
|
|
53
54
|
"eslint-config-chartjs": "^0.3.0",
|
|
54
55
|
"eslint-plugin-es": "^4.1.0",
|
|
55
56
|
"eslint-plugin-html": "^6.1.2",
|
|
@@ -63,20 +64,19 @@
|
|
|
63
64
|
"karma-jasmine-html-reporter": "^1.5.4",
|
|
64
65
|
"karma-rollup-preprocessor": "^7.0.7",
|
|
65
66
|
"karma-spec-reporter": "0.0.32",
|
|
66
|
-
"karma-summary-reporter": "^
|
|
67
|
+
"karma-summary-reporter": "^3.0.0",
|
|
67
68
|
"pixelmatch": "^5.2.1",
|
|
68
69
|
"rollup": "^2.45.1",
|
|
69
70
|
"rollup-plugin-analyzer": "^4.0.0",
|
|
70
71
|
"rollup-plugin-istanbul": "^3.0.0",
|
|
71
72
|
"rollup-plugin-terser": "^7.0.2",
|
|
72
|
-
"typescript": "^4.
|
|
73
|
+
"typescript": "^4.3.5",
|
|
73
74
|
"vuepress": "^1.8.2",
|
|
74
|
-
"vuepress-plugin-flexsearch": "^0.
|
|
75
|
+
"vuepress-plugin-flexsearch": "^0.3.0",
|
|
75
76
|
"vuepress-plugin-redirect": "^1.2.5",
|
|
76
77
|
"vuepress-theme-chartjs": "^0.2.0"
|
|
77
78
|
},
|
|
78
79
|
"peerDependencies": {
|
|
79
80
|
"chart.js": "^3.0.0"
|
|
80
|
-
}
|
|
81
|
-
"dependencies": {}
|
|
81
|
+
}
|
|
82
82
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Chart,
|
|
3
|
+
ChartComponent,
|
|
4
|
+
DatasetController,
|
|
5
|
+
Element,
|
|
6
|
+
ScriptableContext, Color, Scriptable, FontSpec
|
|
7
|
+
} from 'chart.js';
|
|
8
|
+
|
|
9
|
+
type TreemapScriptableContext = ScriptableContext<'treemap'> & {
|
|
10
|
+
raw: TreemapDataPoint
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type TreemapControllerDatasetCaptionsOptions = {
|
|
14
|
+
align?: Scriptable<LabelAlign, TreemapScriptableContext>,
|
|
15
|
+
color?: Scriptable<Color, TreemapScriptableContext>,
|
|
16
|
+
display?: boolean;
|
|
17
|
+
formatter?: Scriptable<string, TreemapScriptableContext>,
|
|
18
|
+
font?: FontSpec,
|
|
19
|
+
hoverColor?: Scriptable<Color, TreemapScriptableContext>,
|
|
20
|
+
hoverFont?: FontSpec,
|
|
21
|
+
padding?: number,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type TreemapControllerDatasetLabelsOptions = {
|
|
25
|
+
align?: Scriptable<LabelAlign, TreemapScriptableContext>,
|
|
26
|
+
color?: Scriptable<Color, TreemapScriptableContext>,
|
|
27
|
+
display?: boolean;
|
|
28
|
+
formatter?: Scriptable<string | Array<string>, TreemapScriptableContext>,
|
|
29
|
+
font?: FontSpec,
|
|
30
|
+
hoverColor?: Scriptable<Color, TreemapScriptableContext>,
|
|
31
|
+
hoverFont?: FontSpec,
|
|
32
|
+
padding?: number,
|
|
33
|
+
position?: Scriptable<LabelPosition, TreemapScriptableContext>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type LabelPosition = 'top' | 'middle' | 'bottom';
|
|
37
|
+
|
|
38
|
+
export type LabelAlign = 'left' | 'center' | 'right';
|
|
39
|
+
|
|
40
|
+
type TreemapControllerDatasetDividersOptions = {
|
|
41
|
+
display?: boolean,
|
|
42
|
+
lineCapStyle?: string,
|
|
43
|
+
lineColor?: string,
|
|
44
|
+
lineDash?: number[],
|
|
45
|
+
lineDashOffset?: number,
|
|
46
|
+
lineWidth?: number,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface TreemapControllerDatasetOptions<DType> {
|
|
50
|
+
spacing?: number,
|
|
51
|
+
rtl?: boolean,
|
|
52
|
+
|
|
53
|
+
backgroundColor?: Scriptable<Color, TreemapScriptableContext>;
|
|
54
|
+
borderColor?: Scriptable<Color, TreemapScriptableContext>;
|
|
55
|
+
borderWidth?: number;
|
|
56
|
+
|
|
57
|
+
hoverBackgroundColor?: Scriptable<Color, TreemapScriptableContext>;
|
|
58
|
+
hoverBorderColor?: Scriptable<Color, TreemapScriptableContext>;
|
|
59
|
+
hoverBorderWidth?: number;
|
|
60
|
+
|
|
61
|
+
captions?: TreemapControllerDatasetCaptionsOptions;
|
|
62
|
+
dividers?: TreemapControllerDatasetDividersOptions;
|
|
63
|
+
labels?: TreemapControllerDatasetLabelsOptions;
|
|
64
|
+
label?: string;
|
|
65
|
+
|
|
66
|
+
data: TreemapDataPoint[]; // This will be auto-generated from `tree`
|
|
67
|
+
groups?: Array<keyof DType>;
|
|
68
|
+
tree: number[] | DType[];
|
|
69
|
+
key?: keyof DType;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface TreemapDataPoint {
|
|
73
|
+
x: number,
|
|
74
|
+
y: number,
|
|
75
|
+
w: number,
|
|
76
|
+
h: number,
|
|
77
|
+
/**
|
|
78
|
+
* Value
|
|
79
|
+
*/
|
|
80
|
+
v: number,
|
|
81
|
+
/**
|
|
82
|
+
* Sum
|
|
83
|
+
*/
|
|
84
|
+
s: number,
|
|
85
|
+
/**
|
|
86
|
+
* Depth, only available if grouping
|
|
87
|
+
*/
|
|
88
|
+
l?: number,
|
|
89
|
+
/**
|
|
90
|
+
* Group name, only available if grouping
|
|
91
|
+
*/
|
|
92
|
+
g?: string,
|
|
93
|
+
/**
|
|
94
|
+
* Group Sum, only available if grouping
|
|
95
|
+
*/
|
|
96
|
+
gs?: number,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/*
|
|
100
|
+
export interface TreemapInteractionOptions {
|
|
101
|
+
position: Scriptable<"treemap", ScriptableTooltipContext<"treemap">>
|
|
102
|
+
}*/
|
|
103
|
+
|
|
104
|
+
declare module 'chart.js' {
|
|
105
|
+
export interface ChartTypeRegistry {
|
|
106
|
+
treemap: {
|
|
107
|
+
chartOptions: CoreChartOptions<'treemap'>;
|
|
108
|
+
datasetOptions: TreemapControllerDatasetOptions<Record<string, unknown>>;
|
|
109
|
+
defaultDataPoint: TreemapDataPoint;
|
|
110
|
+
metaExtensions: {};
|
|
111
|
+
parsedDataType: unknown,
|
|
112
|
+
scales: never;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// interface TooltipOptions<TType extends ChartType> extends CoreInteractionOptions, TreemapInteractionOptions {
|
|
117
|
+
// }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
type TreemapOptions = {
|
|
121
|
+
backgroundColor: Color;
|
|
122
|
+
borderColor: Color;
|
|
123
|
+
borderWidth: number | { top?: number, right?: number, bottom?: number, left?: number }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
type TreemapConfig = {
|
|
127
|
+
x: number;
|
|
128
|
+
y: number;
|
|
129
|
+
width: number;
|
|
130
|
+
height: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export type TreemapController = DatasetController;
|
|
134
|
+
export const TreemapController: ChartComponent & {
|
|
135
|
+
prototype: TreemapController;
|
|
136
|
+
new(chart: Chart, datasetIndex: number): TreemapController
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export type TreemapElement = Element<TreemapConfig, TreemapOptions>;
|
|
140
|
+
export const TreemapElement: ChartComponent & {
|
|
141
|
+
prototype: TreemapElement;
|
|
142
|
+
new(cfg: TreemapConfig): TreemapElement
|
|
143
|
+
};
|