/** * Typescript definition tests for d3/d3-hierarchy module * * Note: These tests are intended to test the definitions only * in the sense of typing and call signature consistency. They * are not intended as functional tests. */ import * as d3Hierarchy from 'd3-hierarchy'; // ----------------------------------------------------------------------- // Preparatory Steps // ----------------------------------------------------------------------- let str: string; let num: number; let numOrUndefined: number | undefined; let size: [number, number]; let sizeOrNull: [number, number] | null; let idString: string | undefined; // ----------------------------------------------------------------------- // Hierarchy // ----------------------------------------------------------------------- interface HierarchyDatum { name: string; val: number; children?: HierarchyDatum[]; } let hierarchyRootDatum: HierarchyDatum = { name: 'n0', val: 10, children: [ { name: 'n11', val: 5 }, { name: 'n12', val: 4, children: [ { name: 'n121', val: 30 } ] } ] }; let hierarchyNodeArray: Array> = []; let hierarchyNodeArrayOrUndefined: Array> | undefined; let hierarchyNode: d3Hierarchy.HierarchyNode; let hierarchyPointNodeArray: Array> = []; let hierarchyPointNodeArrayOrUndefined: Array> | undefined; let hierarchyPointNode: d3Hierarchy.HierarchyPointNode; let hierarchyRectangularNodeArray: Array> = []; let hierarchyRectangularNodeArrayOrUndefined: Array> | undefined; let hierarchyRectangularNode: d3Hierarchy.HierarchyRectangularNode; let hierarchyCircularNodeArray: Array> = []; let hierarchyCircularNodeArrayOrUndefined: Array> | undefined; let hierarchyCircularNode: d3Hierarchy.HierarchyCircularNode; // Create Hierarchy Layout Root Node ===================================== let hierarchyRootNode: d3Hierarchy.HierarchyNode; hierarchyRootNode = d3Hierarchy.hierarchy(hierarchyRootDatum); hierarchyRootNode = d3Hierarchy.hierarchy(hierarchyRootDatum, (d) => { return d.children; }); hierarchyRootNode = d3Hierarchy.hierarchy(hierarchyRootDatum, (d) => { return d.children || null; }); // Use Hierarchy Node ==================================================== // data, depth, height --------------------------------------------------- hierarchyRootDatum = hierarchyRootNode.data; num = hierarchyRootNode.depth; num = hierarchyRootNode.height; // children, parent ------------------------------------------------------ hierarchyNodeArrayOrUndefined = hierarchyRootNode.children; let parentNode: d3Hierarchy.HierarchyNode | null; parentNode = hierarchyNodeArray.length ? hierarchyNodeArray[0].parent : null; parentNode = hierarchyNodeArray[0].parent; // id -------------------------------------------------------------------- idString = hierarchyRootNode.id; // ancestors(), descendants() -------------------------------------------- const ancestors: Array> = hierarchyRootNode.ancestors(); const descendants: Array> = hierarchyRootNode.descendants(); // leaves() -------------------------------------------------------------- hierarchyNodeArray = hierarchyRootNode.leaves(); // path() ---------------------------------------------------------------- hierarchyNode = descendants[descendants.length - 1]; const path: Array> = hierarchyRootNode.path(hierarchyNode); // links() and HierarchyLink<...> ---------------------------------------- let links: Array>; links = hierarchyRootNode.links(); let link: d3Hierarchy.HierarchyLink; link = links[0]; hierarchyNode = link.source; hierarchyNode = link.target; // sum() and value ------------------------------------------------------- hierarchyRootNode = hierarchyRootNode.sum((d) => d.val); numOrUndefined = hierarchyRootNode.value; // count() and value ----------------------------------------------------- hierarchyRootNode = hierarchyRootNode.count(); numOrUndefined = hierarchyRootNode.value; // sort ------------------------------------------------------------------ hierarchyRootNode = hierarchyRootNode.sort((a, b) => { console.log('Raw values in data of a and b:', a.data.val, ' and ', b.data.val); // a and b are of type HierarchyNode return b.height - a.height || b.value! - a.value!; }); // each(), eachAfter(), eachBefore() ------------------------------------- hierarchyRootNode = hierarchyRootNode.each((node) => { console.log('Raw value of node:', node.data.val); // node type is HierarchyNode console.log('Aggregated value of node:', node.value); // node type is HierarchyNode }); hierarchyRootNode = hierarchyRootNode.eachAfter((node) => { console.log('Raw value of node:', node.data.val); // node type is HierarchyNode console.log('Aggregated value of node:', node.value); // node type is HierarchyNode }); hierarchyRootNode = hierarchyRootNode.eachBefore((node) => { console.log('Raw value of node:', node.data.val); // node type is HierarchyNode console.log('Aggregated value of node:', node.value); // node type is HierarchyNode }); // copy() ---------------------------------------------------------------- let copiedHierarchyNode: d3Hierarchy.HierarchyNode; copiedHierarchyNode = hierarchyRootNode.copy(); // ----------------------------------------------------------------------- // Stratify // ----------------------------------------------------------------------- interface HierarchyDatumWithParentId extends HierarchyDatum { parentId: string | null; } interface TabularHierarchyDatum { name: string; parentId: string | null; val: number; } let tabularData: TabularHierarchyDatum[]; tabularData = [ { name: 'n0', parentId: null, val: 10 }, { name: 'n11', parentId: 'n0', val: 5 }, { name: 'n12', parentId: 'n0', val: 4 }, { name: 'n121', parentId: 'n12', val: 30 } ]; let idStringAccessor: (d: TabularHierarchyDatum, i: number, data: TabularHierarchyDatum[]) => (string | null | '' | undefined); // Create Stratify Operator --------------------------------------------- let stratificatorizer: d3Hierarchy.StratifyOperator; stratificatorizer = d3Hierarchy.stratify(); // Configure Stratify Operator ------------------------------------------ // id(...) stratificatorizer = stratificatorizer.id((d) => { return d.name; // d is of type TabularHierarchyDatum }); stratificatorizer = stratificatorizer.id((d, i, data) => { console.log('Length of tabular array: ', data.length); console.log('Name of first entry in tabular array: ', data[0].name); // data of type Array return d.name; // d is of type TabularHierarchyDatum }); idStringAccessor = stratificatorizer.id(); // parentId(...) stratificatorizer = stratificatorizer.parentId((d) => { return d.parentId; // d is of type TabularHierarchyDatum }); stratificatorizer = stratificatorizer.parentId((d, i, data) => { console.log('Length of tabular array: ', data.length); console.log('Name of first entry in tabular array: ', data[0].name); // data of type Array return d.parentId; // d is of type TabularHierarchyDatum }); idStringAccessor = stratificatorizer.parentId(); // Use Stratify Operator ------------------------------------------------ const stratifiedRootNode: d3Hierarchy.HierarchyNode = stratificatorizer(tabularData); const pId: string | null = stratifiedRootNode.data.parentId; // ----------------------------------------------------------------------- // Cluster // ----------------------------------------------------------------------- // Create cluster layout generator ======================================= let clusterLayout: d3Hierarchy.ClusterLayout; clusterLayout = d3Hierarchy.cluster(); // Configure cluster layout generator ==================================== // size() ---------------------------------------------------------------- clusterLayout = clusterLayout.size([200, 200]); sizeOrNull = clusterLayout.size(); // nodeSize() ------------------------------------------------------------ clusterLayout = clusterLayout.nodeSize([10, 10]); sizeOrNull = clusterLayout.nodeSize(); // separation() ---------------------------------------------------------- clusterLayout = clusterLayout.separation(function separation(a, b) { return a.data.parentId === b.data.parentId ? 1 : 2; // a and b are nodes of type HierarchyPointNode }); let separationAccessor: (a: d3Hierarchy.HierarchyPointNode, b: d3Hierarchy.HierarchyPointNode) => number; separationAccessor = clusterLayout.separation(); // Use cluster layout generator ========================================== let clusterRootNode: d3Hierarchy.HierarchyPointNode; clusterRootNode = clusterLayout(stratifiedRootNode); // Use HierarchyPointNode ================================================ // x and y coordinates --------------------------------------------------- num = clusterRootNode.x; num = clusterRootNode.y; // data, depth, height --------------------------------------------------- const clusterDatum: HierarchyDatumWithParentId = clusterRootNode.data; num = clusterRootNode.depth; num = clusterRootNode.height; // children, parent ------------------------------------------------------ hierarchyPointNodeArrayOrUndefined = clusterRootNode.children; let parentPointNode: d3Hierarchy.HierarchyPointNode | null; parentPointNode = hierarchyPointNodeArray.length ? hierarchyPointNodeArray[0].parent : null; parentPointNode = hierarchyPointNodeArray[0].parent; // id -------------------------------------------------------------------- idString = clusterRootNode.id; // ancestors(), descendants() -------------------------------------------- const pointNodeAncestors: Array> = clusterRootNode.ancestors(); const pointNodeDescendants: Array> = clusterRootNode.descendants(); // leaves() -------------------------------------------------------------- hierarchyPointNodeArray = clusterRootNode.leaves(); // path() ---------------------------------------------------------------- hierarchyPointNode = pointNodeDescendants[pointNodeDescendants.length - 1]; const clusterPath: Array> = clusterRootNode.path(hierarchyPointNode); // links() and HierarchyPointLink<...> ----------------------------------- let pointLinks: Array>; pointLinks = clusterRootNode.links(); let pointLink: d3Hierarchy.HierarchyPointLink; pointLink = pointLinks[0]; hierarchyPointNode = pointLink.source; hierarchyPointNode = pointLink.target; // sum() and value ------------------------------------------------------- clusterRootNode = clusterRootNode.sum((d) => d.val); numOrUndefined = clusterRootNode.value; // count() and value ----------------------------------------------------- clusterRootNode = clusterRootNode.count(); numOrUndefined = clusterRootNode.value; // sort ------------------------------------------------------------------ clusterRootNode = clusterRootNode.sort((a, b) => { console.log('x-coordinates of a:', a.x, ' and b:', b.x); // a and b are of type HierarchyPointNode console.log('Raw values in data of a and b:', a.data.val, ' and ', b.data.val); // a and b are of type HierarchyPointNode return b.height - a.height || b.value! - a.value!; }); // each(), eachAfter(), eachBefore() ------------------------------------- clusterRootNode = clusterRootNode.each((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyPointNode console.log('X-coordinate of node:', node.x); // node type is HierarchyPointNode }); clusterRootNode = clusterRootNode.eachAfter((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyPointNode console.log('X-coordinate of node:', node.x); // node type is HierarchyPointNode }); clusterRootNode = clusterRootNode.eachBefore((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyPointNode console.log('X-coordinate of node:', node.x); // node type is HierarchyPointNode }); // copy() ---------------------------------------------------------------- let copiedClusterNode: d3Hierarchy.HierarchyPointNode; copiedClusterNode = clusterRootNode.copy(); // ----------------------------------------------------------------------- // Tree // ----------------------------------------------------------------------- // Create tree layout generator ========================================== let treeLayout: d3Hierarchy.TreeLayout; treeLayout = d3Hierarchy.tree(); // Configure tree layout generator ======================================= // size() ---------------------------------------------------------------- treeLayout = treeLayout.size([200, 200]); sizeOrNull = treeLayout.size(); // nodeSize() ------------------------------------------------------------ treeLayout = treeLayout.nodeSize([10, 10]); sizeOrNull = treeLayout.nodeSize(); // separation() ---------------------------------------------------------- treeLayout = treeLayout.separation(function separation(a, b) { return a.data.parentId === b.data.parentId ? 1 : 2; // a and b are nodes of type HierarchyPointNode }); separationAccessor = treeLayout.separation(); // Use cluster layout generator ========================================== let treeRootNode: d3Hierarchy.HierarchyPointNode; treeRootNode = treeLayout(stratifiedRootNode); // ----------------------------------------------------------------------- // Treemap // ----------------------------------------------------------------------- let numberRectangularNodeAccessor: (node: d3Hierarchy.HierarchyRectangularNode) => number; // Create treemap layout generator ======================================= let treemapLayout: d3Hierarchy.TreemapLayout; treemapLayout = d3Hierarchy.treemap(); // Configure treemap layout generator ==================================== // tile() ---------------------------------------------------------------- treemapLayout = treemapLayout.tile((node, x0, y0, x1, y1) => { console.log('x0 coordinate of node: ', node.x0); console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode num = x0; // number num = y0; // number num = x1; // number num = y1; // number // tile away }); treemapLayout = treemapLayout.tile(d3Hierarchy.treemapDice); let tilingFn: (node: d3Hierarchy.HierarchyRectangularNode, x0: number, y0: number, x1: number, y1: number) => void; tilingFn = treemapLayout.tile(); // size() ---------------------------------------------------------------- treemapLayout = treemapLayout.size([400, 200]); size = treemapLayout.size(); // round() --------------------------------------------------------------- treemapLayout = treemapLayout.round(true); let roundFlag: boolean = treemapLayout.round(); // padding() ------------------------------------------------------------- treemapLayout = treemapLayout.padding(1); treemapLayout = treemapLayout.padding((node) => { console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode return node.x0 > 10 ? 2 : 1; }); numberRectangularNodeAccessor = treemapLayout.padding(); // paddingInner() -------------------------------------------------------- treemapLayout = treemapLayout.paddingInner(1); treemapLayout = treemapLayout.paddingInner((node) => { console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode return node.x0 > 10 ? 2 : 1; }); numberRectangularNodeAccessor = treemapLayout.paddingInner(); // paddingOuter() -------------------------------------------------------- treemapLayout = treemapLayout.paddingOuter(1); treemapLayout = treemapLayout.paddingOuter((node) => { console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode return node.x0 > 10 ? 2 : 1; }); numberRectangularNodeAccessor = treemapLayout.paddingOuter(); // paddingTop() ---------------------------------------------------------- treemapLayout = treemapLayout.paddingTop(1); treemapLayout = treemapLayout.paddingTop((node) => { console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode return node.x0 > 10 ? 2 : 1; }); numberRectangularNodeAccessor = treemapLayout.paddingTop(); // paddingRight() -------------------------------------------------------- treemapLayout = treemapLayout.paddingRight(1); treemapLayout = treemapLayout.paddingRight((node) => { console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode return node.x0 > 10 ? 2 : 1; }); numberRectangularNodeAccessor = treemapLayout.paddingRight(); // paddingBottom() ------------------------------------------------------- treemapLayout = treemapLayout.paddingBottom(1); treemapLayout = treemapLayout.paddingBottom((node) => { console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode return node.x0 > 10 ? 2 : 1; }); numberRectangularNodeAccessor = treemapLayout.paddingBottom(); // paddingLeft() --------------------------------------------------------- treemapLayout = treemapLayout.paddingLeft(1); treemapLayout = treemapLayout.paddingLeft((node) => { console.log('Node parent id: ', node.data.parentId); // type of node is HierarchyRectangularNode return node.x0 > 10 ? 2 : 1; }); numberRectangularNodeAccessor = treemapLayout.paddingLeft(); // Use treemap layout generator ========================================== let treemapRootNode: d3Hierarchy.HierarchyRectangularNode; treemapRootNode = treemapLayout(stratifiedRootNode); // Tiling functions ====================================================== tilingFn = d3Hierarchy.treemapBinary; tilingFn = d3Hierarchy.treemapDice; tilingFn = d3Hierarchy.treemapSlice; tilingFn = d3Hierarchy.treemapSliceDice; // Tiling Factory functions treemapSquarify() and treemapResquarify() ==== let tilingFactoryFn: d3Hierarchy.RatioSquarifyTilingFactory; tilingFactoryFn = d3Hierarchy.treemapSquarify; tilingFactoryFn = d3Hierarchy.treemapSquarify.ratio(2); treemapLayout.tile(d3Hierarchy.treemapSquarify.ratio(2)); tilingFactoryFn = d3Hierarchy.treemapResquarify; tilingFactoryFn = d3Hierarchy.treemapResquarify.ratio(2); treemapLayout.tile(d3Hierarchy.treemapResquarify.ratio(2)); // Use HierarchyRectangularNode ========================================== // x and y coordinates --------------------------------------------------- num = treemapRootNode.x0; num = treemapRootNode.y0; num = treemapRootNode.x1; num = treemapRootNode.y1; // data, depth, height --------------------------------------------------- const treemapDatum: HierarchyDatumWithParentId = treemapRootNode.data; num = treemapRootNode.depth; num = treemapRootNode.height; // children, parent ------------------------------------------------------ hierarchyRectangularNodeArrayOrUndefined = treemapRootNode.children; let parentRectangularNode: d3Hierarchy.HierarchyRectangularNode | null; parentRectangularNode = hierarchyRectangularNodeArray.length ? hierarchyRectangularNodeArray[0].parent : null; parentRectangularNode = hierarchyRectangularNodeArray[0].parent; // id -------------------------------------------------------------------- idString = treemapRootNode.id; // ancestors(), descendants() -------------------------------------------- const rectangularNodeAncestors: Array> = treemapRootNode.ancestors(); const rectangularNodeDescendants: Array> = treemapRootNode.descendants(); // leaves() -------------------------------------------------------------- hierarchyRectangularNodeArray = treemapRootNode.leaves(); // path() ---------------------------------------------------------------- hierarchyRectangularNode = rectangularNodeDescendants[rectangularNodeDescendants.length - 1]; const treemapPath: Array> = treemapRootNode.path(hierarchyRectangularNode); // links() and HierarchyRectangularLink<...> ----------------------------- let rectangularLinks: Array>; rectangularLinks = treemapRootNode.links(); let rectangularLink: d3Hierarchy.HierarchyRectangularLink; rectangularLink = rectangularLinks[0]; hierarchyRectangularNode = rectangularLink.source; hierarchyRectangularNode = rectangularLink.target; // sum() and value ------------------------------------------------------- treemapRootNode = treemapRootNode.sum((d) => d.val); numOrUndefined = treemapRootNode.value; // count() and value ----------------------------------------------------- treemapRootNode = treemapRootNode.count(); numOrUndefined = treemapRootNode.value; // sort ------------------------------------------------------------------ treemapRootNode = treemapRootNode.sort((a, b) => { console.log('x0-coordinates of a:', a.x0, ' and b:', b.x0); // a and b are of type HierarchyRectangularNode console.log('Raw values in data of a and b:', a.data.val, ' and ', b.data.val); // a and b are of type HierarchyRectangularNode return b.height - a.height || b.value! - a.value!; }); // each(), eachAfter(), eachBefore() ------------------------------------- treemapRootNode = treemapRootNode.each((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyRectangularNode console.log('X0-coordinate of node:', node.x0); // node type is HierarchyRectangularNode }); treemapRootNode = treemapRootNode.eachAfter((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyRectangularNode console.log('X0-coordinate of node:', node.x0); // node type is HierarchyRectangularNode }); treemapRootNode = treemapRootNode.eachBefore((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyRectangularNode console.log('X0-coordinate of node:', node.x0); // node type is HierarchyRectangularNode }); // copy() ---------------------------------------------------------------- let copiedTreemapNode: d3Hierarchy.HierarchyRectangularNode; copiedTreemapNode = treemapRootNode.copy(); // ----------------------------------------------------------------------- // Partition // ----------------------------------------------------------------------- // Create partition layout generator ===================================== let partitionLayout: d3Hierarchy.PartitionLayout; partitionLayout = d3Hierarchy.partition(); // Configure partition layout generator ================================== // size() ---------------------------------------------------------------- partitionLayout = partitionLayout.size([400, 200]); size = partitionLayout.size(); // round() --------------------------------------------------------------- partitionLayout = partitionLayout.round(true); roundFlag = partitionLayout.round(); // padding() ------------------------------------------------------------- partitionLayout = partitionLayout.padding(1); num = partitionLayout.padding(); // Use partition layout generator ======================================== let partitionRootNode: d3Hierarchy.HierarchyRectangularNode; partitionRootNode = partitionLayout(stratifiedRootNode); // ----------------------------------------------------------------------- // Pack // ----------------------------------------------------------------------- type CircularAccessor = (node: d3Hierarchy.HierarchyCircularNode) => number; let numberCircularNodeAccessor: CircularAccessor; let numberCircularNodeAccessorOrNull: CircularAccessor | null; // Create pack layout generator ========================================== let packLayout: d3Hierarchy.PackLayout; packLayout = d3Hierarchy.pack(); // Configure pack layout generator ======================================= // size() ---------------------------------------------------------------- packLayout = packLayout.size([400, 400]); size = packLayout.size(); // radius() -------------------------------------------------------------- packLayout = packLayout.radius(null); packLayout = packLayout.radius((node) => { console.log('Radius property of node before completing accessor: ', node.r); // node is of type HierarchyCircularNode console.log('Parent id of node: ', node.data.parentId); // node is of type HierarchyCircularNode return node.value!; }); numberCircularNodeAccessorOrNull = packLayout.radius(); // padding() ------------------------------------------------------------- packLayout = packLayout.padding(1); packLayout = packLayout.padding((node) => { console.log('Radius property of node: ', node.r); // node is of type HierarchyCircularNode console.log('Parent id of node: ', node.data.parentId); // node is of type HierarchyCircularNode return node.value! > 10 ? 2 : 1; }); numberCircularNodeAccessor = packLayout.padding(); // Use partition layout generator ======================================== let packRootNode: d3Hierarchy.HierarchyCircularNode; packRootNode = packLayout(stratifiedRootNode); // Use HierarchyCircularNode ============================================= // x and y coordinates and radius r -------------------------------------- num = packRootNode.x; num = packRootNode.y; num = packRootNode.r; // data, depth, height --------------------------------------------------- const packDatum: HierarchyDatumWithParentId = packRootNode.data; num = packRootNode.depth; num = packRootNode.height; // children, parent ------------------------------------------------------ hierarchyCircularNodeArrayOrUndefined = packRootNode.children; let parentCircularNode: d3Hierarchy.HierarchyCircularNode | null; parentCircularNode = hierarchyCircularNodeArray.length ? hierarchyCircularNodeArray[0].parent : null; parentCircularNode = hierarchyCircularNodeArray[0].parent; // id -------------------------------------------------------------------- idString = packRootNode.id; // ancestors(), descendants() -------------------------------------------- const circularNodeAncestors: Array> = packRootNode.ancestors(); const circularNodeDescendants: Array> = packRootNode.descendants(); // leaves() -------------------------------------------------------------- hierarchyCircularNodeArray = packRootNode.leaves(); // path() ---------------------------------------------------------------- hierarchyCircularNode = circularNodeDescendants[circularNodeDescendants.length - 1]; const packPath: Array> = packRootNode.path(hierarchyCircularNode); // links() and HierarchyRectangularLink<...> ----------------------------- let circularLinks: Array>; circularLinks = packRootNode.links(); let circularLink: d3Hierarchy.HierarchyCircularLink; circularLink = circularLinks[0]; hierarchyCircularNode = circularLink.source; hierarchyCircularNode = circularLink.target; // sum() and value ------------------------------------------------------- packRootNode = packRootNode.sum((d) => d.val); numOrUndefined = packRootNode.value; // count() and value ----------------------------------------------------- packRootNode = packRootNode.count(); numOrUndefined = packRootNode.value; // sort ------------------------------------------------------------------ packRootNode = packRootNode.sort((a, b) => { console.log('radius of a:', a.r, ' and b:', b.r); // a and b are of type HierarchyCircularNode console.log('Raw values in data of a and b:', a.data.val, ' and ', b.data.val); // a and b are of type HierarchyCircularNode return b.height - a.height || b.value! - a.value!; }); // each(), eachAfter(), eachBefore() ------------------------------------- packRootNode = packRootNode.each((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyCircularNode console.log('Radius of node:', node.r); // node type is HierarchyCircularNode }); packRootNode = packRootNode.eachAfter((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyCircularNode console.log('Radius of node:', node.r); // node type is HierarchyCircularNode }); packRootNode = packRootNode.eachBefore((node) => { console.log('ParentId:', node.data.parentId); // node type is HierarchyCircularNode console.log('Radius of node:', node.r); // node type is HierarchyCircularNode }); // copy() ---------------------------------------------------------------- let copiedPackNode: d3Hierarchy.HierarchyCircularNode; copiedPackNode = packRootNode.copy(); // ----------------------------------------------------------------------- // Pack Siblings and Enclosure // ----------------------------------------------------------------------- const radius = [ { r: 10, v: 'a' }, { r: 30, v: 'b' }, { r: 20, v: 'c' } ]; // packSiblings const circles = d3Hierarchy.packSiblings(radius); str = circles[0].v; num = circles[0].r; num = circles[0].x; num = circles[0].y; // packEnclose const moreCircles = [ { r: 10, v: 'a', x: 0, y: 10 }, { r: 30, v: 'b', x: 5, y: 15 }, { r: 20, v: 'c', x: 7, y: 30 } ]; const circle = d3Hierarchy.packEnclose(moreCircles); num = circle.r; num = circle.x; num = circle.y; // $ExpectError str = circle.v; // fails, property 'v' does not exist // $ExpectError d3Hierarchy.packEnclose(radius);