@fluentui/react-charting 5.24.21 → 5.24.22

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 (84) hide show
  1. package/CHANGELOG.json +40 -1
  2. package/CHANGELOG.md +15 -2
  3. package/bundle-size/ScatterChart.fixture.js +7 -0
  4. package/dist/react-charting.d.ts +27 -2
  5. package/dist/react-charting.js +1 -1
  6. package/dist/react-charting.min.js +1 -1
  7. package/etc/react-charting.api.md +8 -2
  8. package/lib/components/AreaChart/AreaChart.base.js +3 -3
  9. package/lib/components/AreaChart/AreaChart.base.js.map +1 -1
  10. package/lib/components/CommonComponents/CartesianChart.base.js +4 -4
  11. package/lib/components/CommonComponents/CartesianChart.base.js.map +1 -1
  12. package/lib/components/CommonComponents/CartesianChart.types.d.ts +18 -3
  13. package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
  14. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.d.ts +10 -0
  15. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +187 -11
  16. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  17. package/lib/components/LineChart/LineChart.base.d.ts +0 -9
  18. package/lib/components/LineChart/LineChart.base.js +82 -138
  19. package/lib/components/LineChart/LineChart.base.js.map +1 -1
  20. package/lib/components/ScatterChart/ScatterChart.base.js +37 -62
  21. package/lib/components/ScatterChart/ScatterChart.base.js.map +1 -1
  22. package/lib/components/VerticalBarChart/VerticalBarChart.base.js +2 -2
  23. package/lib/components/VerticalBarChart/VerticalBarChart.base.js.map +1 -1
  24. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.base.js +2 -2
  25. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.base.js.map +1 -1
  26. package/lib/index.d.ts +1 -1
  27. package/lib/index.js.map +1 -1
  28. package/lib/types/IDataPoint.d.ts +9 -0
  29. package/lib/types/IDataPoint.js.map +1 -1
  30. package/lib/utilities/utilities.d.ts +29 -28
  31. package/lib/utilities/utilities.js +127 -110
  32. package/lib/utilities/utilities.js.map +1 -1
  33. package/lib-amd/components/AreaChart/AreaChart.base.js +2 -2
  34. package/lib-amd/components/AreaChart/AreaChart.base.js.map +1 -1
  35. package/lib-amd/components/CommonComponents/CartesianChart.base.js +4 -4
  36. package/lib-amd/components/CommonComponents/CartesianChart.base.js.map +1 -1
  37. package/lib-amd/components/CommonComponents/CartesianChart.types.d.ts +18 -3
  38. package/lib-amd/components/CommonComponents/CartesianChart.types.js.map +1 -1
  39. package/lib-amd/components/DeclarativeChart/PlotlySchemaAdapter.d.ts +10 -0
  40. package/lib-amd/components/DeclarativeChart/PlotlySchemaAdapter.js +188 -11
  41. package/lib-amd/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  42. package/lib-amd/components/LineChart/LineChart.base.d.ts +0 -9
  43. package/lib-amd/components/LineChart/LineChart.base.js +80 -136
  44. package/lib-amd/components/LineChart/LineChart.base.js.map +1 -1
  45. package/lib-amd/components/ScatterChart/ScatterChart.base.js +35 -60
  46. package/lib-amd/components/ScatterChart/ScatterChart.base.js.map +1 -1
  47. package/lib-amd/components/VerticalBarChart/VerticalBarChart.base.js +1 -1
  48. package/lib-amd/components/VerticalBarChart/VerticalBarChart.base.js.map +1 -1
  49. package/lib-amd/components/VerticalStackedBarChart/VerticalStackedBarChart.base.js +1 -1
  50. package/lib-amd/components/VerticalStackedBarChart/VerticalStackedBarChart.base.js.map +1 -1
  51. package/lib-amd/index.d.ts +1 -1
  52. package/lib-amd/index.js.map +1 -1
  53. package/lib-amd/types/IDataPoint.d.ts +9 -0
  54. package/lib-amd/types/IDataPoint.js.map +1 -1
  55. package/lib-amd/utilities/utilities.d.ts +29 -28
  56. package/lib-amd/utilities/utilities.js +133 -113
  57. package/lib-amd/utilities/utilities.js.map +1 -1
  58. package/lib-commonjs/components/AreaChart/AreaChart.base.js +2 -2
  59. package/lib-commonjs/components/AreaChart/AreaChart.base.js.map +1 -1
  60. package/lib-commonjs/components/CommonComponents/CartesianChart.base.js +4 -4
  61. package/lib-commonjs/components/CommonComponents/CartesianChart.base.js.map +1 -1
  62. package/lib-commonjs/components/CommonComponents/CartesianChart.types.d.ts +18 -3
  63. package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
  64. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.d.ts +10 -0
  65. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +188 -11
  66. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  67. package/lib-commonjs/components/LineChart/LineChart.base.d.ts +0 -9
  68. package/lib-commonjs/components/LineChart/LineChart.base.js +80 -136
  69. package/lib-commonjs/components/LineChart/LineChart.base.js.map +1 -1
  70. package/lib-commonjs/components/ScatterChart/ScatterChart.base.js +35 -60
  71. package/lib-commonjs/components/ScatterChart/ScatterChart.base.js.map +1 -1
  72. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.base.js +1 -1
  73. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.base.js.map +1 -1
  74. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.base.js +1 -1
  75. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.base.js.map +1 -1
  76. package/lib-commonjs/index.d.ts +1 -1
  77. package/lib-commonjs/index.js.map +1 -1
  78. package/lib-commonjs/types/IDataPoint.d.ts +9 -0
  79. package/lib-commonjs/types/IDataPoint.js.map +1 -1
  80. package/lib-commonjs/utilities/utilities.d.ts +29 -28
  81. package/lib-commonjs/utilities/utilities.js +134 -114
  82. package/lib-commonjs/utilities/utilities.js.map +1 -1
  83. package/package.json +4 -4
  84. package/src/components/CommonComponents/CartesianChart.types.ts +22 -2
