mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[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:
parent
f7aaae801f
commit
04907932c4
27 changed files with 634 additions and 19 deletions
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"],
|
||||
|
|
145
x-pack/packages/ml/aiops_components/BUILD.bazel
Normal file
145
x-pack/packages/ml/aiops_components/BUILD.bazel
Normal 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"],
|
||||
)
|
5
x-pack/packages/ml/aiops_components/README.md
Normal file
5
x-pack/packages/ml/aiops_components/README.md
Normal 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
|
12
x-pack/packages/ml/aiops_components/jest.config.js
Normal file
12
x-pack/packages/ml/aiops_components/jest.config.js
Normal 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'],
|
||||
};
|
11
x-pack/packages/ml/aiops_components/package.json
Normal file
11
x-pack/packages/ml/aiops_components/package.json
Normal 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"
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
.aiops-dual-brush {
|
||||
.handle {
|
||||
fill: $euiColorDarkShade;
|
||||
}
|
||||
|
||||
.brush .selection {
|
||||
stroke: none;
|
||||
fill: $euiColorDarkShade !important;
|
||||
opacity: .5 !important;
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -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';
|
9
x-pack/packages/ml/aiops_components/src/index.ts
Normal file
9
x-pack/packages/ml/aiops_components/src/index.ts
Normal 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';
|
|
@ -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';
|
22
x-pack/packages/ml/aiops_components/tsconfig.json
Normal file
22
x-pack/packages/ml/aiops_components/tsconfig.json
Normal 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/**/*"
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
]
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
81
yarn.lock
81
yarn.lock
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue