From b91f42a1db1d002075df655b12cc34510654b49b Mon Sep 17 00:00:00 2001 From: stockiNail Date: Sun, 18 Sep 2022 10:02:11 +0200 Subject: [PATCH] Enable tree data as an object using the hierarchy of its properties (#98) * Enable tree data as an object using its hierarchy * reduces complexity to group function * removes hardcoded group key using index number as string * fixes parent group converting as string * adds test case with tree object with groups with number array * adds treeLeafKey option * fixes path calculation * changes check if the tree is an object * tests pull_request_target event on CI * reverts pull_request_target from CI * adds sample * adds sample - 2 --- docs/.vuepress/config.js | 1 + docs/samples/tree.md | 77 +++++++++++++++ docs/scripts/data.js | 81 ++++++++++++++++ docs/usage.md | 6 +- src/controller.js | 16 ++-- src/element.js | 4 +- src/utils.js | 90 ++++++++++++++++-- test/fixtures/grouped/treeBasic.js | 54 +++++++++++ test/fixtures/grouped/treeBasic.png | Bin 0 -> 8723 bytes test/fixtures/grouped/treeBasicAndCaptions.js | 54 +++++++++++ .../fixtures/grouped/treeBasicAndCaptions.png | Bin 0 -> 9983 bytes .../grouped/treeBasicWithGroupsNumbers.js | 54 +++++++++++ .../grouped/treeBasicWithGroupsNumbers.png | Bin 0 -> 8723 bytes test/fixtures/grouped/treeBasicWithLeafKey.js | 55 +++++++++++ .../fixtures/grouped/treeBasicWithLeafKey.png | Bin 0 -> 8723 bytes test/specs/utils.spec.js | 29 +++++- types/index.esm.d.ts | 3 +- 17 files changed, 501 insertions(+), 23 deletions(-) create mode 100644 docs/samples/tree.md create mode 100644 test/fixtures/grouped/treeBasic.js create mode 100644 test/fixtures/grouped/treeBasic.png create mode 100644 test/fixtures/grouped/treeBasicAndCaptions.js create mode 100644 test/fixtures/grouped/treeBasicAndCaptions.png create mode 100644 test/fixtures/grouped/treeBasicWithGroupsNumbers.js create mode 100644 test/fixtures/grouped/treeBasicWithGroupsNumbers.png create mode 100644 test/fixtures/grouped/treeBasicWithLeafKey.js create mode 100644 test/fixtures/grouped/treeBasicWithLeafKey.png diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9edfb0c..b910838 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -49,6 +49,7 @@ module.exports = { 'basic', 'labels', 'groups', + 'tree', 'captions', 'dividers', 'rtl' diff --git a/docs/samples/tree.md b/docs/samples/tree.md new file mode 100644 index 0000000..e84db0c --- /dev/null +++ b/docs/samples/tree.md @@ -0,0 +1,77 @@ +# Tree + +```js chart-editor +// +const options = { + plugins: { + title: { + display: true + }, + legend: { + display: false + }, + tooltip: { + callbacks: { + title(items) { + const dataItem = items[0].raw; + const obj = dataItem._data; + return obj.name; + }, + } + } + } +}; +// + +// +const config = { + type: 'treemap', + data: { + datasets: [{ + tree: Data.objectsTree, + treeLeafKey: 'name', + key: 'value', + groups: [], + spacing: 1, + borderWidth: 0.5, + borderColor: '#FF8F00', + backgroundColor: 'rgba(255,167,38,0.3)', + hoverBackgroundColor: 'rgba(238,238,238,0.5)', + captions: { + align: 'center' + }, + labels: { + display: true, + formatter: (ctx) => { + return ctx.raw.v; + } + } + }] + }, + options +}; +// + +function toggle(chart) { + const dataset = chart.data.datasets[0]; + if (dataset.groups.length) { + dataset.groups = []; + } else { + dataset.groups = [0, 1]; + dataset.groups.push('name'); + } + chart.update(); +} + +const actions = [ + { + name: 'Toggle GroupBy', + handler: (chart) => toggle(chart) + } +]; + +module.exports = { + actions, + config, +}; +``` diff --git a/docs/scripts/data.js b/docs/scripts/data.js index 11df710..df65eb1 100644 --- a/docs/scripts/data.js +++ b/docs/scripts/data.js @@ -460,3 +460,84 @@ export const statsByState = [ area: 253335 } ]; + +export const objectsTree = { + analytics: { + cluster: { + agglomerative: { + value: 3938 + }, + communityStructure: { + value: 3812 + }, + hierarchical: { + value: 6714 + }, + mergeEdge: { + value: 743 + }, + }, + graph: { + betweennessCentrality: { + value: 3534 + }, + linkDistance: { + value: 5731 + }, + maxFlowMinCut: { + value: 7840 + }, + shortestPaths: { + value: 5914 + }, + spanningTree: { + value: 3416 + }, + }, + optimization: { + aspectRatioBanker: { + value: 7074 + } + } + }, + animate: { + easing: { + value: 17010 + }, + functionSequence: { + vaue: 5842 + }, + interpolate: { + arrayInterpolator: { + value: 1983 + }, + colorInterpolator: { + value: 2047 + }, + dateInterpolator: { + value: 1375 + }, + interpolator: { + value: 8746 + }, + matrixInterpolator: { + value: 2202 + }, + numberInterpolator: { + value: 1382 + }, + objectInterpolator: { + value: 1629 + }, + pointInterpolator: { + value: 1675 + }, + rectangleInterpolator: { + value: 2042 + }, + }, + schedulable: { + value: 1041 + } + } +}; diff --git a/docs/usage.md b/docs/usage.md index 3404b11..a62b2d3 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -101,7 +101,8 @@ These are used to set display properties for a specific dataset. | [`labels`](#labels) | `object` | - | | [`rtl`](#general) | `boolean` | - | `false` | [`spacing`](#styling) | `number` | - | `0.5` -| [`tree`](#general) | `number[]` \| `object[]` | - | **required** +| [`tree`](#general) | `number[]` \| `object[]` \| `object` | - | **required** +| [`treeLeafKey`](#general) | `string` | - | `_leaf` | All these values, if `undefined`, fallback to the scopes described in [option resolution](https://www.chartjs.org/docs/latest/general/options.html). @@ -114,8 +115,9 @@ All these values, if `undefined`, fallback to the scopes described in [option re | `label` | The label for the dataset which appears in the legend and tooltips. | `rtl` | If `true`, the treemap elements are rendering from right to left. | `tree` | Tree data should be provided in `tree` property of dataset. `data` is then automatically build. +| `treeLeafKey` | The name of the key where the object key of leaf node of tree object is stored. Used only when `tree` is an `object`, as hierarchical data. -Only the `tree`, `key` and `groups` options need to be specified in the dataset namespace. +Only the `tree`, `treeLeafKey`, `key` and `groups` options need to be specified in the dataset namespace. ```js function colorFromRaw(ctx) { diff --git a/src/controller.js b/src/controller.js index a74306b..5b55ce2 100644 --- a/src/controller.js +++ b/src/controller.js @@ -1,6 +1,6 @@ import {Chart, DatasetController, registry} from 'chart.js'; -import {toFont, valueOrDefault} from 'chart.js/helpers'; -import {group, requireVersion} from './utils'; +import {toFont, valueOrDefault, isObject} from 'chart.js/helpers'; +import {group, requireVersion, normalizeTreeToArray, getGroupKey} from './utils'; import {shouldDrawCaption} from './element'; import squarify from './squarify'; import {version} from '../package.json'; @@ -30,7 +30,11 @@ function arrayNotEqual(a1, a2) { function buildData(dataset, mainRect, captions) { const key = dataset.key || ''; + const treeLeafKey = dataset.treeLeafKey || '_leaf'; let tree = dataset.tree || []; + if (isObject(tree)) { + tree = normalizeTreeToArray(key, treeLeafKey, tree); + } const groups = dataset.groups || []; const glen = groups.length; const sp = valueOrDefault(dataset.spacing, 0) + valueOrDefault(dataset.borderWidth, 0); @@ -39,9 +43,9 @@ function buildData(dataset, mainRect, captions) { const padding = valueOrDefault(captions.padding, 3); function recur(gidx, rect, parent, gs) { - const g = groups[gidx]; - const pg = (gidx > 0) && groups[gidx - 1]; - const gdata = group(tree, g, key, pg, parent); + const g = getGroupKey(groups[gidx]); + const pg = (gidx > 0) && getGroupKey(groups[gidx - 1]); + const gdata = group(tree, g, key, treeLeafKey, pg, parent, groups.filter((item, index) => index <= gidx)); const gsq = squarify(gdata, rect, key, g, gidx, gs); const ret = gsq.slice(); let subRect; @@ -199,7 +203,7 @@ TreemapController.overrides = { label(item) { const dataset = item.dataset; const dataItem = dataset.data[item.dataIndex]; - const label = dataItem.g || dataset.label; + const label = dataItem.g || dataItem._data.label || dataset.label; return (label ? label + ': ' : '') + dataItem.v; } } diff --git a/src/element.js b/src/element.js index df26557..3dfe78a 100644 --- a/src/element.js +++ b/src/element.js @@ -276,7 +276,7 @@ TreemapElement.defaults = { align: undefined, color: 'black', display: true, - formatter: (ctx) => ctx.raw.g || '', + formatter: (ctx) => ctx.raw.g || ctx.raw._data.label || '', font: {}, padding: 3 }, @@ -284,7 +284,7 @@ TreemapElement.defaults = { align: 'center', color: 'black', display: false, - formatter: (ctx) => ctx.raw.g ? [ctx.raw.g, ctx.raw.v] : ctx.raw.v, + formatter: (ctx) => ctx.raw.g ? [ctx.raw.g, ctx.raw.v] : (ctx.raw._data.label ? [ctx.raw._data.label, ctx.raw.v] : ctx.raw.v), font: {}, position: 'middle', padding: 3 diff --git a/src/utils.js b/src/utils.js index 5b91171..8f1e095 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,54 @@ import {isObject} from 'chart.js/helpers'; +export const getGroupKey = (lvl) => '' + lvl; + +function scanTreeObject(key, treeLeafKey, obj, tree = [], lvl = 0, result = []) { + const objIndex = lvl - 1; + if (key in obj && lvl > 0) { + const record = tree.reduce(function(reduced, item, i) { + if (i !== objIndex) { + reduced[getGroupKey(i)] = item; + } + return reduced; + }, {}); + record[treeLeafKey] = tree[objIndex]; + record[key] = obj[key]; + result.push(record); + } else { + for (const childKey of Object.keys(obj)) { + const child = obj[childKey]; + if (isObject(child)) { + tree.push(childKey); + scanTreeObject(key, treeLeafKey, child, tree, lvl + 1, result); + } + } + } + tree.splice(objIndex, 1); + return result; +} + +export function normalizeTreeToArray(key, treeLeafKey, obj) { + const data = scanTreeObject(key, treeLeafKey, obj); + if (!data.length) { + return data; + } + const max = data.reduce(function(maxValue, element) { + // minus 2 because _leaf and value properties are added + // on top to groups ones + const keys = Object.keys(element).length - 2; + return maxValue > keys ? maxValue : keys; + }); + data.forEach(function(element) { + for (let i = 0; i < max; i++) { + const groupKey = getGroupKey(i); + if (!element[groupKey]) { + element[groupKey] = ''; + } + } + }); + return data; +} + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat export function flatten(input) { const stack = [...input]; @@ -18,36 +67,59 @@ export function flatten(input) { return res.reverse(); } +function getPath(groups, value, defaultValue) { + if (!groups.length) { + return; + } + const path = []; + for (const grp of groups) { + const item = value[grp]; + if (item === '') { + path.push(defaultValue); + break; + } + path.push(item); + } + return path.length ? path.join('.') : defaultValue; +} + /** * @param {[]} values * @param {string} grp * @param {string} key + * @param {string} treeeLeafKey * @param {string} [mainGrp] * @param {*} [mainValue] + * @param {[]} groups */ -export function group(values, grp, key, mainGrp, mainValue) { +export function group(values, grp, key, treeLeafKey, mainGrp, mainValue, groups = []) { const tmp = Object.create(null); const data = Object.create(null); const ret = []; - let g, i, n, v; + let g, i, n; for (i = 0, n = values.length; i < n; ++i) { - v = values[i]; + const v = values[i]; if (mainGrp && v[mainGrp] !== mainValue) { continue; } - g = v[grp] || ''; + g = v[grp] || v[treeLeafKey] || ''; if (!(g in tmp)) { - tmp[g] = 0; + tmp[g] = {value: 0}; data[g] = []; } - tmp[g] += +v[key]; + tmp[g].value += +v[key]; + tmp[g].label = v[grp] || ''; + tmp[g].path = getPath(groups, v, g); data[g].push(v); } Object.keys(tmp).forEach((k) => { - v = {children: data[k]}; - v[key] = +tmp[k]; - v[grp] = k; + const v = {children: data[k]}; + v[key] = +tmp[k].value; + v[grp] = tmp[k].label; + v.label = k; + v.path = tmp[k].path; + if (mainGrp) { v[mainGrp] = mainValue; } diff --git a/test/fixtures/grouped/treeBasic.js b/test/fixtures/grouped/treeBasic.js new file mode 100644 index 0000000..b19b28d --- /dev/null +++ b/test/fixtures/grouped/treeBasic.js @@ -0,0 +1,54 @@ +const data = { + A: { + C: { + C1: { + C1a: { + value: 6.25 + }, + C1b: { + value: 6.25 + }, + }, + C2: { + value: 12.5 + } + }, + D: { + value: 25 + } + }, + B: { + value: 50, + }, + G: { + C: { + value: 50 + } + }, +}; + +export default { + config: { + type: 'treemap', + data: { + datasets: [{ + tree: data, + key: 'value', + groups: ['0', '1', '2', '_leaf'], + captions: { + display: false + }, + labels: { + display: true + } + }] + }, + }, + options: { + canvas: { + height: 256, + width: 512 + }, + spriteText: true + } +}; diff --git a/test/fixtures/grouped/treeBasic.png b/test/fixtures/grouped/treeBasic.png new file mode 100644 index 0000000000000000000000000000000000000000..3b441c4b5faf8953770e2002056fc8623ddeaad1 GIT binary patch literal 8723 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

wK* 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 literal 0 HcmV?d00001 diff --git a/test/fixtures/grouped/treeBasicWithGroupsNumbers.js b/test/fixtures/grouped/treeBasicWithGroupsNumbers.js new file mode 100644 index 0000000..e379856 --- /dev/null +++ b/test/fixtures/grouped/treeBasicWithGroupsNumbers.js @@ -0,0 +1,54 @@ +const data = { + A: { + C: { + C1: { + C1a: { + value: 6.25 + }, + C1b: { + value: 6.25 + }, + }, + C2: { + value: 12.5 + } + }, + D: { + value: 25 + } + }, + B: { + value: 50, + }, + G: { + C: { + value: 50 + } + }, +}; + +export default { + config: { + type: 'treemap', + data: { + datasets: [{ + tree: data, + key: 'value', + groups: [0, 1, 2, '_leaf'], + captions: { + display: false + }, + labels: { + display: true + } + }] + }, + }, + options: { + canvas: { + height: 256, + width: 512 + }, + spriteText: true + } +}; diff --git a/test/fixtures/grouped/treeBasicWithGroupsNumbers.png b/test/fixtures/grouped/treeBasicWithGroupsNumbers.png new file mode 100644 index 0000000000000000000000000000000000000000..3b441c4b5faf8953770e2002056fc8623ddeaad1 GIT binary patch literal 8723 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

wK* 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

wK* zbb*@MBsSxa`z4<)M|6hqvS8sK-9v3~sKn%2@&yNQQP)Po7 zDKxwgoK5C$6jji$j$;QFxEzRvLY3^;s>nw;i2#=|s)48^?1!$-Nxi)ZW|MeiDZpf6 zel-3^2GR7VQ2KhS62E=>woQCWR~E^DcCC)RUsP0-%SbLSFL#(KSC>oA!&biXW+>TJ zfxa`EQ!|1w!XQd(QGBFbj6pS*zS-V$7HseI%pV=n>wkCDS4#WOfEsU)Z=%|?-#>Y93ARzUMbjYa-r zV`CLc@xHsj?~{wf{*WeLTLD6*sIRFfN-|i=yF~cD*lHlBNYMZ0J{2Z6ytb-wGuF4q z*`w(O;AW00Vp!#+8?Hs zFB}NENdpV>S%240R9;XimnffftUJqp(w9~w=!1^G3H)veABgE11`y$`#&4xhKUcu| zMcv^1utv+8?uda^DeEZLqh+G>CK=qet70_t)Hs0qZTu$$CheaWhxSB^zsS?f0_LLP zdmZ7?PR-!Jlu%GUkXIxbX7}WkeVnO~cWdjSW_g&dN5$`)7*>kH;7MN$fPPCJIOgY9 z5JH#msC*7eGRB~%(#O-KjgPakt^oV{%fQ>|awYyH;`FawVNEvU&(uslhe*ZKn}DIM zHmE%h6F6bnttbp1-z5rA6f*+9_rIYwn6-T-E3G;D9E-*`Bm;ZVfCeJak;06iz0QQa z6KqJ*qnrh}G8k+ifd-Oo6GC4lA)A`RqRKofYitO!CNE`LBxX>v7UcnpodGF%y36rxli8Db4y zw;Iatkq*(uYaL_WPK^!F>P_`ghPEONlIdc76c!6phYKC+Kw%sxBu}%dutJz7d|ZUA zkAiz=SbMI9`JWgYzq&Wu2q_m7Xn(eM3_N%0cmP=#oB9pRyWaB!pi>MshaKdY=J zcx}WeeiGKF^$&g&2mOc+oggHJe`dyY*YfGnx>b@qid4Xe|;UD`X!jhvM!0v%{k@IE4yR?DE^XVf% z<8rj)XVjXP^^IR8%+B9-p0V|1Hr1;no{kJYkj9ZGah+tVkNb~KZ zyUv4thgVXT`)HQ1KSbzL2H z6`!FU-c^4Q2R3>n9)S?9vuzt13L)TqT?lJBQ43w)K>j^MZk575ST1@F0pm}K28G6h zWP>Q!r*C(l81}W^IYoq!-E?zl0fcN7-|nrjlHloWNJ0RX)Qi=JeKj}cQS9L9d0|Wg13#Xi^ly>23D?JKB0K-`Vo}yMqJeM?ifi>WM3*x@Zpj^b8GBe?p?D0W69}mlzrkd za8q?Y_P;O#VvW#4Fdtmf)Mql8<|(E=zrb>Fv^lIrqw$OG0(%SZO(rDJf6el#0$xJl zP_FOzZjQ3fVUM1PmlgsFQ8FJDuL1d8w=e@1*1o^I$2WjB*)TpAaNCqmMjJz|`mYXH zsm!q>PQ95vg1C^QA(6iQRTVjDJNG+8#O@?*1wLxlq@kL*TtE6`9a*5AK5@RJxVYVs zKDF=P?F`y^9J2k>Jhm(XW{cDpb6jxXE995*#cB~KG%2KBl>n!|LU41#wHKPf6!lhvy%GzmJ%o z9`)8;=etw(4hoY(g)n&q5e9`r>SwKnOUy8!>mZkort4xz>03H86!b7NT&qmY2i6>Y z){Y%FKyz#hn$*!5j!S}_6!)%dt=f5^5DqI$f(L)tqK?Mzj~_6A4OpK>A-pW>*<37) z;LS;vhI!$!*JOSYr`7c^hnj)4t_9{OiY(~Ikr{145;n8ewT*JXJ=aX%<;5=JMt2H5SJj=9Pu^%on=kpX6 zc5Y5yXRWx7t>&BIJUCyC?X&Sf3-!c$CtT!yZ-z4*^JB9=Ec?R^cFft@JpK&+FW{-- zzW_gi?f)M#jDllpiWchy1mf|t+k<@{rMS{R%-?Ac|8wZ``i_R2wWlr*%)+S& { data: TreemapDataPoint[]; // This will be auto-generated from `tree` groups?: Array; - tree: number[] | DType[]; + tree: number[] | DType[] | AnyObject; + treeLeafKey?: keyof DType; key?: keyof DType; }