@fluentui/react-charts 0.0.0-nightly-20250827-0407.1 → 0.0.0-nightly-20250829-0406.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -15
- package/dist/index.d.ts +27 -2
- package/lib/components/AreaChart/AreaChart.js +3 -3
- package/lib/components/AreaChart/AreaChart.js.map +1 -1
- package/lib/components/CommonComponents/CartesianChart.js +4 -4
- package/lib/components/CommonComponents/CartesianChart.js.map +1 -1
- package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
- package/lib/components/DeclarativeChart/DeclarativeChart.js +1 -1
- package/lib/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
- package/lib/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -1
- package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +59 -13
- package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
- package/lib/components/FunnelChart/funnelGeometry.js.map +1 -1
- package/lib/components/GaugeChart/GaugeChart.js.map +1 -1
- package/lib/components/LineChart/LineChart.js +195 -250
- package/lib/components/LineChart/LineChart.js.map +1 -1
- package/lib/components/ResponsiveContainer/withResponsiveContainer.js.map +1 -1
- package/lib/components/SankeyChart/SankeyChart.js.map +1 -1
- package/lib/components/ScatterChart/ScatterChart.js +30 -54
- package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib/components/VerticalBarChart/VerticalBarChart.js +2 -2
- package/lib/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +2 -2
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib/types/DataPoint.js +6 -1
- package/lib/types/DataPoint.js.map +1 -1
- package/lib/utilities/Common.styles.raw.js.map +1 -1
- package/lib/utilities/image-export-utils.js.map +1 -1
- package/lib/utilities/scatterpolar-utils.js +7 -18
- package/lib/utilities/scatterpolar-utils.js.map +1 -1
- package/lib/utilities/utilities.js +130 -127
- package/lib/utilities/utilities.js.map +1 -1
- package/lib/utilities/vbc-utils.js.map +1 -1
- package/lib-commonjs/components/AreaChart/AreaChart.js +2 -2
- package/lib-commonjs/components/AreaChart/AreaChart.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/CartesianChart.js +4 -4
- package/lib-commonjs/components/CommonComponents/CartesianChart.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
- package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js +1 -1
- package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
- package/lib-commonjs/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -1
- package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +58 -12
- package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
- package/lib-commonjs/components/FunnelChart/funnelGeometry.js.map +1 -1
- package/lib-commonjs/components/GaugeChart/GaugeChart.js.map +1 -1
- package/lib-commonjs/components/LineChart/LineChart.js +193 -248
- package/lib-commonjs/components/LineChart/LineChart.js.map +1 -1
- package/lib-commonjs/components/ResponsiveContainer/withResponsiveContainer.js.map +1 -1
- package/lib-commonjs/components/SankeyChart/SankeyChart.js.map +1 -1
- package/lib-commonjs/components/ScatterChart/ScatterChart.js +28 -52
- package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js +1 -1
- package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +1 -1
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib-commonjs/types/DataPoint.js +6 -1
- package/lib-commonjs/types/DataPoint.js.map +1 -1
- package/lib-commonjs/utilities/Common.styles.raw.js.map +1 -1
- package/lib-commonjs/utilities/image-export-utils.js.map +1 -1
- package/lib-commonjs/utilities/scatterpolar-utils.js +7 -18
- package/lib-commonjs/utilities/scatterpolar-utils.js.map +1 -1
- package/lib-commonjs/utilities/utilities.js +142 -118
- package/lib-commonjs/utilities/utilities.js.map +1 -1
- package/lib-commonjs/utilities/vbc-utils.js.map +1 -1
- package/package.json +12 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { axisRight as d3AxisRight, axisBottom as d3AxisBottom, axisLeft as d3AxisLeft } from 'd3-axis';
|
|
2
2
|
import { max as d3Max, min as d3Min, ticks as d3Ticks, nice as d3nice, sum as d3Sum, mean as d3Mean, median as d3Median } from 'd3-array';
|
|
3
|
-
import { scaleLinear as d3ScaleLinear, scaleBand as d3ScaleBand, scaleUtc as d3ScaleUtc, scaleTime as d3ScaleTime } from 'd3-scale';
|
|
3
|
+
import { scaleLinear as d3ScaleLinear, scaleBand as d3ScaleBand, scaleUtc as d3ScaleUtc, scaleTime as d3ScaleTime, scaleLog as d3ScaleLog } from 'd3-scale';
|
|
4
4
|
import { select as d3Select, selectAll as d3SelectAll } from 'd3-selection';
|
|
5
5
|
import { format as d3Format } from 'd3-format';
|
|
6
6
|
import { timeFormat as d3TimeFormat, timeFormatLocale as d3TimeFormatLocale, utcFormat as d3UtcFormat } from 'd3-time-format';
|
|
@@ -8,7 +8,7 @@ import { timeSecond as d3TimeSecond, timeMinute as d3TimeMinute, timeHour as d3T
|
|
|
8
8
|
import { curveLinear as d3CurveLinear, curveNatural as d3CurveNatural, curveStep as d3CurveStep, curveStepAfter as d3CurveStepAfter, curveStepBefore as d3CurveStepBefore } from 'd3-shape';
|
|
9
9
|
import { formatPrefix as d3FormatPrefix } from 'd3-format';
|
|
10
10
|
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
|
|
11
|
-
import { formatDateToLocaleString, formatToLocaleString, getMultiLevelDateTimeFormatOptions } from '@fluentui/chart-utilities';
|
|
11
|
+
import { formatDateToLocaleString, formatToLocaleString, getMultiLevelDateTimeFormatOptions, isInvalidValue } from '@fluentui/chart-utilities';
|
|
12
12
|
export const MIN_DOMAIN_MARGIN = 8;
|
|
13
13
|
export const MIN_DONUT_RADIUS = 1;
|
|
14
14
|
export var ChartTypes = /*#__PURE__*/ function(ChartTypes) {
|
|
@@ -63,9 +63,9 @@ function yAxisTickFormatterInternal(value, limitWidth = false) {
|
|
|
63
63
|
* Create Numeric X axis
|
|
64
64
|
* @export
|
|
65
65
|
* @param {IXAxisParams} xAxisParams
|
|
66
|
-
*/ export function createNumericXAxis(xAxisParams, tickParams, chartType, culture) {
|
|
66
|
+
*/ export function createNumericXAxis(xAxisParams, tickParams, chartType, culture, scaleType) {
|
|
67
67
|
const { domainNRangeValues, showRoundOffXTickValues = false, xAxistickSize = 6, tickPadding = 10, xAxisCount, xAxisElement, hideTickOverlap, calcMaxLabelWidth } = xAxisParams;
|
|
68
|
-
const xAxisScale =
|
|
68
|
+
const xAxisScale = createNumericScale(scaleType).domain([
|
|
69
69
|
domainNRangeValues.dStartValue,
|
|
70
70
|
domainNRangeValues.dEndValue
|
|
71
71
|
]).range([
|
|
@@ -74,19 +74,19 @@ function yAxisTickFormatterInternal(value, limitWidth = false) {
|
|
|
74
74
|
]);
|
|
75
75
|
showRoundOffXTickValues && xAxisScale.nice();
|
|
76
76
|
let tickCount = xAxisCount !== null && xAxisCount !== void 0 ? xAxisCount : 6;
|
|
77
|
-
const tickFormat = (domainValue, _index)=>{
|
|
77
|
+
const tickFormat = (domainValue, _index, defaultFormat)=>{
|
|
78
78
|
if (tickParams.tickFormat) {
|
|
79
79
|
return d3Format(tickParams.tickFormat)(domainValue);
|
|
80
80
|
}
|
|
81
81
|
const xAxisValue = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
|
|
82
|
-
return formatToLocaleString(xAxisValue, culture);
|
|
82
|
+
return (defaultFormat === null || defaultFormat === void 0 ? void 0 : defaultFormat(xAxisValue)) === '' ? '' : formatToLocaleString(xAxisValue, culture);
|
|
83
83
|
};
|
|
84
84
|
if (hideTickOverlap && typeof xAxisCount === 'undefined') {
|
|
85
|
-
const longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map(tickFormat)) + 20;
|
|
85
|
+
const longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map((v, i)=>tickFormat(v, i))) + 20;
|
|
86
86
|
const [start, end] = xAxisScale.range();
|
|
87
87
|
tickCount = Math.min(Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)), 10);
|
|
88
88
|
}
|
|
89
|
-
const xAxis = d3AxisBottom(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).ticks(tickCount).tickFormat(tickFormat);
|
|
89
|
+
const xAxis = d3AxisBottom(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).ticks(tickCount).tickFormat((v, i)=>tickFormat(v, i, xAxisScale.tickFormat(tickCount)));
|
|
90
90
|
if ([
|
|
91
91
|
6,
|
|
92
92
|
8
|
|
@@ -502,7 +502,7 @@ export function createYAxisForHorizontalBarChartWithAxis(yAxisParams, isRtl) {
|
|
|
502
502
|
yAxisElement ? d3Select(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true') : '';
|
|
503
503
|
return yAxisScale;
|
|
504
504
|
}
|
|
505
|
-
export function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDataset, chartType, useSecondaryYScale = false, roundedTicks = false) {
|
|
505
|
+
export function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDataset, chartType, useSecondaryYScale = false, roundedTicks = false, scaleType) {
|
|
506
506
|
const { yMinMaxValues = {
|
|
507
507
|
startValue: 0,
|
|
508
508
|
endValue: 0
|
|
@@ -519,16 +519,38 @@ export function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDatas
|
|
|
519
519
|
yMin = yMin - yPadding;
|
|
520
520
|
yMax = yMax + yPadding;
|
|
521
521
|
}
|
|
522
|
-
|
|
522
|
+
let scaleDomain = [
|
|
523
523
|
domainValues[0],
|
|
524
|
-
|
|
525
|
-
]
|
|
524
|
+
domainValues[domainValues.length - 1]
|
|
525
|
+
];
|
|
526
|
+
if (scaleType === 'log') {
|
|
527
|
+
let domainStart = yMinMaxValues.startValue;
|
|
528
|
+
let domainEnd = yMinMaxValues.endValue;
|
|
529
|
+
if (yMinValue > 0) {
|
|
530
|
+
domainStart = Math.min(domainStart, yMinValue);
|
|
531
|
+
}
|
|
532
|
+
if (yMaxValue > 0) {
|
|
533
|
+
domainEnd = Math.max(domainEnd, yMaxValue);
|
|
534
|
+
}
|
|
535
|
+
scaleDomain = [
|
|
536
|
+
domainStart,
|
|
537
|
+
domainEnd
|
|
538
|
+
];
|
|
539
|
+
}
|
|
540
|
+
const yAxisScale = createNumericScale(scaleType).domain(scaleDomain).range([
|
|
526
541
|
containerHeight - margins.bottom,
|
|
527
542
|
margins.top + (eventAnnotationProps ? eventLabelHeight : 0)
|
|
528
543
|
]);
|
|
529
544
|
const axis = !isRtl && useSecondaryYScale || isRtl && !useSecondaryYScale ? d3AxisRight(yAxisScale) : d3AxisLeft(yAxisScale);
|
|
530
|
-
const yAxis = axis.tickPadding(tickPadding).
|
|
531
|
-
|
|
545
|
+
const yAxis = axis.tickPadding(tickPadding).tickSizeInner(-(containerWidth - margins.left - margins.right));
|
|
546
|
+
if (scaleType !== 'log') {
|
|
547
|
+
yAxis.tickValues(domainValues);
|
|
548
|
+
}
|
|
549
|
+
const tickFormat = (domainValue, index, defaultFormat)=>{
|
|
550
|
+
const value = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
|
|
551
|
+
return (defaultFormat === null || defaultFormat === void 0 ? void 0 : defaultFormat(value)) === '' ? '' : defaultYAxisTickFormatter(value);
|
|
552
|
+
};
|
|
553
|
+
yAxisTickFormat ? yAxis.tickFormat(yAxisTickFormat) : yAxis.tickFormat((v, i)=>tickFormat(v, i, yAxisScale.tickFormat(yAxisTickCount)));
|
|
532
554
|
yAxisElement ? d3Select(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true') : '';
|
|
533
555
|
axisData.yAxisDomainValues = domainValues;
|
|
534
556
|
return yAxisScale;
|
|
@@ -850,51 +872,14 @@ export function tooltipOfAxislabels(axistooltipProps) {
|
|
|
850
872
|
* @param {number} width
|
|
851
873
|
* @param {boolean} isRTL
|
|
852
874
|
* @returns {IDomainNRange}
|
|
853
|
-
*/ export function
|
|
854
|
-
const isScatterPolar = isScatterPolarSeries(points);
|
|
855
|
-
const xMin = d3Min(points, (point)=>{
|
|
856
|
-
return d3Min(point.data, (item)=>item.x);
|
|
857
|
-
});
|
|
858
|
-
const xMax = d3Max(points, (point)=>{
|
|
859
|
-
return d3Max(point.data, (item)=>{
|
|
860
|
-
return item.x;
|
|
861
|
-
});
|
|
862
|
-
});
|
|
863
|
-
const rStartValue = margins.left;
|
|
864
|
-
const rEndValue = width - margins.right;
|
|
865
|
-
return isRTL ? {
|
|
866
|
-
dStartValue: isScatterPolar ? 1 : xMax,
|
|
867
|
-
dEndValue: isScatterPolar ? -1 : xMin,
|
|
868
|
-
rStartValue,
|
|
869
|
-
rEndValue
|
|
870
|
-
} : {
|
|
871
|
-
dStartValue: isScatterPolar ? -1 : xMin,
|
|
872
|
-
dEndValue: isScatterPolar ? 1 : xMax,
|
|
873
|
-
rStartValue,
|
|
874
|
-
rEndValue
|
|
875
|
-
};
|
|
876
|
-
}
|
|
877
|
-
/**
|
|
878
|
-
* Calculates Domain and range values for Numeric X axis for scatter chart.
|
|
879
|
-
* @export
|
|
880
|
-
* @param {LineChartPoints[]} points
|
|
881
|
-
* @param {IMargins} margins
|
|
882
|
-
* @param {number} width
|
|
883
|
-
* @param {boolean} isRTL
|
|
884
|
-
* @returns {IDomainNRange}
|
|
885
|
-
*/ export function domainRangeOfNumericForScatterChart(points, margins, width, isRTL) {
|
|
875
|
+
*/ export function domainRangeOfNumericForAreaLineScatterCharts(points, margins, width, isRTL, scaleType, hasMarkersMode) {
|
|
886
876
|
const isScatterPolar = isScatterPolarSeries(points);
|
|
887
|
-
let xMin =
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
});
|
|
894
|
-
});
|
|
895
|
-
const xPadding = (xMax - xMin) * 0.1;
|
|
896
|
-
xMin = xMin - xPadding;
|
|
897
|
-
xMax = xMax + xPadding;
|
|
877
|
+
let [xMin, xMax] = getScatterXDomainExtent(points, scaleType);
|
|
878
|
+
if (hasMarkersMode) {
|
|
879
|
+
const xPadding = getDomainPaddingForMarkers(xMin, xMax, scaleType);
|
|
880
|
+
xMin = xMin - xPadding.start;
|
|
881
|
+
xMax = xMax + xPadding.end;
|
|
882
|
+
}
|
|
898
883
|
const rStartValue = margins.left;
|
|
899
884
|
const rEndValue = width - margins.right;
|
|
900
885
|
return isRTL ? {
|
|
@@ -1032,22 +1017,15 @@ export function tooltipOfAxislabels(axistooltipProps) {
|
|
|
1032
1017
|
* @param {boolean} isRTL
|
|
1033
1018
|
* @param {Date[] | number[]} tickValues
|
|
1034
1019
|
* @returns {IDomainNRange}
|
|
1035
|
-
*/ export function
|
|
1020
|
+
*/ export function domainRangeOfDateForAreaLineScatterVerticalBarCharts(points, margins, width, isRTL, tickValues = [], chartType, barWidth, hasMarkersMode) {
|
|
1036
1021
|
let sDate;
|
|
1037
1022
|
let lDate;
|
|
1038
|
-
if (
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
});
|
|
1045
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1046
|
-
lDate = d3Max(points, (point)=>{
|
|
1047
|
-
return d3Max(point.data, (item)=>{
|
|
1048
|
-
return item.x;
|
|
1049
|
-
});
|
|
1050
|
-
});
|
|
1023
|
+
if ([
|
|
1024
|
+
0,
|
|
1025
|
+
1,
|
|
1026
|
+
7
|
|
1027
|
+
].includes(chartType)) {
|
|
1028
|
+
[sDate, lDate] = getScatterXDomainExtent(points);
|
|
1051
1029
|
// Need to draw graph with given small and large date
|
|
1052
1030
|
// (Which Involves customization of date axis tick values)
|
|
1053
1031
|
// That may be Either from given graph data or from prop 'tickValues' date values.
|
|
@@ -1065,6 +1043,11 @@ export function tooltipOfAxislabels(axistooltipProps) {
|
|
|
1065
1043
|
sDate = d3Min(points, (point)=>point.x);
|
|
1066
1044
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1067
1045
|
lDate = d3Max(points, (point)=>point.x);
|
|
1046
|
+
if (hasMarkersMode || chartType === 7) {
|
|
1047
|
+
const xPadding = getDomainPaddingForMarkers(sDate.getTime(), lDate.getTime());
|
|
1048
|
+
sDate = new Date(sDate.getTime() - xPadding.start);
|
|
1049
|
+
lDate = new Date(lDate.getTime() + xPadding.end);
|
|
1050
|
+
}
|
|
1068
1051
|
}
|
|
1069
1052
|
const rStartValue = margins.left;
|
|
1070
1053
|
const rEndValue = width - margins.right;
|
|
@@ -1080,59 +1063,6 @@ export function tooltipOfAxislabels(axistooltipProps) {
|
|
|
1080
1063
|
rEndValue
|
|
1081
1064
|
};
|
|
1082
1065
|
}
|
|
1083
|
-
/**
|
|
1084
|
-
* Calculates Domain and range values for Date X axis for scatter chart.
|
|
1085
|
-
* @export
|
|
1086
|
-
* @param {LineChartPoints[]} points
|
|
1087
|
-
* @param {IMargins} margins
|
|
1088
|
-
* @param {number} width
|
|
1089
|
-
* @param {boolean} isRTL
|
|
1090
|
-
* @param {Date[] | number[]} tickValues
|
|
1091
|
-
* @returns {IDomainNRange}
|
|
1092
|
-
*/ export function domainRangeOfDateForScatterChart(points, margins, width, isRTL, tickValues = []) {
|
|
1093
|
-
let sDate;
|
|
1094
|
-
let lDate;
|
|
1095
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1096
|
-
sDate = d3Min(points, (point)=>{
|
|
1097
|
-
return d3Min(point.data, (item)=>{
|
|
1098
|
-
return item.x;
|
|
1099
|
-
});
|
|
1100
|
-
});
|
|
1101
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1102
|
-
lDate = d3Max(points, (point)=>{
|
|
1103
|
-
return d3Max(point.data, (item)=>{
|
|
1104
|
-
return item.x;
|
|
1105
|
-
});
|
|
1106
|
-
});
|
|
1107
|
-
const xPadding = (lDate.getTime() - sDate.getTime()) * 0.1;
|
|
1108
|
-
sDate = new Date(sDate.getTime() - xPadding);
|
|
1109
|
-
lDate = new Date(lDate.getTime() + xPadding);
|
|
1110
|
-
// Need to draw graph with given small and large date
|
|
1111
|
-
// (Which Involves customization of date axis tick values)
|
|
1112
|
-
// That may be Either from given graph data or from prop 'tickValues' date values.
|
|
1113
|
-
// So, Finding smallest and largest dates
|
|
1114
|
-
sDate = d3Min([
|
|
1115
|
-
...tickValues,
|
|
1116
|
-
sDate
|
|
1117
|
-
]);
|
|
1118
|
-
lDate = d3Max([
|
|
1119
|
-
...tickValues,
|
|
1120
|
-
lDate
|
|
1121
|
-
]);
|
|
1122
|
-
const rStartValue = margins.left;
|
|
1123
|
-
const rEndValue = width - margins.right;
|
|
1124
|
-
return isRTL ? {
|
|
1125
|
-
dStartValue: lDate,
|
|
1126
|
-
dEndValue: sDate,
|
|
1127
|
-
rStartValue,
|
|
1128
|
-
rEndValue
|
|
1129
|
-
} : {
|
|
1130
|
-
dStartValue: sDate,
|
|
1131
|
-
dEndValue: lDate,
|
|
1132
|
-
rStartValue,
|
|
1133
|
-
rEndValue
|
|
1134
|
-
};
|
|
1135
|
-
}
|
|
1136
1066
|
/**
|
|
1137
1067
|
* Calculate domain and range values to the Vertical bar chart - For Numeric axis
|
|
1138
1068
|
* @export
|
|
@@ -1164,12 +1094,14 @@ export function tooltipOfAxislabels(axistooltipProps) {
|
|
|
1164
1094
|
* @export
|
|
1165
1095
|
* @param {LineChartPoints[]} points
|
|
1166
1096
|
* @returns {{ startValue: number; endValue: number }}
|
|
1167
|
-
*/ export function findNumericMinMaxOfY(points, yAxisType, useSecondaryYScale) {
|
|
1097
|
+
*/ export function findNumericMinMaxOfY(points, yAxisType, useSecondaryYScale, scaleType) {
|
|
1168
1098
|
const values = [];
|
|
1169
1099
|
points.forEach((point)=>{
|
|
1170
1100
|
if (!useSecondaryYScale === !point.useSecondaryYScale) {
|
|
1171
1101
|
point.data.forEach((data)=>{
|
|
1172
|
-
|
|
1102
|
+
if (isValidDomainValue(data.y, scaleType)) {
|
|
1103
|
+
values.push(data.y);
|
|
1104
|
+
}
|
|
1173
1105
|
});
|
|
1174
1106
|
}
|
|
1175
1107
|
});
|
|
@@ -1617,3 +1549,74 @@ export const createMeasurementSpan = (text, className, parentElement)=>{
|
|
|
1617
1549
|
return typeof ((_item_lineOptions = item.lineOptions) === null || _item_lineOptions === void 0 ? void 0 : _item_lineOptions.mode) === 'string' && item.lineOptions.mode === 'text';
|
|
1618
1550
|
});
|
|
1619
1551
|
}
|
|
1552
|
+
// TODO: Refactor to encapsulate the complete numeric scale creation logic here, including setting domain and range.
|
|
1553
|
+
const createNumericScale = (scaleType)=>{
|
|
1554
|
+
if (scaleType === 'log') {
|
|
1555
|
+
return d3ScaleLog();
|
|
1556
|
+
} else {
|
|
1557
|
+
return d3ScaleLinear();
|
|
1558
|
+
}
|
|
1559
|
+
};
|
|
1560
|
+
export const getDomainPaddingForMarkers = (minVal, maxVal, scaleType)=>{
|
|
1561
|
+
if (scaleType === 'log') {
|
|
1562
|
+
return {
|
|
1563
|
+
start: minVal * 0.5,
|
|
1564
|
+
end: maxVal
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
const defaultPadding = (maxVal - minVal) * 0.1;
|
|
1568
|
+
return {
|
|
1569
|
+
start: defaultPadding,
|
|
1570
|
+
end: defaultPadding
|
|
1571
|
+
};
|
|
1572
|
+
};
|
|
1573
|
+
/**
|
|
1574
|
+
* Determines whether a value is valid for inclusion in the scale domain.
|
|
1575
|
+
* For log scales, ensures the value is strictly positive to prevent undefined scale behavior.
|
|
1576
|
+
*/ // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1577
|
+
export const isValidDomainValue = (value, scaleType)=>{
|
|
1578
|
+
return typeof value !== 'number' || scaleType !== 'log' || value > 0;
|
|
1579
|
+
};
|
|
1580
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1581
|
+
export const isPlottable = (x, y)=>{
|
|
1582
|
+
return !isInvalidValue(x) && !isInvalidValue(y);
|
|
1583
|
+
};
|
|
1584
|
+
export const getScatterXDomainExtent = (points, scaleType)=>{
|
|
1585
|
+
const isValidDataPointForScale = (item)=>isValidDomainValue(item.x, scaleType);
|
|
1586
|
+
const xMin = d3Min(points, (point)=>{
|
|
1587
|
+
return d3Min(point.data.filter(isValidDataPointForScale), (item)=>item.x);
|
|
1588
|
+
});
|
|
1589
|
+
const xMax = d3Max(points, (point)=>{
|
|
1590
|
+
return d3Max(point.data.filter(isValidDataPointForScale), (item)=>{
|
|
1591
|
+
return item.x;
|
|
1592
|
+
});
|
|
1593
|
+
});
|
|
1594
|
+
return [
|
|
1595
|
+
xMin,
|
|
1596
|
+
xMax
|
|
1597
|
+
];
|
|
1598
|
+
};
|
|
1599
|
+
export const getRangeForScatterMarkerSize = ({ data, xScale, yScalePrimary, yScaleSecondary, useSecondaryYScale, xScaleType, yScaleType: primaryYScaleType, secondaryYScaleType })=>{
|
|
1600
|
+
// Note: This function is executed after the scale is created, so the actual padding can be
|
|
1601
|
+
// obtained by calculating the difference between the respective minimums or maximums of the
|
|
1602
|
+
// scale domain and the data. However, doing so often causes the marker size to scale up
|
|
1603
|
+
// unnecessarily when the scale uses a wider domain than required (due to the use of D3's nice
|
|
1604
|
+
// function or our own tick value calculations).
|
|
1605
|
+
// A better approach could be to treat the marker size as a fixed pixel value and adjust the
|
|
1606
|
+
// scale domain with sufficient padding to accommodate the maximum marker size—instead of doing
|
|
1607
|
+
// it the other way around (i.e., adjusting the scale domain first with padding and then scaling
|
|
1608
|
+
// the markers to fit inside the plot area).
|
|
1609
|
+
const [xMin, xMax] = getScatterXDomainExtent(data, xScaleType);
|
|
1610
|
+
const xPadding = getDomainPaddingForMarkers(+xMin, +xMax, xScaleType);
|
|
1611
|
+
const scaleXMin = xMin instanceof Date ? new Date(+xMin - xPadding.start) : xMin - xPadding.start;
|
|
1612
|
+
const scaleXMax = xMax instanceof Date ? new Date(+xMax + xPadding.end) : xMax + xPadding.end;
|
|
1613
|
+
const extraXPixels = Math.min(Math.abs(xScale(xMin) - xScale(scaleXMin)), Math.abs(xScale(scaleXMax) - xScale(xMax)));
|
|
1614
|
+
const yScaleType = useSecondaryYScale ? secondaryYScaleType : primaryYScaleType;
|
|
1615
|
+
const { startValue: yMin, endValue: yMax } = findNumericMinMaxOfY(data, undefined, useSecondaryYScale, yScaleType);
|
|
1616
|
+
const yPadding = getDomainPaddingForMarkers(yMin, yMax, yScaleType);
|
|
1617
|
+
const scaleYMin = yMin - yPadding.start;
|
|
1618
|
+
const scaleYMax = yMax + yPadding.end;
|
|
1619
|
+
const yScale = useSecondaryYScale ? yScaleSecondary : yScalePrimary;
|
|
1620
|
+
const extraYPixels = Math.min(Math.abs(yScale(scaleYMin) - yScale(yMin)), Math.abs(yScale(yMax) - yScale(scaleYMax)));
|
|
1621
|
+
return Math.min(extraXPixels, extraYPixels);
|
|
1622
|
+
};
|