@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.
Files changed (37) hide show
  1. package/dist/GroupTreePlot.d.ts +6 -1
  2. package/dist/GroupTreePlot.js +43 -43
  3. package/dist/GroupTreePlot.js.map +1 -1
  4. package/dist/components/PlotErrorOverlay.d.ts +5 -0
  5. package/dist/components/PlotErrorOverlay.js +7 -0
  6. package/dist/components/PlotErrorOverlay.js.map +1 -0
  7. package/dist/components/TreePlotRenderer/TreePlotRenderer.d.ts +11 -0
  8. package/dist/components/TreePlotRenderer/TreePlotRenderer.js +85 -0
  9. package/dist/components/TreePlotRenderer/TreePlotRenderer.js.map +1 -0
  10. package/dist/components/TreePlotRenderer/index.d.ts +1 -0
  11. package/dist/components/TreePlotRenderer/index.js +2 -0
  12. package/dist/components/TreePlotRenderer/index.js.map +1 -0
  13. package/dist/components/TreePlotRenderer/privateComponents/HiddenChildren.d.ts +6 -0
  14. package/dist/components/TreePlotRenderer/privateComponents/HiddenChildren.js +13 -0
  15. package/dist/components/TreePlotRenderer/privateComponents/HiddenChildren.js.map +1 -0
  16. package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeEdge.d.ts +10 -0
  17. package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeEdge.js +30 -0
  18. package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeEdge.js.map +1 -0
  19. package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeNode.d.ts +11 -0
  20. package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeNode.js +37 -0
  21. package/dist/components/TreePlotRenderer/privateComponents/TransitionTreeNode.js.map +1 -0
  22. package/dist/hooks/useCollapseMotionProps.d.ts +15 -0
  23. package/dist/hooks/useCollapseMotionProps.js +46 -0
  24. package/dist/hooks/useCollapseMotionProps.js.map +1 -0
  25. package/dist/types.d.ts +3 -0
  26. package/dist/types.js.map +1 -1
  27. package/dist/utils/DataAssembler.d.ts +74 -0
  28. package/dist/utils/DataAssembler.js +179 -0
  29. package/dist/utils/DataAssembler.js.map +1 -0
  30. package/dist/utils/treePlot.d.ts +36 -0
  31. package/dist/utils/treePlot.js +85 -0
  32. package/dist/utils/treePlot.js.map +1 -0
  33. package/package.json +3 -2
  34. package/dist/GroupTreeAssembler/groupTreeAssembler.d.ts +0 -64
  35. package/dist/GroupTreeAssembler/groupTreeAssembler.js +0 -579
  36. package/dist/GroupTreeAssembler/groupTreeAssembler.js.map +0 -1
  37. /package/dist/{GroupTreeAssembler/group_tree.css → group_tree.css} +0 -0
@@ -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>;
@@ -1,47 +1,47 @@
1
1
  import React from "react";
