123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /* *
- *
- * (c) 2016-2019 Highsoft AS
- *
- * Authors: Jon Arild Nygard
- *
- * License: www.highcharts.com/license
- *
- * */
- /* eslint no-console: 0 */
- 'use strict';
- import H from '../parts/Globals.js';
- import '../parts/Utilities.js';
- var extend = H.extend,
- isNumber = H.isNumber,
- pick = H.pick,
- isFunction = function (x) {
- return typeof x === 'function';
- };
- /**
- * Creates an object map from parent id to childrens index.
- *
- * @private
- * @function Highcharts.Tree#getListOfParents
- *
- * @param {Array<*>} data
- * List of points set in options. `Array<*>.parent`is parent id of point.
- *
- * @param {Array<string>} ids
- * List of all point ids.
- *
- * @return {object}
- * Map from parent id to children index in data
- */
- var getListOfParents = function (data, ids) {
- var listOfParents = data.reduce(function (prev, curr) {
- var parent = pick(curr.parent, '');
- if (prev[parent] === undefined) {
- prev[parent] = [];
- }
- prev[parent].push(curr);
- return prev;
- }, {}),
- parents = Object.keys(listOfParents);
- // If parent does not exist, hoist parent to root of tree.
- parents.forEach(function (parent, list) {
- var children = listOfParents[parent];
- if ((parent !== '') && (ids.indexOf(parent) === -1)) {
- children.forEach(function (child) {
- list[''].push(child);
- });
- delete list[parent];
- }
- });
- return listOfParents;
- };
- var getNode = function (id, parent, level, data, mapOfIdToChildren, options) {
- var descendants = 0,
- height = 0,
- after = options && options.after,
- before = options && options.before,
- node = {
- data: data,
- depth: level - 1,
- id: id,
- level: level,
- parent: parent
- },
- start,
- end,
- children;
- // Allow custom logic before the children has been created.
- if (isFunction(before)) {
- before(node, options);
- }
- // Call getNode recursively on the children. Calulate the height of the
- // node, and the number of descendants.
- children = ((mapOfIdToChildren[id] || [])).map(function (child) {
- var node = getNode(
- child.id,
- id,
- (level + 1),
- child,
- mapOfIdToChildren,
- options
- ),
- childStart = child.start,
- childEnd = (
- child.milestone === true ?
- childStart :
- child.end
- );
- // Start should be the lowest child.start.
- start = (
- (!isNumber(start) || childStart < start) ?
- childStart :
- start
- );
- // End should be the largest child.end.
- // If child is milestone, then use start as end.
- end = (
- (!isNumber(end) || childEnd > end) ?
- childEnd :
- end
- );
- descendants = descendants + 1 + node.descendants;
- height = Math.max(node.height + 1, height);
- return node;
- });
- // Calculate start and end for point if it is not already explicitly set.
- if (data) {
- data.start = pick(data.start, start);
- data.end = pick(data.end, end);
- }
- extend(node, {
- children: children,
- descendants: descendants,
- height: height
- });
- // Allow custom logic after the children has been created.
- if (isFunction(after)) {
- after(node, options);
- }
- return node;
- };
- var getTree = function (data, options) {
- var ids = data.map(function (d) {
- return d.id;
- }),
- mapOfIdToChildren = getListOfParents(data, ids);
- return getNode('', null, 1, null, mapOfIdToChildren, options);
- };
- var Tree = {
- getListOfParents: getListOfParents,
- getNode: getNode,
- getTree: getTree
- };
- export default Tree;
|