@fluentui/react-charting 5.19.17 → 5.19.19
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.json +45 -1
- package/CHANGELOG.md +21 -2
- package/dist/react-charting.js +1 -1
- package/dist/react-charting.min.js +1 -1
- package/lib/components/HeatMapChart/HeatMapChart.base.js +43 -43
- package/lib/components/HeatMapChart/HeatMapChart.base.js.map +1 -1
- package/lib/components/SankeyChart/SankeyChart.base.d.ts +1 -27
- package/lib/components/SankeyChart/SankeyChart.base.js +246 -260
- package/lib/components/SankeyChart/SankeyChart.base.js.map +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/lib-amd/components/HeatMapChart/HeatMapChart.base.js +43 -43
- package/lib-amd/components/HeatMapChart/HeatMapChart.base.js.map +1 -1
- package/lib-amd/components/SankeyChart/SankeyChart.base.d.ts +1 -27
- package/lib-amd/components/SankeyChart/SankeyChart.base.js +241 -255
- package/lib-amd/components/SankeyChart/SankeyChart.base.js.map +1 -1
- package/lib-amd/version.js +1 -1
- package/lib-amd/version.js.map +1 -1
- package/lib-commonjs/components/HeatMapChart/HeatMapChart.base.js +43 -43
- package/lib-commonjs/components/HeatMapChart/HeatMapChart.base.js.map +1 -1
- package/lib-commonjs/components/SankeyChart/SankeyChart.base.d.ts +1 -27
- package/lib-commonjs/components/SankeyChart/SankeyChart.base.js +245 -259
- package/lib-commonjs/components/SankeyChart/SankeyChart.base.js.map +1 -1
- package/lib-commonjs/version.js +1 -1
- package/lib-commonjs/version.js.map +1 -1
- package/package.json +3 -3
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SankeyChartBase = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var
|
|
5
|
+
var react_focus_1 = require("@fluentui/react-focus");
|
|
6
|
+
var Callout_1 = require("@fluentui/react/lib/Callout");
|
|
6
7
|
var Utilities_1 = require("@fluentui/react/lib/Utilities");
|
|
8
|
+
var d3_array_1 = require("d3-array");
|
|
7
9
|
var d3_sankey_1 = require("d3-sankey");
|
|
10
|
+
var d3_selection_1 = require("d3-selection");
|
|
8
11
|
var d3_shape_1 = require("d3-shape");
|
|
9
|
-
var
|
|
12
|
+
var React = require("react");
|
|
10
13
|
var index_1 = require("../../index");
|
|
11
|
-
var Callout_1 = require("@fluentui/react/lib/Callout");
|
|
12
|
-
var d3_selection_1 = require("d3-selection");
|
|
13
|
-
var react_focus_1 = require("@fluentui/react-focus");
|
|
14
14
|
var getClassNames = (0, Utilities_1.classNamesFunction)();
|
|
15
15
|
var PADDING_PERCENTAGE = 0.3;
|
|
16
16
|
var NON_SELECTED_NODE_AND_STREAM_COLOR = '#757575';
|
|
@@ -34,12 +34,167 @@ var SELECTED_STREAM_OPACITY = 0.3;
|
|
|
34
34
|
var NON_SELECTED_STREAM_BORDER_OPACITY = 0.5;
|
|
35
35
|
var DEFAULT_TEXT_COLOR = '#323130';
|
|
36
36
|
var NON_SELECTED_TEXT_COLOR = '#FFFFFF';
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
function getSelectedNodes(selectedLinks) {
|
|
39
|
+
var nodes = [];
|
|
40
|
+
selectedLinks.forEach(function (link) {
|
|
41
|
+
nodes.push(link.target);
|
|
42
|
+
if (nodes.indexOf(link.source) === -1) {
|
|
43
|
+
nodes.push(link.source);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return nodes;
|
|
47
|
+
}
|
|
48
|
+
function getSelectedLinks(singleNode) {
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, no-array-constructor
|
|
50
|
+
var q = new Array();
|
|
51
|
+
var finalLinks = new Set();
|
|
52
|
+
singleNode.sourceLinks.forEach(function (link) {
|
|
53
|
+
q.push(link);
|
|
54
|
+
finalLinks.add(link);
|
|
55
|
+
});
|
|
56
|
+
while (q.length > 0) {
|
|
57
|
+
var poppedLink = q.shift();
|
|
58
|
+
var node = poppedLink.target;
|
|
59
|
+
if (node && node.sourceLinks) {
|
|
60
|
+
node.sourceLinks.forEach(function (link) {
|
|
61
|
+
finalLinks.add(link);
|
|
62
|
+
q.push(link);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (singleNode.targetLinks) {
|
|
67
|
+
singleNode.targetLinks.forEach(function (link) {
|
|
68
|
+
q.push(link);
|
|
69
|
+
finalLinks.add(link);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
while (q.length > 0) {
|
|
73
|
+
var poppedLink = q.shift();
|
|
74
|
+
var node = poppedLink.source;
|
|
75
|
+
if (node && node.targetLinks) {
|
|
76
|
+
node.targetLinks.forEach(function (link) {
|
|
77
|
+
finalLinks.add(link);
|
|
78
|
+
q.push(link);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return finalLinks;
|
|
83
|
+
}
|
|
84
|
+
function getSelectedLinksforStreamHover(singleLink) {
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, no-array-constructor
|
|
86
|
+
var q = new Array();
|
|
87
|
+
var finalLinks = new Set();
|
|
88
|
+
var finalNodes = new Set();
|
|
89
|
+
q.push(singleLink.source);
|
|
90
|
+
finalLinks.add(singleLink);
|
|
91
|
+
while (q.length > 0) {
|
|
92
|
+
var poppedNode = q.shift();
|
|
93
|
+
finalNodes.add(poppedNode);
|
|
94
|
+
if (poppedNode.targetLinks && poppedNode.targetLinks.length > 0) {
|
|
95
|
+
poppedNode.targetLinks.forEach(function (link) {
|
|
96
|
+
q.push(link.source);
|
|
97
|
+
finalLinks.add(link);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
q.push(singleLink.target);
|
|
102
|
+
while (q.length > 0) {
|
|
103
|
+
var poppedNode = q.shift();
|
|
104
|
+
finalNodes.add(poppedNode);
|
|
105
|
+
if (poppedNode.sourceLinks && poppedNode.sourceLinks.length > 0) {
|
|
106
|
+
poppedNode.sourceLinks.forEach(function (link) {
|
|
107
|
+
q.push(link.target);
|
|
108
|
+
finalLinks.add(link);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
selectedLinks: finalLinks,
|
|
114
|
+
selectedNodes: finalNodes,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* This is used to group nodes by column index.
|
|
119
|
+
*/
|
|
120
|
+
function populateNodeInColumns(graph, sankey) {
|
|
121
|
+
sankey(graph);
|
|
122
|
+
var nodesInColumn = {};
|
|
123
|
+
graph.nodes.forEach(function (node) {
|
|
124
|
+
var columnId = node.layer;
|
|
125
|
+
if (nodesInColumn[columnId]) {
|
|
126
|
+
nodesInColumn[columnId].push(node);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
nodesInColumn[columnId] = [node];
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return nodesInColumn;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* This is used to normalize the nodes value whose value is less than 1% of the total column value.
|
|
136
|
+
*/
|
|
137
|
+
function adjustOnePercentHeightNodes(nodesInColumn) {
|
|
138
|
+
var totalColumnValue = Object.values(nodesInColumn).map(function (column) {
|
|
139
|
+
return (0, d3_array_1.sum)(column, function (node) { return node.value; });
|
|
140
|
+
});
|
|
141
|
+
totalColumnValue.forEach(function (columnValue, index) {
|
|
142
|
+
var totalPercentage = 0;
|
|
143
|
+
nodesInColumn[index].forEach(function (node) {
|
|
144
|
+
var nodePercentage = (node.value / columnValue) * 100;
|
|
145
|
+
node.actualValue = node.value;
|
|
146
|
+
//if the value is less than 1% then we are making it as 1% of total .
|
|
147
|
+
if (nodePercentage < 1) {
|
|
148
|
+
node.value = 0.01 * columnValue;
|
|
149
|
+
totalPercentage = totalPercentage + 1;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
totalPercentage = totalPercentage + nodePercentage;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
//since we have adjusted the value to be 1% but we need to keep the sum of the percentage value under 100.
|
|
156
|
+
var scalingRatio = totalPercentage !== 0 ? totalPercentage / 100 : 1;
|
|
157
|
+
if (scalingRatio > 1) {
|
|
158
|
+
nodesInColumn[index].forEach(function (node) {
|
|
159
|
+
node.value = node.value / scalingRatio;
|
|
160
|
+
changeColumnValue(node, node.actualValue, node.value);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* This is used for normalizing each links value for reflecting the normalized node value.
|
|
167
|
+
*/
|
|
168
|
+
function changeColumnValue(node, originalValue, normalizedValue) {
|
|
169
|
+
node.sourceLinks.forEach(function (link) {
|
|
170
|
+
link.unnormalizedValue = link.value;
|
|
171
|
+
var linkRatio = link.value / originalValue;
|
|
172
|
+
link.value = normalizedValue * linkRatio;
|
|
173
|
+
});
|
|
174
|
+
node.targetLinks.forEach(function (link) {
|
|
175
|
+
link.unnormalizedValue = link.value;
|
|
176
|
+
var linkRatio = link.value / originalValue;
|
|
177
|
+
link.value = normalizedValue * linkRatio;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* This is used for calculating the node non normalized value based on link non normalized value.
|
|
182
|
+
*/
|
|
183
|
+
function populateNodeActualValue(data) {
|
|
184
|
+
data.links.forEach(function (link) {
|
|
185
|
+
if (!link.unnormalizedValue) {
|
|
186
|
+
link.unnormalizedValue = link.value;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
data.nodes.forEach(function (node) {
|
|
190
|
+
node.actualValue = Math.max((0, d3_array_1.sum)(node.sourceLinks, function (link) { return link.unnormalizedValue; }), (0, d3_array_1.sum)(node.targetLinks, function (link) { return link.unnormalizedValue; }));
|
|
191
|
+
});
|
|
192
|
+
}
|
|
37
193
|
var SankeyChartBase = /** @class */ (function (_super) {
|
|
38
194
|
tslib_1.__extends(SankeyChartBase, _super);
|
|
39
195
|
function SankeyChartBase(props) {
|
|
40
196
|
var _this = _super.call(this, props) || this;
|
|
41
197
|
_this._isRtl = (0, Utilities_1.getRTL)();
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
198
|
_this._onCloseCallout = function () {
|
|
44
199
|
_this.setState({
|
|
45
200
|
isCalloutVisible: false,
|
|
@@ -50,27 +205,27 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
50
205
|
_this._onBlur = function () {
|
|
51
206
|
/**/
|
|
52
207
|
};
|
|
53
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
208
|
_this._fillNodeColors = function (singleNode) {
|
|
55
|
-
|
|
209
|
+
var state = _this.state;
|
|
210
|
+
if (!state.selectedState) {
|
|
56
211
|
return singleNode.color;
|
|
57
212
|
}
|
|
58
|
-
else if (
|
|
59
|
-
return
|
|
213
|
+
else if (state.selectedState && state.selectedNodes.has(singleNode.index) && state.selectedNode) {
|
|
214
|
+
return state.selectedNode.color;
|
|
60
215
|
}
|
|
61
|
-
else if (
|
|
216
|
+
else if (state.selectedState && !state.selectedNode) {
|
|
62
217
|
return singleNode.color;
|
|
63
218
|
}
|
|
64
219
|
};
|
|
65
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
220
|
_this._fillNodeBorder = function (singleNode) {
|
|
67
|
-
|
|
221
|
+
var state = _this.state;
|
|
222
|
+
if (!state.selectedState) {
|
|
68
223
|
return singleNode.borderColor;
|
|
69
224
|
}
|
|
70
|
-
else if (
|
|
71
|
-
return
|
|
225
|
+
else if (state.selectedState && state.selectedNodes.has(singleNode.index) && state.selectedNode) {
|
|
226
|
+
return state.selectedNode.borderColor;
|
|
72
227
|
}
|
|
73
|
-
else if (
|
|
228
|
+
else if (state.selectedState && state.selectedNodes.has(singleNode.index)) {
|
|
74
229
|
return singleNode.borderColor;
|
|
75
230
|
}
|
|
76
231
|
return singleNode.borderColor;
|
|
@@ -107,148 +262,70 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
107
262
|
var _this = this;
|
|
108
263
|
if (!this._isChartEmpty()) {
|
|
109
264
|
var _a = this.props, theme = _a.theme, className = _a.className, styles = _a.styles, pathColor = _a.pathColor;
|
|
110
|
-
|
|
265
|
+
var state = this.state;
|
|
266
|
+
var classNames = getClassNames(styles, {
|
|
111
267
|
theme: theme,
|
|
112
|
-
width:
|
|
113
|
-
height:
|
|
268
|
+
width: state.containerWidth,
|
|
269
|
+
height: state.containerHeight,
|
|
114
270
|
pathColor: pathColor,
|
|
115
271
|
className: className,
|
|
116
272
|
});
|
|
117
273
|
// We are using the this._margins.left and this._margins.top in sankey extent while constructing the layout
|
|
118
274
|
var _b = this._preRenderLayout(), height = _b.height, width = _b.width;
|
|
119
|
-
this.
|
|
275
|
+
var sankeyChartData = this.props.data.SankeyChartData;
|
|
276
|
+
this._normalizeData(sankeyChartData);
|
|
120
277
|
var nodePadding = 8;
|
|
121
278
|
nodePadding = this._adjustPadding(this._sankey, height - 6, this._nodesInColumn);
|
|
122
279
|
this._sankey.nodePadding(nodePadding);
|
|
123
|
-
this._sankey(
|
|
124
|
-
|
|
280
|
+
this._sankey(sankeyChartData);
|
|
281
|
+
populateNodeActualValue(sankeyChartData);
|
|
125
282
|
this._assignNodeColors();
|
|
126
|
-
var nodeData = this._createNodes(
|
|
283
|
+
var nodeData = this._createNodes(classNames);
|
|
127
284
|
var linkData = this._createLinks();
|
|
128
285
|
var calloutProps = {
|
|
129
|
-
isCalloutVisible:
|
|
286
|
+
isCalloutVisible: state.isCalloutVisible,
|
|
130
287
|
directionalHint: Callout_1.DirectionalHint.topAutoEdge,
|
|
131
288
|
id: "toolTip".concat(this._calloutId),
|
|
132
|
-
target:
|
|
133
|
-
color:
|
|
134
|
-
XValue:
|
|
135
|
-
YValue:
|
|
136
|
-
descriptionMessage:
|
|
289
|
+
target: state.refSelected,
|
|
290
|
+
color: state.color,
|
|
291
|
+
XValue: state.xCalloutValue,
|
|
292
|
+
YValue: state.yCalloutValue ? state.yCalloutValue : state.dataForHoverCard,
|
|
293
|
+
descriptionMessage: state.descriptionMessage,
|
|
137
294
|
isBeakVisible: false,
|
|
138
295
|
gapSpace: 15,
|
|
139
296
|
onDismiss: this._onCloseCallout,
|
|
140
|
-
className:
|
|
297
|
+
className: classNames.calloutContentRoot,
|
|
141
298
|
preventDismissOnLostFocus: true,
|
|
142
299
|
};
|
|
143
|
-
return (React.createElement("div", { className:
|
|
300
|
+
return (React.createElement("div", { className: classNames.root, role: 'presentation', ref: function (rootElem) { return (_this.chartContainer = rootElem); }, onMouseLeave: this._onCloseCallout },
|
|
144
301
|
React.createElement(react_focus_1.FocusZone, { direction: react_focus_1.FocusZoneDirection.bidirectional, isCircularNavigation: true, handleTabKey: react_focus_1.FocusZoneTabbableElements.all },
|
|
145
302
|
React.createElement("svg", { width: width, height: height, id: (0, Utilities_1.getId)('sankeyChart') },
|
|
146
|
-
React.createElement("g", { className:
|
|
147
|
-
React.createElement("g", { className:
|
|
303
|
+
React.createElement("g", { className: classNames.links, strokeOpacity: 1 }, linkData),
|
|
304
|
+
React.createElement("g", { className: classNames.nodes }, nodeData),
|
|
148
305
|
calloutProps.isCalloutVisible && (React.createElement(Callout_1.Callout, tslib_1.__assign({}, calloutProps),
|
|
149
306
|
React.createElement(index_1.ChartHoverCard, { XValue: calloutProps.XValue, YValue: calloutProps.YValue, color: calloutProps.color, descriptionMessage: calloutProps.descriptionMessage ? calloutProps.descriptionMessage : '' })))))));
|
|
150
307
|
}
|
|
151
308
|
return (React.createElement("div", { id: this._emptyChartId, role: 'alert', style: { opacity: '0' }, "aria-label": 'Graph has no data to display' }));
|
|
152
309
|
};
|
|
153
310
|
SankeyChartBase.prototype._preRenderLayout = function () {
|
|
154
|
-
var
|
|
155
|
-
var
|
|
311
|
+
var _a = this.state, containerHeight = _a.containerHeight, containerWidth = _a.containerWidth;
|
|
312
|
+
var _b = this._margins, left = _b.left, right = _b.right, top = _b.top, bottom = _b.bottom;
|
|
313
|
+
var width = containerWidth - right;
|
|
314
|
+
var height = containerHeight - bottom > 0 ? containerHeight - bottom : 0;
|
|
156
315
|
this._sankey = (0, d3_sankey_1.sankey)()
|
|
157
316
|
.nodeWidth(124)
|
|
158
317
|
.extent([
|
|
159
|
-
[
|
|
318
|
+
[left, top],
|
|
160
319
|
[width - 1, height - 6],
|
|
161
320
|
])
|
|
162
321
|
.nodeAlign(this._isRtl ? d3_sankey_1.sankeyRight : d3_sankey_1.sankeyJustify);
|
|
163
322
|
return { height: height, width: width };
|
|
164
323
|
};
|
|
165
|
-
/**
|
|
166
|
-
* This is used for calculating the node non normalized value based on link non normalized value.
|
|
167
|
-
*
|
|
168
|
-
*/
|
|
169
|
-
SankeyChartBase.prototype._populateNodeActualValue = function (data) {
|
|
170
|
-
data.links.forEach(function (link) {
|
|
171
|
-
if (!link.unnormalizedValue) {
|
|
172
|
-
link.unnormalizedValue = link.value;
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
data.nodes.forEach(function (node) {
|
|
176
|
-
node.actualValue = Math.max((0, d3_array_1.sum)(node.sourceLinks, function (link) { return link.unnormalizedValue; }), (0, d3_array_1.sum)(node.targetLinks, function (link) { return link.unnormalizedValue; }));
|
|
177
|
-
});
|
|
178
|
-
};
|
|
179
324
|
SankeyChartBase.prototype._normalizeSankeyData = function (data) {
|
|
180
|
-
this._nodesInColumn =
|
|
181
|
-
|
|
325
|
+
var nodesInColumn = (this._nodesInColumn = populateNodeInColumns(data, this._sankey));
|
|
326
|
+
adjustOnePercentHeightNodes(nodesInColumn);
|
|
182
327
|
};
|
|
183
328
|
/**
|
|
184
|
-
*
|
|
185
|
-
* This is used to group nodes by column index.
|
|
186
|
-
*/
|
|
187
|
-
SankeyChartBase.prototype._populateNodeInColumns = function (graph, sankey) {
|
|
188
|
-
sankey(graph);
|
|
189
|
-
var nodesInColumn = {};
|
|
190
|
-
graph.nodes.forEach(function (node) {
|
|
191
|
-
var columnId = node.layer;
|
|
192
|
-
if (nodesInColumn[columnId]) {
|
|
193
|
-
nodesInColumn[columnId].push(node);
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
nodesInColumn[columnId] = [node];
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
return nodesInColumn;
|
|
200
|
-
};
|
|
201
|
-
/**
|
|
202
|
-
* This is used to normalize the nodes value whose value is less than 1% of the total column value.
|
|
203
|
-
*
|
|
204
|
-
*/
|
|
205
|
-
SankeyChartBase.prototype._adjustOnePercentHeightNodes = function (nodesInColumn) {
|
|
206
|
-
var _this = this;
|
|
207
|
-
var totalColumnValue = Object.values(nodesInColumn).map(function (column) {
|
|
208
|
-
return (0, d3_array_1.sum)(column, function (node) { return node.value; });
|
|
209
|
-
});
|
|
210
|
-
totalColumnValue.forEach(function (columnValue, index) {
|
|
211
|
-
var totalPercentage = 0;
|
|
212
|
-
nodesInColumn[index].forEach(function (node) {
|
|
213
|
-
var nodePercentage = (node.value / columnValue) * 100;
|
|
214
|
-
node.actualValue = node.value;
|
|
215
|
-
//if the value is less than 1% then we are making it as 1% of total .
|
|
216
|
-
if (nodePercentage < 1) {
|
|
217
|
-
node.value = 0.01 * columnValue;
|
|
218
|
-
totalPercentage = totalPercentage + 1;
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
totalPercentage = totalPercentage + nodePercentage;
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
//since we have adjusted the value to be 1% but we need to keep the sum of the percentage value under 100.
|
|
225
|
-
var scalingRatio = totalPercentage !== 0 ? totalPercentage / 100 : 1;
|
|
226
|
-
if (scalingRatio > 1) {
|
|
227
|
-
nodesInColumn[index].forEach(function (node) {
|
|
228
|
-
node.value = node.value / scalingRatio;
|
|
229
|
-
_this._changeColumnValue(node, node.actualValue, node.value);
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
};
|
|
234
|
-
/**
|
|
235
|
-
*
|
|
236
|
-
* This is used for normalizing each links value for reflecting the normalized node value.
|
|
237
|
-
*/
|
|
238
|
-
SankeyChartBase.prototype._changeColumnValue = function (node, originalValue, normalizedValue) {
|
|
239
|
-
node.sourceLinks.forEach(function (link) {
|
|
240
|
-
link.unnormalizedValue = link.value;
|
|
241
|
-
var linkRatio = link.value / originalValue;
|
|
242
|
-
link.value = normalizedValue * linkRatio;
|
|
243
|
-
});
|
|
244
|
-
node.targetLinks.forEach(function (link) {
|
|
245
|
-
link.unnormalizedValue = link.value;
|
|
246
|
-
var linkRatio = link.value / originalValue;
|
|
247
|
-
link.value = normalizedValue * linkRatio;
|
|
248
|
-
});
|
|
249
|
-
};
|
|
250
|
-
/**
|
|
251
|
-
*
|
|
252
329
|
* This is used to introduce dynamic padding for cases where the number of nodes in a column is huge
|
|
253
330
|
* so that we maintain a node to space ratio for such columns as if we fail to do so the
|
|
254
331
|
* chart is devoid of nodes and only shows links.
|
|
@@ -270,8 +347,10 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
270
347
|
SankeyChartBase.prototype._createLinks = function () {
|
|
271
348
|
var _this = this;
|
|
272
349
|
var links = [];
|
|
273
|
-
|
|
274
|
-
|
|
350
|
+
var sankeyChartData = this.props.data.SankeyChartData;
|
|
351
|
+
if (sankeyChartData) {
|
|
352
|
+
var linkId_1 = this._linkId;
|
|
353
|
+
sankeyChartData.links.forEach(function (singleLink, index) {
|
|
275
354
|
var onMouseOut = function () {
|
|
276
355
|
_this._onStreamLeave(singleLink);
|
|
277
356
|
};
|
|
@@ -292,10 +371,10 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
292
371
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
293
372
|
.y1(function (p) { return p.y1; })
|
|
294
373
|
.curve(d3_shape_1.curveBumpX);
|
|
295
|
-
var gradientUrl = "url(#gradient-".concat(
|
|
296
|
-
var link = (React.createElement("g", { key: "".concat(
|
|
374
|
+
var gradientUrl = "url(#gradient-".concat(linkId_1, "-").concat(index, ")");
|
|
375
|
+
var link = (React.createElement("g", { key: "".concat(linkId_1, "-").concat(index) },
|
|
297
376
|
React.createElement("defs", null,
|
|
298
|
-
React.createElement("linearGradient", { id: "gradient-".concat(
|
|
377
|
+
React.createElement("linearGradient", { id: "gradient-".concat(linkId_1, "-").concat(index), x1: "0%", y1: "0%", x2: "100%", y2: "0%" },
|
|
299
378
|
React.createElement("stop", { offset: "0", stopColor: singleLink.source.color }),
|
|
300
379
|
React.createElement("stop", { offset: "100%", stopColor: singleLink.target.color }))),
|
|
301
380
|
React.createElement("path", { d: linkArea(dataPoints), id: (0, Utilities_1.getId)('link'), fill: _this._fillStreamColors(singleLink, gradientUrl), stroke: _this._fillStreamBorder(singleLink, gradientUrl), strokeWidth: "2", strokeOpacity: _this._getOpacityStreamBorder(singleLink), onMouseOver: _this._onStreamHover.bind(_this, singleLink), onMouseOut: onMouseOut, onFocus: _this._onFocusLink.bind(_this, singleLink), onBlur: _this._onBlur, fillOpacity: _this._getOpacityStream(singleLink), "data-is-focusable": true, "aria-label": 'link from' +
|
|
@@ -309,12 +388,13 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
309
388
|
}
|
|
310
389
|
return links;
|
|
311
390
|
};
|
|
312
|
-
SankeyChartBase.prototype._createNodes = function (
|
|
391
|
+
SankeyChartBase.prototype._createNodes = function (classNames) {
|
|
313
392
|
var _this = this;
|
|
314
393
|
var nodes = [];
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
394
|
+
var sankeyChartData = this.props.data.SankeyChartData;
|
|
395
|
+
if (sankeyChartData) {
|
|
396
|
+
var state_1 = this.state;
|
|
397
|
+
sankeyChartData.nodes.forEach(function (singleNode, index) {
|
|
318
398
|
var onMouseOut = function () {
|
|
319
399
|
_this._onLeave(singleNode);
|
|
320
400
|
};
|
|
@@ -339,28 +419,21 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
339
419
|
var truncatedname = _this._truncateText(singleNode.name, 116, padding);
|
|
340
420
|
var isTruncated = truncatedname.slice(-3) === '...';
|
|
341
421
|
var id = (0, Utilities_1.getId)('tooltip');
|
|
342
|
-
var div = (0, d3_selection_1.select)('body')
|
|
343
|
-
.append('div')
|
|
344
|
-
.attr('id', id)
|
|
345
|
-
.attr('class', _this._classNames.toolTip)
|
|
346
|
-
.style('opacity', 0);
|
|
422
|
+
var div = (0, d3_selection_1.select)('body').append('div').attr('id', id).attr('class', classNames.toolTip).style('opacity', 0);
|
|
347
423
|
var nodeId = (0, Utilities_1.getId)('nodeBar');
|
|
424
|
+
// TODO: Should the `aria-label` be localized?
|
|
348
425
|
var node = (React.createElement("g", { key: index, id: (0, Utilities_1.getId)('nodeGElement') },
|
|
349
426
|
React.createElement("rect", { x: singleNode.x0, y: singleNode.y0, height: height, width: singleNode.x1 - singleNode.x0, fill: _this._fillNodeColors(singleNode), id: nodeId, onMouseOver: _this._onHover.bind(_this, singleNode), onMouseOut: onMouseOut, onFocus: _this._onCloseCallout.bind(_this), stroke: _this._fillNodeBorder(singleNode), strokeWidth: "2", opacity: "1", "data-is-focusable": true, "aria-label": 'node' + "".concat(singleNode.name) + 'with weight' + "".concat(singleNode.actualValue), role: "img" }),
|
|
350
|
-
singleNode.y1 - singleNode.y0 > MIN_HEIGHT_FOR_TYPE && (React.createElement("g", { className:
|
|
427
|
+
singleNode.y1 - singleNode.y0 > MIN_HEIGHT_FOR_TYPE && (React.createElement("g", { className: classNames.nodeTextContainer },
|
|
351
428
|
React.createElement("g", { className: "nodeName" },
|
|
352
|
-
React.createElement("text", { id: "".concat(nodeId, "-name"), x: singleNode.x0, y: singleNode.y0, dy: '1.2em', dx: '0.4em', textAnchor: _this._isRtl ? 'end' : 'start', fontWeight: "regular", "aria-hidden": "true", fill: !(!
|
|
353
|
-
(
|
|
354
|
-
|
|
355
|
-
_this.state.selectedNode) ||
|
|
356
|
-
(_this.state.selectedState && !_this.state.selectedNode))
|
|
429
|
+
React.createElement("text", { id: "".concat(nodeId, "-name"), x: singleNode.x0, y: singleNode.y0, dy: '1.2em', dx: '0.4em', textAnchor: _this._isRtl ? 'end' : 'start', fontWeight: "regular", "aria-hidden": "true", fill: !(!state_1.selectedState ||
|
|
430
|
+
(state_1.selectedState && state_1.selectedNodes.has(singleNode.index) && state_1.selectedNode) ||
|
|
431
|
+
(state_1.selectedState && !state_1.selectedNode))
|
|
357
432
|
? DEFAULT_TEXT_COLOR
|
|
358
433
|
: NON_SELECTED_TEXT_COLOR, fontSize: 10, onMouseOver: _this._showTooltip.bind(_this, singleNode.name, isTruncated, div), onMouseOut: _this._hideTooltip.bind(_this, div) }, truncatedname)),
|
|
359
|
-
React.createElement("text", { x: height > MIN_HEIGHT_FOR_DOUBLINE_TYPE ? singleNode.x0 : singleNode.x1 - textLengthForNodeWeight - 8, y: singleNode.y0, dy: height > MIN_HEIGHT_FOR_DOUBLINE_TYPE ? '2em' : '1em', dx: height > MIN_HEIGHT_FOR_DOUBLINE_TYPE ? '0.4em' : '0em', textAnchor: _this._isRtl ? 'end' : 'start', fontWeight: "bold", "aria-hidden": "true", fill: !(!
|
|
360
|
-
(
|
|
361
|
-
|
|
362
|
-
_this.state.selectedNode) ||
|
|
363
|
-
(_this.state.selectedState && !_this.state.selectedNode))
|
|
434
|
+
React.createElement("text", { x: height > MIN_HEIGHT_FOR_DOUBLINE_TYPE ? singleNode.x0 : singleNode.x1 - textLengthForNodeWeight - 8, y: singleNode.y0, dy: height > MIN_HEIGHT_FOR_DOUBLINE_TYPE ? '2em' : '1em', dx: height > MIN_HEIGHT_FOR_DOUBLINE_TYPE ? '0.4em' : '0em', textAnchor: _this._isRtl ? 'end' : 'start', fontWeight: "bold", "aria-hidden": "true", fill: !(!state_1.selectedState ||
|
|
435
|
+
(state_1.selectedState && state_1.selectedNodes.has(singleNode.index) && state_1.selectedNode) ||
|
|
436
|
+
(state_1.selectedState && !state_1.selectedNode))
|
|
364
437
|
? DEFAULT_TEXT_COLOR
|
|
365
438
|
: NON_SELECTED_TEXT_COLOR, fontSize: 14 }, singleNode.actualValue)))));
|
|
366
439
|
nodes.push(node);
|
|
@@ -368,7 +441,6 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
368
441
|
return nodes;
|
|
369
442
|
}
|
|
370
443
|
};
|
|
371
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
372
444
|
SankeyChartBase.prototype._onLeave = function (singleNode) {
|
|
373
445
|
if (this.state.selectedState) {
|
|
374
446
|
this.setState({
|
|
@@ -379,13 +451,12 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
379
451
|
});
|
|
380
452
|
}
|
|
381
453
|
};
|
|
382
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
383
454
|
SankeyChartBase.prototype._onHover = function (singleNode, mouseEvent) {
|
|
384
455
|
mouseEvent.persist();
|
|
385
456
|
this._onCloseCallout();
|
|
386
457
|
if (!this.state.selectedState) {
|
|
387
|
-
var selectedLinks =
|
|
388
|
-
var selectedNodes =
|
|
458
|
+
var selectedLinks = getSelectedLinks(singleNode);
|
|
459
|
+
var selectedNodes = getSelectedNodes(selectedLinks);
|
|
389
460
|
selectedNodes.push(singleNode);
|
|
390
461
|
this.setState({
|
|
391
462
|
selectedState: true,
|
|
@@ -401,12 +472,11 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
401
472
|
});
|
|
402
473
|
}
|
|
403
474
|
};
|
|
404
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
405
475
|
SankeyChartBase.prototype._onStreamHover = function (singleLink, mouseEvent) {
|
|
406
476
|
mouseEvent.persist();
|
|
407
477
|
this._onCloseCallout();
|
|
408
478
|
if (!this.state.selectedState) {
|
|
409
|
-
var _a =
|
|
479
|
+
var _a = getSelectedLinksforStreamHover(singleLink), selectedLinks = _a.selectedLinks, selectedNodes = _a.selectedNodes;
|
|
410
480
|
this.setState({
|
|
411
481
|
selectedState: true,
|
|
412
482
|
selectedNodes: new Set(Array.from(selectedNodes).map(function (node) { return node.index; })),
|
|
@@ -417,7 +487,7 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
417
487
|
color: singleLink.source.color,
|
|
418
488
|
xCalloutValue: singleLink.target.name,
|
|
419
489
|
yCalloutValue: singleLink.unnormalizedValue.toString(),
|
|
420
|
-
descriptionMessage: 'from ' + singleLink.source.name,
|
|
490
|
+
descriptionMessage: 'from ' + singleLink.source.name, // TODO: Does this need to be localized?
|
|
421
491
|
});
|
|
422
492
|
}
|
|
423
493
|
};
|
|
@@ -442,7 +512,7 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
442
512
|
xCalloutValue: singleLink.target.name,
|
|
443
513
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
444
514
|
yCalloutValue: singleLink.source.actualValue,
|
|
445
|
-
descriptionMessage: 'from ' + singleLink.source.name,
|
|
515
|
+
descriptionMessage: 'from ' + singleLink.source.name, // TODO: Does this need to be localized?
|
|
446
516
|
});
|
|
447
517
|
};
|
|
448
518
|
/**
|
|
@@ -452,9 +522,10 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
452
522
|
SankeyChartBase.prototype._assignNodeColors = function () {
|
|
453
523
|
var colors;
|
|
454
524
|
var borders;
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
525
|
+
var _a = this.props, colorsForNodes = _a.colorsForNodes, borderColorsForNodes = _a.borderColorsForNodes;
|
|
526
|
+
if (colorsForNodes && borderColorsForNodes) {
|
|
527
|
+
colors = colorsForNodes;
|
|
528
|
+
borders = borderColorsForNodes;
|
|
458
529
|
}
|
|
459
530
|
else {
|
|
460
531
|
colors = DEFAULT_NODE_COLORS.map(function (color) { return color.fillColor; });
|
|
@@ -475,126 +546,43 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
475
546
|
currentIndex = (currentIndex + 1) % colors.length;
|
|
476
547
|
});
|
|
477
548
|
};
|
|
478
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
479
549
|
SankeyChartBase.prototype._fillStreamColors = function (singleLink, gradientUrl) {
|
|
480
|
-
|
|
481
|
-
|
|
550
|
+
var state = this.state;
|
|
551
|
+
if (state.selectedState && state.selectedLinks.has(singleLink.index) && state.selectedNode) {
|
|
552
|
+
return state.selectedNode.color;
|
|
482
553
|
}
|
|
483
|
-
else if (
|
|
554
|
+
else if (state.selectedState && state.selectedLinks.has(singleLink.index)) {
|
|
484
555
|
return gradientUrl;
|
|
485
556
|
}
|
|
486
557
|
};
|
|
487
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
488
558
|
SankeyChartBase.prototype._fillStreamBorder = function (singleLink, gradientUrl) {
|
|
489
|
-
|
|
559
|
+
var state = this.state;
|
|
560
|
+
if (!state.selectedState) {
|
|
490
561
|
return NON_SELECTED_NODE_AND_STREAM_COLOR;
|
|
491
562
|
}
|
|
492
|
-
else if (
|
|
493
|
-
return
|
|
563
|
+
else if (state.selectedState && state.selectedLinks.has(singleLink.index) && state.selectedNode) {
|
|
564
|
+
return state.selectedNode.borderColor;
|
|
494
565
|
}
|
|
495
|
-
else if (
|
|
566
|
+
else if (state.selectedState && state.selectedLinks.has(singleLink.index)) {
|
|
496
567
|
return gradientUrl;
|
|
497
568
|
}
|
|
498
569
|
return NON_SELECTED_NODE_AND_STREAM_COLOR;
|
|
499
570
|
};
|
|
500
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
501
|
-
SankeyChartBase.prototype._getSelectedNodes = function (selectedLinks) {
|
|
502
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
503
|
-
var nodes = [];
|
|
504
|
-
selectedLinks.forEach(function (link) {
|
|
505
|
-
nodes.push(link.target);
|
|
506
|
-
if (nodes.indexOf(link.source) === -1) {
|
|
507
|
-
nodes.push(link.source);
|
|
508
|
-
}
|
|
509
|
-
});
|
|
510
|
-
return nodes;
|
|
511
|
-
};
|
|
512
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
513
|
-
SankeyChartBase.prototype._getSelectedLinks = function (singleNode) {
|
|
514
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, no-array-constructor
|
|
515
|
-
var q = new Array();
|
|
516
|
-
var finalLinks = new Set();
|
|
517
|
-
singleNode.sourceLinks.forEach(function (link) {
|
|
518
|
-
q.push(link);
|
|
519
|
-
finalLinks.add(link);
|
|
520
|
-
});
|
|
521
|
-
while (q.length > 0) {
|
|
522
|
-
var poppedLink = q.shift();
|
|
523
|
-
var node = poppedLink.target;
|
|
524
|
-
if (node && node.sourceLinks) {
|
|
525
|
-
node.sourceLinks.forEach(function (link) {
|
|
526
|
-
finalLinks.add(link);
|
|
527
|
-
q.push(link);
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
if (singleNode.targetLinks) {
|
|
532
|
-
singleNode.targetLinks.forEach(function (link) {
|
|
533
|
-
q.push(link);
|
|
534
|
-
finalLinks.add(link);
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
while (q.length > 0) {
|
|
538
|
-
var poppedLink = q.shift();
|
|
539
|
-
var node = poppedLink.source;
|
|
540
|
-
if (node && node.targetLinks) {
|
|
541
|
-
node.targetLinks.forEach(function (link) {
|
|
542
|
-
finalLinks.add(link);
|
|
543
|
-
q.push(link);
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
return finalLinks;
|
|
548
|
-
};
|
|
549
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
550
|
-
SankeyChartBase.prototype._getSelectedLinksforStreamHover = function (singleLink) {
|
|
551
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, no-array-constructor
|
|
552
|
-
var q = new Array();
|
|
553
|
-
var finalLinks = new Set();
|
|
554
|
-
var finalNodes = new Set();
|
|
555
|
-
q.push(singleLink.source);
|
|
556
|
-
finalLinks.add(singleLink);
|
|
557
|
-
while (q.length > 0) {
|
|
558
|
-
var poppedNode = q.shift();
|
|
559
|
-
finalNodes.add(poppedNode);
|
|
560
|
-
if (poppedNode.targetLinks && poppedNode.targetLinks.length > 0) {
|
|
561
|
-
poppedNode.targetLinks.forEach(function (link) {
|
|
562
|
-
q.push(link.source);
|
|
563
|
-
finalLinks.add(link);
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
q.push(singleLink.target);
|
|
568
|
-
while (q.length > 0) {
|
|
569
|
-
var poppedNode = q.shift();
|
|
570
|
-
finalNodes.add(poppedNode);
|
|
571
|
-
if (poppedNode.sourceLinks && poppedNode.sourceLinks.length > 0) {
|
|
572
|
-
poppedNode.sourceLinks.forEach(function (link) {
|
|
573
|
-
q.push(link.target);
|
|
574
|
-
finalLinks.add(link);
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
return {
|
|
579
|
-
selectedLinks: finalLinks,
|
|
580
|
-
selectedNodes: finalNodes,
|
|
581
|
-
};
|
|
582
|
-
};
|
|
583
571
|
SankeyChartBase.prototype._getOpacityStream = function (singleLink) {
|
|
584
|
-
|
|
585
|
-
|
|
572
|
+
var state = this.state;
|
|
573
|
+
if (state.selectedState) {
|
|
574
|
+
if (!state.selectedLinks.has(singleLink.index)) {
|
|
586
575
|
return NON_SELECTED_OPACITY;
|
|
587
576
|
}
|
|
588
|
-
else if (
|
|
589
|
-
this.state.selectedLinks.has(singleLink.index) &&
|
|
590
|
-
!this.state.selectedNode) {
|
|
577
|
+
else if (state.selectedLinks.has(singleLink.index) && !state.selectedNode) {
|
|
591
578
|
return SELECTED_STREAM_OPACITY;
|
|
592
579
|
}
|
|
593
580
|
}
|
|
594
581
|
return REST_STREAM_OPACITY;
|
|
595
582
|
};
|
|
596
583
|
SankeyChartBase.prototype._getOpacityStreamBorder = function (singleLink) {
|
|
597
|
-
|
|
584
|
+
var state = this.state;
|
|
585
|
+
if (state.selectedState && !state.selectedLinks.has(singleLink.index) && !state.selectedNode) {
|
|
598
586
|
return NON_SELECTED_STREAM_BORDER_OPACITY;
|
|
599
587
|
}
|
|
600
588
|
return NON_SELECTED_OPACITY;
|
|
@@ -616,7 +604,6 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
616
604
|
});
|
|
617
605
|
};
|
|
618
606
|
/**
|
|
619
|
-
*
|
|
620
607
|
* @param text is the text which we are trying to truncate
|
|
621
608
|
* @param rectangleWidth is the width of the rectangle which will contain the text
|
|
622
609
|
* @param padding is the space we need to leave between the rect lines and other text
|
|
@@ -675,10 +662,9 @@ var SankeyChartBase = /** @class */ (function (_super) {
|
|
|
675
662
|
div.style('opacity', 0);
|
|
676
663
|
};
|
|
677
664
|
SankeyChartBase.prototype._isChartEmpty = function () {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
this.props.data.SankeyChartData.links.length > 0);
|
|
665
|
+
var _a;
|
|
666
|
+
var sankeyChartData = (_a = this.props.data) === null || _a === void 0 ? void 0 : _a.SankeyChartData;
|
|
667
|
+
return !(sankeyChartData && sankeyChartData.nodes.length > 0 && sankeyChartData.links.length > 0);
|
|
682
668
|
};
|
|
683
669
|
return SankeyChartBase;
|
|
684
670
|
}(React.Component));
|