@fluentui/react-charting 5.14.43 → 5.15.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.
Files changed (39) hide show
  1. package/CHANGELOG.json +37 -1
  2. package/CHANGELOG.md +21 -2
  3. package/dist/react-charting.js +1 -1
  4. package/dist/react-charting.min.js +1 -1
  5. package/lib/components/SankeyChart/SankeyChart.base.d.ts +79 -2
  6. package/lib/components/SankeyChart/SankeyChart.base.js +599 -32
  7. package/lib/components/SankeyChart/SankeyChart.base.js.map +1 -1
  8. package/lib/components/SankeyChart/SankeyChart.styles.js +39 -2
  9. package/lib/components/SankeyChart/SankeyChart.styles.js.map +1 -1
  10. package/lib/components/SankeyChart/SankeyChart.types.d.ts +20 -0
  11. package/lib/components/SankeyChart/SankeyChart.types.js.map +1 -1
  12. package/lib/types/IDataPoint.d.ts +5 -1
  13. package/lib/types/IDataPoint.js.map +1 -1
  14. package/lib/version.js +1 -1
  15. package/lib/version.js.map +1 -1
  16. package/lib-amd/components/SankeyChart/SankeyChart.base.d.ts +79 -2
  17. package/lib-amd/components/SankeyChart/SankeyChart.base.js +592 -31
  18. package/lib-amd/components/SankeyChart/SankeyChart.base.js.map +1 -1
  19. package/lib-amd/components/SankeyChart/SankeyChart.styles.js +38 -3
  20. package/lib-amd/components/SankeyChart/SankeyChart.styles.js.map +1 -1
  21. package/lib-amd/components/SankeyChart/SankeyChart.types.d.ts +20 -0
  22. package/lib-amd/components/SankeyChart/SankeyChart.types.js.map +1 -1
  23. package/lib-amd/types/IDataPoint.d.ts +5 -1
  24. package/lib-amd/types/IDataPoint.js.map +1 -1
  25. package/lib-amd/version.js +1 -1
  26. package/lib-amd/version.js.map +1 -1
  27. package/lib-commonjs/components/SankeyChart/SankeyChart.base.d.ts +79 -2
  28. package/lib-commonjs/components/SankeyChart/SankeyChart.base.js +597 -30
  29. package/lib-commonjs/components/SankeyChart/SankeyChart.base.js.map +1 -1
  30. package/lib-commonjs/components/SankeyChart/SankeyChart.styles.js +39 -2
  31. package/lib-commonjs/components/SankeyChart/SankeyChart.styles.js.map +1 -1
  32. package/lib-commonjs/components/SankeyChart/SankeyChart.types.d.ts +20 -0
  33. package/lib-commonjs/components/SankeyChart/SankeyChart.types.js.map +1 -1
  34. package/lib-commonjs/types/IDataPoint.d.ts +5 -1
  35. package/lib-commonjs/types/IDataPoint.js.map +1 -1
  36. package/lib-commonjs/version.js +1 -1
  37. package/lib-commonjs/version.js.map +1 -1
  38. package/package.json +5 -5
  39. package/src/components/SankeyChart/SankeyChart.types.ts +26 -0