@@ -5,7 +5,7 @@ import { format as d3Format } from 'd3-format';
5
5
  import { DataVizPalette, getColorFromToken } from '../../utilities/colors';
6
6
  import { GaugeChartVariant } from '../GaugeChart/index';
7
7
  import { findNumericMinMaxOfY, formatScientificLimitWidth, MIN_DONUT_RADIUS } from '../../utilities/utilities';
8
- import { isArrayOrTypedArray, isDate, isDateArray, isNumberArray, isStringArray, isYearArray, isInvalidValue, formatToLocaleString, } from '@fluentui/chart-utilities';
8
+ import { isArrayOrTypedArray, isDate, isDateArray, isNumberArray, isStringArray, isYearArray, isInvalidValue, formatToLocaleString, isNumber, isObjectArray, getAxisIds, getAxisKey, } from '@fluentui/chart-utilities';
9
9
  import { curveCardinal as d3CurveCardinal } from 'd3-shape';
10
10
  import { getOpacity, extractColor, resolveColor, createColorScale } from './PlotlyColorAdapter';
11
11
  import { rgb } from 'd3-color';
@@ -203,6 +203,124 @@ export var resolveXAxisPoint = function (x, isXYearCategory, isXString, isXDate,
203
203
  }
204
204
  return x;
205
205
  };
