@automattic/charts 1.4.0 → 1.4.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 +9 -5
- package/dist/index.cjs +140 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +98 -53
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/charts/area-chart/area-chart.tsx +124 -54
- package/src/charts/area-chart/test/area-chart.test.tsx +203 -0
- package/AGENTS.md +0 -78
package/dist/index.js
CHANGED
|
@@ -467,7 +467,7 @@ var require_es6 = __commonJS({
|
|
|
467
467
|
|
|
468
468
|
// src/charts/area-chart/area-chart.tsx
|
|
469
469
|
import { formatNumberCompact as formatNumberCompact3 } from "@automattic/number-formatters";
|
|
470
|
-
import { XYChart as XYChart2,
|
|
470
|
+
import { XYChart as XYChart2, AnimatedAreaSeries, AnimatedAreaStack, Grid as Grid2, Axis as Axis2 } from "@visx/xychart";
|
|
471
471
|
import { __ as __4 } from "@wordpress/i18n";
|
|
472
472
|
import clsx5 from "clsx";
|
|
473
473
|
import { useMemo as useMemo16, useContext as useContext13, forwardRef as forwardRef5, useImperativeHandle as useImperativeHandle4, useState as useState10, useRef as useRef10, useCallback as useCallback9 } from "react";
|
|
@@ -4203,6 +4203,42 @@ var AreaChartInternal = /* @__PURE__ */ forwardRef5(({
|
|
|
4203
4203
|
chartRef,
|
|
4204
4204
|
totalPoints: dataSorted[0]?.data.length || 0
|
|
4205
4205
|
});
|
|
4206
|
+
const fixedYDomain = useMemo16(() => {
|
|
4207
|
+
if (!legendInteractive || !dataSorted.length || !dataSorted[0].data.length || stacked && stackOffset !== "none") {
|
|
4208
|
+
return void 0;
|
|
4209
|
+
}
|
|
4210
|
+
if (stacked) {
|
|
4211
|
+
const numPoints = Math.max(...dataSorted.map((s) => s.data.length));
|
|
4212
|
+
let posMax = 0;
|
|
4213
|
+
let negMin = 0;
|
|
4214
|
+
for (let i = 0; i < numPoints; i++) {
|
|
4215
|
+
let posSum = 0;
|
|
4216
|
+
let negSum = 0;
|
|
4217
|
+
for (const series of dataSorted) {
|
|
4218
|
+
const v = Number(series.data[i]?.value);
|
|
4219
|
+
if (Number.isNaN(v)) continue;
|
|
4220
|
+
if (v >= 0) posSum += v;
|
|
4221
|
+
else negSum += v;
|
|
4222
|
+
}
|
|
4223
|
+
if (posSum > posMax) posMax = posSum;
|
|
4224
|
+
if (negSum < negMin) negMin = negSum;
|
|
4225
|
+
}
|
|
4226
|
+
return [negMin, posMax];
|
|
4227
|
+
}
|
|
4228
|
+
let max = -Infinity;
|
|
4229
|
+
let min = Infinity;
|
|
4230
|
+
for (const series of dataSorted) {
|
|
4231
|
+
for (const point of series.data) {
|
|
4232
|
+
const v = Number(point?.value);
|
|
4233
|
+
if (!Number.isNaN(v)) {
|
|
4234
|
+
if (v > max) max = v;
|
|
4235
|
+
if (v < min) min = v;
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
4239
|
+
if (max === -Infinity) return void 0;
|
|
4240
|
+
return [Math.min(0, min), max];
|
|
4241
|
+
}, [dataSorted, stacked, stackOffset, legendInteractive]);
|
|
4206
4242
|
const chartOptions = useMemo16(() => {
|
|
4207
4243
|
const formatter = options?.axis?.x?.tickFormat || getFormatter(dataSorted);
|
|
4208
4244
|
return {
|
|
@@ -4231,10 +4267,13 @@ var AreaChartInternal = /* @__PURE__ */ forwardRef5(({
|
|
|
4231
4267
|
nice: true,
|
|
4232
4268
|
// Stacked areas should always include zero so the baseline is meaningful.
|
|
4233
4269
|
zero: stacked,
|
|
4270
|
+
...fixedYDomain ? {
|
|
4271
|
+
domain: fixedYDomain
|
|
4272
|
+
} : {},
|
|
4234
4273
|
...options?.yScale
|
|
4235
4274
|
}
|
|
4236
4275
|
};
|
|
4237
|
-
}, [options, dataSorted, width, stacked]);
|
|
4276
|
+
}, [options, dataSorted, width, stacked, fixedYDomain]);
|
|
4238
4277
|
const defaultMargin = useChartMargin(height, chartOptions, dataSorted, theme);
|
|
4239
4278
|
const error = validateData2(dataSorted);
|
|
4240
4279
|
const isDataValid = !error;
|
|
@@ -4257,10 +4296,33 @@ var AreaChartInternal = /* @__PURE__ */ forwardRef5(({
|
|
|
4257
4296
|
metadata: chartMetadata
|
|
4258
4297
|
});
|
|
4259
4298
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
4299
|
+
const animationEnabled = !!animation && !prefersReducedMotion;
|
|
4260
4300
|
const accessors = {
|
|
4261
4301
|
xAccessor: (d) => d?.date,
|
|
4262
4302
|
yAccessor: (d) => d?.value
|
|
4263
4303
|
};
|
|
4304
|
+
const zeroYAccessor = useCallback9(() => 0, []);
|
|
4305
|
+
const visibleLabels = useMemo16(() => new Set(seriesWithVisibility.filter((s) => s.isVisible).map((s) => s.series.label)), [seriesWithVisibility]);
|
|
4306
|
+
const filteredRenderTooltip = useCallback9((params) => {
|
|
4307
|
+
if (!legendInteractive) return renderTooltip(params);
|
|
4308
|
+
const datumByKey = params?.tooltipData?.datumByKey;
|
|
4309
|
+
if (!datumByKey) return renderTooltip(params);
|
|
4310
|
+
const filtered = Object.fromEntries(Object.entries(datumByKey).filter(([key]) => visibleLabels.has(key)));
|
|
4311
|
+
if (Object.keys(filtered).length === 0) return null;
|
|
4312
|
+
const nearestDatum = params?.tooltipData?.nearestDatum;
|
|
4313
|
+
const nextNearest = nearestDatum && visibleLabels.has(nearestDatum.key) ? nearestDatum : {
|
|
4314
|
+
...Object.values(filtered)[0],
|
|
4315
|
+
distance: nearestDatum?.distance ?? 0
|
|
4316
|
+
};
|
|
4317
|
+
return renderTooltip({
|
|
4318
|
+
...params,
|
|
4319
|
+
tooltipData: {
|
|
4320
|
+
...params.tooltipData,
|
|
4321
|
+
datumByKey: filtered,
|
|
4322
|
+
nearestDatum: nextNearest
|
|
4323
|
+
}
|
|
4324
|
+
});
|
|
4325
|
+
}, [renderTooltip, legendInteractive, visibleLabels]);
|
|
4264
4326
|
const resolvedFillOpacity = fillOpacity ?? (stacked ? 0.85 : 0.4);
|
|
4265
4327
|
const resolvedWithStroke = withStroke ?? !stacked;
|
|
4266
4328
|
if (error) {
|
|
@@ -4286,6 +4348,35 @@ var AreaChartInternal = /* @__PURE__ */ forwardRef5(({
|
|
|
4286
4348
|
isVisible
|
|
4287
4349
|
}) => isVisible);
|
|
4288
4350
|
const curve = getCurveType(curveType, smoothing);
|
|
4351
|
+
const renderSeries = ({
|
|
4352
|
+
series: seriesData,
|
|
4353
|
+
index,
|
|
4354
|
+
isVisible
|
|
4355
|
+
}) => {
|
|
4356
|
+
const {
|
|
4357
|
+
color,
|
|
4358
|
+
lineStyles
|
|
4359
|
+
} = getElementStyles({
|
|
4360
|
+
data: seriesData,
|
|
4361
|
+
index
|
|
4362
|
+
});
|
|
4363
|
+
return /* @__PURE__ */ _jsx17(AnimatedAreaSeries, {
|
|
4364
|
+
dataKey: seriesData?.label,
|
|
4365
|
+
data: seriesData.data,
|
|
4366
|
+
xAccessor: accessors.xAccessor,
|
|
4367
|
+
yAccessor: isVisible || !legendInteractive ? accessors.yAccessor : zeroYAccessor,
|
|
4368
|
+
fill: color,
|
|
4369
|
+
fillOpacity: resolvedFillOpacity,
|
|
4370
|
+
...stacked ? {} : {
|
|
4371
|
+
renderLine: resolvedWithStroke,
|
|
4372
|
+
curve
|
|
4373
|
+
},
|
|
4374
|
+
lineProps: {
|
|
4375
|
+
stroke: color,
|
|
4376
|
+
...lineStyles
|
|
4377
|
+
}
|
|
4378
|
+
}, seriesData?.label || index);
|
|
4379
|
+
};
|
|
4289
4380
|
return /* @__PURE__ */ _jsx17(SingleChartContext.Provider, {
|
|
4290
4381
|
value: {
|
|
4291
4382
|
chartId,
|
|
@@ -4299,7 +4390,7 @@ var AreaChartInternal = /* @__PURE__ */ forwardRef5(({
|
|
|
4299
4390
|
legendChildren,
|
|
4300
4391
|
gap,
|
|
4301
4392
|
className: clsx5("area-chart", area_chart_module_default["area-chart"], {
|
|
4302
|
-
[area_chart_module_default["area-chart--animated"]]:
|
|
4393
|
+
[area_chart_module_default["area-chart--animated"]]: animationEnabled
|
|
4303
4394
|
}, className),
|
|
4304
4395
|
style: {
|
|
4305
4396
|
width,
|
|
@@ -4348,63 +4439,17 @@ var AreaChartInternal = /* @__PURE__ */ forwardRef5(({
|
|
|
4348
4439
|
width,
|
|
4349
4440
|
height: chartHeight,
|
|
4350
4441
|
children: __4("All series are hidden. Click legend items to show data.", "jetpack-charts")
|
|
4351
|
-
}) : null, !allSeriesHidden && stacked && /* @__PURE__ */ _jsx17(
|
|
4442
|
+
}) : null, !allSeriesHidden && stacked && /* @__PURE__ */ _jsx17(AnimatedAreaStack, {
|
|
4352
4443
|
curve,
|
|
4353
4444
|
offset: stackOffset,
|
|
4354
4445
|
renderLine: resolvedWithStroke,
|
|
4355
|
-
children:
|
|
4356
|
-
|
|
4357
|
-
index
|
|
4358
|
-
}) => {
|
|
4359
|
-
const {
|
|
4360
|
-
color,
|
|
4361
|
-
lineStyles
|
|
4362
|
-
} = getElementStyles({
|
|
4363
|
-
data: seriesData,
|
|
4364
|
-
index
|
|
4365
|
-
});
|
|
4366
|
-
return /* @__PURE__ */ _jsx17(AreaSeries2, {
|
|
4367
|
-
dataKey: seriesData?.label,
|
|
4368
|
-
data: seriesData.data,
|
|
4369
|
-
...accessors,
|
|
4370
|
-
fill: color,
|
|
4371
|
-
fillOpacity: resolvedFillOpacity,
|
|
4372
|
-
lineProps: {
|
|
4373
|
-
stroke: color,
|
|
4374
|
-
...lineStyles
|
|
4375
|
-
}
|
|
4376
|
-
}, seriesData?.label || index);
|
|
4377
|
-
})
|
|
4378
|
-
}), !allSeriesHidden && !stacked && visibleSeries.map(({
|
|
4379
|
-
series: seriesData,
|
|
4380
|
-
index
|
|
4381
|
-
}) => {
|
|
4382
|
-
const {
|
|
4383
|
-
color,
|
|
4384
|
-
lineStyles
|
|
4385
|
-
} = getElementStyles({
|
|
4386
|
-
data: seriesData,
|
|
4387
|
-
index
|
|
4388
|
-
});
|
|
4389
|
-
return /* @__PURE__ */ _jsx17(AreaSeries2, {
|
|
4390
|
-
dataKey: seriesData?.label,
|
|
4391
|
-
data: seriesData.data,
|
|
4392
|
-
...accessors,
|
|
4393
|
-
fill: color,
|
|
4394
|
-
fillOpacity: resolvedFillOpacity,
|
|
4395
|
-
renderLine: resolvedWithStroke,
|
|
4396
|
-
curve,
|
|
4397
|
-
lineProps: {
|
|
4398
|
-
stroke: color,
|
|
4399
|
-
...lineStyles
|
|
4400
|
-
}
|
|
4401
|
-
}, seriesData?.label || index);
|
|
4402
|
-
}), withTooltips && /* @__PURE__ */ _jsxs7(_Fragment4, {
|
|
4446
|
+
children: seriesWithVisibility.map(renderSeries)
|
|
4447
|
+
}), !allSeriesHidden && !stacked && seriesWithVisibility.map(renderSeries), withTooltips && /* @__PURE__ */ _jsxs7(_Fragment4, {
|
|
4403
4448
|
children: [/* @__PURE__ */ _jsx17(AccessibleTooltip, {
|
|
4404
4449
|
detectBounds: true,
|
|
4405
4450
|
snapTooltipToDatumX: true,
|
|
4406
4451
|
snapTooltipToDatumY: !stacked,
|
|
4407
|
-
renderTooltip,
|
|
4452
|
+
renderTooltip: filteredRenderTooltip,
|
|
4408
4453
|
showVerticalCrosshair: withTooltipCrosshairs?.showVertical,
|
|
4409
4454
|
showHorizontalCrosshair: withTooltipCrosshairs?.showHorizontal,
|
|
4410
4455
|
selectedIndex,
|