@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/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, AreaSeries as AreaSeries2, AreaStack, Grid as Grid2, Axis as Axis2 } from "@visx/xychart";
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"]]: animation && !prefersReducedMotion
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(AreaStack, {
4442
+ }) : null, !allSeriesHidden && stacked && /* @__PURE__ */ _jsx17(AnimatedAreaStack, {
4352
4443
  curve,
4353
4444
  offset: stackOffset,
4354
4445
  renderLine: resolvedWithStroke,
4355
- children: visibleSeries.map(({
4356
- series: seriesData,
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,