206
+ /**
207
+ * Checks if a key should be ignored during normalization
208
+ * @param key The key to check
209
+ * @returns true if the key should be ignored
210
+ */
211
+ var shouldIgnoreKey = function (key) {
212
+ var lowerKey = key.toLowerCase();
213
+ if (lowerKey.includes('style') || lowerKey === 'style') {
214
+ return true;
215
+ }
216
+ // Use regex to match common CSS property patterns
217
+ // (color, fill, stroke, border, background, font, shadow, outline, etc.)
218
+ var cssKeyRegex = new RegExp('^(color|fill|stroke|border|background|font|shadow|outline|margin|padding|gap|align|justify|display|flex|grid|' +
219
+ 'text|line|letter|word|vertical|horizontal|overflow|position|top|right|bottom|left|zindex|z-index|opacity|' +
220
+ 'filter|clip|cursor|resize|transition|animation|transform|box|column|row|direction|visibility|' +
221
+ 'content|width|height|aspect|image|user|pointer|caret|scroll|%)|(-webkit-|-moz-|-ms-|-o-)', 'i');
222
+ if (cssKeyRegex.test(lowerKey)) {
223
+ return true;
224
+ }
225
+ return false;
226
+ };
227
+ /**
228
+ * Flattens a nested object into a single level object with dot notation keys
229
+ * @param obj Object to flatten
230
+ * @param prefix Optional prefix for keys
231
+ * @returns Flattened object
232
+ */
233
+ var flattenObject = function (obj, prefix) {
234
+ if (prefix === void 0) { prefix = ''; }
235
+ var flattened = {};
236
+ for (var key in obj) {
237
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
238
+ var newKey = prefix ? "".concat(prefix, ".").concat(key) : key;
239
+ var value = obj[key];
240
+ if (typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof Date)) {
241
+ // Recursively flatten nested objects
242
+ Object.assign(flattened, flattenObject(value, newKey));
243
+ }
244
+ else {
245
+ flattened[newKey] = value;
246
+ }
247
+ }
248
+ }
249
+ return flattened;
250
+ };
251
+ /**
252
+ * Normalizes an array of objects by flattening nested structures and creating grouped data
253
+ * Uses json_normalize approach with D3 color detection and filtering
254
+ * @param data Array of objects to normalize
255
+ * @returns Object containing traces for grouped vertical bar chart
256
+ */
257
+ export var normalizeObjectArrayForGVBC = function (data, xLabels) {
258
+ if (!data || data.length === 0) {
259
+ return { traces: [], x: [] };
260
+ }
261
+ // Use provided xLabels if available, otherwise default to Item 1, Item 2, ...
262
+ var x = xLabels && xLabels.length === data.length ? xLabels : data.map(function (_, index) { return "Item ".concat(index + 1); });
263
+ // First, flatten all objects and collect all unique keys, excluding style keys
264
+ var flattenedObjects = data.map(function (item, index) {
265
+ var _a;
266
+ if (typeof item === 'object' && item !== null) {
267
+ var flattened_1 = flattenObject(item);
268
+ // Only keep keys where the value is numeric (number or numeric string) and not a style key
269
+ var filtered_1 = {};
270
+ Object.keys(flattened_1).forEach(function (key) {
271
+ var value = flattened_1[key];
272
+ if (!shouldIgnoreKey(key) && (typeof value === 'number' || (typeof value === 'string' && isNumber(value)))) {
273
+ filtered_1[key] = value;
274
+ }
275
+ });
276
+ return filtered_1;
277
+ }
278
+ else if (typeof item === 'number' || (typeof item === 'string' && isNumber(item))) {
279
+ // Only keep primitive numeric values
280
+ return _a = {}, _a[x[index] || "item_".concat(index)] = item, _a;
281
+ }
282
+ else {
283
+ // Non-numeric primitive, ignore by returning empty object
284
+ return {};
285
+ }
286
+ });
287
+ // Collect all unique keys across all objects
288
+ var allKeys = new Set();
289
+ flattenedObjects.forEach(function (obj) {
290
+ Object.keys(obj).forEach(function (key) { return allKeys.add(key); });
291
+ });
292
+ // Create traces for each key (property)
293
+ var traces = [];
294
+ allKeys.forEach(function (key) {
295
+ var yValues = [];
296
+ var hasValidData = false;
297
+ var isNumericData = false;
298
+ flattenedObjects.forEach(function (obj, index) {
299
+ var value = obj[key];
300
+ if (typeof value === 'number') {
301
+ yValues.push(value);
302
+ hasValidData = true;
303
+ isNumericData = true;
304
+ }
305
+ else if (typeof value === 'string' && isNumber(value)) {
306
+ yValues.push(parseFloat(value));
307
+ hasValidData = true;
308
+ isNumericData = true;
309
+ }
310
+ });
311
+ // Only create trace if we have valid numeric data
312
+ if (hasValidData && isNumericData) {
313
+ var trace = {
314
+ type: 'bar',
315
+ name: key,
316
+ x: x,
317
+ y: yValues,
318
+ };
319
+ traces.push(trace);
320
+ }
321
+ });
322
+ return { traces: traces, x: x };
323
+ };
206
324
  export var transformPlotlyJsonToDonutProps = function (input, isMultiPlot, colorMap, colorwayType, isDarkTheme) {
207
325
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
208
326
  var firstData = input.data[0];
@@ -337,16 +455,37 @@ export var transformPlotlyJsonToVSBCProps = function (input, isMultiPlot, colorM
337
455
  };
338
456
  export var transformPlotlyJsonToGVBCProps = function (input, isMultiPlot, colorMap, colorwayType, isDarkTheme) {
339
457
  var _a, _b, _c, _d;
458
+ // Handle object arrays in y values by normalizing the data first
459
+ var processedInput = __assign({}, input);
460
+ // Check if any bar traces have object arrays as y values
461
+ var hasObjectArrayData = input.data.some(function (series) { return series.type === 'bar' && isObjectArray(series.y); });
462
+ if (hasObjectArrayData) {
463
+ // Process each trace that has object array y values
464
+ var processedData = input.data
465
+ .map(function (series, index) {
466
+ if (series.type === 'bar' && isObjectArray(series.y)) {
467
+ // Normalize the object array to create multiple traces for GVBC
468
+ var traces = normalizeObjectArrayForGVBC(series.y, Array.isArray(series.x) ? series.x : undefined).traces;
469
+ // Return all the new traces, each representing a property from the objects
470
+ return traces.map(function (trace) { return (__assign(__assign({}, trace), {
471
+ // Copy other properties from the original series if needed
472
+ marker: series.marker })); });
473
+ }
474
+ return [series];
475
+ })
476
+ .flat();
477
+ processedInput = __assign(__assign({}, input), { data: processedData });
478
+ }
340
479
  var mapXToDataPoints = {};
341
- var secondaryYAxisValues = getSecondaryYAxisValues(input.data, input.layout, 0, 0);
342
- var _e = getLegendProps(input.data, input.layout, isMultiPlot), legends = _e.legends, hideLegend = _e.hideLegend;
480
+ var secondaryYAxisValues = getSecondaryYAxisValues(processedInput.data, processedInput.layout, 0, 0);
481
+ var _e = getLegendProps(processedInput.data, processedInput.layout, isMultiPlot), legends = _e.legends, hideLegend = _e.hideLegend;
343
482
  var colorScale = undefined;
344
- var yAxisTickFormat = getYAxisTickFormat(input.data[0], input.layout);
345
- input.data.forEach(function (series, index1) {
483
+ var yAxisTickFormat = getYAxisTickFormat(processedInput.data[0], processedInput.layout);
484
+ processedInput.data.forEach(function (series, index1) {
346
485
  var _a, _b, _c, _d, _e;
347
- colorScale = createColorScale(input.layout, series, colorScale);
486
+ colorScale = createColorScale(processedInput.layout, series, colorScale);
348
487
  // extract colors for each series only once
349
- var extractedColors = extractColor((_c = (_b = (_a = input.layout) === null || _a === void 0 ? void 0 : _a.template) === null || _b === void 0 ? void 0 : _b.layout) === null || _c === void 0 ? void 0 : _c.colorway, colorwayType, (_d = series.marker) === null || _d === void 0 ? void 0 : _d.color, colorMap, isDarkTheme);
488
+ var extractedColors = extractColor((_c = (_b = (_a = processedInput.layout) === null || _a === void 0 ? void 0 : _a.template) === null || _b === void 0 ? void 0 : _b.layout) === null || _c === void 0 ? void 0 : _c.colorway, colorwayType, (_d = series.marker) === null || _d === void 0 ? void 0 : _d.color, colorMap, isDarkTheme);
350
489
  (_e = series.x) === null || _e === void 0 ? void 0 : _e.forEach(function (x, xIndex) {
351
490
  var _a, _b, _c, _d, _e, _f;
352
491
  if (isInvalidValue(x) || isInvalidValue((_a = series.y) === null || _a === void 0 ? void 0 : _a[xIndex])) {
@@ -371,14 +510,14 @@ export var transformPlotlyJsonToGVBCProps = function (input, isMultiPlot, colorM
371
510
  xAxisCalloutData: x,
372
511
  color: (_f = rgb(color).copy({ opacity: opacity }).formatHex8()) !== null && _f !== void 0 ? _f : color,
373
512
  legend: legend,
374
- useSecondaryYScale: usesSecondaryYScale(series, input.layout),
513
+ useSecondaryYScale: usesSecondaryYScale(series, processedInput.layout),
375
514
  yAxisCalloutData: getFormattedCalloutYData(yVal, yAxisTickFormat),
376
515
  });
377
516
  }
378
517
  });
379
518
  });
380
519
  var gvbcData = Object.values(mapXToDataPoints);
381
- return __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({ data: gvbcData, width: (_a = input.layout) === null || _a === void 0 ? void 0 : _a.width, height: (_c = (_b = input.layout) === null || _b === void 0 ? void 0 : _b.height) !== null && _c !== void 0 ? _c : 350, barwidth: 'auto', mode: 'plotly' }, secondaryYAxisValues), { hideTickOverlap: true, hideLegend: hideLegend, roundCorners: true, wrapXAxisLables: typeof ((_d = gvbcData[0]) === null || _d === void 0 ? void 0 : _d.name) === 'string' }), getTitles(input.layout)), getAxisCategoryOrderProps(input.data, input.layout)), getYMinMaxValues(input.data[0], input.layout)), getXAxisTickFormat(input.data[0], input.layout)), yAxisTickFormat), getBarProps(input.data, input.layout));
520
+ return __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({ data: gvbcData, width: (_a = processedInput.layout) === null || _a === void 0 ? void 0 : _a.width, height: (_c = (_b = processedInput.layout) === null || _b === void 0 ? void 0 : _b.height) !== null && _c !== void 0 ? _c : 350, barwidth: 'auto', mode: 'plotly' }, secondaryYAxisValues), { hideTickOverlap: true, hideLegend: hideLegend, roundCorners: true, wrapXAxisLables: typeof ((_d = gvbcData[0]) === null || _d === void 0 ? void 0 : _d.name) === 'string' }), getTitles(processedInput.layout)), getAxisCategoryOrderProps(processedInput.data, processedInput.layout)), getYMinMaxValues(processedInput.data[0], processedInput.layout)), getXAxisTickFormat(processedInput.data[0], processedInput.layout)), yAxisTickFormat), getBarProps(processedInput.data, processedInput.layout));
382
521
  };
