Automattic / Automattic/jetpack

Allow custom domain and padding in yScale in LineChart

Open
#41,255 2 comments 0 reactions 0 assignees View on GitHub
[JS Package] Charts [Pri] Normal Enhancement
Dominant language
PHP
Stars
1.8k
Forks
898
Avg merge
1d 18h
Merged PRs (30d)
774

Description

### Impacted plugin

None / Other

### What

I would like to specify custom `domain` for the yScale in LineChart so that it appears nicer for my use case.

### How

Currently the `yScale` for the LineChart is set like this:

https://github.com/Automattic/jetpack/blob/92cd80bda476cd6f3f63eae1b81aca60fa68a40c/projects/js-packages/charts/src/components/line-chart/line-chart.tsx#L127

The code generates line charts like these:

![Image](https://github.com/user-attachments/assets/88aeb858-0f0e-4d78-956a-3a1375ee7c64)

![Image](https://github.com/user-attachments/assets/5327c6d4-3c11-4176-a5f7-7e9db97ee6fe)

- The yScale above does not allow us to specify a custom domain (for reference, see https://d3js.org/d3-scale/linear).
- It starts with 0 by default. If let's say we have a line with 3 data points `[13000, 14000, 15000]`, the y-axis will start at 0, and there would be a big space gap between the line series and the bottom x-axis.
- As shown in the screenshots above, the line series may go above the visible max value on the y-axis or go below the visible min value on the y-axis. It's not clear what is the real max value or min value in the line series. It would be better if the line series is contained within the min and max values of the y-axis.

In WooCommerce Analytics, we would like to achieve a line chart like this:

![Image](https://github.com/user-attachments/assets/2d015fe2-c3d7-45af-83c7-7cbed2fd8df5)

We have an implementation that works like this:

```js
/**
* Calculate a nice domain for the y-axis.
*
* This is so that the chart looks nice and the lines don't touch the edge of the chart.
*/
const calculateNiceDomain = ( values: Array< number > ) => {
const minValue = Math.min( ...values );
const maxValue = Math.max( ...values );

// Add 10% padding
const range = maxValue - minValue;
const padding = range * 0.1;

// Round to nice numbers
const niceMin = Math.floor( minValue - padding );
const niceMax = Math.ceil( maxValue + padding );

return [ niceMin, niceMax ];
};

// in component:
const allYValues = lines
.map( ( line ) => line.data.map( line.yAccessor ) )
.flat();

const yDomain = calculateNiceDomain( allYValues );

```

The above produces a line chart with yScale like this:

![Image](https://github.com/user-attachments/assets/aee602a8-7821-423b-974f-9a200bce1f5c)

It would be great if we can incorporate this into LineChart component.

Contributor guide

Open the contributing guide

Research direction

Read projects/js-packages/charts/src/components/line-chart/line-chart.tsx around line 127 and inspect how the LineChart component currently constructs its yScale. Determine how custom domain and padding should be exposed, then verify that charts can use those values and keep the plotted series within the visible y-axis range.

Written by the indexing model from the issue text.

Assessment

Tech stack
d3js, react, typescript
Domain
data-visualization, frontend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.