@webviz/group-tree-plot 1.3.24 → 1.4.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/dist/GroupTreePlot.d.ts +6 -1
- package/dist/GroupTreePlot.js +43 -43
- package/dist/GroupTreePlot.js.map +1 -1
- package/dist/components/PlotErrorOverlay.d.ts +5 -0
- package/dist/components/PlotErrorOverlay.js +7 -0
- package/dist/components/PlotErrorOverlay.js.map +1 -0
- package/dist/components/TreePlotRenderer/TreePlotRenderer.d.ts +11 -0
- package/dist/components/TreePlotRenderer/TreePlotRenderer.js +85 -0
- package/dist/components/TreePlotRenderer/TreePlotRenderer.js.map +1 -0
- package/dist/components/TreePlotRenderer/index.d.ts +1 -0
- package/dist/components/TreePlotRenderer/index.js +2 -0
- package/dist/components/TreePlotRenderer/index.js.map +1 -0
- package/dist/components/TreePlotRenderer/privateComponents/HiddenChildren.d.ts +6 -0
- package/dist/components/TreePlotRenderer/privateComponents/HiddenChildren.js +13 -0
- package/dist/components/TreePlotRenderer/privateComponents/HiddenChildren.js.map +1 -0
- package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeEdge.d.ts +10 -0
- package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeEdge.js +30 -0
- package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeEdge.js.map +1 -0
- package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeNode.d.ts +11 -0
- package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeNode.js +37 -0
- package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeNode.js.map +1 -0
- package/dist/hooks/useCollapseMotionProps.d.ts +15 -0
- package/dist/hooks/useCollapseMotionProps.js +46 -0
- package/dist/hooks/useCollapseMotionProps.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/DataAssembler.d.ts +74 -0
- package/dist/utils/DataAssembler.js +179 -0
- package/dist/utils/DataAssembler.js.map +1 -0
- package/dist/utils/treePlot.d.ts +36 -0
- package/dist/utils/treePlot.js +85 -0
- package/dist/utils/treePlot.js.map +1 -0
- package/package.json +3 -2
- package/dist/GroupTreeAssembler/groupTreeAssembler.d.ts +0 -64
- package/dist/GroupTreeAssembler/groupTreeAssembler.js +0 -579
- package/dist/GroupTreeAssembler/groupTreeAssembler.js.map +0 -1
- /package/dist/{GroupTreeAssembler/group_tree.css → group_tree.css} +0 -0
package/dist/GroupTreePlot.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import "./group_tree.css";
|
|
2
3
|
import type { DatedTree, EdgeMetadata, NodeMetadata } from "./types";
|
|
3
4
|
export interface GroupTreePlotProps {
|
|
4
5
|
id: string;
|
|
@@ -8,5 +9,9 @@ export interface GroupTreePlotProps {
|
|
|
8
9
|
selectedEdgeKey: string;
|
|
9
10
|
selectedNodeKey: string;
|
|
10
11
|
selectedDateTime: string;
|
|
12
|
+
initialVisibleDepth?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function GroupTreePlot(props: GroupTreePlotProps): React.ReactNode;
|
|
15
|
+
export declare namespace GroupTreePlot {
|
|
16
|
+
var displayName: string;
|
|
11
17
|
}
|
|
12
|
-
export declare const GroupTreePlot: React.FC<GroupTreePlotProps>;
|
package/dist/GroupTreePlot.js
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const [
|
|
11
|
-
const [
|
|
12
|
-
const [
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
import _ from "lodash";
|
|
3
|
+
import "./group_tree.css";
|
|
4
|
+
import { TreePlotRenderer } from "./components/TreePlotRenderer";
|
|
5
|
+
import { PlotErrorOverlay } from "./components/PlotErrorOverlay";
|
|
6
|
+
import { useDataAssembler, useUpdateAssemblerDate, } from "./utils/DataAssembler";
|
|
7
|
+
export function GroupTreePlot(props) {
|
|
8
|
+
// References to handle resizing
|
|
9
|
+
const svgRootRef = React.useRef(null);
|
|
10
|
+
const [svgHeight, setSvgHeight] = React.useState(0);
|
|
11
|
+
const [svgWidth, setSvgWidth] = React.useState(0);
|
|
12
|
+
const [dataAssembler, initError] = useDataAssembler(props.datedTrees, props.edgeMetadataList, props.nodeMetadataList);
|
|
13
|
+
const dateUpdateError = useUpdateAssemblerDate(dataAssembler, props.selectedDateTime);
|
|
14
|
+
const errorToPrint = initError !== null && initError !== void 0 ? initError : dateUpdateError;
|
|
15
|
+
// Mount hook
|
|
16
|
+
React.useEffect(function setupResizeObserver() {
|
|
17
|
+
if (!svgRootRef.current)
|
|
18
|
+
throw new Error("Expected root ref to be set");
|
|
19
|
+
const svgElement = svgRootRef.current;
|
|
20
|
+
// Debounce to avoid excessive re-renders
|
|
21
|
+
const debouncedResizeObserverCheck = _.debounce(function debouncedResizeObserverCheck(entries) {
|
|
22
|
+
if (!Array.isArray(entries))
|
|
23
|
+
return;
|
|
24
|
+
if (!entries.length)
|
|
25
|
+
return;
|
|
26
|
+
const entry = entries[0];
|
|
27
|
+
setSvgWidth(entry.contentRect.width);
|
|
28
|
+
setSvgHeight(entry.contentRect.height);
|
|
29
|
+
}, 100);
|
|
30
|
+
// Since the debounce will delay calling the setters, we call them early now
|
|
31
|
+
setSvgHeight(svgElement.getBoundingClientRect().height);
|
|
32
|
+
setSvgWidth(svgElement.getBoundingClientRect().width);
|
|
33
|
+
// Set up a resize-observer to check for svg size changes
|
|
34
|
+
const resizeObserver = new ResizeObserver(debouncedResizeObserverCheck);
|
|
35
|
+
resizeObserver.observe(svgElement);
|
|
36
|
+
// Cleanup on unmount
|
|
37
|
+
return () => {
|
|
38
|
+
debouncedResizeObserverCheck.cancel();
|
|
39
|
+
resizeObserver.disconnect();
|
|
40
|
+
};
|
|
17
41
|
}, []);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
(
|
|
21
|
-
|
|
22
|
-
setPrevDatedTrees(props.datedTrees);
|
|
23
|
-
setPrevId(divRef.current.id);
|
|
24
|
-
groupTreeAssemblerRef.current = new GroupTreeAssembler(divRef.current.id, props.datedTrees, props.selectedEdgeKey, props.selectedNodeKey, props.selectedDateTime, props.edgeMetadataList, props.nodeMetadataList);
|
|
25
|
-
}
|
|
26
|
-
if (prevSelectedEdgeKey !== props.selectedEdgeKey) {
|
|
27
|
-
setPrevSelectedEdgeKey(props.selectedEdgeKey);
|
|
28
|
-
if (groupTreeAssemblerRef.current) {
|
|
29
|
-
groupTreeAssemblerRef.current.flowrate = props.selectedEdgeKey;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
if (prevSelectedNodeKey !== props.selectedNodeKey) {
|
|
33
|
-
setPrevSelectedNodeKey(props.selectedNodeKey);
|
|
34
|
-
if (groupTreeAssemblerRef.current) {
|
|
35
|
-
groupTreeAssemblerRef.current.nodeinfo = props.selectedNodeKey;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (prevSelectedDateTime !== props.selectedDateTime) {
|
|
39
|
-
setPrevSelectedDateTime(props.selectedDateTime);
|
|
40
|
-
if (groupTreeAssemblerRef.current) {
|
|
41
|
-
groupTreeAssemblerRef.current.update(props.selectedDateTime);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return React.createElement("div", { id: props.id, ref: divRef });
|
|
45
|
-
};
|
|
42
|
+
return (React.createElement("svg", { ref: svgRootRef, height: "100%", width: "100%" },
|
|
43
|
+
dataAssembler && svgHeight && svgWidth && (React.createElement(TreePlotRenderer, { dataAssembler: dataAssembler, primaryEdgeProperty: props.selectedEdgeKey, primaryNodeProperty: props.selectedNodeKey, width: svgWidth, height: svgHeight, initialVisibleDepth: props.initialVisibleDepth })),
|
|
44
|
+
errorToPrint && React.createElement(PlotErrorOverlay, { message: errorToPrint })));
|
|
45
|
+
}
|
|
46
46
|
GroupTreePlot.displayName = "GroupTreePlot";
|
|
47
47
|
//# sourceMappingURL=GroupTreePlot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupTreePlot.js","sourceRoot":"","sources":["../src/GroupTreePlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"GroupTreePlot.js","sourceRoot":"","sources":["../src/GroupTreePlot.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export function PlotErrorOverlay(props) {
|
|
3
|
+
return (React.createElement(React.Fragment, null,
|
|
4
|
+
React.createElement("rect", { className: "error-overlay-background", width: "100%", height: "100%", fill: "rgba(255, 255, 255, 0.8)" }),
|
|
5
|
+
React.createElement("text", { x: "50%", y: "50%", fill: "red", textAnchor: "middle", dominantBaseline: "middle", fontSize: 16 }, props.message)));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=PlotErrorOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlotErrorOverlay.js","sourceRoot":"","sources":["../../src/components/PlotErrorOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,UAAU,gBAAgB,CAC5B,KAA4B;IAE5B,OAAO,CACH;QACI,8BACI,SAAS,EAAC,0BAA0B,EACpC,KAAK,EAAC,MAAM,EACZ,MAAM,EAAC,MAAM,EACb,IAAI,EAAC,0BAA0B,GACjC;QACF,8BACI,CAAC,EAAC,KAAK,EACP,CAAC,EAAC,KAAK,EACP,IAAI,EAAC,KAAK,EACV,UAAU,EAAC,QAAQ,EACnB,gBAAgB,EAAC,QAAQ,EACzB,QAAQ,EAAE,EAAE,IAEX,KAAK,CAAC,OAAO,CACX,CACR,CACN,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { DataAssembler } from "../../utils/DataAssembler";
|
|
3
|
+
export type TreePlotRendererProps = {
|
|
4
|
+
dataAssembler: DataAssembler;
|
|
5
|
+
primaryEdgeProperty: string;
|
|
6
|
+
primaryNodeProperty: string;
|
|
7
|
+
height: number;
|
|
8
|
+
width: number;
|
|
9
|
+
initialVisibleDepth?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function TreePlotRenderer(props: TreePlotRendererProps): ReactNode;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import _ from "lodash";
|
|
3
|
+
import * as d3 from "d3";
|
|
4
|
+
import { AnimatePresence } from "motion/react";
|
|
5
|
+
import { makeLinkId, makeNodeId } from "../../utils/treePlot";
|
|
6
|
+
import { TransitionTreeEdge } from "./privateComponents/TransitionTreeEdge";
|
|
7
|
+
import { TransitionTreeNode } from "./privateComponents/TransitionTreeNode";
|
|
8
|
+
const PLOT_MARGINS = {
|
|
9
|
+
top: 10,
|
|
10
|
+
right: 120,
|
|
11
|
+
bottom: 10,
|
|
12
|
+
left: 70,
|
|
13
|
+
};
|
|
14
|
+
export function TreePlotRenderer(props) {
|
|
15
|
+
const activeTree = props.dataAssembler.getActiveTree();
|
|
16
|
+
const rootTreeNode = activeTree.tree;
|
|
17
|
+
const [nodeCollapseFlags, setNodeCollapseFlags] = React.useState({});
|
|
18
|
+
const heightPadding = PLOT_MARGINS.top + PLOT_MARGINS.bottom;
|
|
19
|
+
const widthPadding = PLOT_MARGINS.left + PLOT_MARGINS.right;
|
|
20
|
+
const layoutHeight = props.height - heightPadding;
|
|
21
|
+
const layoutWidth = props.width - widthPadding;
|
|
22
|
+
const treeLayout = React.useMemo(function computeLayout() {
|
|
23
|
+
// Note that we invert height / width to render the tree sideways
|
|
24
|
+
return d3
|
|
25
|
+
.tree()
|
|
26
|
+
.size([layoutHeight, layoutWidth]);
|
|
27
|
+
}, [layoutHeight, layoutWidth]);
|
|
28
|
+
const nodeTree = React.useMemo(function computeTree() {
|
|
29
|
+
const hierarchy = d3.hierarchy(rootTreeNode).each((node) => {
|
|
30
|
+
// Collapse nodes based on collapse flags and minimum depth
|
|
31
|
+
// ! I'd argue that it'd be more correct to collapse nodes using the hierarchy constructor:
|
|
32
|
+
// d3.hierarchy(rootTreeNode, (datum) => {
|
|
33
|
+
// if(someCheck) return null
|
|
34
|
+
// else return datum.children
|
|
35
|
+
// })
|
|
36
|
+
// However, nodes are being collapsed after-the-fact here, since we need the depth value for implicit collapses, and it's not available in the constructor
|
|
37
|
+
var _a;
|
|
38
|
+
const collapseFlag = nodeCollapseFlags[makeNodeId(node)];
|
|
39
|
+
const visibleDepth = (_a = props.initialVisibleDepth) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
|
|
40
|
+
// Return only if collapse flag is *explicitly* set to false
|
|
41
|
+
if (collapseFlag === false)
|
|
42
|
+
return;
|
|
43
|
+
if (node.depth >= visibleDepth || collapseFlag === true) {
|
|
44
|
+
node.children = undefined;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return treeLayout(hierarchy);
|
|
48
|
+
}, [treeLayout, rootTreeNode, nodeCollapseFlags, props.initialVisibleDepth]);
|
|
49
|
+
// Storing the previous value so entering nodes know where to expand from
|
|
50
|
+
const oldNodeTree = usePreviousTree(nodeTree);
|
|
51
|
+
function toggleNodeCollapse(node) {
|
|
52
|
+
var _a;
|
|
53
|
+
const nodeIdent = makeNodeId(node);
|
|
54
|
+
// Might be collapsed implicitly due to visibleDepth prop
|
|
55
|
+
const collapsed = Boolean((_a = node.children) === null || _a === void 0 ? void 0 : _a.length);
|
|
56
|
+
setNodeCollapseFlags((prev) => {
|
|
57
|
+
const existingVal = prev[nodeIdent];
|
|
58
|
+
const newVal = collapsed && !existingVal;
|
|
59
|
+
const newFlags = Object.assign(Object.assign({}, prev), { [nodeIdent]: newVal });
|
|
60
|
+
// When closing a node, reset any stored flag for all children
|
|
61
|
+
if (newVal) {
|
|
62
|
+
node.descendants()
|
|
63
|
+
// descendants() includes this node, slice to skip it
|
|
64
|
+
.slice(1)
|
|
65
|
+
.forEach((child) => delete newFlags[makeNodeId(child)]);
|
|
66
|
+
}
|
|
67
|
+
return newFlags;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return (React.createElement("g", { transform: `translate(${PLOT_MARGINS.left},${PLOT_MARGINS.top})` },
|
|
71
|
+
React.createElement(AnimatePresence, { custom: nodeTree },
|
|
72
|
+
nodeTree.links().map((link) => (React.createElement(TransitionTreeEdge, { key: makeLinkId(link), link: link, dataAssembler: props.dataAssembler, primaryEdgeProperty: props.primaryEdgeProperty, oldNodeTree: oldNodeTree }))),
|
|
73
|
+
nodeTree.descendants().map((node) => (React.createElement(TransitionTreeNode, { key: makeNodeId(node), primaryNodeProperty: props.primaryNodeProperty, dataAssembler: props.dataAssembler, node: node, oldNodeTree: oldNodeTree, onNodeClick: toggleNodeCollapse }))))));
|
|
74
|
+
}
|
|
75
|
+
function usePreviousTree(treeRootNode) {
|
|
76
|
+
// Make the first "old" tree be just the root, so everything expands from the root
|
|
77
|
+
const initRoot = _.clone(treeRootNode);
|
|
78
|
+
initRoot.children = undefined;
|
|
79
|
+
const oldNodeTree = React.useRef(initRoot);
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
oldNodeTree.current = treeRootNode;
|
|
82
|
+
}, [treeRootNode]);
|
|
83
|
+
return oldNodeTree.current;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=TreePlotRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreePlotRenderer.js","sourceRoot":"","sources":["../../../src/components/TreePlotRenderer/TreePlotRenderer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TreePlotRenderer } from "./TreePlotRenderer";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/TreePlotRenderer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export function HiddenChildren(props) {
|
|
3
|
+
let msg = "+ " + props.hiddenChildren.length;
|
|
4
|
+
if (props.hiddenChildren.length > 1) {
|
|
5
|
+
msg += " children";
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
msg += " child";
|
|
9
|
+
}
|
|
10
|
+
return (React.createElement("g", null,
|
|
11
|
+
React.createElement("text", { x: 21, textAnchor: "start", dominantBaseline: "middle", fontSize: 10, fontFamily: "sans-serif" }, msg)));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=HiddenChildren.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HiddenChildren.js","sourceRoot":"","sources":["../../../../src/components/TreePlotRenderer/privateComponents/HiddenChildren.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,UAAU,cAAc,CAAC,KAA0B;IACrD,IAAI,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;IAC7C,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,GAAG,IAAI,WAAW,CAAC;IACvB,CAAC;SAAM,CAAC;QACJ,GAAG,IAAI,QAAQ,CAAC;IACpB,CAAC;IAED,OAAO,CACH;QACI,8BACI,CAAC,EAAE,EAAE,EACL,UAAU,EAAC,OAAO,EAClB,gBAAgB,EAAC,QAAQ,EACzB,QAAQ,EAAE,EAAE,EACZ,UAAU,EAAC,YAAY,IAEtB,GAAG,CACD,CACP,CACP,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DataAssembler } from "../../../utils/DataAssembler";
|
|
3
|
+
import type { D3TreeEdge, D3TreeNode } from "../../../types";
|
|
4
|
+
export type TreeEdgeProps = {
|
|
5
|
+
link: D3TreeEdge;
|
|
6
|
+
dataAssembler: DataAssembler;
|
|
7
|
+
primaryEdgeProperty: string;
|
|
8
|
+
oldNodeTree: D3TreeNode;
|
|
9
|
+
};
|
|
10
|
+
export declare function TransitionTreeEdge(props: TreeEdgeProps): React.ReactNode;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { motion } from "motion/react";
|
|
3
|
+
import { diagonalPath } from "../../../utils/treePlot";
|
|
4
|
+
import { useCollapseMotionProps } from "../../../hooks/useCollapseMotionProps";
|
|
5
|
+
export function TransitionTreeEdge(props) {
|
|
6
|
+
const linkPath = diagonalPath(props.link);
|
|
7
|
+
const mainTreeNode = props.link.target.data;
|
|
8
|
+
const edgeData = mainTreeNode.edge_data;
|
|
9
|
+
const linkId = React.useId();
|
|
10
|
+
const groupPropertyStrokeClass = `grouptree_link__${props.primaryEdgeProperty}`;
|
|
11
|
+
const edgeTooltip = props.dataAssembler.getTooltip(edgeData);
|
|
12
|
+
const normalizedValue = props.dataAssembler.normalizeValue(edgeData, props.primaryEdgeProperty);
|
|
13
|
+
// Keep minimum width at 2 so line doesnt dissapear
|
|
14
|
+
const strokeWidth = Math.max(normalizedValue, 2);
|
|
15
|
+
const motionProps = useCollapseMotionProps(props.link.target, props.oldNodeTree, {
|
|
16
|
+
strokeOpacity: 1,
|
|
17
|
+
strokeWidth: strokeWidth,
|
|
18
|
+
d: linkPath,
|
|
19
|
+
}, (collapseTarget) => ({
|
|
20
|
+
strokeOpacity: 0,
|
|
21
|
+
strokeWidth: strokeWidth / 4,
|
|
22
|
+
d: diagonalPath({ source: collapseTarget, target: collapseTarget }),
|
|
23
|
+
}));
|
|
24
|
+
return (React.createElement(motion.g, null,
|
|
25
|
+
React.createElement(motion.path, Object.assign({}, motionProps, { id: linkId, className: `link grouptree_link ${groupPropertyStrokeClass}`, strokeDasharray: normalizedValue > 0 ? "none" : "5,5" }),
|
|
26
|
+
React.createElement("title", null, edgeTooltip)),
|
|
27
|
+
React.createElement(motion.text, { transition: motionProps.transition, initial: { fillOpacity: 0 }, animate: { fillOpacity: 1 }, exit: { fillOpacity: 0 }, dominantBaseline: "central", textAnchor: "middle" },
|
|
28
|
+
React.createElement("textPath", { className: "edge_info_text", startOffset: "50%", href: "#" + linkId }, mainTreeNode.edge_label))));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=TransitionTreeEdge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransitionTreeEdge.js","sourceRoot":"","sources":["../../../../src/components/TreePlotRenderer/privateComponents/TransitionTreeEdge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAW/E,MAAM,UAAU,kBAAkB,CAAC,KAAoB;IACnD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE1C,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC;IAExC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAE7B,MAAM,wBAAwB,GAAG,mBAAmB,KAAK,CAAC,mBAAmB,EAAE,CAAC;IAEhF,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7D,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,CAAC,cAAc,CACtD,QAAQ,EACR,KAAK,CAAC,mBAAmB,CAC5B,CAAC;IAEF,mDAAmD;IACnD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAEjD,MAAM,WAAW,GAAG,sBAAsB,CACtC,KAAK,CAAC,IAAI,CAAC,MAAM,EACjB,KAAK,CAAC,WAAW,EACjB;QACI,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,WAAW;QACxB,CAAC,EAAE,QAAQ;KACd,EACD,CAAC,cAA0B,EAAE,EAAE,CAAC,CAAC;QAC7B,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,WAAW,GAAG,CAAC;QAC5B,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;KACtE,CAAC,CACL,CAAC;IAEF,OAAO,CACH,oBAAC,MAAM,CAAC,CAAC;QACL,oBAAC,MAAM,CAAC,IAAI,oBACJ,WAAW,IACf,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,uBAAuB,wBAAwB,EAAE,EAC5D,eAAe,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;YAErD,mCAAQ,WAAW,CAAS,CAClB;QAEd,oBAAC,MAAM,CAAC,IAAI,IACR,UAAU,EAAE,WAAW,CAAC,UAAU,EAClC,OAAO,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,EAC3B,OAAO,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,EAC3B,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,EACxB,gBAAgB,EAAC,SAAS,EAC1B,UAAU,EAAC,QAAQ;YAEnB,kCACI,SAAS,EAAC,gBAAgB,EAC1B,WAAW,EAAC,KAAK,EACjB,IAAI,EAAE,GAAG,GAAG,MAAM,IAEjB,YAAY,CAAC,UAAU,CACjB,CACD,CACP,CACd,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DataAssembler } from "../../../utils/DataAssembler";
|
|
3
|
+
import type { D3TreeNode } from "../../../types";
|
|
4
|
+
export type TransitionTreeNodeProps = {
|
|
5
|
+
primaryNodeProperty: string;
|
|
6
|
+
dataAssembler: DataAssembler;
|
|
7
|
+
node: D3TreeNode;
|
|
8
|
+
oldNodeTree: D3TreeNode;
|
|
9
|
+
onNodeClick?: (node: TransitionTreeNodeProps["node"], evt: React.MouseEvent<SVGGElement, MouseEvent>) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare function TransitionTreeNode(props: TransitionTreeNodeProps): React.ReactNode;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { motion } from "motion/react";
|
|
3
|
+
import { printTreeValue } from "../../../utils/treePlot";
|
|
4
|
+
import { useCollapseMotionProps } from "../../../hooks/useCollapseMotionProps";
|
|
5
|
+
import { HiddenChildren } from "./HiddenChildren";
|
|
6
|
+
export function TransitionTreeNode(props) {
|
|
7
|
+
var _a, _b, _c;
|
|
8
|
+
const recursiveTreeNode = props.node.data;
|
|
9
|
+
const nodeData = recursiveTreeNode.node_data;
|
|
10
|
+
// ! This is whether the node is a leaf *in the actual tree*, not the rendered one
|
|
11
|
+
const isLeaf = !((_a = recursiveTreeNode.children) === null || _a === void 0 ? void 0 : _a.length);
|
|
12
|
+
const canBeExpanded = !((_b = props.node.children) === null || _b === void 0 ? void 0 : _b.length) && !isLeaf;
|
|
13
|
+
const nodeLabel = recursiveTreeNode.node_label;
|
|
14
|
+
let circleClass = "grouptree__node";
|
|
15
|
+
if (!isLeaf)
|
|
16
|
+
circleClass += " grouptree__node--withchildren";
|
|
17
|
+
const [, primaryUnit] = props.dataAssembler.getPropertyInfo(props.primaryNodeProperty);
|
|
18
|
+
const toolTip = props.dataAssembler.getTooltip(nodeData);
|
|
19
|
+
const primaryNodeValue = props.dataAssembler.getPropertyValue(nodeData, props.primaryNodeProperty);
|
|
20
|
+
const motionProps = useCollapseMotionProps(props.node, props.oldNodeTree, {
|
|
21
|
+
opacity: 1,
|
|
22
|
+
x: props.node.y,
|
|
23
|
+
y: props.node.x,
|
|
24
|
+
}, (collapseTarget) => ({
|
|
25
|
+
opacity: 0,
|
|
26
|
+
x: collapseTarget.y,
|
|
27
|
+
y: collapseTarget.x,
|
|
28
|
+
}));
|
|
29
|
+
return (React.createElement(motion.g, Object.assign({}, motionProps, { className: "node", cursor: !isLeaf ? "pointer" : undefined, onClick: (evt) => { var _a; return (_a = props.onNodeClick) === null || _a === void 0 ? void 0 : _a.call(props, props.node, evt); } }),
|
|
30
|
+
React.createElement("circle", { className: circleClass, r: 15 }),
|
|
31
|
+
React.createElement("text", { className: "grouptree__nodelabel", dominantBaseline: "middle", x: isLeaf ? 21 : -21, textAnchor: isLeaf ? "start" : "end" }, nodeLabel),
|
|
32
|
+
React.createElement("text", { className: "grouptree__pressurelabel", textAnchor: "middle", y: "-.05em" }, printTreeValue(primaryNodeValue)),
|
|
33
|
+
React.createElement("text", { className: "grouptree__pressureunit", y: ".04em", dominantBaseline: "text-before-edge", textAnchor: "middle" }, primaryUnit),
|
|
34
|
+
React.createElement("title", null, toolTip),
|
|
35
|
+
canBeExpanded && (React.createElement(HiddenChildren, { hiddenChildren: (_c = recursiveTreeNode.children) !== null && _c !== void 0 ? _c : [] }))));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=TransitionTreeNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransitionTreeNode.js","sourceRoot":"","sources":["../../../../src/components/TreePlotRenderer/privateComponents/TransitionTreeNode.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { SVGMotionProps, TargetAndTransition, Transition } from "motion/dist/react";
|
|
2
|
+
import type { D3TreeNode } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Settings for the tree's animation timing
|
|
5
|
+
*/
|
|
6
|
+
export declare const TREE_MOTION_TRANSITION: Transition;
|
|
7
|
+
/**
|
|
8
|
+
* Generates component properties for a tree element that animates to collapse/expand into other nodes in tree
|
|
9
|
+
* @param node The main node that should be animated (for edges, the target node)
|
|
10
|
+
* @param oldTreeRoot A reference to the old tree
|
|
11
|
+
* @param animationTarget The normal animation target for the node
|
|
12
|
+
* @param buildCollapseTargets A generator method to build an animation target for the node fully collapsed
|
|
13
|
+
* @returns A properties object for the node's animation
|
|
14
|
+
*/
|
|
15
|
+
export declare function useCollapseMotionProps(node: D3TreeNode, oldTreeRoot: D3TreeNode, animationTarget: TargetAndTransition, buildCollapseTargets: (targetNode: D3TreeNode) => TargetAndTransition): SVGMotionProps<SVGPathElement>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { findClosestVisibleInNewTree } from "../utils/treePlot";
|
|
2
|
+
/**
|
|
3
|
+
* Settings for the tree's animation timing
|
|
4
|
+
*/
|
|
5
|
+
export const TREE_MOTION_TRANSITION = {
|
|
6
|
+
// Other settings that might be nice
|
|
7
|
+
// type: "tween",
|
|
8
|
+
// ease: "anticipate",
|
|
9
|
+
// ease: (@motion).cubicBezier(0.77, 0.12, 0.54, 0.91),
|
|
10
|
+
type: "spring",
|
|
11
|
+
bounce: 0,
|
|
12
|
+
duration: 0.5,
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Generates component properties for a tree element that animates to collapse/expand into other nodes in tree
|
|
16
|
+
* @param node The main node that should be animated (for edges, the target node)
|
|
17
|
+
* @param oldTreeRoot A reference to the old tree
|
|
18
|
+
* @param animationTarget The normal animation target for the node
|
|
19
|
+
* @param buildCollapseTargets A generator method to build an animation target for the node fully collapsed
|
|
20
|
+
* @returns A properties object for the node's animation
|
|
21
|
+
*/
|
|
22
|
+
export function useCollapseMotionProps(node, oldTreeRoot, animationTarget, buildCollapseTargets) {
|
|
23
|
+
const variants = {
|
|
24
|
+
expand() {
|
|
25
|
+
const collapseInto = findClosestVisibleInNewTree(node, oldTreeRoot);
|
|
26
|
+
return buildCollapseTargets(collapseInto);
|
|
27
|
+
},
|
|
28
|
+
expanded() {
|
|
29
|
+
return animationTarget;
|
|
30
|
+
},
|
|
31
|
+
collapse(futureTree) {
|
|
32
|
+
if (!futureTree)
|
|
33
|
+
return {};
|
|
34
|
+
const collapseInto = findClosestVisibleInNewTree(node, futureTree);
|
|
35
|
+
return buildCollapseTargets(collapseInto);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
initial: "expand",
|
|
40
|
+
animate: "expanded",
|
|
41
|
+
exit: "collapse",
|
|
42
|
+
transition: TREE_MOTION_TRANSITION,
|
|
43
|
+
variants,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=useCollapseMotionProps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCollapseMotionProps.js","sourceRoot":"","sources":["../../src/hooks/useCollapseMotionProps.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAe;IAC9C,oCAAoC;IACpC,iBAAiB;IACjB,sBAAsB;IACtB,uDAAuD;IAEvD,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,GAAG;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAClC,IAAgB,EAChB,WAAuB,EACvB,eAAoC,EACpC,oBAAqE;IAErE,MAAM,QAAQ,GAAa;QACvB,MAAM;YACF,MAAM,YAAY,GAAG,2BAA2B,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACpE,OAAO,oBAAoB,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC;QACD,QAAQ;YACJ,OAAO,eAAe,CAAC;QAC3B,CAAC;QACD,QAAQ,CAAC,UAAuB;YAC5B,IAAI,CAAC,UAAU;gBAAE,OAAO,EAAE,CAAC;YAE3B,MAAM,YAAY,GAAG,2BAA2B,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACnE,OAAO,oBAAoB,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC;KACJ,CAAC;IAEF,OAAO;QACH,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,sBAAsB;QAClC,QAAQ;KACX,CAAC;AACN,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import type { HierarchyPointNode, HierarchyPointLink } from "d3";
|
|
2
3
|
import PropTypes from "prop-types";
|
|
3
4
|
export interface NodeData {
|
|
4
5
|
[key: string]: number[];
|
|
@@ -49,3 +50,5 @@ export declare const DatedTreePropTypes: PropTypes.Requireable<PropTypes.InferPr
|
|
|
49
50
|
dates: PropTypes.Validator<(string | null | undefined)[]>;
|
|
50
51
|
tree: PropTypes.Validator<NonNullable<PropTypes.InferProps<import("react").WeakValidationMap<RecursiveTreeNode>>>>;
|
|
51
52
|
}>>;
|
|
53
|
+
export type D3TreeNode = HierarchyPointNode<RecursiveTreeNode>;
|
|
54
|
+
export type D3TreeEdge = HierarchyPointLink<RecursiveTreeNode>;
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,YAAY,CAAC;AAyCnC,iFAAiF;AAEjF,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAC/C,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,CAC5D,CAAC;AACF,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAC,KAAK,CAAC;IACjD,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;IAChC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;IAClC,IAAI,EAAE,SAAS,CAAC,MAAM;CACzB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAC/C,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,CAC5D,CAAC;AACF,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAC,KAAK,CAAC;IACjD,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;IAChC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;IAClC,IAAI,EAAE,SAAS,CAAC,MAAM;CACzB,CAAC,CAAC;AAEH,kIAAkI;AAClI,mEAAmE;AACnE,qHAAqH;AACrH,MAAM,sBAAsB,GAA+C;IACvE,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;IACvC,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;IACvC,SAAS,EAAE,iBAAiB,CAAC,UAAU;IACvC,SAAS,EAAE,iBAAiB,CAAC,UAAU;CAC1C,CAAC;AACF,MAAM,CAAC,MAAM,CAAC,sBAAsB,EAAE;IAClC,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU;IACxD,QAAQ,EAAE,SAAS,CAAC,OAAO,CACvB,SAAS,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,UAAU,CACrD;CACJ,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,SAAS,CAAC,KAAK,CACrD,sBAAsB,CACzB,CAAC,UAAU,CAAC;AAEb,iCAAiC;AACjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC,KAAK,CAAC;IAC9C,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,UAAU;IACrD,IAAI,EAAE,0BAA0B;CACnC,CAAC,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { DatedTree, EdgeData, EdgeMetadata, NodeData, NodeMetadata } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Utility class to assemble and combine data for one or more dated flow network trees.
|
|
4
|
+
* The instance allows setting an active date, and provides methods to get data and labels pertaining to the given date
|
|
5
|
+
*/
|
|
6
|
+
export declare class DataAssembler {
|
|
7
|
+
datedTrees: DatedTree[];
|
|
8
|
+
edgeMetadataList: EdgeMetadata[];
|
|
9
|
+
nodeMetadataList: NodeMetadata[];
|
|
10
|
+
private _propertyToLabelMap;
|
|
11
|
+
private _propertyMaxVals;
|
|
12
|
+
private _currentTreeIndex;
|
|
13
|
+
private _currentDateIndex;
|
|
14
|
+
/**
|
|
15
|
+
* @param datedTrees A list of dated tree objects. List cannot be empty
|
|
16
|
+
* @param edgeMetadataList A list of labels and units to use when representing values from tree edges
|
|
17
|
+
* @param nodeMetadataList A list of labels and units to use when representing values from tree nodes
|
|
18
|
+
* @throws Throws if dated tree list is empty
|
|
19
|
+
*/
|
|
20
|
+
constructor(datedTrees: DatedTree[], edgeMetadataList: EdgeMetadata[], nodeMetadataList: NodeMetadata[]);
|
|
21
|
+
/**
|
|
22
|
+
* Changes the active date for the instance. Raises if date is invalid
|
|
23
|
+
* @param newDate A date string, formatted as YYYY-MM-DD (eg. 2001-01-30)
|
|
24
|
+
* @throws Will throw if the date is invalid, or if no tree uses the given date
|
|
25
|
+
*/
|
|
26
|
+
setActiveDate(newDate: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Gets the currently active tree
|
|
29
|
+
* @returns A dated tree
|
|
30
|
+
*/
|
|
31
|
+
getActiveTree(): DatedTree;
|
|
32
|
+
/**
|
|
33
|
+
* Pretty-prints all values in the given object with labels and units added
|
|
34
|
+
* @param data Data from a node or edge
|
|
35
|
+
* @returns A formatted string presentation of the data value
|
|
36
|
+
*/
|
|
37
|
+
getTooltip(data: NodeData | EdgeData): string;
|
|
38
|
+
/**
|
|
39
|
+
* Gets a property's value at the currently active date
|
|
40
|
+
* @param data Data from a node or edge
|
|
41
|
+
* @param property A key for a property
|
|
42
|
+
* @returns The value, if found
|
|
43
|
+
*/
|
|
44
|
+
getPropertyValue(data: EdgeData | NodeData, property: string): number | null;
|
|
45
|
+
/**
|
|
46
|
+
* Gets the label and unit strings for a given property
|
|
47
|
+
* @param propertyKey The key for the property
|
|
48
|
+
* @returns The label and unit for the property. If not found, label defaults to "", and unit defaults to "?"
|
|
49
|
+
*/
|
|
50
|
+
getPropertyInfo(propertyKey: string): [label: string, unit: string];
|
|
51
|
+
/**
|
|
52
|
+
* Returns a property's value to a normalized value between 2 and 100. A value of 0 will be returned as is.
|
|
53
|
+
* Will also return 0 if no data is found
|
|
54
|
+
* @param data Data object to take data from
|
|
55
|
+
* @param property The property key to take from
|
|
56
|
+
* @returns The normalized value.
|
|
57
|
+
*/
|
|
58
|
+
normalizeValue(data: EdgeData | NodeData, property: string): number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Updates the active date in a data-assembler instance.
|
|
62
|
+
* @param dataAssembler An instance of DataAssembler
|
|
63
|
+
* @param targetDate A date string
|
|
64
|
+
* @returns An error message, if the date was invalid
|
|
65
|
+
*/
|
|
66
|
+
export declare function useUpdateAssemblerDate(dataAssembler: DataAssembler | null, targetDate: string): string | void;
|
|
67
|
+
/**
|
|
68
|
+
* Initializes a memoized data-assembler instance. Creates a new instance every time data changes, but returns the last valid instance if the new data is invalid.
|
|
69
|
+
* @param datedTrees A list of dated trees. *Assumes all node labels are unique across all node types*
|
|
70
|
+
* @param edgeMetadataList Dated metadata for each tree edge
|
|
71
|
+
* @param nodeMetadataList Dated metadata for each tree node
|
|
72
|
+
* @returns A data-assembler instance, and an error message (if the instance could not be created)
|
|
73
|
+
*/
|
|
74
|
+
export declare function useDataAssembler(datedTrees: DatedTree[], edgeMetadataList: EdgeMetadata[], nodeMetadataList: NodeMetadata[]): [DataAssembler | null, string];
|