Skip to content

Commit 5473f20

Browse files
authored
[ML] Update some d3 v3 usage to d3 v4 packages. (#233638)
## Summary Part of #194171. Updates some imports still using the full `d3` v3 package to use smaller focused v4 versions instead. Note instead of plain `d3-color` we have to use `@elastic/kibana-d3-color` v2.0.1. Background: The original `d3-color` has a bug in v1+2, therefore Elastic manages its own fork of the packages with a fix. The original `d3-color` v3.1.0 fixes the bug too, but we cannot update to it yet because the package setup switched to ESM only which Kibana doesn't support yet. Related issue about ESM support (upvote!): #106868 ### New dependency `@types/d3-color` - **Purpose**: `@types/d3-color` provides typescript support for the `d3-color` package. So far `d3-color` was already present as a child dependency in `node_modules`, for example as part of `d3-scale`. This PR makes use of `d3-color` as a direct import that's why this adds the TS package too. - **Justification**: Since `d3-color` is already part of Kibana, we need `@types/d3-color` for TS support when using it as a direct import. - **Alternatives explored**: No real alternative since we need it for `d3-color`. - **Existing dependencies**: It augments `d3-color` with TS support. ### Note on increased async bundle size. Async bundle size increases with this PR by ~7.1KB. That's because we're still using full `d3` v3 in other places and now use more v4 packages on top of it. This refactor is related to the overall effort to [fix loading async bundles](#197967) on every page load so in the long run it will be a benefit. <img width="1798" height="324" alt="CleanShot 2025-09-02 at 09 14 49@2x" src="https://github.com/user-attachments/assets/2716d3de-a91e-45d6-9eb7-5b643b23d1cc" /> ### Checklist - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels.
1 parent 13b8a83 commit 5473f20

File tree

7 files changed

+36
-28
lines changed

7 files changed

+36
-28
lines changed

.buildkite/scripts/steps/security/third_party_packages.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ tree-dump
66
@a2a-js/sdk
77
@opentelemetry/exporter-metrics-otlp-http
88
inversify
9+
@types/d3-color

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
"@elastic/eui-amsterdam": "npm:@elastic/[email protected]",
130130
"@elastic/eui-theme-borealis": "3.3.2",
131131
"@elastic/filesaver": "1.1.2",
132+
"@elastic/kibana-d3-color": "npm:@elastic/[email protected]",
132133
"@elastic/monaco-esql": "^3.1.7",
133134
"@elastic/node-crypto": "^1.2.3",
134135
"@elastic/numeral": "^2.5.1",
@@ -1720,6 +1721,7 @@
17201721
"@types/d3": "^3.5.43",
17211722
"@types/d3-array": "^2.12.1",
17221723
"@types/d3-brush": "^3.0.0",
1724+
"@types/d3-color": "^2.0.1",
17231725
"@types/d3-interpolate": "^3.0.1",
17241726
"@types/d3-scale": "^3.3.0",
17251727
"@types/d3-selection": "^3.0.0",

renovate.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,9 +2229,11 @@
22292229
{
22302230
"groupName": "d3 modules",
22312231
"matchDepNames": [
2232+
"@elastic/kibana-d3-color",
22322233
"@types/d3",
22332234
"@types/d3-array",
22342235
"@types/d3-brush",
2236+
"@types/d3-color",
22352237
"@types/d3-interpolate",
22362238
"@types/d3-scale",
22372239
"@types/d3-selection",

tsconfig.base.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,6 +2361,9 @@
23612361
"@kbn/zod-helpers": ["src/platform/packages/shared/kbn-zod-helpers"],
23622362
"@kbn/zod-helpers/*": ["src/platform/packages/shared/kbn-zod-helpers/*"],
23632363
// END AUTOMATED PACKAGE LISTING
2364+
// Map @elastic/kibana-d3-color to @types/d3-color for TypeScript compatibility.
2365+
// Can be removed once we're able to update d3-color to the v3.1.0 ESM-only package.
2366+
"@elastic/kibana-d3-color": ["node_modules/@types/d3-color"],
23642367
// Allows for importing from `kibana` package for the exported types.
23652368
"@emotion/core": [
23662369
"typings/@emotion"

x-pack/platform/plugins/shared/ml/public/application/components/color_range_legend/use_color_range.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
* 2.0.
66
*/
77

8-
import d3 from 'd3';
8+
import { range } from 'd3-array';
9+
// TODO to be replaced with the original `d3-color` once we upgrade from v2 to v3
10+
import { rgb } from '@elastic/kibana-d3-color';
11+
import { scaleLinear, scaleSqrt } from 'd3-scale';
912

1013
import { useEuiTheme } from '@elastic/eui';
1114

@@ -19,7 +22,7 @@ import { i18n } from '@kbn/i18n';
1922
* considered influential.
2023
*
2124
* @param n number of influencers
22-
* @returns a function suitable as a preprocessor for d3.scale.linear()
25+
* @returns a function suitable as a preprocessor for scaleLinear()
2326
*/
2427
export const influencerColorScaleFactory = (n: number) => (t: number) => {
2528
// for 1 influencer or less we fall back to a plain linear scale.
@@ -125,7 +128,7 @@ const coloursYGB = [
125128
'#1F2D86',
126129
'#000086',
127130
];
128-
const colourRangeYGB = d3.range(0, 1, 1.0 / (coloursYGB.length - 1));
131+
const colourRangeYGB = range(0, 1, 1.0 / (coloursYGB.length - 1));
129132
colourRangeYGB.push(1);
130133

131134
const colorDomains = {
@@ -152,28 +155,25 @@ export const useColorRange = (
152155

153156
const colorRanges: Record<COLOR_RANGE, string[]> = {
154157
[COLOR_RANGE.BLUE]: [
155-
d3.rgb(euiTheme.colors.emptyShade).toString(),
156-
d3
157-
.rgb(
158-
// Amsterdam: euiTheme.colors.vis.euiColorVis1
159-
// Borealis: euiTheme.colors.vis.euiColorVis2
160-
euiTheme.flags.hasVisColorAdjustment
161-
? euiTheme.colors.vis.euiColorVis1
162-
: euiTheme.colors.vis.euiColorVis2
163-
)
164-
.toString(),
158+
rgb(euiTheme.colors.emptyShade).toString(),
159+
rgb(
160+
// Amsterdam: euiTheme.colors.vis.euiColorVis1
161+
// Borealis: euiTheme.colors.vis.euiColorVis2
162+
euiTheme.flags.hasVisColorAdjustment
163+
? euiTheme.colors.vis.euiColorVis1
164+
: euiTheme.colors.vis.euiColorVis2
165+
).toString(),
165166
],
166167
[COLOR_RANGE.RED]: [
167-
d3.rgb(euiTheme.colors.emptyShade).toString(),
168-
d3.rgb(euiTheme.colors.danger).toString(),
168+
rgb(euiTheme.colors.emptyShade).toString(),
169+
rgb(euiTheme.colors.danger).toString(),
169170
],
170171
[COLOR_RANGE.RED_GREEN]: ['red', 'green'],
171172
[COLOR_RANGE.GREEN_RED]: ['green', 'red'],
172173
[COLOR_RANGE.YELLOW_GREEN_BLUE]: coloursYGB,
173174
};
174175

175-
const linearScale = d3.scale
176-
.linear<string>()
176+
const linearScale = scaleLinear<string>()
177177
.domain(colorDomains[colorRange])
178178
.range(colorRanges[colorRange]);
179179
const influencerColorScale = influencerColorScaleFactory(featureCount);
@@ -182,8 +182,7 @@ export const useColorRange = (
182182
const scaleTypes = {
183183
[COLOR_RANGE_SCALE.LINEAR]: linearScale,
184184
[COLOR_RANGE_SCALE.INFLUENCER]: influencerScaleLinearWrapper,
185-
[COLOR_RANGE_SCALE.SQRT]: d3.scale
186-
.sqrt<string>()
185+
[COLOR_RANGE_SCALE.SQRT]: scaleSqrt<string>()
187186
.domain(colorDomains[colorRange])
188187
// typings for .range() incorrectly don't allow passing in a color extent.
189188
// @ts-ignore

x-pack/platform/plugins/shared/ml/public/application/components/job_selector/job_select_service_utils.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
import { i18n } from '@kbn/i18n';
99
import moment from 'moment';
10-
import d3 from 'd3';
10+
import { extent as d3Extent } from 'd3-array';
11+
import { scaleLinear } from 'd3-scale';
1112

1213
import type { Dictionary } from '../../../../common/types/common';
1314
import type { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs';
@@ -97,7 +98,7 @@ export function getTimeRangeFromSelection(jobs: MlJobWithTimeRange[], selection:
9798
}
9899
});
99100
if (times.length) {
100-
const extent = d3.extent(times);
101+
const extent = d3Extent(times);
101102
const selectedTime = {
102103
from: moment(extent[0]).toISOString(),
103104
to: moment(extent[1]).toISOString(),
@@ -118,7 +119,7 @@ export function normalizeTimes(
118119

119120
const min = Math.min(...jobsWithTimeRange.map((job) => +job.timeRange.from));
120121
const max = Math.max(...jobsWithTimeRange.map((job) => +job.timeRange.to));
121-
const ganttScale = d3.scale.linear().domain([min, max]).range([1, ganttBarWidth]);
122+
const ganttScale = scaleLinear().domain([min, max]).range([1, ganttBarWidth]);
122123

123124
jobs.forEach((job) => {
124125
if (job.timeRange.to !== undefined && job.timeRange.from !== undefined) {

yarn.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,11 @@
23122312
resolved "https://registry.yarnpkg.com/@elastic/filesaver/-/filesaver-1.1.2.tgz#1998ffb3cd89c9da4ec12a7793bfcae10e30c77a"
23132313
integrity sha512-YZbSufYFBhAj+S2cJgiKALoxIJevqXN2MSr6Yqr42rJdaPuM31cj6pUDwflkql1oDjupqD9la+MfxPFjXI1JFQ==
23142314

2315+
"@elastic/kibana-d3-color@npm:@elastic/[email protected]", "d3-color@1 - 2", "d3-color@npm:@elastic/[email protected]":
2316+
version "2.0.1"
2317+
resolved "https://registry.yarnpkg.com/@elastic/kibana-d3-color/-/kibana-d3-color-2.0.1.tgz#f83b9c2fea09273a918659de04d5e8098c82f65c"
2318+
integrity sha512-YZ8hV2bWNyYi833Yj3UWczmTxdHzmo/Xc2IVkNXr/ZqtkrTDlTLysCyJm7SfAt9iBy6EVRGWTn8cPz8QOY6Ixw==
2319+
23152320
"@elastic/makelogs@^6.1.1":
23162321
version "6.1.1"
23172322
resolved "https://registry.yarnpkg.com/@elastic/makelogs/-/makelogs-6.1.1.tgz#5bc173b16acdfd7844fd85c97824ddcffd67cfb3"
@@ -12522,7 +12527,7 @@
1252212527
dependencies:
1252312528
"@types/d3-selection" "*"
1252412529

12525-
"@types/d3-color@*":
12530+
"@types/d3-color@*", "@types/d3-color@^2.0.1":
1252612531
version "2.0.1"
1252712532
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-2.0.1.tgz#570ea7f8b853461301804efa52bd790a640a26db"
1252812533
integrity sha512-u7LTCL7RnaavFSmob2rIAJLNwu50i6gFwY9cHFr80BrQURYQBRkJ+Yv47nA3Fm7FeRhdWTiVTeqvSeOuMAOzBQ==
@@ -17571,11 +17576,6 @@ d3-collection@^1.0.7:
1757117576
resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e"
1757217577
integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==
1757317578

17574-
"d3-color@1 - 2", "d3-color@npm:@elastic/[email protected]":
17575-
version "2.0.1"
17576-
resolved "https://registry.yarnpkg.com/@elastic/kibana-d3-color/-/kibana-d3-color-2.0.1.tgz#f83b9c2fea09273a918659de04d5e8098c82f65c"
17577-
integrity sha512-YZ8hV2bWNyYi833Yj3UWczmTxdHzmo/Xc2IVkNXr/ZqtkrTDlTLysCyJm7SfAt9iBy6EVRGWTn8cPz8QOY6Ixw==
17578-
1757917579
"d3-color@1 - 3", d3-color@^3.1.0:
1758017580
version "3.1.0"
1758117581
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"

0 commit comments

Comments
 (0)