2
- import GroupTreeAssembler from "./GroupTreeAssembler/groupTreeAssembler";
3
- import { isEqual } from "lodash";
4
- export const GroupTreePlot = (props) => {
5
- const divRef = React.useRef(null);
6
- const groupTreeAssemblerRef = React.useRef();
7
- // State to ensure divRef is defined before creating GroupTree
8
- const [isMounted, setIsMounted] = React.useState(false);
9
- // Remove when typescript version is implemented using ref
10
- const [prevId, setPrevId] = React.useState(null);
11
- const [prevDatedTrees, setPrevDatedTrees] = React.useState(null);
12
- const [prevSelectedEdgeKey, setPrevSelectedEdgeKey] = React.useState(props.selectedEdgeKey);
13
- const [prevSelectedNodeKey, setPrevSelectedNodeKey] = React.useState(props.selectedNodeKey);
14
- const [prevSelectedDateTime, setPrevSelectedDateTime] = React.useState(props.selectedDateTime);
15
- React.useEffect(function initialRender() {
16
- setIsMounted(true);
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
- if (isMounted &&
19
- divRef.current &&
20
- (!isEqual(prevDatedTrees, props.datedTrees) ||
21
- prevId !== divRef.current.id)) {
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":"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"}
1
+ {"version":3,"file":"GroupTreePlot.js","sourceRoot":"","sources":["../src/GroupTreePlot.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ export type PlotErrorOverlayProps = {
3
+ message: string;
4
+ };
5
+ export declare function PlotErrorOverlay(props: PlotErrorOverlayProps): React.ReactNode;
@@ -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,2 @@
1
+ export { TreePlotRenderer } from "./TreePlotRenderer";
2
+ //# sourceMappingURL=index.js.map
@@ -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,6 @@
1
+ import React from "react";
2
+ import type { RecursiveTreeNode } from "../../../types";
3
+ export type HiddenChildrenProps = {
4
+ hiddenChildren: RecursiveTreeNode[];
5
+ };
6
+ export declare function HiddenChildren(props: HiddenChildrenProps): React.ReactNode;
@@ -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":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAE/E,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAelD,MAAM,UAAU,kBAAkB,CAC9B,KAA8B;;IAE9B,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,CAAC;IAC7C,kFAAkF;IAClF,MAAM,MAAM,GAAG,CAAC,CAAA,MAAA,iBAAiB,CAAC,QAAQ,0CAAE,MAAM,CAAA,CAAC;IACnD,MAAM,aAAa,GAAG,CAAC,CAAA,MAAA,KAAK,CAAC,IAAI,CAAC,QAAQ,0CAAE,MAAM,CAAA,IAAI,CAAC,MAAM,CAAC;IAC9D,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC;IAE/C,IAAI,WAAW,GAAG,iBAAiB,CAAC;IACpC,IAAI,CAAC,MAAM;QAAE,WAAW,IAAI,iCAAiC,CAAC;IAE9D,MAAM,CAAC,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,eAAe,CACvD,KAAK,CAAC,mBAAmB,CAC5B,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAC,gBAAgB,CACzD,QAAQ,EACR,KAAK,CAAC,mBAAmB,CAC5B,CAAC;IAEF,MAAM,WAAW,GAAG,sBAAsB,CACtC,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,WAAW,EACjB;QACI,OAAO,EAAE,CAAC;QACV,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;KAClB,EACD,CAAC,cAA0B,EAAE,EAAE,CAAC,CAAC;QAC7B,OAAO,EAAE,CAAC;QACV,CAAC,EAAE,cAAc,CAAC,CAAC;QACnB,CAAC,EAAE,cAAc,CAAC,CAAC;KACtB,CAAC,CACL,CAAC;IAEF,OAAO,CACH,oBAAC,MAAM,CAAC,CAAC,oBACD,WAAW,IACf,SAAS,EAAC,MAAM,EAChB,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EACvC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,WAAC,OAAA,MAAA,KAAK,CAAC,WAAW,sDAAG,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA,EAAA;QAEtD,gCAAQ,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,GAAI;QACzC,8BACI,SAAS,EAAC,sBAAsB,EAChC,gBAAgB,EAAC,QAAQ,EACzB,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EACpB,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAEnC,SAAS,CACP;QAEP,8BACI,SAAS,EAAC,0BAA0B,EACpC,UAAU,EAAC,QAAQ,EACnB,CAAC,EAAC,QAAQ,IAET,cAAc,CAAC,gBAAgB,CAAC,CAC9B;QAEP,8BACI,SAAS,EAAC,yBAAyB,EACnC,CAAC,EAAC,OAAO,EACT,gBAAgB,EAAC,kBAAkB,EACnC,UAAU,EAAC,QAAQ,IAElB,WAAW,CACT;QACP,mCAAQ,OAAO,CAAS;QAEvB,aAAa,IAAI,CACd,oBAAC,cAAc,IACX,cAAc,EAAE,MAAA,iBAAiB,CAAC,QAAQ,mCAAI,EAAE,GAClD,CACL,CACM,CACd,CAAC;AACN,CAAC"}
@@ -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":"AAAA,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"}
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];