383
522
  export var transformPlotlyJsonToVBCProps = function (input, isMultiPlot, colorMap, colorwayType, isDarkTheme) {
384
523
  var _a, _b, _c, _d;
@@ -538,7 +677,7 @@ var transformPlotlyJsonToScatterTraceProps = function (input, isMultiPlot, chart
538
677
  var scatterChartProps = {
539
678
  scatterChartData: chartData,
540
679
  };
541
- var commonProps = __assign(__assign(__assign(__assign(__assign({ supportNegativeData: true }, secondaryYAxisValues), { width: (_b = input.layout) === null || _b === void 0 ? void 0 : _b.width, height: (_d = (_c = input.layout) === null || _c === void 0 ? void 0 : _c.height) !== null && _d !== void 0 ? _d : 350, hideTickOverlap: true, hideLegend: hideLegend, useUTC: false, optimizeLargeData: numDataPoints > 1000 }), getTitles(input.layout)), getXAxisTickFormat(input.data[0], input.layout)), yAxisTickFormat);
680
+ var commonProps = __assign(__assign(__assign(__assign(__assign(__assign({ supportNegativeData: true }, secondaryYAxisValues), { width: (_b = input.layout) === null || _b === void 0 ? void 0 : _b.width, height: (_d = (_c = input.layout) === null || _c === void 0 ? void 0 : _c.height) !== null && _d !== void 0 ? _d : 350, hideTickOverlap: true, hideLegend: hideLegend, useUTC: false, optimizeLargeData: numDataPoints > 1000 }), getTitles(input.layout)), getXAxisTickFormat(input.data[0], input.layout)), yAxisTickFormat), getAxisScaleTypeProps(input.data, input.layout));
542
681
  if (isAreaChart) {
543
682
  return __assign({ data: chartProps, mode: mode }, commonProps);
544
683
  }
@@ -1771,7 +1910,15 @@ var parseLocalDate = function (value) {
1771
1910
  var getBarProps = function (data, layout, isHorizontal) {
1772
1911
  var padding;
1773
1912
  if (typeof (layout === null || layout === void 0 ? void 0 : layout.bargap) === 'number') {
1774
- padding = layout.bargap;
1913
+ if (layout.bargap >= 0 && layout.bargap <= 1) {
1914
+ padding = layout.bargap;
1915
+ }
1916
+ else {
1917
+ // Plotly uses a default bargap of 0.2, as noted here: https://github.com/plotly/plotly.js/blob/1d5a249e43dd31ae50acf02117a19e5ac97387e9/src/traces/bar/layout_defaults.js#L58.
1918
+ // However, we don't use this value as our default padding because it causes the bars to
1919
+ // appear disproportionately wide in large containers.
1920
+ padding = 0.2;
1921
+ }
1775
1922
  }
1776
1923
  var plotlyBarWidths = data
1777
1924
  .map(function (series) {
@@ -1802,4 +1949,33 @@ var getBarProps = function (data, layout, isHorizontal) {
1802
1949
  xAxisOuterPadding: padding / 2,
1803
1950
  };
1804
1951
  };
1952
+ var getAxisScaleTypeProps = function (data, layout) {
1953
+ var result = {};
1954
+ // Traces are grouped by their xaxis property, and for each group/subplot, the adapter functions
1955
+ // are called with the corresponding filtered data. As a result, all traces passed to an adapter
1956
+ // function share the same xaxis.
1957
+ var xAxisId;
1958
+ var yAxisIds = new Set();
1959
+ data.forEach(function (series) {
1960
+ var axisIds = getAxisIds(series);
1961
+ xAxisId = axisIds.x;
1962
+ yAxisIds.add(axisIds.y);
1963
+ });
1964
+ var isLogAxis = function (axLetter, axId) {
1965
+ var _a;
1966
+ var axisKey = getAxisKey(axLetter, axId);
1967
+ return ((_a = layout === null || layout === void 0 ? void 0 : layout[axisKey]) === null || _a === void 0 ? void 0 : _a.type) === 'log';
1968
+ };
1969
+ if (typeof xAxisId === 'number' && isLogAxis('x', xAxisId)) {
1970
+ result.xScaleType = 'log';
1971
+ }
1972
+ var sortedYAxisIds = Array.from(yAxisIds).sort();
1973
+ if (sortedYAxisIds.length > 0 && isLogAxis('y', sortedYAxisIds[0])) {
1974
+ result.yScaleType = 'log';
1975
+ }
1976
+ if (sortedYAxisIds.length > 1 && isLogAxis('y', sortedYAxisIds[1])) {
1977
+ result.secondaryYScaleType = 'log';
1978
+ }
1979
+ return result;
1980
+ };
1805
1981
  //# sourceMappingURL=PlotlySchemaAdapter.js.map