@@ -1,16 +1,85 @@
1
- define(["require", "exports", "tslib", "react", "@fluentui/react/lib/Utilities", "d3-sankey"], function (require, exports, tslib_1, React, Utilities_1, d3Sankey) {
1
+ define(["require", "exports", "tslib", "react", "@fluentui/react/lib/Utilities", "d3-sankey", "d3-shape", "d3-array", "../../index", "@fluentui/react/lib/Callout", "d3-selection", "@fluentui/react-focus"], function (require, exports, tslib_1, React, Utilities_1, d3Sankey, d3_shape_1, d3_array_1, index_1, Callout_1, d3_selection_1, react_focus_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.SankeyChartBase = void 0;
5
5
  var getClassNames = Utilities_1.classNamesFunction();
6
+ var PADDING_PERCENTAGE = 0.3;
7
+ var NON_SELECTED_NODE_AND_STREAM_COLOR = '#757575';
8
+ var DEFAULT_NODE_COLORS = [
9
+ { fillColor: '#00758F', borderColor: '#002E39' },
10
+ { fillColor: '#77004D', borderColor: '#43002C' },
11
+ { fillColor: '#4F6BED', borderColor: '#3B52B4' },
12
+ { fillColor: '#937600', borderColor: '#6D5700' },
13
+ { fillColor: '#286EA8', borderColor: '#00457E' },
14
+ { fillColor: '#A43FB1', borderColor: '#7C158A' },
15
+ { fillColor: '#CC3595', borderColor: '#7F215D' },
16
+ { fillColor: '#0E7878', borderColor: '#004E4E' },
17
+ { fillColor: '#8764B8', borderColor: '#4B3867' },
18
+ { fillColor: '#9C663F', borderColor: '#6D4123' },
19
+ ];
20
+ var MIN_HEIGHT_FOR_DOUBLINE_TYPE = 36;
21
+ var MIN_HEIGHT_FOR_TYPE = 24;
22
+ var REST_STREAM_OPACITY = 1;
23
+ var NON_SELECTED_OPACITY = 1;
24
+ var SELECTED_STREAM_OPACITY = 0.3;
25
+ var NON_SELECTED_STREAM_BORDER_OPACITY = 0.5;
26
+ var DEFAULT_TEXT_COLOR = '#323130';
27
+ var NON_SELECTED_TEXT_COLOR = '#FFFFFF';
6
28
  var SankeyChartBase = /** @class */ (function (_super) {
7
29
  tslib_1.__extends(SankeyChartBase, _super);
8
30
  function SankeyChartBase(props) {
9
31
  var _this = _super.call(this, props) || this;
32
+ _this._isRtl = Utilities_1.getRTL();
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ _this._onCloseCallout = function () {
35
+ _this.setState({
36
+ isCalloutVisible: false,
37
+ refSelected: undefined,
38
+ descriptionMessage: '',
39
+ });
40
+ };
41
+ _this._onBlur = function () {
42
+ /**/
43
+ };
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ _this._fillNodeColors = function (singleNode) {
46
+ if (!_this.state.selectedState) {
47
+ return singleNode.color;
48
+ }
49
+ else if (_this.state.selectedState && _this.state.selectedNodes.has(singleNode.index) && _this.state.selectedNode) {
50
+ return _this.state.selectedNode.color;
51
+ }
52
+ else if (_this.state.selectedState && !_this.state.selectedNode) {
53
+ return singleNode.color;
54
+ }
55
+ };
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ _this._fillNodeBorder = function (singleNode) {
58
+ if (!_this.state.selectedState) {
59
+ return singleNode.borderColor;
60
+ }
61
+ else if (_this.state.selectedState && _this.state.selectedNodes.has(singleNode.index) && _this.state.selectedNode) {
62
+ return _this.state.selectedNode.borderColor;
63
+ }
64
+ else if (_this.state.selectedState && _this.state.selectedNodes.has(singleNode.index)) {
65
+ return singleNode.borderColor;
66
+ }
67
+ return singleNode.borderColor;
68
+ };
10
69
  _this.state = {
11
- containerHeight: 0,
12
- containerWidth: 0,
70
+ containerHeight: 468,
71
+ containerWidth: 912,
72
+ selectedState: false,
73
+ selectedLinks: new Set(),
74
+ selectedNodes: new Set(),
75
+ shouldOverflow: false,
76
+ isCalloutVisible: false,
13
77
  };
78
+ _this._calloutId = Utilities_1.getId('callout');
79
+ _this._linkId = Utilities_1.getId('link');
80
+ _this._margins = { top: 36, right: 48, bottom: 32, left: 48 };
81
+ _this._preRenderLayout();
82
+ _this._normalizeData = Utilities_1.memoizeFunction(function (data) { return _this._normalizeSankeyData(data); });
14
83
  return _this;
15
84
  }
16
85
  SankeyChartBase.prototype.componentDidMount = function () {
@@ -34,58 +103,491 @@ define(["require", "exports", "tslib", "react", "@fluentui/react/lib/Utilities",
34
103
  pathColor: pathColor,
35
104
  className: className,
36
105
  });
37
- var margin = { top: 10, right: 0, bottom: 10, left: 0 };
38
- var width = this.state.containerWidth - margin.left - margin.right;
39
- var height = this.state.containerHeight - margin.top - margin.bottom > 0
40
- ? this.state.containerHeight - margin.top - margin.bottom
41
- : 0;
42
- var sankey = d3Sankey
106
+ // We are using the this._margins.left and this._margins.top in sankey extent while constructing the layout
107
+ var _b = this._preRenderLayout(), height = _b.height, width = _b.width;
108
+ this._normalizeData(this.props.data.SankeyChartData);
109
+ var nodePadding = 8;
110
+ nodePadding = this._adjustPadding(this._sankey, height - 6, this._nodesInColumn);
111
+ this._sankey.nodePadding(nodePadding);
112
+ this._sankey(this.props.data.SankeyChartData);
113
+ this._populateNodeActualValue(this.props.data.SankeyChartData);
114
+ this._assignNodeColors();
115
+ var nodeData = this._createNodes(width);
116
+ var linkData = this._createLinks();
117
+ var calloutProps = {
118
+ isCalloutVisible: this.state.isCalloutVisible,
119
+ directionalHint: Callout_1.DirectionalHint.topAutoEdge,
120
+ id: "toolTip" + this._calloutId,
121
+ target: this.state.refSelected,
122
+ color: this.state.color,
123
+ XValue: this.state.xCalloutValue,
124
+ YValue: this.state.yCalloutValue ? this.state.yCalloutValue : this.state.dataForHoverCard,
125
+ descriptionMessage: this.state.descriptionMessage,
126
+ isBeakVisible: false,
127
+ gapSpace: 15,
128
+ onDismiss: this._onCloseCallout,
129
+ className: this._classNames.calloutContentRoot,
130
+ preventDismissOnLostFocus: true,
131
+ };
132
+ return (React.createElement("div", { className: this._classNames.root, role: 'presentation', ref: function (rootElem) { return (_this.chartContainer = rootElem); }, onMouseLeave: this._onCloseCallout },
133
+ React.createElement(react_focus_1.FocusZone, { direction: react_focus_1.FocusZoneDirection.bidirectional, isCircularNavigation: true, handleTabKey: react_focus_1.FocusZoneTabbableElements.all },
134
+ React.createElement("svg", { width: width, height: height, id: Utilities_1.getId('sankeyChart') },
135
+ React.createElement("g", { className: this._classNames.links, strokeOpacity: 1 }, linkData),
136
+ React.createElement("g", { className: this._classNames.nodes }, nodeData),
137
+ calloutProps.isCalloutVisible && (React.createElement(Callout_1.Callout, tslib_1.__assign({}, calloutProps),
138
+ React.createElement(index_1.ChartHoverCard, { XValue: calloutProps.XValue, YValue: calloutProps.YValue, color: calloutProps.color, descriptionMessage: calloutProps.descriptionMessage ? calloutProps.descriptionMessage : '' })))))));
139
+ };
140
+ SankeyChartBase.prototype._preRenderLayout = function () {
141
+ var width = this.state.containerWidth - this._margins.right;
142
+ var height = this.state.containerHeight - this._margins.bottom > 0 ? this.state.containerHeight - this._margins.bottom : 0;
143
+ this._sankey = d3Sankey
43
144
  .sankey()
44
- .nodeWidth(5)
45
- .nodePadding(6)
145
+ .nodeWidth(124)
46
146
  .extent([
47
- [1, 1],
147
+ [this._margins.left, this._margins.top],
48
148
  [width - 1, height - 6],
49
- ]);
50
- sankey(this.props.data.SankeyChartData);
51
- var nodeData = this._createNodes(width);
52
- var linkData = this._createLinks();
53
- return (React.createElement("div", { className: this._classNames.root, role: 'presentation', ref: function (rootElem) { return (_this.chartContainer = rootElem); } },
54
- React.createElement("svg", { width: width, height: height, id: Utilities_1.getId('sankeyChart') },
55
- React.createElement("g", { className: this._classNames.nodes }, nodeData),
56
- React.createElement("g", { className: this._classNames.links, strokeOpacity: 0.2 }, linkData))));
149
+ ])
150
+ .nodeAlign(this._isRtl ? d3Sankey.sankeyRight : d3Sankey.sankeyJustify);
151
+ return { height: height, width: width };
152
+ };
153
+ /**
154
+ * This is used for calculating the node non normalized value based on link non normalized value.
155
+ *
156
+ */
157
+ SankeyChartBase.prototype._populateNodeActualValue = function (data) {
158
+ data.links.forEach(function (link) {
159
+ if (!link.unnormalizedValue) {
160
+ link.unnormalizedValue = link.value;
161
+ }
162
+ });
163
+ data.nodes.forEach(function (node) {
164
+ node.actualValue = Math.max(d3_array_1.sum(node.sourceLinks, function (link) { return link.unnormalizedValue; }), d3_array_1.sum(node.targetLinks, function (link) { return link.unnormalizedValue; }));
165
+ });
166
+ };
167
+ SankeyChartBase.prototype._normalizeSankeyData = function (data) {
168
+ this._nodesInColumn = this._populateNodeInColumns(data, this._sankey);
169
+ this._adjustOnePercentHeightNodes(this._nodesInColumn);
170
+ };
171
+ /**
172
+ *
173
+ * This is used to group nodes by column index.
174
+ */
175
+ SankeyChartBase.prototype._populateNodeInColumns = function (graph, sankey) {
176
+ sankey(graph);
177
+ var nodesInColumn = {};
178
+ graph.nodes.forEach(function (node) {
179
+ var columnId = node.layer;
180
+ if (nodesInColumn[columnId]) {
181
+ nodesInColumn[columnId].push(node);
182
+ }
183
+ else {
184
+ nodesInColumn[columnId] = [node];
185
+ }
186
+ });
187
+ return nodesInColumn;
188
+ };
189
+ /**
190
+ * This is used to normalize the nodes value whose value is less than 1% of the total column value.
191
+ *
192
+ */
193
+ SankeyChartBase.prototype._adjustOnePercentHeightNodes = function (nodesInColumn) {
194
+ var _this = this;
195
+ var totalColumnValue = Object.values(nodesInColumn).map(function (column) {
196
+ return d3_array_1.sum(column, function (node) { return node.value; });
197
+ });
198
+ totalColumnValue.forEach(function (columnValue, index) {
199
+ var totalPercentage = 0;
200
+ nodesInColumn[index].forEach(function (node) {
201
+ var nodePercentage = (node.value / columnValue) * 100;
202
+ node.actualValue = node.value;
203
+ //if the value is less than 1% then we are making it as 1% of total .
204
+ if (nodePercentage < 1) {
205
+ node.value = 0.01 * columnValue;
206
+ totalPercentage = totalPercentage + 1;
207
+ }
208
+ else {
209
+ totalPercentage = totalPercentage + nodePercentage;
210
+ }
211
+ });
212
+ //since we have adjusted the value to be 1% but we need to keep the sum of the percentage value under 100.
213
+ var scalingRatio = totalPercentage !== 0 ? totalPercentage / 100 : 1;
214
+ if (scalingRatio > 1) {
215
+ nodesInColumn[index].forEach(function (node) {
216
+ node.value = node.value / scalingRatio;
217
+ _this._changeColumnValue(node, node.actualValue, node.value);
218
+ });
219
+ }
220
+ });
221
+ };
222
+ /**
223
+ *
224
+ * This is used for normalizing each links value for reflecting the normalized node value.
225
+ */
226
+ SankeyChartBase.prototype._changeColumnValue = function (node, originalValue, normalizedValue) {
227
+ node.sourceLinks.forEach(function (link) {
228
+ link.unnormalizedValue = link.value;
229
+ var linkRatio = link.value / originalValue;
230
+ link.value = normalizedValue * linkRatio;
231
+ });
232
+ node.targetLinks.forEach(function (link) {
233
+ link.unnormalizedValue = link.value;
234
+ var linkRatio = link.value / originalValue;
235
+ link.value = normalizedValue * linkRatio;
236
+ });
237
+ };
238
+ /**
239
+ *
240
+ * This is used to introduce dynamic padding for cases where the number of nodes in a column is huge
241
+ * so that we maintain a node to space ratio for such columns as if we fail to do so the
242
+ * chart is devoid of nodes and only shows links.
243
+ */
244
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
245
+ SankeyChartBase.prototype._adjustPadding = function (sankey, height, nodesInColumn) {
246
+ var padding = this._sankey.nodePadding();
247
+ Object.values(nodesInColumn).forEach(function (column) {
248
+ var minPadding = PADDING_PERCENTAGE * height;
249
+ var toatlPaddingInColumn = height - d3_array_1.sum(column, function (node) { return node.y1 - node.y0; });
250
+ if (minPadding < toatlPaddingInColumn) {
251
+ //Here we are calculating the min of default and calculated padding, we will not increase the padding
252
+ //in any scenario.
253
+ padding = Math.min(padding, minPadding / (column.length - 1));
254
+ }
255
+ });
256
+ return padding;
57
257
  };
58
258
  SankeyChartBase.prototype._createLinks = function () {
259
+ var _this = this;
59
260
  var links = [];
60
261
  if (this.props.data.SankeyChartData) {
61
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
262
  this.props.data.SankeyChartData.links.forEach(function (singleLink, index) {
63
- var path = d3Sankey.sankeyLinkHorizontal();
64
- var pathValue = path(singleLink);
65
- var link = (React.createElement("path", { key: index, d: pathValue ? pathValue : undefined, strokeWidth: Math.max(1, singleLink.width), id: Utilities_1.getId('link') },
66
- React.createElement("title", null,
67
- React.createElement("text", null, singleLink.source.name + ' → ' + singleLink.target.name + '\n' + singleLink.value))));
263
+ var onMouseOut = function () {
264
+ _this._onStreamLeave(singleLink);
265
+ };
266
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
267
+ var data = function (d) {
268
+ return [
269
+ { x: d.source.x1, y0: d.y0 + d.width / 2, y1: d.y0 - d.width / 2 },
270
+ { x: d.target.x0, y0: d.y1 + d.width / 2, y1: d.y1 - d.width / 2 },
271
+ ];
272
+ };
273
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
+ var dataPoints = data(singleLink);
275
+ var linkArea = d3_shape_1.area()
276
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
277
+ .x(function (p) { return p.x; })
278
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
279
+ .y0(function (p) { return p.y0; })
280
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
281
+ .y1(function (p) { return p.y1; })
282
+ .curve(d3_shape_1.curveBumpX);
283
+ var gradientUrl = "url(#gradient-" + _this._linkId + "-" + index + ")";
284
+ var link = (React.createElement("g", { key: _this._linkId + "-" + index },
285
+ React.createElement("defs", null,
286
+ React.createElement("linearGradient", { id: "gradient-" + _this._linkId + "-" + index, x1: "0%", y1: "0%", x2: "100%", y2: "0%" },
287
+ React.createElement("stop", { offset: "0", stopColor: singleLink.source.color }),
288
+ React.createElement("stop", { offset: "100%", stopColor: singleLink.target.color }))),
289
+ React.createElement("path", { d: linkArea(dataPoints), id: 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' +
290
+ singleLink.source.name +
291
+ 'to' +
292
+ singleLink.target.name +
293
+ 'with weight' +
294
+ singleLink.unnormalizedValue, role: "img" })));
68
295
  links.push(link);
69
296
  });
70
297
  }
71
298
  return links;
72
299
  };
73
300
  SankeyChartBase.prototype._createNodes = function (width) {
301
+ var _this = this;
74
302
  var nodes = [];
75
303
  if (this.props.data.SankeyChartData) {
76
304
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
305
  this.props.data.SankeyChartData.nodes.forEach(function (singleNode, index) {
306
+ var onMouseOut = function () {
307
+ _this._onLeave(singleNode);
308
+ };
78
309
  var height = singleNode.y1 - singleNode.y0 > 0 ? singleNode.y1 - singleNode.y0 : 0;
79
- var node = (React.createElement("g", { id: Utilities_1.getId('nodeGElement'), key: index },
80
- React.createElement("rect", { x: singleNode.x0, y: singleNode.y0, height: height, width: singleNode.x1 - singleNode.x0, fill: singleNode.color, id: Utilities_1.getId('nodeBar') }),
81
- React.createElement("text", { x: singleNode.x0 < width / 2 ? singleNode.x1 + 6 : singleNode.x0 - 6, y: (singleNode.y1 + singleNode.y0) / 2, dy: '0.35em', textAnchor: singleNode.x0 < width / 2 ? 'start' : 'end' }, singleNode.name),
82
- React.createElement("title", null,
83
- React.createElement("text", null, singleNode.name + '\n' + singleNode.value))));
310
+ var padding = 8;
311
+ var textLengthForNodeWeight = 0;
312
+ // If the nodeWeight is in the same line as node description an extra padding
313
+ // of 6 px is required between node description and node weight.
314
+ if (height < MIN_HEIGHT_FOR_DOUBLINE_TYPE) {
315
+ padding = padding + 6;
316
+ var tspan = d3_selection_1.select('.nodeName').append('text').attr('class', 'tempText').append('tspan').text(null);
317
+ tspan.text(singleNode.actualValue);
318
+ if (tspan.node() !== null) {
319
+ textLengthForNodeWeight = tspan.node().getComputedTextLength();
320
+ padding = padding + textLengthForNodeWeight;
321
+ }
322
+ tspan.text(null);
323
+ d3_selection_1.selectAll('.tempText').remove();
324
+ }
325
+ // Since the total width of the node is 124 and we are giving margin of 8px from the left .
326
+ //So the actual value on which it will be truncated is 124-8=116.
327
+ var truncatedname = _this._truncateText(singleNode.name, 116, padding);
328
+ var isTruncated = truncatedname.slice(-3) === '...';
329
+ var id = Utilities_1.getId('tooltip');
330
+ var div = d3_selection_1.select('body')
331
+ .append('div')
332
+ .attr('id', id)
333
+ .attr('class', _this._classNames.toolTip)
334
+ .style('opacity', 0);
335
+ var nodeId = Utilities_1.getId('nodeBar');
336
+ var node = (React.createElement("g", { key: index, id: Utilities_1.getId('nodeGElement') },
337
+ 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' + ("" + singleNode.name) + 'with weight' + ("" + singleNode.actualValue), role: "img" }),
338
+ singleNode.y1 - singleNode.y0 > MIN_HEIGHT_FOR_TYPE && (React.createElement("g", { className: _this._classNames.nodeTextContainer },
339
+ React.createElement("g", { className: "nodeName" },
340
+ React.createElement("text", { id: 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: !(!_this.state.selectedState ||
341
+ (_this.state.selectedState &&
342
+ _this.state.selectedNodes.has(singleNode.index) &&
343
+ _this.state.selectedNode) ||
344
+ (_this.state.selectedState && !_this.state.selectedNode))
345
+ ? DEFAULT_TEXT_COLOR
346
+ : NON_SELECTED_TEXT_COLOR, fontSize: 10, onMouseOver: _this._showTooltip.bind(_this, singleNode.name, isTruncated, div), onMouseOut: _this._hideTooltip.bind(_this, div) }, truncatedname)),
347
+ 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: !(!_this.state.selectedState ||
348
+ (_this.state.selectedState &&
349
+ _this.state.selectedNodes.has(singleNode.index) &&
350
+ _this.state.selectedNode) ||
351
+ (_this.state.selectedState && !_this.state.selectedNode))
352
+ ? DEFAULT_TEXT_COLOR
353
+ : NON_SELECTED_TEXT_COLOR, fontSize: 14 }, singleNode.actualValue)))));
84
354
  nodes.push(node);
85
355
  });
86
356
  return nodes;
87
357
  }
88
358
  };
359
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
360
+ SankeyChartBase.prototype._onLeave = function (singleNode) {
361
+ if (this.state.selectedState) {
362
+ this.setState({
363
+ selectedState: false,
364
+ selectedNodes: new Set(),
365
+ selectedLinks: new Set(),
366
+ selectedNode: undefined,
367
+ });
368
+ }
369
+ };
370
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
371
+ SankeyChartBase.prototype._onHover = function (singleNode, mouseEvent) {
372
+ mouseEvent.persist();
373
+ this._onCloseCallout();
374
+ if (!this.state.selectedState) {
375
+ var selectedLinks = this._getSelectedLinks(singleNode);
376
+ var selectedNodes = this._getSelectedNodes(selectedLinks);
377
+ selectedNodes.push(singleNode);
378
+ this.setState({
379
+ selectedState: true,
380
+ selectedNodes: new Set(Array.from(selectedNodes).map(function (node) { return node.index; })),
381
+ selectedLinks: new Set(Array.from(selectedLinks).map(function (link) { return link.index; })),
382
+ selectedNode: singleNode,
383
+ refSelected: mouseEvent,
384
+ isCalloutVisible: singleNode.y1 - singleNode.y0 < MIN_HEIGHT_FOR_TYPE,
385
+ color: singleNode.color,
386
+ xCalloutValue: singleNode.name,
387
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
388
+ yCalloutValue: singleNode.actualValue,
389
+ });
390
+ }
391
+ };
392
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
393
+ SankeyChartBase.prototype._onStreamHover = function (singleLink, mouseEvent) {
394
+ mouseEvent.persist();
395
+ this._onCloseCallout();
396
+ if (!this.state.selectedState) {
397
+ var _a = this._getSelectedLinksforStreamHover(singleLink), selectedLinks = _a.selectedLinks, selectedNodes = _a.selectedNodes;
398
+ this.setState({
399
+ selectedState: true,
400
+ selectedNodes: new Set(Array.from(selectedNodes).map(function (node) { return node.index; })),
401
+ selectedLinks: new Set(Array.from(selectedLinks).map(function (link) { return link.index; })),
402
+ refSelected: mouseEvent,
403
+ selectedLink: singleLink,
404
+ isCalloutVisible: true,
405
+ color: singleLink.source.color,
406
+ xCalloutValue: singleLink.target.name,
407
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
408
+ yCalloutValue: singleLink.source.actualValue,
409
+ descriptionMessage: 'from ' + singleLink.source.name,
410
+ });
411
+ }
412
+ };
413
+ SankeyChartBase.prototype._onStreamLeave = function (singleLink) {
414
+ if (this.state.selectedState) {
415
+ this.setState({
416
+ selectedState: false,
417
+ selectedNodes: new Set(),
418
+ selectedLinks: new Set(),
419
+ selectedLink: undefined,
420
+ });
421
+ }
422
+ };
423
+ SankeyChartBase.prototype._onFocusLink = function (singleLink, element) {
424
+ element.persist();
425
+ this._onCloseCallout();
426
+ this.setState({
427
+ refSelected: element.currentTarget,
428
+ selectedLink: singleLink,
429
+ isCalloutVisible: true,
430
+ color: singleLink.source.color,
431
+ xCalloutValue: singleLink.target.name,
432
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
433
+ yCalloutValue: singleLink.source.actualValue,
434
+ descriptionMessage: 'from ' + singleLink.source.name,
435
+ });
436
+ };
437
+ /**
438
+ * This is used to assign node fillcolors and borderColor cyclically when the user doesnt
439
+ * provide color to individual node.
440
+ */
441
+ SankeyChartBase.prototype._assignNodeColors = function () {
442
+ var colors;
443
+ var borders;
444
+ if (this.props.colorsForNodes && this.props.borderColorsForNodes) {
445
+ colors = this.props.colorsForNodes;
446
+ borders = this.props.borderColorsForNodes;
447
+ }
448
+ else {
449
+ colors = DEFAULT_NODE_COLORS.map(function (color) { return color.fillColor; });
450
+ borders = DEFAULT_NODE_COLORS.map(function (color) { return color.borderColor; });
451
+ }
452
+ var currentIndex = 0;
453
+ this.props.data.SankeyChartData.nodes.forEach(function (node) {
454
+ if (!node.color && !node.borderColor) {
455
+ node.color = colors[currentIndex];
456
+ node.borderColor = borders[currentIndex];
457
+ }
458
+ else if (node.color && !node.borderColor) {
459
+ node.borderColor = '#757575';
460
+ }
461
+ else if (node.borderColor && !node.color) {
462
+ node.color = '#F5F5F5';
463
+ }
464
+ currentIndex = (currentIndex + 1) % colors.length;
465
+ });
466
+ };
467
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
468
+ SankeyChartBase.prototype._fillStreamColors = function (singleLink, gradientUrl) {
469
+ if (this.state.selectedState && this.state.selectedLinks.has(singleLink.index) && this.state.selectedNode) {
470
+ return this.state.selectedNode.color;
471
+ }
472
+ else if (this.state.selectedState && this.state.selectedLinks.has(singleLink.index)) {
473
+ return gradientUrl;
474
+ }
475
+ };
476
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
477
+ SankeyChartBase.prototype._fillStreamBorder = function (singleLink, gradientUrl) {
478
+ if (!this.state.selectedState) {
479
+ return NON_SELECTED_NODE_AND_STREAM_COLOR;
480
+ }
481
+ else if (this.state.selectedState && this.state.selectedLinks.has(singleLink.index) && this.state.selectedNode) {
482
+ return this.state.selectedNode.borderColor;
483
+ }
484
+ else if (this.state.selectedState && this.state.selectedLinks.has(singleLink.index)) {
485
+ return gradientUrl;
486
+ }
487
+ return NON_SELECTED_NODE_AND_STREAM_COLOR;
488
+ };
489
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
490
+ SankeyChartBase.prototype._getSelectedNodes = function (selectedLinks) {
491
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
492
+ var nodes = [];
493
+ selectedLinks.forEach(function (link) {
494
+ nodes.push(link.target);
495
+ if (nodes.indexOf(link.source) === -1) {
496
+ nodes.push(link.source);
497
+ }
498
+ });
499
+ return nodes;
500
+ };
501
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
502
+ SankeyChartBase.prototype._getSelectedLinks = function (singleNode) {
503
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-array-constructor
504
+ var q = new Array();
505
+ var finalLinks = new Set();
506
+ singleNode.sourceLinks.forEach(function (link) {
507
+ q.push(link);
508
+ finalLinks.add(link);
509
+ });
510
+ while (q.length > 0) {
511
+ var poppedLink = q.shift();
512
+ var node = poppedLink.target;
513
+ if (node && node.sourceLinks) {
514
+ node.sourceLinks.forEach(function (link) {
515
+ finalLinks.add(link);
516
+ q.push(link);
517
+ });
518
+ }
519
+ }
520
+ if (singleNode.targetLinks) {
521
+ singleNode.targetLinks.forEach(function (link) {
522
+ q.push(link);
523
+ finalLinks.add(link);
524
+ });
525
+ }
526
+ while (q.length > 0) {
527
+ var poppedLink = q.shift();
528
+ var node = poppedLink.source;
529
+ if (node && node.targetLinks) {
530
+ node.targetLinks.forEach(function (link) {
531
+ finalLinks.add(link);
532
+ q.push(link);
533
+ });
534
+ }
535
+ }
536
+ return finalLinks;
537
+ };
538
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
539
+ SankeyChartBase.prototype._getSelectedLinksforStreamHover = function (singleLink) {
540
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-array-constructor
541
+ var q = new Array();
542
+ var finalLinks = new Set();
543
+ var finalNodes = new Set();
544
+ q.push(singleLink.source);
545
+ finalLinks.add(singleLink);
546
+ while (q.length > 0) {
547
+ var poppedNode = q.shift();
548
+ finalNodes.add(poppedNode);
549
+ if (poppedNode.targetLinks && poppedNode.targetLinks.length > 0) {
550
+ poppedNode.targetLinks.forEach(function (link) {
551
+ q.push(link.source);
552
+ finalLinks.add(link);
553
+ });
554
+ }
555
+ }
556
+ q.push(singleLink.target);
557
+ while (q.length > 0) {
558
+ var poppedNode = q.shift();
559
+ finalNodes.add(poppedNode);
560
+ if (poppedNode.sourceLinks && poppedNode.sourceLinks.length > 0) {
561
+ poppedNode.sourceLinks.forEach(function (link) {
562
+ q.push(link.target);
563
+ finalLinks.add(link);
564
+ });
565
+ }
566
+ }
567
+ return {
568
+ selectedLinks: finalLinks,
569
+ selectedNodes: finalNodes,
570
+ };
571
+ };
572
+ SankeyChartBase.prototype._getOpacityStream = function (singleLink) {
573
+ if (this.state.selectedState) {
574
+ if (!this.state.selectedLinks.has(singleLink.index)) {
575
+ return NON_SELECTED_OPACITY;
576
+ }
577
+ else if (this.state.selectedState &&
578
+ this.state.selectedLinks.has(singleLink.index) &&
579
+ !this.state.selectedNode) {
580
+ return SELECTED_STREAM_OPACITY;
581
+ }
582
+ }
583
+ return REST_STREAM_OPACITY;
584
+ };
585
+ SankeyChartBase.prototype._getOpacityStreamBorder = function (singleLink) {
586
+ if (this.state.selectedState && !this.state.selectedLinks.has(singleLink.index) && !this.state.selectedNode) {
587
+ return NON_SELECTED_STREAM_BORDER_OPACITY;
588
+ }
589
+ return NON_SELECTED_OPACITY;
590
+ };
89
591
  SankeyChartBase.prototype._fitParentContainer = function () {
90
592
  var _this = this;
91
593
  var _a = this.state, containerWidth = _a.containerWidth, containerHeight = _a.containerHeight;
@@ -102,6 +604,65 @@ define(["require", "exports", "tslib", "react", "@fluentui/react/lib/Utilities",
102
604
  }
103
605
  });
104
606
  };
607
+ /**
608
+ *
609
+ * @param text is the text which we are trying to truncate
610
+ * @param rectangleWidth is the width of the rectangle which will contain the text
611
+ * @param padding is the space we need to leave between the rect lines and other text
612
+ * @param nodeWeight is the text if present needs to be accomodate in the same line as text.
613
+ * @returns the truncated text , if truncated given the above parameters.
614
+ */
615
+ SankeyChartBase.prototype._truncateText = function (text, rectangleWidth, padding) {
616
+ var textLengthForNodeName = rectangleWidth - padding;
617
+ var elipsisLength = 0;
618
+ var tspan = d3_selection_1.select('.nodeName')
619
+ .append('text')
620
+ .attr('class', 'tempText')
621
+ .attr('font-size', '10')
622
+ .append('tspan')
623
+ .text(null);
624
+ tspan.text(text);
625
+ if (tspan.node() !== null && tspan.node().getComputedTextLength() <= textLengthForNodeName) {
626
+ return text;
627
+ }
628
+ tspan.text(null);
629
+ tspan.text('...');
630
+ if (tspan.node() !== null) {
631
+ elipsisLength = tspan.node().getComputedTextLength();
632
+ }
633
+ tspan.text(null);
634
+ var line = '';
635
+ for (var i = 0; i < text.length; i++) {
636
+ line += text[i];
637
+ tspan.text(line);
638
+ if (tspan.node() !== null) {
639
+ var w = tspan.node().getComputedTextLength();
640
+ if (w >= textLengthForNodeName - elipsisLength) {
641
+ line = line.slice(0, -1);
642
+ line += '...';
643
+ break;
644
+ }
645
+ }
646
+ }
647
+ tspan.text(null);
648
+ d3_selection_1.selectAll('.tempText').remove();
649
+ return line;
650
+ };
651
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
652
+ SankeyChartBase.prototype._showTooltip = function (text, checkTrcuncated, div, evt) {
653
+ if (checkTrcuncated) {
654
+ //Fixing tooltip position by attaching it to the element rather than page
655
+ div.style('opacity', 0.9);
656
+ div
657
+ .html(text)
658
+ .style('left', evt.pageX + 'px')
659
+ .style('top', evt.pageY - 28 + 'px');
660
+ }
661
+ };
662
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
663
+ SankeyChartBase.prototype._hideTooltip = function (div) {
664
+ div.style('opacity', 0);
665
+ };
105
666
  return SankeyChartBase;
106
667
  }(React.Component));
107
668
  exports.SankeyChartBase = SankeyChartBase;