chartjs-chart-treemap 5.0.0-next.2 → 5.0.0-next.3
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/dist/chartjs-chart-treemap.cjs +159 -121
- package/dist/chartjs-chart-treemap.esm.js +159 -121
- package/dist/chartjs-chart-treemap.min.js +2 -2
- package/dist/chartjs-chart-treemap.min.js.map +1 -1
- package/dist/controller.d.ts +15 -0
- package/dist/element.d.ts +2 -7
- package/dist/options.d.ts +7 -1
- package/dist/text.d.ts +2 -2
- package/dist/types.d.ts +9 -4
- package/dist/utils.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* chartjs-chart-treemap v5.0.0-next.
|
|
2
|
+
* chartjs-chart-treemap v5.0.0-next.3
|
|
3
3
|
* https://chartjs-chart-treemap.pages.dev/
|
|
4
4
|
* (c) 2026 Jukka Kurkela
|
|
5
5
|
* Released under the MIT license
|
|
@@ -10,7 +10,7 @@ typeof define === 'function' && define.amd ? define(['exports', 'chart.js', 'cha
|
|
|
10
10
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["chartjs-chart-treemap"] = {}, global.Chart, global.Chart.helpers));
|
|
11
11
|
})(this, (function (exports, chart_js, helpers) { 'use strict';
|
|
12
12
|
|
|
13
|
-
var version = "5.0.0-next.
|
|
13
|
+
var version = "5.0.0-next.3";
|
|
14
14
|
|
|
15
15
|
function scaleRect(sq, xScale, yScale, sp) {
|
|
16
16
|
const sp2 = sp * 2;
|
|
@@ -49,6 +49,11 @@ function arrayNotEqual(a, b) {
|
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
const layoutDefaults = {
|
|
53
|
+
displayMode: 'containerBoxes',
|
|
54
|
+
rtl: false,
|
|
55
|
+
spacing: 0.5
|
|
56
|
+
};
|
|
52
57
|
function limit(value, min, max) {
|
|
53
58
|
return Math.max(Math.min(value, max), min);
|
|
54
59
|
}
|
|
@@ -237,7 +242,7 @@ class StatArray {
|
|
|
237
242
|
const isOlderPart = (act, req)=>req > act || act.length > req.length && act.startsWith(req);
|
|
238
243
|
const getGroupKey = (lvl)=>String(lvl);
|
|
239
244
|
const hasGroupValue = (value)=>value !== undefined && value !== null && value !== '';
|
|
240
|
-
function scanTreeObject(keys,
|
|
245
|
+
function scanTreeObject(keys, leafKey, obj, tree = [], lvl = 0, result = []) {
|
|
241
246
|
const objIndex = lvl - 1;
|
|
242
247
|
if (keys[0] in obj && lvl > 0) {
|
|
243
248
|
const record = tree.reduce((reduced, item, i)=>{
|
|
@@ -246,7 +251,7 @@ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = [])
|
|
|
246
251
|
}
|
|
247
252
|
return reduced;
|
|
248
253
|
}, {});
|
|
249
|
-
record[
|
|
254
|
+
record[leafKey] = tree[objIndex];
|
|
250
255
|
keys.forEach((k)=>{
|
|
251
256
|
record[k] = obj[k];
|
|
252
257
|
});
|
|
@@ -256,15 +261,15 @@ function scanTreeObject(keys, treeLeafKey, obj, tree = [], lvl = 0, result = [])
|
|
|
256
261
|
const child = obj[childKey];
|
|
257
262
|
if (helpers.isObject(child)) {
|
|
258
263
|
tree.push(childKey);
|
|
259
|
-
scanTreeObject(keys,
|
|
264
|
+
scanTreeObject(keys, leafKey, child, tree, lvl + 1, result);
|
|
260
265
|
}
|
|
261
266
|
}
|
|
262
267
|
}
|
|
263
268
|
tree.splice(objIndex, 1);
|
|
264
269
|
return result;
|
|
265
270
|
}
|
|
266
|
-
function normalizeTreeToArray(keys,
|
|
267
|
-
const data = scanTreeObject(keys,
|
|
271
|
+
function normalizeTreeToArray(keys, leafKey, obj) {
|
|
272
|
+
const data = scanTreeObject(keys, leafKey, obj);
|
|
268
273
|
if (!data.length) {
|
|
269
274
|
return data;
|
|
270
275
|
}
|
|
@@ -308,7 +313,7 @@ function getPath(groups, value, defaultValue) {
|
|
|
308
313
|
}
|
|
309
314
|
return path.length ? path.join('.') : defaultValue;
|
|
310
315
|
}
|
|
311
|
-
function resolveGroup(value,
|
|
316
|
+
function resolveGroup(value, leafKey, allGroups, groupIndex) {
|
|
312
317
|
for(let idx = groupIndex; idx < allGroups.length; idx++){
|
|
313
318
|
const groupKey = getGroupKey(allGroups[idx]);
|
|
314
319
|
if (hasGroupValue(value[groupKey])) {
|
|
@@ -319,11 +324,11 @@ function resolveGroup(value, treeLeafKey, allGroups, groupIndex) {
|
|
|
319
324
|
};
|
|
320
325
|
}
|
|
321
326
|
}
|
|
322
|
-
if (hasGroupValue(value[
|
|
327
|
+
if (hasGroupValue(value[leafKey])) {
|
|
323
328
|
return {
|
|
324
|
-
group:
|
|
329
|
+
group: leafKey,
|
|
325
330
|
groupIndex,
|
|
326
|
-
value: value[
|
|
331
|
+
value: value[leafKey]
|
|
327
332
|
};
|
|
328
333
|
}
|
|
329
334
|
return undefined;
|
|
@@ -341,7 +346,7 @@ function ensureGroup(tmp, data, groupValue, addKeys) {
|
|
|
341
346
|
});
|
|
342
347
|
data[groupValue] = [];
|
|
343
348
|
}
|
|
344
|
-
function group(values, grp, keys,
|
|
349
|
+
function group(values, grp, keys, leafKey, mainGrp, mainValue, groups = [], allGroups = groups, groupIndex = groups.length - 1) {
|
|
345
350
|
const key = keys[0];
|
|
346
351
|
const addKeys = keys.slice(1);
|
|
347
352
|
const tmp = Object.create(null);
|
|
@@ -358,7 +363,7 @@ function group(values, grp, keys, treeLeafKey, mainGrp, mainValue, groups = [],
|
|
|
358
363
|
if (mainGrp && v[mainGrp] !== mainValue) {
|
|
359
364
|
continue;
|
|
360
365
|
}
|
|
361
|
-
const itemGroup = resolveGroup(v,
|
|
366
|
+
const itemGroup = resolveGroup(v, leafKey, resolvedAllGroups, resolvedGroupIndex);
|
|
362
367
|
if (!itemGroup) {
|
|
363
368
|
return [];
|
|
364
369
|
}
|
|
@@ -533,20 +538,41 @@ function getCaptionHeight(displayMode, rect, font, padding) {
|
|
|
533
538
|
const captionHeight = font.lineHeight + padding * 2;
|
|
534
539
|
return rect.h < 2 * captionHeight ? rect.h / 3 : captionHeight;
|
|
535
540
|
}
|
|
536
|
-
function drawText(ctx, rect, options, item, element) {
|
|
537
|
-
const { captions, labels
|
|
541
|
+
function drawText(ctx, rect, options, item, element, layout) {
|
|
542
|
+
const { captions, labels } = options;
|
|
543
|
+
const { displayMode } = layout;
|
|
538
544
|
ctx.save();
|
|
539
545
|
ctx.beginPath();
|
|
540
546
|
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
|
541
547
|
ctx.clip();
|
|
542
548
|
const isLeaf = item && (!helpers.defined(item.l) || item.isLeaf);
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
549
|
+
let block;
|
|
550
|
+
if (isLeaf) {
|
|
551
|
+
if (labels.display) {
|
|
552
|
+
block = labelBlock(ctx, rect, options, item, element);
|
|
553
|
+
}
|
|
554
|
+
} else if (shouldDrawCaption(displayMode, rect, captions)) {
|
|
555
|
+
block = captionBlock(ctx, rect, options, item, element, layout);
|
|
556
|
+
}
|
|
557
|
+
if (block) {
|
|
558
|
+
drawTextBlock(ctx, rect, block);
|
|
547
559
|
}
|
|
548
560
|
ctx.restore();
|
|
549
561
|
}
|
|
562
|
+
function drawTextBlock(ctx, rect, block) {
|
|
563
|
+
const { align, colors, fonts, lines, padding, top } = block;
|
|
564
|
+
const x = calculateX(rect, align, padding);
|
|
565
|
+
ctx.textAlign = align;
|
|
566
|
+
ctx.textBaseline = 'middle';
|
|
567
|
+
let offset = 0;
|
|
568
|
+
lines.forEach((line, i)=>{
|
|
569
|
+
const font = fonts[Math.min(i, fonts.length - 1)];
|
|
570
|
+
ctx.font = font.string;
|
|
571
|
+
ctx.fillStyle = colors[Math.min(i, colors.length - 1)];
|
|
572
|
+
ctx.fillText(line, x, top + offset + font.lineHeight / 2);
|
|
573
|
+
offset += font.lineHeight;
|
|
574
|
+
});
|
|
575
|
+
}
|
|
550
576
|
function callbackContext(element, item) {
|
|
551
577
|
const context = element.$context || {
|
|
552
578
|
active: !!element.active,
|
|
@@ -563,16 +589,12 @@ function resolveOption(option, context) {
|
|
|
563
589
|
function resolveCaptionText(captions, element, item) {
|
|
564
590
|
return resolveOption(captions.formatter, callbackContext(element, item)) || item.g || '';
|
|
565
591
|
}
|
|
566
|
-
function
|
|
567
|
-
const {
|
|
592
|
+
function captionBlock(ctx, rect, options, item, element, layout) {
|
|
593
|
+
const { displayMode, rtl, spacing } = layout;
|
|
594
|
+
const { captions } = options;
|
|
568
595
|
const { color, hoverColor, font, hoverFont, padding, align } = captions;
|
|
569
|
-
const oColor = (rect.active ? hoverColor : color) || color;
|
|
570
|
-
const oAlign = align || (rtl ? 'right' : 'left');
|
|
571
596
|
const optFont = (rect.active ? hoverFont : font) || font;
|
|
572
597
|
const oFont = helpers.toFont(optFont);
|
|
573
|
-
const fonts = [
|
|
574
|
-
oFont
|
|
575
|
-
];
|
|
576
598
|
if (oFont.lineHeight > rect.h) {
|
|
577
599
|
return;
|
|
578
600
|
}
|
|
@@ -580,20 +602,62 @@ function drawCaption(ctx, rect, options, item, element) {
|
|
|
580
602
|
if (!text) {
|
|
581
603
|
return;
|
|
582
604
|
}
|
|
583
|
-
const
|
|
605
|
+
const fonts = [
|
|
606
|
+
oFont
|
|
607
|
+
];
|
|
608
|
+
if (measureLabelSize(ctx, [
|
|
584
609
|
text
|
|
585
|
-
], fonts)
|
|
586
|
-
if (captionSize.width + 2 * padding > rect.w) {
|
|
610
|
+
], fonts).width + 2 * padding > rect.w) {
|
|
587
611
|
text = sliceTextToFitWidth(ctx, text, rect.w - 2 * padding, fonts);
|
|
588
612
|
}
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
613
|
+
const top = displayMode === 'headerBoxes' ? rect.y + (rect.h - oFont.lineHeight) / 2 : rect.y + padding + spacing;
|
|
614
|
+
return {
|
|
615
|
+
align: align || (rtl ? 'right' : 'left'),
|
|
616
|
+
colors: [
|
|
617
|
+
(rect.active ? hoverColor : color) || color
|
|
618
|
+
],
|
|
619
|
+
fonts,
|
|
620
|
+
lines: [
|
|
621
|
+
text
|
|
622
|
+
],
|
|
623
|
+
padding,
|
|
624
|
+
top
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
function labelBlock(ctx, rect, options, item, element) {
|
|
628
|
+
const labels = options.labels;
|
|
629
|
+
const content = resolveOption(labels.formatter, callbackContext(element, item));
|
|
630
|
+
if (!content) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
const lines = helpers.isArray(content) ? content : [
|
|
634
|
+
content
|
|
635
|
+
];
|
|
636
|
+
let fonts = getFontFromOptions(rect, labels);
|
|
637
|
+
let labelSize = measureLabelSize(ctx, lines, fonts);
|
|
638
|
+
const lblToDraw = labelToDraw(rect, labels, labelSize);
|
|
639
|
+
if (!lblToDraw) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
if (helpers.isNumber(lblToDraw)) {
|
|
643
|
+
labelSize = {
|
|
644
|
+
height: labelSize.height * lblToDraw,
|
|
645
|
+
width: labelSize.width * lblToDraw
|
|
646
|
+
};
|
|
647
|
+
fonts = toFonts(fonts, lblToDraw);
|
|
648
|
+
}
|
|
649
|
+
const { color, hoverColor, align, padding } = labels;
|
|
650
|
+
const optColor = (rect.active ? hoverColor : color) || color;
|
|
651
|
+
return {
|
|
652
|
+
align,
|
|
653
|
+
colors: helpers.isArray(optColor) ? optColor : [
|
|
654
|
+
optColor
|
|
655
|
+
],
|
|
656
|
+
fonts,
|
|
657
|
+
lines,
|
|
658
|
+
padding,
|
|
659
|
+
top: calculateBlockTop(rect, labels, labelSize)
|
|
660
|
+
};
|
|
597
661
|
}
|
|
598
662
|
function sliceTextToFitWidth(ctx, text, width, fonts) {
|
|
599
663
|
const ellipsis = '...';
|
|
@@ -658,7 +722,7 @@ function toFonts(fonts, fitRatio) {
|
|
|
658
722
|
});
|
|
659
723
|
});
|
|
660
724
|
}
|
|
661
|
-
function labelToDraw(
|
|
725
|
+
function labelToDraw(rect, options, labelSize) {
|
|
662
726
|
const { overflow, padding } = options;
|
|
663
727
|
const { width, height } = labelSize;
|
|
664
728
|
if (overflow === 'hidden') {
|
|
@@ -678,62 +742,15 @@ function getFontFromOptions(rect, labels) {
|
|
|
678
742
|
helpers.toFont(optFont)
|
|
679
743
|
];
|
|
680
744
|
}
|
|
681
|
-
function
|
|
682
|
-
const
|
|
683
|
-
const content = resolveOption(labels.formatter, callbackContext(element, item));
|
|
684
|
-
if (!content) {
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
const contents = helpers.isArray(content) ? content : [
|
|
688
|
-
content
|
|
689
|
-
];
|
|
690
|
-
let fonts = getFontFromOptions(rect, labels);
|
|
691
|
-
let labelSize = measureLabelSize(ctx, contents, fonts);
|
|
692
|
-
const lblToDraw = labelToDraw(ctx, rect, labels, labelSize);
|
|
693
|
-
if (!lblToDraw) {
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
if (helpers.isNumber(lblToDraw)) {
|
|
697
|
-
labelSize = {
|
|
698
|
-
height: labelSize.height * lblToDraw,
|
|
699
|
-
width: labelSize.width * lblToDraw
|
|
700
|
-
};
|
|
701
|
-
fonts = toFonts(fonts, lblToDraw);
|
|
702
|
-
}
|
|
703
|
-
const { color, hoverColor, align } = labels;
|
|
704
|
-
const optColor = (rect.active ? hoverColor : color) || color;
|
|
705
|
-
const colors = helpers.isArray(optColor) ? optColor : [
|
|
706
|
-
optColor
|
|
707
|
-
];
|
|
708
|
-
const xyPoint = calculateXYLabel(rect, labels, labelSize);
|
|
709
|
-
ctx.textAlign = align;
|
|
710
|
-
ctx.textBaseline = 'middle';
|
|
711
|
-
let lhs = 0;
|
|
712
|
-
contents.forEach((l, i)=>{
|
|
713
|
-
const c = colors[Math.min(i, colors.length - 1)];
|
|
714
|
-
const f = fonts[Math.min(i, fonts.length - 1)];
|
|
715
|
-
const lh = f.lineHeight;
|
|
716
|
-
ctx.font = f.string;
|
|
717
|
-
ctx.fillStyle = c;
|
|
718
|
-
ctx.fillText(l, xyPoint.x, xyPoint.y + lh / 2 + lhs);
|
|
719
|
-
lhs += lh;
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
function calculateXYLabel(rect, options, labelSize) {
|
|
723
|
-
const { align, position, padding } = options;
|
|
724
|
-
const x = calculateX(rect, align, padding);
|
|
725
|
-
let y;
|
|
745
|
+
function calculateBlockTop(rect, options, labelSize) {
|
|
746
|
+
const { position, padding } = options;
|
|
726
747
|
if (position === 'top') {
|
|
727
|
-
|
|
728
|
-
} else if (position === 'bottom') {
|
|
729
|
-
y = rect.y + rect.h - padding - labelSize.height;
|
|
730
|
-
} else {
|
|
731
|
-
y = rect.y + (rect.h - labelSize.height) / 2 + padding;
|
|
748
|
+
return rect.y + padding;
|
|
732
749
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
750
|
+
if (position === 'bottom') {
|
|
751
|
+
return rect.y + rect.h - padding - labelSize.height;
|
|
752
|
+
}
|
|
753
|
+
return rect.y + (rect.h - labelSize.height) / 2 + padding;
|
|
737
754
|
}
|
|
738
755
|
function calculateX(rect, align, padding) {
|
|
739
756
|
if (align === 'left') {
|
|
@@ -744,24 +761,22 @@ function calculateX(rect, align, padding) {
|
|
|
744
761
|
return rect.x + rect.w / 2;
|
|
745
762
|
}
|
|
746
763
|
|
|
747
|
-
function buildData(tree,
|
|
748
|
-
const
|
|
764
|
+
function buildData(tree, keys, mainRect, layout) {
|
|
765
|
+
const { borderWidth, captions, displayMode, groups, leafKey } = layout;
|
|
749
766
|
if (helpers.isObject(tree)) {
|
|
750
|
-
tree = normalizeTreeToArray(keys,
|
|
767
|
+
tree = normalizeTreeToArray(keys, leafKey, tree);
|
|
751
768
|
}
|
|
752
|
-
const groups = dataset.groups || [];
|
|
753
769
|
const glen = groups.length;
|
|
754
|
-
const sp =
|
|
755
|
-
const captions = dataset.captions || {};
|
|
770
|
+
const sp = displayMode === 'headerBoxes' ? 0 : layout.spacing;
|
|
756
771
|
const font = helpers.toFont(captions.font);
|
|
757
772
|
const padding = helpers.valueOrDefault(captions.padding, 3);
|
|
758
773
|
function getSubRect(sq, rect) {
|
|
759
|
-
const bw =
|
|
774
|
+
const bw = displayMode === 'headerBoxes' ? {
|
|
760
775
|
b: 0,
|
|
761
776
|
l: 0,
|
|
762
777
|
r: 0,
|
|
763
778
|
t: 0
|
|
764
|
-
} : parseBorderWidth(
|
|
779
|
+
} : parseBorderWidth(borderWidth, sq.w / 2, sq.h / 2);
|
|
765
780
|
const subRect = {
|
|
766
781
|
...rect,
|
|
767
782
|
h: sq.h - 2 * sp - bw.t - bw.b,
|
|
@@ -769,8 +784,8 @@ function buildData(tree, dataset, keys, mainRect) {
|
|
|
769
784
|
x: sq.x + sp + bw.l,
|
|
770
785
|
y: sq.y + sp + bw.t
|
|
771
786
|
};
|
|
772
|
-
if (shouldDrawCaption(
|
|
773
|
-
const captionHeight = getCaptionHeight(
|
|
787
|
+
if (shouldDrawCaption(displayMode, subRect, captions)) {
|
|
788
|
+
const captionHeight = getCaptionHeight(displayMode, subRect, font, padding);
|
|
774
789
|
subRect.y += captionHeight;
|
|
775
790
|
subRect.h -= captionHeight;
|
|
776
791
|
}
|
|
@@ -778,7 +793,7 @@ function buildData(tree, dataset, keys, mainRect) {
|
|
|
778
793
|
}
|
|
779
794
|
function recur(treeElements, gidx, rect, parent, gs) {
|
|
780
795
|
const g = getGroupKey(groups[gidx]);
|
|
781
|
-
const gdata = group(treeElements, g, keys,
|
|
796
|
+
const gdata = group(treeElements, g, keys, leafKey, undefined, parent, groups.filter((_item, index)=>index <= gidx), groups, gidx);
|
|
782
797
|
const gsq = squarify(gdata, rect, keys, g, gidx, gs);
|
|
783
798
|
const ret = gsq.slice();
|
|
784
799
|
if (gidx < glen - 1) {
|
|
@@ -801,13 +816,13 @@ function buildData(tree, dataset, keys, mainRect) {
|
|
|
801
816
|
}
|
|
802
817
|
const result = glen ? recur(tree, 0, mainRect) : squarify(tree, mainRect, keys);
|
|
803
818
|
return result.map((d)=>{
|
|
804
|
-
if (
|
|
819
|
+
if (displayMode !== 'headerBoxes' || d.isLeaf) {
|
|
805
820
|
return d;
|
|
806
821
|
}
|
|
807
|
-
if (!shouldDrawCaption(
|
|
822
|
+
if (!shouldDrawCaption(displayMode, d, captions)) {
|
|
808
823
|
return undefined;
|
|
809
824
|
}
|
|
810
|
-
const captionHeight = getCaptionHeight(
|
|
825
|
+
const captionHeight = getCaptionHeight(displayMode, d, font, padding);
|
|
811
826
|
return {
|
|
812
827
|
...d,
|
|
813
828
|
h: captionHeight
|
|
@@ -866,13 +881,26 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
866
881
|
yScale.configure();
|
|
867
882
|
}
|
|
868
883
|
}
|
|
884
|
+
_layoutOptions() {
|
|
885
|
+
const dataset = this.getDataset();
|
|
886
|
+
const options = this.options;
|
|
887
|
+
return {
|
|
888
|
+
borderWidth: dataset.borderWidth,
|
|
889
|
+
captions: dataset.captions || {},
|
|
890
|
+
displayMode: options.displayMode,
|
|
891
|
+
groups: options.groups || [],
|
|
892
|
+
leafKey: options.leafKey,
|
|
893
|
+
spacing: helpers.valueOrDefault(dataset.spacing, 0)
|
|
894
|
+
};
|
|
895
|
+
}
|
|
869
896
|
update(mode) {
|
|
870
897
|
const dataset = this.getDataset();
|
|
871
898
|
const { data } = this.getMeta();
|
|
872
|
-
const
|
|
899
|
+
const options = this.options;
|
|
900
|
+
const groups = options.groups || [];
|
|
873
901
|
const keys = [
|
|
874
|
-
|
|
875
|
-
].concat(
|
|
902
|
+
options.key || ''
|
|
903
|
+
].concat(options.sumKeys || []);
|
|
876
904
|
dataset.tree = dataset.tree || dataset.data || [];
|
|
877
905
|
const tree = dataset.tree;
|
|
878
906
|
const treeVersion = dataset.treeVersion;
|
|
@@ -885,7 +913,7 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
885
913
|
this._prevTree = tree;
|
|
886
914
|
this._prevTreeVersion = treeVersion;
|
|
887
915
|
this._rectChanged = false;
|
|
888
|
-
dataset.data = buildData(tree,
|
|
916
|
+
dataset.data = buildData(tree, this._keys, this._rect, this._layoutOptions());
|
|
889
917
|
this._dataCheck();
|
|
890
918
|
this._resyncElements();
|
|
891
919
|
}
|
|
@@ -899,9 +927,10 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
899
927
|
const sharedOptions = this.getSharedOptions(firstOpts);
|
|
900
928
|
const includeOptions = this.includeOptions(mode, sharedOptions || {});
|
|
901
929
|
const { xScale, yScale } = this.getMeta();
|
|
930
|
+
const spacing = this.options.spacing;
|
|
902
931
|
for(let i = start; i < start + count; i++){
|
|
903
932
|
const options = sharedOptions || this.resolveDataElementOptions(i, mode);
|
|
904
|
-
const properties = scaleRect(dataset.data[i], xScale, yScale,
|
|
933
|
+
const properties = scaleRect(dataset.data[i], xScale, yScale, spacing);
|
|
905
934
|
if (reset) {
|
|
906
935
|
properties.width = 0;
|
|
907
936
|
properties.height = 0;
|
|
@@ -918,11 +947,17 @@ class TreemapController extends chart_js.DatasetController {
|
|
|
918
947
|
const metadata = this.getMeta().data || [];
|
|
919
948
|
const dataset = this.getDataset();
|
|
920
949
|
const data = dataset.data;
|
|
950
|
+
const { displayMode, rtl, spacing } = this.options;
|
|
951
|
+
const layout = {
|
|
952
|
+
displayMode,
|
|
953
|
+
rtl,
|
|
954
|
+
spacing
|
|
955
|
+
};
|
|
921
956
|
helpers.clipArea(ctx, chartArea);
|
|
922
957
|
for(let i = 0, ilen = metadata.length; i < ilen; ++i){
|
|
923
958
|
const rect = metadata[i];
|
|
924
959
|
if (!rect.hidden) {
|
|
925
|
-
rect.draw(ctx, data[i]);
|
|
960
|
+
rect.draw(ctx, data[i], layout);
|
|
926
961
|
}
|
|
927
962
|
}
|
|
928
963
|
helpers.unclipArea(ctx);
|
|
@@ -949,7 +984,15 @@ TreemapController.defaults = {
|
|
|
949
984
|
type: 'number'
|
|
950
985
|
}
|
|
951
986
|
},
|
|
952
|
-
dataElementType: 'treemap'
|
|
987
|
+
dataElementType: 'treemap',
|
|
988
|
+
displayMode: layoutDefaults.displayMode,
|
|
989
|
+
groups: [],
|
|
990
|
+
key: '',
|
|
991
|
+
leafKey: '_leaf',
|
|
992
|
+
rtl: layoutDefaults.rtl,
|
|
993
|
+
spacing: layoutDefaults.spacing,
|
|
994
|
+
sumKeys: [],
|
|
995
|
+
unsorted: false
|
|
953
996
|
};
|
|
954
997
|
TreemapController.descriptors = {
|
|
955
998
|
_indexable: false,
|
|
@@ -1079,7 +1122,7 @@ function addNormalRectPath(ctx, rect) {
|
|
|
1079
1122
|
}
|
|
1080
1123
|
|
|
1081
1124
|
class TreemapElement extends chart_js.Element {
|
|
1082
|
-
draw(ctx, data) {
|
|
1125
|
+
draw(ctx, data, layout = layoutDefaults) {
|
|
1083
1126
|
if (!data) {
|
|
1084
1127
|
return;
|
|
1085
1128
|
}
|
|
@@ -1099,7 +1142,7 @@ class TreemapElement extends chart_js.Element {
|
|
|
1099
1142
|
addRectPath(ctx, inner);
|
|
1100
1143
|
ctx.fillStyle = options.backgroundColor;
|
|
1101
1144
|
ctx.fill();
|
|
1102
|
-
drawText(ctx, inner, options, data, this);
|
|
1145
|
+
drawText(ctx, inner, options, data, this, layout);
|
|
1103
1146
|
ctx.restore();
|
|
1104
1147
|
}
|
|
1105
1148
|
inRange(mouseX, mouseY, useFinalPosition) {
|
|
@@ -1150,8 +1193,6 @@ TreemapElement.defaults = {
|
|
|
1150
1193
|
},
|
|
1151
1194
|
padding: 3
|
|
1152
1195
|
},
|
|
1153
|
-
displayMode: 'containerBoxes',
|
|
1154
|
-
label: undefined,
|
|
1155
1196
|
labels: {
|
|
1156
1197
|
align: 'center',
|
|
1157
1198
|
color: 'black',
|
|
@@ -1173,10 +1214,7 @@ TreemapElement.defaults = {
|
|
|
1173
1214
|
overflow: 'cut',
|
|
1174
1215
|
padding: 3,
|
|
1175
1216
|
position: 'middle'
|
|
1176
|
-
}
|
|
1177
|
-
rtl: false,
|
|
1178
|
-
spacing: 0.5,
|
|
1179
|
-
unsorted: false
|
|
1217
|
+
}
|
|
1180
1218
|
};
|
|
1181
1219
|
TreemapElement.descriptors = {
|
|
1182
1220
|
_indexable: false,
|