@atlaskit/charlie-hierarchy 0.1.0 → 0.1.1
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/CHANGELOG.md +7 -0
- package/dist/cjs/charlie-hierarchy/charlie-hierarchy.js +19 -1
- package/dist/cjs/charlie-hierarchy/utils.js +92 -0
- package/dist/es2019/charlie-hierarchy/charlie-hierarchy.js +21 -3
- package/dist/es2019/charlie-hierarchy/utils.js +86 -0
- package/dist/esm/charlie-hierarchy/charlie-hierarchy.js +19 -1
- package/dist/esm/charlie-hierarchy/utils.js +86 -0
- package/dist/types/charlie-hierarchy/charlie-hierarchy.d.ts +10 -0
- package/dist/types/charlie-hierarchy/utils.d.ts +49 -0
- package/dist/types-ts4.5/charlie-hierarchy/charlie-hierarchy.d.ts +10 -0
- package/dist/types-ts4.5/charlie-hierarchy/utils.d.ts +49 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,7 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
16
16
|
var _group = require("@visx/group");
|
|
17
17
|
var _hierarchy = require("@visx/hierarchy");
|
|
18
18
|
var _shape = require("@visx/shape");
|
|
19
|
+
var _utils = require("./utils");
|
|
19
20
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
20
21
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /**
|
|
21
22
|
* CharlieHierarchy is meant to be a generic reusable component for building SVG rendered trees.
|
|
@@ -31,7 +32,7 @@ var staticStyles = {
|
|
|
31
32
|
zoom: "_1tktglyw"
|
|
32
33
|
};
|
|
33
34
|
var CharlieHierarchy = exports.CharlieHierarchy = function CharlieHierarchy(props) {
|
|
34
|
-
var _props$size$, _props$size, _props$size$2, _props$size2, _props$nodeSize$, _props$nodeSize, _props$nodeSize$2, _props$nodeSize2, _props$top, _props$left, _props$renderDependen, _styles$transformMatr, _props$styles2;
|
|
35
|
+
var _props$size$, _props$size, _props$size$2, _props$size2, _props$nodeSize$, _props$nodeSize, _props$nodeSize$2, _props$nodeSize2, _props$top, _props$left, _props$renderDependen, _props$stackingSpacin, _styles$transformMatr, _props$styles2;
|
|
35
36
|
var _React$useTransition = _react.default.useTransition(),
|
|
36
37
|
_React$useTransition2 = (0, _slicedToArray2.default)(_React$useTransition, 2),
|
|
37
38
|
isSuspending = _React$useTransition2[0],
|
|
@@ -56,6 +57,8 @@ var CharlieHierarchy = exports.CharlieHierarchy = function CharlieHierarchy(prop
|
|
|
56
57
|
var cursor = zoom !== null && zoom !== void 0 && zoom.isDragging ? 'grabbing' : 'grab';
|
|
57
58
|
var children = props.children;
|
|
58
59
|
var renderDependencies = (_props$renderDependen = props.renderDependencies) !== null && _props$renderDependen !== void 0 ? _props$renderDependen : [];
|
|
60
|
+
var stackingThreshold = props.stackingThreshold;
|
|
61
|
+
var stackingSpacing = (_props$stackingSpacin = props.stackingSpacing) !== null && _props$stackingSpacin !== void 0 ? _props$stackingSpacin : 70;
|
|
59
62
|
|
|
60
63
|
/**
|
|
61
64
|
* If zoom is enabled, we need to apply the transform matrix to the SVG.
|
|
@@ -80,6 +83,15 @@ var CharlieHierarchy = exports.CharlieHierarchy = function CharlieHierarchy(prop
|
|
|
80
83
|
}, function (tree) {
|
|
81
84
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, tree.links().map(function (link, linkIndex) {
|
|
82
85
|
var _props$styles$lineAtt, _props$styles;
|
|
86
|
+
if (stackingThreshold) {
|
|
87
|
+
link.target.x = (0, _utils.calculateLinkTargetPosition)(link.target.x, link.source.children, stackingThreshold, nodeWidthWithPadding);
|
|
88
|
+
|
|
89
|
+
// For now, don't render links that are beyond the stacking threshold.
|
|
90
|
+
// In the future, we can render the links that are beyond the stacking threshold.
|
|
91
|
+
if (linkIndex > stackingThreshold - 1) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
83
95
|
return /*#__PURE__*/_react.default.createElement(_shape.LinkVerticalStep, (0, _extends2.default)({
|
|
84
96
|
key: "link-".concat(linkIndex),
|
|
85
97
|
data: link,
|
|
@@ -104,9 +116,15 @@ var CharlieHierarchy = exports.CharlieHierarchy = function CharlieHierarchy(prop
|
|
|
104
116
|
nodeSize: nodeSize
|
|
105
117
|
}, function (tree) {
|
|
106
118
|
var descendants = tree.descendants();
|
|
119
|
+
var stackLocations = [];
|
|
107
120
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, descendants.map(function (node, index) {
|
|
108
121
|
var top = node.y - nodeHeight / 2;
|
|
109
122
|
var left = node.x - nodeWidth / 2;
|
|
123
|
+
if (stackingThreshold) {
|
|
124
|
+
var layout = (0, _utils.updateNodeLayout)(index, stackingThreshold, nodeWidthWithPadding, stackLocations, stackingSpacing, top, left, node);
|
|
125
|
+
top = layout.top;
|
|
126
|
+
left = layout.left;
|
|
127
|
+
}
|
|
110
128
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
111
129
|
key: "tree-node-".concat(index),
|
|
112
130
|
style: {
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.updateNodeLayout = exports.calculateStackingShift = exports.calculateNodePosition = exports.calculateLinkTargetPosition = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Utility functions for Charlie Hierarchy component
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Calculates the horizontal shift needed to center nodes when some children are stacked vertically
|
|
13
|
+
* @param totalChildren - Total number of children for a parent node
|
|
14
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
15
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
16
|
+
* @returns The horizontal offset to apply for centering
|
|
17
|
+
*/
|
|
18
|
+
var calculateStackingShift = exports.calculateStackingShift = function calculateStackingShift(totalChildren, stackingThreshold, nodeWidthWithPadding) {
|
|
19
|
+
var stackedChildren = Math.max(0, totalChildren - stackingThreshold);
|
|
20
|
+
return stackedChildren * nodeWidthWithPadding / 2;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Calculates the adjusted position for a node when stacking is enabled
|
|
25
|
+
* @param originalLeft - The original left position of the node
|
|
26
|
+
* @param parentChildren - Array of parent's children (to get total count)
|
|
27
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
28
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
29
|
+
* @returns The adjusted left position
|
|
30
|
+
*/
|
|
31
|
+
var calculateNodePosition = exports.calculateNodePosition = function calculateNodePosition(originalLeft, parentChildren, stackingThreshold, nodeWidthWithPadding) {
|
|
32
|
+
if (!parentChildren || parentChildren.length <= stackingThreshold) {
|
|
33
|
+
return originalLeft;
|
|
34
|
+
}
|
|
35
|
+
var stackingShift = calculateStackingShift(parentChildren.length, stackingThreshold, nodeWidthWithPadding);
|
|
36
|
+
return originalLeft + stackingShift;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Calculates the adjusted x position for a link target when stacking is enabled
|
|
41
|
+
* @param originalX - The original x position of the link target
|
|
42
|
+
* @param sourceChildren - Array of source node's children (to get total count)
|
|
43
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
44
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
45
|
+
* @returns The adjusted x position
|
|
46
|
+
*/
|
|
47
|
+
var calculateLinkTargetPosition = exports.calculateLinkTargetPosition = function calculateLinkTargetPosition(originalX, sourceChildren, stackingThreshold, nodeWidthWithPadding) {
|
|
48
|
+
if (!sourceChildren || sourceChildren.length <= stackingThreshold) {
|
|
49
|
+
return originalX;
|
|
50
|
+
}
|
|
51
|
+
var stackingShift = calculateStackingShift(sourceChildren.length, stackingThreshold, nodeWidthWithPadding);
|
|
52
|
+
return originalX + stackingShift;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Updates the layout position for a single node in a hierarchical tree with stacking support
|
|
57
|
+
* @param index - The index of the current node in the descendants array (0-based)
|
|
58
|
+
* @param stackingThreshold - Maximum number of nodes to display horizontally before stacking
|
|
59
|
+
* @param nodeWidthWithPadding - Width of a node including its padding for spacing calculations
|
|
60
|
+
* @param stackLocations - Mutable array storing positions of horizontal nodes for stacked node reference
|
|
61
|
+
* @param stackingSpacing - Vertical spacing in pixels between stacked nodes
|
|
62
|
+
* @param top - Initial top position of the node (before stacking adjustments)
|
|
63
|
+
* @param left - Initial left position of the node (before centering/stacking adjustments)
|
|
64
|
+
* @param node - The hierarchy node object containing parent/children relationships
|
|
65
|
+
* @returns Object containing the final calculated { top, left } position for the node
|
|
66
|
+
*/
|
|
67
|
+
var updateNodeLayout = exports.updateNodeLayout = function updateNodeLayout(index, stackingThreshold, nodeWidthWithPadding, stackLocations, stackingSpacing, top, left, node) {
|
|
68
|
+
if (index <= stackingThreshold) {
|
|
69
|
+
if (index > 0) {
|
|
70
|
+
var _node$parent;
|
|
71
|
+
left = calculateNodePosition(left, (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.children, stackingThreshold, nodeWidthWithPadding);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Add the stack location to the array so we can reference it later
|
|
75
|
+
stackLocations.push({
|
|
76
|
+
top: top,
|
|
77
|
+
left: left
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
var stackRefrencePoint = stackLocations[index - stackingThreshold];
|
|
81
|
+
top = stackRefrencePoint.top + stackingSpacing;
|
|
82
|
+
left = stackRefrencePoint.left;
|
|
83
|
+
stackLocations.push({
|
|
84
|
+
top: top,
|
|
85
|
+
left: left
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
top: top,
|
|
90
|
+
left: left
|
|
91
|
+
};
|
|
92
|
+
};
|
|
@@ -13,6 +13,7 @@ import React from 'react';
|
|
|
13
13
|
import { Group } from '@visx/group';
|
|
14
14
|
import { Tree } from '@visx/hierarchy';
|
|
15
15
|
import { LinkVerticalStep } from '@visx/shape';
|
|
16
|
+
import { calculateLinkTargetPosition, updateNodeLayout } from './utils';
|
|
16
17
|
const staticStyles = {
|
|
17
18
|
hierarchyWrapper: "_kqswh2mm",
|
|
18
19
|
nodeGroupWrapper: "_kqswstnw",
|
|
@@ -21,7 +22,7 @@ const staticStyles = {
|
|
|
21
22
|
zoom: "_1tktglyw"
|
|
22
23
|
};
|
|
23
24
|
export const CharlieHierarchy = props => {
|
|
24
|
-
var _props$size$, _props$size, _props$size$2, _props$size2, _props$nodeSize$, _props$nodeSize, _props$nodeSize$2, _props$nodeSize2, _props$top, _props$left, _props$renderDependen, _styles$transformMatr, _props$styles2;
|
|
25
|
+
var _props$size$, _props$size, _props$size$2, _props$size2, _props$nodeSize$, _props$nodeSize, _props$nodeSize$2, _props$nodeSize2, _props$top, _props$left, _props$renderDependen, _props$stackingSpacin, _styles$transformMatr, _props$styles2;
|
|
25
26
|
const [isSuspending, startSuspending] = React.useTransition();
|
|
26
27
|
const styles = {
|
|
27
28
|
...{
|
|
@@ -46,6 +47,8 @@ export const CharlieHierarchy = props => {
|
|
|
46
47
|
const cursor = zoom !== null && zoom !== void 0 && zoom.isDragging ? 'grabbing' : 'grab';
|
|
47
48
|
const children = props.children;
|
|
48
49
|
const renderDependencies = (_props$renderDependen = props.renderDependencies) !== null && _props$renderDependen !== void 0 ? _props$renderDependen : [];
|
|
50
|
+
const stackingThreshold = props.stackingThreshold;
|
|
51
|
+
const stackingSpacing = (_props$stackingSpacin = props.stackingSpacing) !== null && _props$stackingSpacin !== void 0 ? _props$stackingSpacin : 70;
|
|
49
52
|
|
|
50
53
|
/**
|
|
51
54
|
* If zoom is enabled, we need to apply the transform matrix to the SVG.
|
|
@@ -70,6 +73,15 @@ export const CharlieHierarchy = props => {
|
|
|
70
73
|
}, tree => {
|
|
71
74
|
return /*#__PURE__*/React.createElement(React.Fragment, null, tree.links().map((link, linkIndex) => {
|
|
72
75
|
var _props$styles$lineAtt, _props$styles;
|
|
76
|
+
if (stackingThreshold) {
|
|
77
|
+
link.target.x = calculateLinkTargetPosition(link.target.x, link.source.children, stackingThreshold, nodeWidthWithPadding);
|
|
78
|
+
|
|
79
|
+
// For now, don't render links that are beyond the stacking threshold.
|
|
80
|
+
// In the future, we can render the links that are beyond the stacking threshold.
|
|
81
|
+
if (linkIndex > stackingThreshold - 1) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
73
85
|
return /*#__PURE__*/React.createElement(LinkVerticalStep, _extends({
|
|
74
86
|
key: `link-${linkIndex}`,
|
|
75
87
|
data: link,
|
|
@@ -94,9 +106,15 @@ export const CharlieHierarchy = props => {
|
|
|
94
106
|
nodeSize: nodeSize
|
|
95
107
|
}, tree => {
|
|
96
108
|
const descendants = tree.descendants();
|
|
109
|
+
const stackLocations = [];
|
|
97
110
|
return /*#__PURE__*/React.createElement(React.Fragment, null, descendants.map((node, index) => {
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
let top = node.y - nodeHeight / 2;
|
|
112
|
+
let left = node.x - nodeWidth / 2;
|
|
113
|
+
if (stackingThreshold) {
|
|
114
|
+
const layout = updateNodeLayout(index, stackingThreshold, nodeWidthWithPadding, stackLocations, stackingSpacing, top, left, node);
|
|
115
|
+
top = layout.top;
|
|
116
|
+
left = layout.left;
|
|
117
|
+
}
|
|
100
118
|
return /*#__PURE__*/React.createElement("div", {
|
|
101
119
|
key: `tree-node-${index}`,
|
|
102
120
|
style: {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for Charlie Hierarchy component
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Calculates the horizontal shift needed to center nodes when some children are stacked vertically
|
|
7
|
+
* @param totalChildren - Total number of children for a parent node
|
|
8
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
9
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
10
|
+
* @returns The horizontal offset to apply for centering
|
|
11
|
+
*/
|
|
12
|
+
export const calculateStackingShift = (totalChildren, stackingThreshold, nodeWidthWithPadding) => {
|
|
13
|
+
const stackedChildren = Math.max(0, totalChildren - stackingThreshold);
|
|
14
|
+
return stackedChildren * nodeWidthWithPadding / 2;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Calculates the adjusted position for a node when stacking is enabled
|
|
19
|
+
* @param originalLeft - The original left position of the node
|
|
20
|
+
* @param parentChildren - Array of parent's children (to get total count)
|
|
21
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
22
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
23
|
+
* @returns The adjusted left position
|
|
24
|
+
*/
|
|
25
|
+
export const calculateNodePosition = (originalLeft, parentChildren, stackingThreshold, nodeWidthWithPadding) => {
|
|
26
|
+
if (!parentChildren || parentChildren.length <= stackingThreshold) {
|
|
27
|
+
return originalLeft;
|
|
28
|
+
}
|
|
29
|
+
const stackingShift = calculateStackingShift(parentChildren.length, stackingThreshold, nodeWidthWithPadding);
|
|
30
|
+
return originalLeft + stackingShift;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calculates the adjusted x position for a link target when stacking is enabled
|
|
35
|
+
* @param originalX - The original x position of the link target
|
|
36
|
+
* @param sourceChildren - Array of source node's children (to get total count)
|
|
37
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
38
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
39
|
+
* @returns The adjusted x position
|
|
40
|
+
*/
|
|
41
|
+
export const calculateLinkTargetPosition = (originalX, sourceChildren, stackingThreshold, nodeWidthWithPadding) => {
|
|
42
|
+
if (!sourceChildren || sourceChildren.length <= stackingThreshold) {
|
|
43
|
+
return originalX;
|
|
44
|
+
}
|
|
45
|
+
const stackingShift = calculateStackingShift(sourceChildren.length, stackingThreshold, nodeWidthWithPadding);
|
|
46
|
+
return originalX + stackingShift;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Updates the layout position for a single node in a hierarchical tree with stacking support
|
|
51
|
+
* @param index - The index of the current node in the descendants array (0-based)
|
|
52
|
+
* @param stackingThreshold - Maximum number of nodes to display horizontally before stacking
|
|
53
|
+
* @param nodeWidthWithPadding - Width of a node including its padding for spacing calculations
|
|
54
|
+
* @param stackLocations - Mutable array storing positions of horizontal nodes for stacked node reference
|
|
55
|
+
* @param stackingSpacing - Vertical spacing in pixels between stacked nodes
|
|
56
|
+
* @param top - Initial top position of the node (before stacking adjustments)
|
|
57
|
+
* @param left - Initial left position of the node (before centering/stacking adjustments)
|
|
58
|
+
* @param node - The hierarchy node object containing parent/children relationships
|
|
59
|
+
* @returns Object containing the final calculated { top, left } position for the node
|
|
60
|
+
*/
|
|
61
|
+
export const updateNodeLayout = (index, stackingThreshold, nodeWidthWithPadding, stackLocations, stackingSpacing, top, left, node) => {
|
|
62
|
+
if (index <= stackingThreshold) {
|
|
63
|
+
if (index > 0) {
|
|
64
|
+
var _node$parent;
|
|
65
|
+
left = calculateNodePosition(left, (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.children, stackingThreshold, nodeWidthWithPadding);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Add the stack location to the array so we can reference it later
|
|
69
|
+
stackLocations.push({
|
|
70
|
+
top: top,
|
|
71
|
+
left: left
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
const stackRefrencePoint = stackLocations[index - stackingThreshold];
|
|
75
|
+
top = stackRefrencePoint.top + stackingSpacing;
|
|
76
|
+
left = stackRefrencePoint.left;
|
|
77
|
+
stackLocations.push({
|
|
78
|
+
top: top,
|
|
79
|
+
left: left
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
top,
|
|
84
|
+
left
|
|
85
|
+
};
|
|
86
|
+
};
|
|
@@ -18,6 +18,7 @@ import React from 'react';
|
|
|
18
18
|
import { Group } from '@visx/group';
|
|
19
19
|
import { Tree } from '@visx/hierarchy';
|
|
20
20
|
import { LinkVerticalStep } from '@visx/shape';
|
|
21
|
+
import { calculateLinkTargetPosition, updateNodeLayout } from './utils';
|
|
21
22
|
var staticStyles = {
|
|
22
23
|
hierarchyWrapper: "_kqswh2mm",
|
|
23
24
|
nodeGroupWrapper: "_kqswstnw",
|
|
@@ -26,7 +27,7 @@ var staticStyles = {
|
|
|
26
27
|
zoom: "_1tktglyw"
|
|
27
28
|
};
|
|
28
29
|
export var CharlieHierarchy = function CharlieHierarchy(props) {
|
|
29
|
-
var _props$size$, _props$size, _props$size$2, _props$size2, _props$nodeSize$, _props$nodeSize, _props$nodeSize$2, _props$nodeSize2, _props$top, _props$left, _props$renderDependen, _styles$transformMatr, _props$styles2;
|
|
30
|
+
var _props$size$, _props$size, _props$size$2, _props$size2, _props$nodeSize$, _props$nodeSize, _props$nodeSize$2, _props$nodeSize2, _props$top, _props$left, _props$renderDependen, _props$stackingSpacin, _styles$transformMatr, _props$styles2;
|
|
30
31
|
var _React$useTransition = React.useTransition(),
|
|
31
32
|
_React$useTransition2 = _slicedToArray(_React$useTransition, 2),
|
|
32
33
|
isSuspending = _React$useTransition2[0],
|
|
@@ -51,6 +52,8 @@ export var CharlieHierarchy = function CharlieHierarchy(props) {
|
|
|
51
52
|
var cursor = zoom !== null && zoom !== void 0 && zoom.isDragging ? 'grabbing' : 'grab';
|
|
52
53
|
var children = props.children;
|
|
53
54
|
var renderDependencies = (_props$renderDependen = props.renderDependencies) !== null && _props$renderDependen !== void 0 ? _props$renderDependen : [];
|
|
55
|
+
var stackingThreshold = props.stackingThreshold;
|
|
56
|
+
var stackingSpacing = (_props$stackingSpacin = props.stackingSpacing) !== null && _props$stackingSpacin !== void 0 ? _props$stackingSpacin : 70;
|
|
54
57
|
|
|
55
58
|
/**
|
|
56
59
|
* If zoom is enabled, we need to apply the transform matrix to the SVG.
|
|
@@ -75,6 +78,15 @@ export var CharlieHierarchy = function CharlieHierarchy(props) {
|
|
|
75
78
|
}, function (tree) {
|
|
76
79
|
return /*#__PURE__*/React.createElement(React.Fragment, null, tree.links().map(function (link, linkIndex) {
|
|
77
80
|
var _props$styles$lineAtt, _props$styles;
|
|
81
|
+
if (stackingThreshold) {
|
|
82
|
+
link.target.x = calculateLinkTargetPosition(link.target.x, link.source.children, stackingThreshold, nodeWidthWithPadding);
|
|
83
|
+
|
|
84
|
+
// For now, don't render links that are beyond the stacking threshold.
|
|
85
|
+
// In the future, we can render the links that are beyond the stacking threshold.
|
|
86
|
+
if (linkIndex > stackingThreshold - 1) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
78
90
|
return /*#__PURE__*/React.createElement(LinkVerticalStep, _extends({
|
|
79
91
|
key: "link-".concat(linkIndex),
|
|
80
92
|
data: link,
|
|
@@ -99,9 +111,15 @@ export var CharlieHierarchy = function CharlieHierarchy(props) {
|
|
|
99
111
|
nodeSize: nodeSize
|
|
100
112
|
}, function (tree) {
|
|
101
113
|
var descendants = tree.descendants();
|
|
114
|
+
var stackLocations = [];
|
|
102
115
|
return /*#__PURE__*/React.createElement(React.Fragment, null, descendants.map(function (node, index) {
|
|
103
116
|
var top = node.y - nodeHeight / 2;
|
|
104
117
|
var left = node.x - nodeWidth / 2;
|
|
118
|
+
if (stackingThreshold) {
|
|
119
|
+
var layout = updateNodeLayout(index, stackingThreshold, nodeWidthWithPadding, stackLocations, stackingSpacing, top, left, node);
|
|
120
|
+
top = layout.top;
|
|
121
|
+
left = layout.left;
|
|
122
|
+
}
|
|
105
123
|
return /*#__PURE__*/React.createElement("div", {
|
|
106
124
|
key: "tree-node-".concat(index),
|
|
107
125
|
style: {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for Charlie Hierarchy component
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Calculates the horizontal shift needed to center nodes when some children are stacked vertically
|
|
7
|
+
* @param totalChildren - Total number of children for a parent node
|
|
8
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
9
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
10
|
+
* @returns The horizontal offset to apply for centering
|
|
11
|
+
*/
|
|
12
|
+
export var calculateStackingShift = function calculateStackingShift(totalChildren, stackingThreshold, nodeWidthWithPadding) {
|
|
13
|
+
var stackedChildren = Math.max(0, totalChildren - stackingThreshold);
|
|
14
|
+
return stackedChildren * nodeWidthWithPadding / 2;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Calculates the adjusted position for a node when stacking is enabled
|
|
19
|
+
* @param originalLeft - The original left position of the node
|
|
20
|
+
* @param parentChildren - Array of parent's children (to get total count)
|
|
21
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
22
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
23
|
+
* @returns The adjusted left position
|
|
24
|
+
*/
|
|
25
|
+
export var calculateNodePosition = function calculateNodePosition(originalLeft, parentChildren, stackingThreshold, nodeWidthWithPadding) {
|
|
26
|
+
if (!parentChildren || parentChildren.length <= stackingThreshold) {
|
|
27
|
+
return originalLeft;
|
|
28
|
+
}
|
|
29
|
+
var stackingShift = calculateStackingShift(parentChildren.length, stackingThreshold, nodeWidthWithPadding);
|
|
30
|
+
return originalLeft + stackingShift;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calculates the adjusted x position for a link target when stacking is enabled
|
|
35
|
+
* @param originalX - The original x position of the link target
|
|
36
|
+
* @param sourceChildren - Array of source node's children (to get total count)
|
|
37
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
38
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
39
|
+
* @returns The adjusted x position
|
|
40
|
+
*/
|
|
41
|
+
export var calculateLinkTargetPosition = function calculateLinkTargetPosition(originalX, sourceChildren, stackingThreshold, nodeWidthWithPadding) {
|
|
42
|
+
if (!sourceChildren || sourceChildren.length <= stackingThreshold) {
|
|
43
|
+
return originalX;
|
|
44
|
+
}
|
|
45
|
+
var stackingShift = calculateStackingShift(sourceChildren.length, stackingThreshold, nodeWidthWithPadding);
|
|
46
|
+
return originalX + stackingShift;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Updates the layout position for a single node in a hierarchical tree with stacking support
|
|
51
|
+
* @param index - The index of the current node in the descendants array (0-based)
|
|
52
|
+
* @param stackingThreshold - Maximum number of nodes to display horizontally before stacking
|
|
53
|
+
* @param nodeWidthWithPadding - Width of a node including its padding for spacing calculations
|
|
54
|
+
* @param stackLocations - Mutable array storing positions of horizontal nodes for stacked node reference
|
|
55
|
+
* @param stackingSpacing - Vertical spacing in pixels between stacked nodes
|
|
56
|
+
* @param top - Initial top position of the node (before stacking adjustments)
|
|
57
|
+
* @param left - Initial left position of the node (before centering/stacking adjustments)
|
|
58
|
+
* @param node - The hierarchy node object containing parent/children relationships
|
|
59
|
+
* @returns Object containing the final calculated { top, left } position for the node
|
|
60
|
+
*/
|
|
61
|
+
export var updateNodeLayout = function updateNodeLayout(index, stackingThreshold, nodeWidthWithPadding, stackLocations, stackingSpacing, top, left, node) {
|
|
62
|
+
if (index <= stackingThreshold) {
|
|
63
|
+
if (index > 0) {
|
|
64
|
+
var _node$parent;
|
|
65
|
+
left = calculateNodePosition(left, (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.children, stackingThreshold, nodeWidthWithPadding);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Add the stack location to the array so we can reference it later
|
|
69
|
+
stackLocations.push({
|
|
70
|
+
top: top,
|
|
71
|
+
left: left
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
var stackRefrencePoint = stackLocations[index - stackingThreshold];
|
|
75
|
+
top = stackRefrencePoint.top + stackingSpacing;
|
|
76
|
+
left = stackRefrencePoint.left;
|
|
77
|
+
stackLocations.push({
|
|
78
|
+
top: top,
|
|
79
|
+
left: left
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
top: top,
|
|
84
|
+
left: left
|
|
85
|
+
};
|
|
86
|
+
};
|
|
@@ -61,5 +61,15 @@ export interface CharlieHierarchyProps<Datum> extends Omit<TreeProps<Datum>, 'ch
|
|
|
61
61
|
* Pass any dependencies that on change should trigger a re-render of the tree.
|
|
62
62
|
*/
|
|
63
63
|
renderDependencies?: React.DependencyList;
|
|
64
|
+
/**
|
|
65
|
+
* When specified, enables vertical stacking of overflow children.
|
|
66
|
+
* Children beyond this threshold will be stacked vertically under the first child.
|
|
67
|
+
*/
|
|
68
|
+
stackingThreshold?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Vertical spacing between stacked nodes in pixels.
|
|
71
|
+
* @default 70
|
|
72
|
+
*/
|
|
73
|
+
stackingSpacing?: number;
|
|
64
74
|
}
|
|
65
75
|
export declare const CharlieHierarchy: <Datum>(props: CharlieHierarchyProps<Datum>) => JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for Charlie Hierarchy component
|
|
3
|
+
*/
|
|
4
|
+
import type { HierarchyPointNode } from "@visx/hierarchy/lib/types";
|
|
5
|
+
/**
|
|
6
|
+
* Calculates the horizontal shift needed to center nodes when some children are stacked vertically
|
|
7
|
+
* @param totalChildren - Total number of children for a parent node
|
|
8
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
9
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
10
|
+
* @returns The horizontal offset to apply for centering
|
|
11
|
+
*/
|
|
12
|
+
export declare const calculateStackingShift: (totalChildren: number, stackingThreshold: number, nodeWidthWithPadding: number) => number;
|
|
13
|
+
/**
|
|
14
|
+
* Calculates the adjusted position for a node when stacking is enabled
|
|
15
|
+
* @param originalLeft - The original left position of the node
|
|
16
|
+
* @param parentChildren - Array of parent's children (to get total count)
|
|
17
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
18
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
19
|
+
* @returns The adjusted left position
|
|
20
|
+
*/
|
|
21
|
+
export declare const calculateNodePosition: (originalLeft: number, parentChildren: unknown[] | undefined, stackingThreshold: number, nodeWidthWithPadding: number) => number;
|
|
22
|
+
/**
|
|
23
|
+
* Calculates the adjusted x position for a link target when stacking is enabled
|
|
24
|
+
* @param originalX - The original x position of the link target
|
|
25
|
+
* @param sourceChildren - Array of source node's children (to get total count)
|
|
26
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
27
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
28
|
+
* @returns The adjusted x position
|
|
29
|
+
*/
|
|
30
|
+
export declare const calculateLinkTargetPosition: (originalX: number, sourceChildren: unknown[] | undefined, stackingThreshold: number, nodeWidthWithPadding: number) => number;
|
|
31
|
+
/**
|
|
32
|
+
* Updates the layout position for a single node in a hierarchical tree with stacking support
|
|
33
|
+
* @param index - The index of the current node in the descendants array (0-based)
|
|
34
|
+
* @param stackingThreshold - Maximum number of nodes to display horizontally before stacking
|
|
35
|
+
* @param nodeWidthWithPadding - Width of a node including its padding for spacing calculations
|
|
36
|
+
* @param stackLocations - Mutable array storing positions of horizontal nodes for stacked node reference
|
|
37
|
+
* @param stackingSpacing - Vertical spacing in pixels between stacked nodes
|
|
38
|
+
* @param top - Initial top position of the node (before stacking adjustments)
|
|
39
|
+
* @param left - Initial left position of the node (before centering/stacking adjustments)
|
|
40
|
+
* @param node - The hierarchy node object containing parent/children relationships
|
|
41
|
+
* @returns Object containing the final calculated { top, left } position for the node
|
|
42
|
+
*/
|
|
43
|
+
export declare const updateNodeLayout: <Datum>(index: number, stackingThreshold: number, nodeWidthWithPadding: number, stackLocations: {
|
|
44
|
+
top: number;
|
|
45
|
+
left: number;
|
|
46
|
+
}[], stackingSpacing: number, top: number, left: number, node: HierarchyPointNode<Datum>) => {
|
|
47
|
+
top: number;
|
|
48
|
+
left: number;
|
|
49
|
+
};
|
|
@@ -61,5 +61,15 @@ export interface CharlieHierarchyProps<Datum> extends Omit<TreeProps<Datum>, 'ch
|
|
|
61
61
|
* Pass any dependencies that on change should trigger a re-render of the tree.
|
|
62
62
|
*/
|
|
63
63
|
renderDependencies?: React.DependencyList;
|
|
64
|
+
/**
|
|
65
|
+
* When specified, enables vertical stacking of overflow children.
|
|
66
|
+
* Children beyond this threshold will be stacked vertically under the first child.
|
|
67
|
+
*/
|
|
68
|
+
stackingThreshold?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Vertical spacing between stacked nodes in pixels.
|
|
71
|
+
* @default 70
|
|
72
|
+
*/
|
|
73
|
+
stackingSpacing?: number;
|
|
64
74
|
}
|
|
65
75
|
export declare const CharlieHierarchy: <Datum>(props: CharlieHierarchyProps<Datum>) => JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for Charlie Hierarchy component
|
|
3
|
+
*/
|
|
4
|
+
import type { HierarchyPointNode } from "@visx/hierarchy/lib/types";
|
|
5
|
+
/**
|
|
6
|
+
* Calculates the horizontal shift needed to center nodes when some children are stacked vertically
|
|
7
|
+
* @param totalChildren - Total number of children for a parent node
|
|
8
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
9
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
10
|
+
* @returns The horizontal offset to apply for centering
|
|
11
|
+
*/
|
|
12
|
+
export declare const calculateStackingShift: (totalChildren: number, stackingThreshold: number, nodeWidthWithPadding: number) => number;
|
|
13
|
+
/**
|
|
14
|
+
* Calculates the adjusted position for a node when stacking is enabled
|
|
15
|
+
* @param originalLeft - The original left position of the node
|
|
16
|
+
* @param parentChildren - Array of parent's children (to get total count)
|
|
17
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
18
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
19
|
+
* @returns The adjusted left position
|
|
20
|
+
*/
|
|
21
|
+
export declare const calculateNodePosition: (originalLeft: number, parentChildren: unknown[] | undefined, stackingThreshold: number, nodeWidthWithPadding: number) => number;
|
|
22
|
+
/**
|
|
23
|
+
* Calculates the adjusted x position for a link target when stacking is enabled
|
|
24
|
+
* @param originalX - The original x position of the link target
|
|
25
|
+
* @param sourceChildren - Array of source node's children (to get total count)
|
|
26
|
+
* @param stackingThreshold - Maximum number of children to display horizontally
|
|
27
|
+
* @param nodeWidthWithPadding - Width of a node including padding
|
|
28
|
+
* @returns The adjusted x position
|
|
29
|
+
*/
|
|
30
|
+
export declare const calculateLinkTargetPosition: (originalX: number, sourceChildren: unknown[] | undefined, stackingThreshold: number, nodeWidthWithPadding: number) => number;
|
|
31
|
+
/**
|
|
32
|
+
* Updates the layout position for a single node in a hierarchical tree with stacking support
|
|
33
|
+
* @param index - The index of the current node in the descendants array (0-based)
|
|
34
|
+
* @param stackingThreshold - Maximum number of nodes to display horizontally before stacking
|
|
35
|
+
* @param nodeWidthWithPadding - Width of a node including its padding for spacing calculations
|
|
36
|
+
* @param stackLocations - Mutable array storing positions of horizontal nodes for stacked node reference
|
|
37
|
+
* @param stackingSpacing - Vertical spacing in pixels between stacked nodes
|
|
38
|
+
* @param top - Initial top position of the node (before stacking adjustments)
|
|
39
|
+
* @param left - Initial left position of the node (before centering/stacking adjustments)
|
|
40
|
+
* @param node - The hierarchy node object containing parent/children relationships
|
|
41
|
+
* @returns Object containing the final calculated { top, left } position for the node
|
|
42
|
+
*/
|
|
43
|
+
export declare const updateNodeLayout: <Datum>(index: number, stackingThreshold: number, nodeWidthWithPadding: number, stackLocations: {
|
|
44
|
+
top: number;
|
|
45
|
+
left: number;
|
|
46
|
+
}[], stackingSpacing: number, top: number, left: number, node: HierarchyPointNode<Datum>) => {
|
|
47
|
+
top: number;
|
|
48
|
+
left: number;
|
|
49
|
+
};
|
package/package.json
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"@atlaskit/button": "^23.3.0",
|
|
31
31
|
"@atlaskit/css": "^0.12.0",
|
|
32
32
|
"@atlaskit/primitives": "^14.11.0",
|
|
33
|
+
"@atlaskit/range": "^9.2.0",
|
|
33
34
|
"@atlaskit/tokens": "^6.0.0",
|
|
34
35
|
"@babel/runtime": "^7.0.0",
|
|
35
36
|
"@compiled/react": "^0.18.3",
|
|
@@ -94,7 +95,7 @@
|
|
|
94
95
|
]
|
|
95
96
|
},
|
|
96
97
|
"name": "@atlaskit/charlie-hierarchy",
|
|
97
|
-
"version": "0.1.
|
|
98
|
+
"version": "0.1.1",
|
|
98
99
|
"description": "A component for building SVG-rendered trees, with support for custom node rendering, zooming, and panning.",
|
|
99
100
|
"author": "Atlassian Pty Ltd",
|
|
100
101
|
"license": "Apache-2.0",
|