[ML] Explain log rate spikes: Add DualBrush component. (#135318)

Adds the code for the dual brush component for users to be able select log rate spikes in histogram charts.
For this PR a new package @kbn/aiops-components was created that also includes ProgressControls from @kbn/aiops-utils now. The reason for this is: The brush component includes code from d3 that cannot be imported on the server side which aiops-utils was also used for.
This commit is contained in:
Walter Rafelsberger 2022-07-06 14:08:05 +02:00 committed by GitHub
parent f7aaae801f
commit 04907932c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 634 additions and 19 deletions

View file

@ -129,6 +129,7 @@
"@hapi/inert": "^6.0.4",
"@hapi/wreck": "^17.1.0",
"@kbn/ace": "link:bazel-bin/packages/kbn-ace",
"@kbn/aiops-components": "link:bazel-bin/x-pack/packages/ml/aiops_components",
"@kbn/aiops-utils": "link:bazel-bin/x-pack/packages/ml/aiops_utils",
"@kbn/alerts": "link:bazel-bin/packages/kbn-alerts",
"@kbn/analytics": "link:bazel-bin/packages/kbn-analytics",
@ -299,11 +300,14 @@
"cytoscape-dagre": "^2.2.2",
"d3": "3.5.17",
"d3-array": "1.2.4",
"d3-brush": "^3.0.0",
"d3-cloud": "1.2.5",
"d3-interpolate": "^3.0.1",
"d3-scale": "^2.2.2",
"d3-selection": "^3.0.0",
"d3-shape": "^1.1.0",
"d3-time": "^1.1.0",
"d3-transition": "^3.0.1",
"dedent": "^0.7.0",
"deep-freeze-strict": "^1.1.1",
"deepmerge": "^4.2.2",
@ -615,11 +619,14 @@
"@types/cytoscape": "^3.14.0",
"@types/d3": "^3.5.43",
"@types/d3-array": "^1.2.7",
"@types/d3-brush": "^3.0.0",
"@types/d3-interpolate": "^2.0.0",
"@types/d3-scale": "^2.2.6",
"@types/d3-selection": "^3.0.0",
"@types/d3-shape": "^1.3.1",
"@types/d3-time": "^1.0.10",
"@types/d3-time-format": "^2.1.1",
"@types/d3-transition": "^3.0.1",
"@types/dedent": "^0.7.0",
"@types/deep-freeze-strict": "^1.1.0",
"@types/delete-empty": "^2.0.0",
@ -664,6 +671,7 @@
"@types/json5": "^0.0.30",
"@types/jsonwebtoken": "^8.5.6",
"@types/kbn__ace": "link:bazel-bin/packages/kbn-ace/npm_module_types",
"@types/kbn__aiops-components": "link:bazel-bin/x-pack/packages/ml/aiops_components/npm_module_types",
"@types/kbn__aiops-utils": "link:bazel-bin/x-pack/packages/ml/aiops_utils/npm_module_types",
"@types/kbn__alerts": "link:bazel-bin/packages/kbn-alerts/npm_module_types",
"@types/kbn__analytics": "link:bazel-bin/packages/kbn-analytics/npm_module_types",

View file

@ -176,6 +176,7 @@ filegroup(
"//packages/shared-ux/page/kibana_no_data:build",
"//packages/shared-ux/prompt/no_data_views:build",
"//x-pack/packages/ml/agg_utils:build",
"//x-pack/packages/ml/aiops_components:build",
"//x-pack/packages/ml/aiops_utils:build",
"//x-pack/packages/ml/is_populated_object:build",
"//x-pack/packages/ml/string_hash:build",
@ -338,6 +339,7 @@ filegroup(
"//packages/shared-ux/page/kibana_no_data:build_types",
"//packages/shared-ux/prompt/no_data_views:build_types",
"//x-pack/packages/ml/agg_utils:build_types",
"//x-pack/packages/ml/aiops_components:build_types",
"//x-pack/packages/ml/aiops_utils:build_types",
"//x-pack/packages/ml/is_populated_object:build_types",
"//x-pack/packages/ml/string_hash:build_types",

View file

@ -38,7 +38,7 @@
"xpack.main": "legacy/plugins/xpack_main",
"xpack.maps": ["plugins/maps"],
"xpack.aiops": [
"packages/ml/aiops_utils",
"packages/ml/aiops_components",
"plugins/aiops"
],
"xpack.ml": ["plugins/ml"],

View file

@ -0,0 +1,145 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_DIRNAME = "aiops_components"
PKG_REQUIRE_NAME = "@kbn/aiops-components"
SOURCE_FILES = glob(
[
"src/**/*.scss",
"src/**/*.ts",
"src/**/*.tsx",
],
exclude = [
"**/*.test.*",
],
)
SRCS = SOURCE_FILES
filegroup(
name = "srcs",
srcs = SRCS,
)
NPM_MODULE_EXTRA_FILES = [
"package.json",
]
# In this array place runtime dependencies, including other packages and NPM packages
# which must be available for this code to run.
#
# To reference other packages use:
# "//repo/relative/path/to/package"
# eg. "//packages/kbn-utils"
#
# To reference a NPM package use:
# "@npm//name-of-package"
# eg. "@npm//lodash"
RUNTIME_DEPS = [
"@npm//d3-brush",
"@npm//d3-scale",
"@npm//d3-selection",
"@npm//d3-transition",
"@npm//react",
"@npm//@elastic/charts",
"@npm//@elastic/eui",
"//packages/kbn-i18n-react",
"//x-pack/packages/ml/aiops_utils",
]
# In this array place dependencies necessary to build the types, which will include the
# :npm_module_types target of other packages and packages from NPM, including @types/*
# packages.
#
# To reference the types for another package use:
# "//repo/relative/path/to/package:npm_module_types"
# eg. "//packages/kbn-utils:npm_module_types"
#
# References to NPM packages work the same as RUNTIME_DEPS
TYPES_DEPS = [
"@npm//@types/d3-brush",
"@npm//@types/d3-scale",
"@npm//@types/d3-selection",
"@npm//@types/d3-transition",
"@npm//@types/node",
"@npm//@types/jest",
"@npm//@types/react",
"@npm//@elastic/charts",
"@npm//@elastic/eui",
"//packages/kbn-i18n-react:npm_module_types",
"//x-pack/packages/ml/aiops_utils:npm_module_types",
]
jsts_transpiler(
name = "target_node",
srcs = SRCS,
build_pkg_name = package_name(),
)
jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
web = True,
additional_args = [
"--copy-files",
"--quiet"
],
)
ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.bazel.json",
],
)
ts_project(
name = "tsc_types",
args = ['--pretty'],
srcs = SRCS,
deps = TYPES_DEPS,
declaration = True,
emit_declaration_only = True,
out_dir = "target_types",
root_dir = "src",
tsconfig = ":tsconfig",
)
js_library(
name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
pkg_npm(
name = "npm_module",
deps = [":" + PKG_DIRNAME],
)
filegroup(
name = "build",
srcs = [":npm_module"],
visibility = ["//visibility:public"],
)
pkg_npm_types(
name = "npm_module_types",
srcs = SRCS,
deps = [":tsc_types"],
package_name = PKG_REQUIRE_NAME,
tsconfig = ":tsconfig",
visibility = ["//visibility:public"],
)
filegroup(
name = "build_types",
srcs = [":npm_module_types"],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,5 @@
# @kbn/aiops-components
React components for AIOps related efforts.
https://docs.elastic.dev/kibana-dev-docs/api/kbn-aiops-components

View file

@ -0,0 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../../../..',
roots: ['<rootDir>/x-pack/packages/ml/aiops_components'],
};

View file

@ -0,0 +1,11 @@
{
"name": "@kbn/aiops-components",
"description": "React components for AIOps related efforts.",
"author": "Machine Learning UI",
"homepage": "https://docs.elastic.dev/kibana-dev-docs/api/kbn-aiops-components",
"private": true,
"version": "1.0.0",
"main": "./target_node/index.js",
"browser": "./target_web/index.js",
"license": "SSPL-1.0 OR Elastic License 2.0"
}

View file

@ -0,0 +1,11 @@
.aiops-dual-brush {
.handle {
fill: $euiColorDarkShade;
}
.brush .selection {
stroke: none;
fill: $euiColorDarkShade !important;
opacity: .5 !important;
}
}

View file

@ -0,0 +1,264 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useEffect, useRef } from 'react';
import * as d3Brush from 'd3-brush';
import * as d3Scale from 'd3-scale';
import * as d3Selection from 'd3-selection';
import * as d3Transition from 'd3-transition';
import type { WindowParameters } from '@kbn/aiops-utils';
import './dual_brush.scss';
const { brush, brushSelection, brushX } = d3Brush;
const { scaleLinear } = d3Scale;
const { select: d3Select } = d3Selection;
// Import fix to apply correct types for the use of d3.select(this).transition()
d3Select.prototype.transition = d3Transition.transition;
const d3 = {
brush,
brushSelection,
brushX,
scaleLinear,
select: d3Select,
transition: d3Transition,
};
const isBrushXSelection = (arg: unknown): arg is [number, number] => {
return (
Array.isArray(arg) &&
arg.length === 2 &&
typeof arg[0] === 'number' &&
typeof arg[1] === 'number'
);
};
interface DualBrush {
id: string;
brush: d3Brush.BrushBehavior<DualBrush>;
start: number;
end: number;
}
const BRUSH_HEIGHT = 20;
const BRUSH_MARGIN = 4;
const BRUSH_HANDLE_SIZE = 4;
const BRUSH_HANDLE_ROUNDED_CORNER = 2;
interface DualBrushProps {
windowParameters: WindowParameters;
min: number;
max: number;
onChange?: (windowParameters: WindowParameters) => void;
marginLeft: number;
width: number;
}
export function DualBrush({
windowParameters,
min,
max,
onChange,
marginLeft,
width,
}: DualBrushProps) {
const d3BrushContainer = useRef(null);
const brushes = useRef<DualBrush[]>([]);
const widthRef = useRef(width);
const { baselineMin, baselineMax, deviationMin, deviationMax } = windowParameters;
useEffect(() => {
if (d3BrushContainer.current && width > 0) {
const gBrushes = d3.select(d3BrushContainer.current);
function newBrush(id: string, start: number, end: number) {
brushes.current.push({
id,
brush: d3.brushX<DualBrush>().handleSize(BRUSH_HANDLE_SIZE).on('end', brushend),
start,
end,
});
function brushend(this: d3Selection.BaseType) {
const currentWidth = widthRef.current;
const x = d3.scaleLinear().domain([min, max]).rangeRound([0, currentWidth]);
const px2ts = (px: number) => Math.round(x.invert(px));
const xMin = x(min) ?? 0;
const xMax = x(max) ?? 0;
const minExtentPx = Math.round((xMax - xMin) / 100);
const baselineBrush = d3.select('#brush-baseline');
const baselineSelection = d3.brushSelection(baselineBrush.node() as SVGGElement);
const deviationBrush = d3.select('#brush-deviation');
const deviationSelection = d3.brushSelection(deviationBrush.node() as SVGGElement);
if (!isBrushXSelection(deviationSelection) || !isBrushXSelection(baselineSelection)) {
return;
}
const baselineOverlay = baselineBrush.selectAll('.overlay');
const deviationOverlay = deviationBrush.selectAll('.overlay');
let baselineWidth;
let deviationWidth;
baselineOverlay.each((d, i, n) => {
baselineWidth = d3.select(n[i]).attr('width');
});
deviationOverlay.each((d, i, n) => {
deviationWidth = d3.select(n[i]).attr('width');
});
if (baselineWidth !== deviationWidth) {
return;
}
const newWindowParameters = {
baselineMin: px2ts(baselineSelection[0]),
baselineMax: px2ts(baselineSelection[1]),
deviationMin: px2ts(deviationSelection[0]),
deviationMax: px2ts(deviationSelection[1]),
};
if (
id === 'deviation' &&
deviationSelection &&
baselineSelection &&
deviationSelection[0] - minExtentPx < baselineSelection[1]
) {
const newDeviationMin = baselineSelection[1] + minExtentPx;
const newDeviationMax = Math.max(deviationSelection[1], newDeviationMin + minExtentPx);
newWindowParameters.deviationMin = px2ts(newDeviationMin);
newWindowParameters.deviationMax = px2ts(newDeviationMax);
d3.select(this)
.transition()
.duration(200)
// @ts-expect-error call doesn't allow the brush move function
.call(brushes.current[1].brush.move, [newDeviationMin, newDeviationMax]);
} else if (
id === 'baseline' &&
deviationSelection &&
baselineSelection &&
deviationSelection[0] < baselineSelection[1] + minExtentPx
) {
const newBaselineMax = deviationSelection[0] - minExtentPx;
const newBaselineMin = Math.min(baselineSelection[0], newBaselineMax - minExtentPx);
newWindowParameters.baselineMin = px2ts(newBaselineMin);
newWindowParameters.baselineMax = px2ts(newBaselineMax);
d3.select(this)
.transition()
.duration(200)
// @ts-expect-error call doesn't allow the brush move function
.call(brushes.current[0].brush.move, [newBaselineMin, newBaselineMax]);
}
brushes.current[0].start = newWindowParameters.baselineMin;
brushes.current[0].end = newWindowParameters.baselineMax;
brushes.current[1].start = newWindowParameters.deviationMin;
brushes.current[1].end = newWindowParameters.deviationMax;
if (onChange) {
onChange(newWindowParameters);
}
drawBrushes();
}
}
function drawBrushes() {
const mlBrushSelection = gBrushes
.selectAll('.brush')
.data<DualBrush>(brushes.current, (d) => (d as DualBrush).id);
// Set up new brushes
mlBrushSelection
.enter()
.insert('g', '.brush')
.attr('class', 'brush')
.attr('id', (b: DualBrush) => {
return 'brush-' + b.id;
})
.each((brushObject: DualBrush, i, n) => {
const x = d3.scaleLinear().domain([min, max]).rangeRound([0, widthRef.current]);
brushObject.brush(d3.select(n[i]));
const xStart = x(brushObject.start) ?? 0;
const xEnd = x(brushObject.end) ?? 0;
brushObject.brush.move(d3.select(n[i]), [xStart, xEnd]);
});
// disable drag-select to reset a brush's selection
mlBrushSelection
.attr('class', 'brush')
.selectAll('.overlay')
.attr('width', width)
.style('pointer-events', 'none');
mlBrushSelection
.selectAll('.handle')
.attr('rx', BRUSH_HANDLE_ROUNDED_CORNER)
.attr('ry', BRUSH_HANDLE_ROUNDED_CORNER);
mlBrushSelection.exit().remove();
}
function updateBrushes() {
const mlBrushSelection = gBrushes
.selectAll('.brush')
.data<DualBrush>(brushes.current, (d) => (d as DualBrush).id);
mlBrushSelection.each(function (brushObject, i, n) {
const x = d3.scaleLinear().domain([min, max]).rangeRound([0, widthRef.current]);
brushObject.brush.extent([
[0, BRUSH_MARGIN],
[width, BRUSH_HEIGHT - BRUSH_MARGIN],
]);
brushObject.brush(d3.select(n[i] as SVGGElement));
const xStart = x(brushObject.start) ?? 0;
const xEnd = x(brushObject.end) ?? 0;
brushObject.brush.move(d3.select(n[i] as SVGGElement), [xStart, xEnd]);
});
}
if (brushes.current.length !== 2) {
widthRef.current = width;
newBrush('baseline', baselineMin, baselineMax);
newBrush('deviation', deviationMin, deviationMax);
} else {
if (widthRef.current !== width) {
widthRef.current = width;
updateBrushes();
}
}
drawBrushes();
}
}, [min, max, width, baselineMin, baselineMax, deviationMin, deviationMax, onChange]);
return (
<>
{width > 0 && (
<svg
className="aiops-dual-brush"
width={width}
height={BRUSH_HEIGHT}
style={{ marginLeft }}
>
<g className="brushes" width={width} ref={d3BrushContainer} />
</svg>
)}
</>
);
}

