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