View file

@ -0,0 +1,46 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { FC } from 'react';
import { RectAnnotation } from '@elastic/charts';
import { useEuiTheme } from '@elastic/eui';
interface BrushAnnotationProps {
id: string;
min: number;
max: number;
}
export const DualBrushAnnotation: FC<BrushAnnotationProps> = ({ id, min, max }) => {
const { euiTheme } = useEuiTheme();
const { colors } = euiTheme;
return (
<RectAnnotation
dataValues={[
{
coordinates: {
x0: min,
x1: max,
y0: 0,
y1: 1000000000,
},
details: id,
},
]}
id={`rect_brush_annotation_${id}`}
style={{
strokeWidth: 1,
stroke: colors.lightShade,
fill: colors.lightShade,
opacity: 1,
}}
hideTooltips={true}
/>
);
};

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { DualBrushAnnotation } from './dual_brush_annotation';
export { DualBrush } from './dual_brush';

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { DualBrush, DualBrushAnnotation } from './dual_brush';
export { ProgressControls } from './progress_controls';

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { ProgressControls } from './progress_controls';

View file

@ -0,0 +1,22 @@
{
"extends": "../../../../tsconfig.bazel.json",
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "target_types",
"rootDir": "src",
"stripInternal": false,
"types": [
"@types/d3-brush",
"@types/d3-scale",
"@types/d3-selection",
"@types/d3-transition",
"jest",
"node",
"react"
]
},
"include": [
"src/**/*"
]
}

View file

@ -38,8 +38,6 @@ NPM_MODULE_EXTRA_FILES = [
# eg. "@npm//lodash"
RUNTIME_DEPS = [
"@npm//react",
"@npm//@elastic/eui",
"//packages/kbn-i18n-react",
"//packages/kbn-logging"
]
@ -56,8 +54,6 @@ TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/jest",
"@npm//@types/react",
"@npm//@elastic/eui",
"//packages/kbn-i18n-react:npm_module_types",
"//packages/kbn-logging:npm_module_types"
]

View file

@ -5,12 +5,11 @@
* 2.0.
*/
export { ProgressControls } from './components/progress_controls';
export { getWindowParameters } from './lib/get_window_parameters';
export type { WindowParameters } from './lib/get_window_parameters';
export { streamFactory } from './lib/stream_factory';
export { useFetchStream } from './lib/use_fetch_stream';
export { getWindowParameters } from './get_window_parameters';
export type { WindowParameters } from './get_window_parameters';
export { streamFactory } from './stream_factory';
export { useFetchStream } from './use_fetch_stream';
export type {
UseFetchStreamCustomReducerParams,
UseFetchStreamParamsDefault,
} from './lib/use_fetch_stream';
} from './use_fetch_stream';

View file

@ -10,7 +10,8 @@ import React, { useEffect, FC } from 'react';
import { EuiCodeBlock, EuiSpacer, EuiText } from '@elastic/eui';
import type { DataView } from '@kbn/data-views-plugin/public';
import { useFetchStream, ProgressControls } from '@kbn/aiops-utils';
import { ProgressControls } from '@kbn/aiops-components';
import { useFetchStream } from '@kbn/aiops-utils';
import type { WindowParameters } from '@kbn/aiops-utils';
import { useKibana } from '@kbn/kibana-react-plugin/public';

View file

@ -2944,6 +2944,10 @@
version "0.0.0"
uid ""
"@kbn/aiops-components@link:bazel-bin/x-pack/packages/ml/aiops_components":
version "0.0.0"
uid ""
"@kbn/aiops-utils@link:bazel-bin/x-pack/packages/ml/aiops_utils":
version "0.0.0"
uid ""
@ -5996,6 +6000,13 @@
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-1.2.7.tgz#34dc654d34fc058c41c31dbca1ed68071a8fcc17"
integrity sha512-51vHWuUyDOi+8XuwPrTw3cFqyh2Slg9y8COYkRfjCPG9TfYqY0hoNPzv/8BrcAy0FeQBzqEo/D/8Nk2caOQJnA==
"@types/d3-brush@^3.0.0":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.1.tgz#ae5f17ce391935ca88b29000e60ee20452c6357c"
integrity sha512-B532DozsiTuQMHu2YChdZU0qsFJSio3Q6jmBYGYNp3gMDzBmuFFgPt9qKA4VYuLZMp4qc6eX7IUFUEsvHiXZAw==
dependencies:
"@types/d3-selection" "*"
"@types/d3-color@*":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-2.0.1.tgz#570ea7f8b853461301804efa52bd790a640a26db"
@ -6020,6 +6031,11 @@
dependencies:
"@types/d3-time" "^1"
"@types/d3-selection@*", "@types/d3-selection@^3.0.0":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.2.tgz#23e48a285b24063630bbe312cc0cfe2276de4a59"
integrity sha512-d29EDd0iUBrRoKhPndhDY6U/PYxOWqgIZwKTooy2UkBfU7TNZNpRho0yLWPxlatQrFWk2mnTu71IZQ4+LRgKlQ==
"@types/d3-shape@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.1.tgz#1b4f92b7efd7306fe2474dc6ee94c0f0ed2e6ab6"
@ -6037,6 +6053,13 @@
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-1.0.10.tgz#d338c7feac93a98a32aac875d1100f92c7b61f4f"
integrity sha512-aKf62rRQafDQmSiv1NylKhIMmznsjRN+MnXRXTqHoqm0U/UZzVpdrtRnSIfdiLS616OuC1soYeX1dBg2n1u8Xw==
"@types/d3-transition@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.1.tgz#c9a96125567173d6163a6985b874f79154f4cc3d"
integrity sha512-Sv4qEI9uq3bnZwlOANvYK853zvpdKEm1yz9rcc8ZTsxvRklcs9Fx4YFuGA3gXoQN/c/1T6QkVNjhaRO/cWj94g==
dependencies:
"@types/d3-selection" "*"
"@types/d3@^3.5.43":
version "3.5.43"
resolved "https://registry.yarnpkg.com/@types/d3/-/d3-3.5.43.tgz#e9b4992817e0b6c5efaa7d6e5bb2cee4d73eab58"
@ -6468,6 +6491,10 @@
version "0.0.0"
uid ""
"@types/kbn__aiops-components@link:bazel-bin/x-pack/packages/ml/aiops_components/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__aiops-utils@link:bazel-bin/x-pack/packages/ml/aiops_utils/npm_module_types":
version "0.0.0"
uid ""
@ -12256,6 +12283,17 @@ d3-array@2, d3-array@^2.3.0:
dependencies:
internmap "^1.0.0"
d3-brush@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c"
integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==
dependencies:
d3-dispatch "1 - 3"
d3-drag "2 - 3"
d3-interpolate "1 - 3"
d3-selection "3"
d3-transition "3"
d3-cloud@1.2.5, d3-cloud@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/d3-cloud/-/d3-cloud-1.2.5.tgz#3e91564f2d27fba47fcc7d812eb5081ea24c603d"
@ -12302,6 +12340,14 @@ d3-delaunay@^6.0.2:
resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58"
integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==
"d3-drag@2 - 3":
version "3.0.0"
resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba"
integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==
dependencies:
d3-dispatch "1 - 3"
d3-selection "3"
d3-dsv@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.2.0.tgz#9d5f75c3a5f8abd611f74d3f5847b0d4338b885c"
@ -12320,6 +12366,11 @@ d3-dsv@^3.0.1:
iconv-lite "0.6"
rw "1"
"d3-ease@1 - 3":
version "1.0.6"
resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.6.tgz#ebdb6da22dfac0a22222f2d4da06f66c416a0ec0"
integrity sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ==
d3-force@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4"
@ -12384,6 +12435,13 @@ d3-interpolate@1, d3-interpolate@^1.1.4:
dependencies:
d3-color "1"
"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
dependencies:
d3-color "1 - 3"
"d3-interpolate@1.2.0 - 2":
version "2.0.1"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163"
@ -12391,13 +12449,6 @@ d3-interpolate@1, d3-interpolate@^1.1.4:
dependencies:
d3-color "1 - 2"
"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
dependencies:
d3-color "1 - 3"
d3-path@1:
version "1.0.9"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
@ -12474,6 +12525,11 @@ d3-scale@^4.0.2:
d3-time "2.1.1 - 3"
d3-time-format "2 - 4"
d3-selection@3, d3-selection@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31"
integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
d3-shape@^1.1.0, d3-shape@^1.2.0:
version "1.3.7"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
@ -12550,6 +12606,17 @@ d3-timer@^3.0.1:
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
d3-transition@3, d3-transition@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f"
integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
dependencies:
d3-color "1 - 3"
d3-dispatch "1 - 3"
d3-ease "1 - 3"
d3-interpolate "1 - 3"
d3-timer "1 - 3"
d3-voronoi@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297"