mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
Move Lens attribute builder to a package (#163422)
closes [#163491](https://github.com/elastic/kibana/issues/163491) ## Summary This PR creates a new package that contains a utility API that helps to generate the JSON with the attributes required to render a Lens chart with the `EmbeddableComponent`. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6e241a8b02
commit
281cc224c9
50 changed files with 786 additions and 477 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -460,6 +460,7 @@ src/plugins/kibana_usage_collection @elastic/kibana-core
|
||||||
src/plugins/kibana_utils @elastic/kibana-app-services
|
src/plugins/kibana_utils @elastic/kibana-app-services
|
||||||
x-pack/plugins/kubernetes_security @elastic/sec-cloudnative-integrations
|
x-pack/plugins/kubernetes_security @elastic/sec-cloudnative-integrations
|
||||||
packages/kbn-language-documentation-popover @elastic/kibana-visualizations
|
packages/kbn-language-documentation-popover @elastic/kibana-visualizations
|
||||||
|
packages/kbn-lens-embeddable-utils @elastic/infra-monitoring-ui
|
||||||
x-pack/plugins/lens @elastic/kibana-visualizations
|
x-pack/plugins/lens @elastic/kibana-visualizations
|
||||||
x-pack/plugins/license_api_guard @elastic/platform-deployment-management
|
x-pack/plugins/license_api_guard @elastic/platform-deployment-management
|
||||||
x-pack/plugins/license_management @elastic/platform-deployment-management
|
x-pack/plugins/license_management @elastic/platform-deployment-management
|
||||||
|
|
|
@ -481,6 +481,7 @@
|
||||||
"@kbn/kibana-utils-plugin": "link:src/plugins/kibana_utils",
|
"@kbn/kibana-utils-plugin": "link:src/plugins/kibana_utils",
|
||||||
"@kbn/kubernetes-security-plugin": "link:x-pack/plugins/kubernetes_security",
|
"@kbn/kubernetes-security-plugin": "link:x-pack/plugins/kubernetes_security",
|
||||||
"@kbn/language-documentation-popover": "link:packages/kbn-language-documentation-popover",
|
"@kbn/language-documentation-popover": "link:packages/kbn-language-documentation-popover",
|
||||||
|
"@kbn/lens-embeddable-utils": "link:packages/kbn-lens-embeddable-utils",
|
||||||
"@kbn/lens-plugin": "link:x-pack/plugins/lens",
|
"@kbn/lens-plugin": "link:x-pack/plugins/lens",
|
||||||
"@kbn/license-api-guard-plugin": "link:x-pack/plugins/license_api_guard",
|
"@kbn/license-api-guard-plugin": "link:x-pack/plugins/license_api_guard",
|
||||||
"@kbn/license-management-plugin": "link:x-pack/plugins/license_management",
|
"@kbn/license-management-plugin": "link:x-pack/plugins/license_management",
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
|
|
||||||
# Lens Attributes Builder
|
# @kbn/lens-embeddable-utils
|
||||||
|
|
||||||
The Lens Attributes Builder is a utility for creating JSON objects used to render charts with Lens. It simplifies the process of configuring and building the necessary attributes for different chart types.
|
## Lens Attributes Builder
|
||||||
|
|
||||||
## Usage
|
The Lens Attributes Builder is a utility for creating JSON objects used to render charts with Lens. It simplifies the process of configuring and building the necessary attributes for different chart types.
|
||||||
|
|
||||||
### Creating a Metric Chart
|
**Notes**:
|
||||||
|
|
||||||
|
This utililty is primarily used by Infra Observability UI and not meant to be used as an official solution provided by the Lens team.
|
||||||
|
|
||||||
|
- The tool has partial support of Lens charts, currently limited to XY and Metric charts.
|
||||||
|
- XY Bucket and Breakdown dimensions are limited respectively to Date Histogram and Top values.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
#### Creating a Metric Chart
|
||||||
|
|
||||||
To create a metric chart, use the `MetricChart` class and provide the required configuration. Here's an example:
|
To create a metric chart, use the `MetricChart` class and provide the required configuration. Here's an example:
|
||||||
|
|
||||||
|
@ -22,13 +31,13 @@ const metricChart = new MetricChart({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
formulaAPI,
|
|
||||||
}),
|
}),
|
||||||
dataView,
|
dataView,
|
||||||
|
formulaAPI
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating an XY Chart
|
#### Creating an XY Chart
|
||||||
|
|
||||||
To create an XY chart, use the `XYChart` class and provide the required configuration. Here's an example:
|
To create an XY chart, use the `XYChart` class and provide the required configuration. Here's an example:
|
||||||
|
|
||||||
|
@ -45,13 +54,72 @@ const xyChart = new XYChart({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
formulaAPI,
|
options: {
|
||||||
|
buckets: {type: 'date_histogram'},
|
||||||
|
},
|
||||||
})],
|
})],
|
||||||
dataView,
|
dataView,
|
||||||
|
formulaAPI
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding Multiple Layers to an XY Chart
|
#### Variations of the XY Chart
|
||||||
|
|
||||||
|
XYChart has different series type variations. Here is an example of how to build a line (default) and area charts
|
||||||
|
|
||||||
|
#### Line chart
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const xyChart = new XYChart({
|
||||||
|
layers: [new XYDataLayer({
|
||||||
|
data: [{
|
||||||
|
label: 'Inbound (RX)',
|
||||||
|
value: "average(system.load.1) / max(system.load.cores)",
|
||||||
|
format: {
|
||||||
|
id: 'percent',
|
||||||
|
params: {
|
||||||
|
decimals: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
}],
|
||||||
|
options: {
|
||||||
|
buckets: {type: 'date_histogram'},
|
||||||
|
seriesType: 'line' // default. it doesn't need to be informed.
|
||||||
|
}
|
||||||
|
})],
|
||||||
|
dataView,
|
||||||
|
formulaAPI
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Area chart
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const xyChart = new XYChart({
|
||||||
|
layers: [new XYDataLayer({
|
||||||
|
data: [{
|
||||||
|
label: 'Inbound (RX)',
|
||||||
|
value: "average(system.load.1) / max(system.load.cores)",
|
||||||
|
format: {
|
||||||
|
id: 'percent',
|
||||||
|
params: {
|
||||||
|
decimals: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
}],
|
||||||
|
options: {
|
||||||
|
buckets: {type: 'date_histogram'},
|
||||||
|
seriesType: 'area'
|
||||||
|
}
|
||||||
|
})],
|
||||||
|
dataView,
|
||||||
|
formulaAPI
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Adding Multiple Layers to an XY Chart
|
||||||
|
|
||||||
An XY chart can have multiple layers. Here's an example of containing a Reference Line Layer:
|
An XY chart can have multiple layers. Here's an example of containing a Reference Line Layer:
|
||||||
|
|
||||||
|
@ -69,10 +137,13 @@ const xyChart = new XYChart({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
formulaAPI,
|
options: {
|
||||||
|
buckets: {type: 'date_histogram'},
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
new XYReferenceLineLayer({
|
new XYReferenceLineLayer({
|
||||||
data: [{
|
data: [{
|
||||||
|
|
||||||
value: "1",
|
value: "1",
|
||||||
format: {
|
format: {
|
||||||
id: 'percent',
|
id: 'percent',
|
||||||
|
@ -84,10 +155,11 @@ const xyChart = new XYChart({
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
dataView,
|
dataView,
|
||||||
|
formulaAPI
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding Multiple Data Sources in the Same Layer
|
#### Adding Multiple Data Sources in the Same Layer
|
||||||
|
|
||||||
In an XY chart, it's possible to define multiple data sources within the same layer.
|
In an XY chart, it's possible to define multiple data sources within the same layer.
|
||||||
|
|
||||||
|
@ -115,13 +187,16 @@ const xyChart = new XYChart({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
formulaAPI,
|
options: {
|
||||||
|
buckets: {type: 'date_histogram'},
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
dataView,
|
dataView,
|
||||||
|
formulaAPI
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building Lens Chart Attributes
|
#### Building Lens Chart Attributes
|
||||||
|
|
||||||
The `LensAttributesBuilder` is responsible for creating the full JSON object that combines the attributes returned by the chart classes. Here's an example:
|
The `LensAttributesBuilder` is responsible for creating the full JSON object that combines the attributes returned by the chart classes. Here's an example:
|
||||||
|
|
||||||
|
@ -150,10 +225,10 @@ const builder = new LensAttributesBuilder({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
formulaAPI,
|
|
||||||
}),
|
}),
|
||||||
dataView,
|
dataView,
|
||||||
})
|
formulaAPI
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const lensAttributes = builder.build();
|
const lensAttributes = builder.build();
|
||||||
|
@ -163,4 +238,4 @@ const lensAttributes = builder.build();
|
||||||
viewMode={ViewMode.VIEW}
|
viewMode={ViewMode.VIEW}
|
||||||
...
|
...
|
||||||
/>
|
/>
|
||||||
```
|
```
|
|
@ -1,13 +1,14 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DataViewSpec, DataView } from '@kbn/data-plugin/common';
|
import { DataViewSpec, DataView } from '@kbn/data-plugin/common';
|
||||||
|
|
||||||
export const DEFAULT_AD_HOC_DATA_VIEW_ID = 'infra_lens_ad_hoc_default';
|
export const DEFAULT_AD_HOC_DATA_VIEW_ID = 'lens_ad_hoc_default';
|
||||||
|
|
||||||
export class DataViewCache {
|
export class DataViewCache {
|
||||||
private static instance: DataViewCache;
|
private static instance: DataViewCache;
|
|
@ -1,8 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'jest-canvas-mock';
|
import 'jest-canvas-mock';
|
||||||
|
@ -19,7 +20,7 @@ import {
|
||||||
} from './visualization_types';
|
} from './visualization_types';
|
||||||
import type { FormulaPublicApi, GenericIndexPatternColumn } from '@kbn/lens-plugin/public';
|
import type { FormulaPublicApi, GenericIndexPatternColumn } from '@kbn/lens-plugin/public';
|
||||||
import { ReferenceBasedIndexPatternColumn } from '@kbn/lens-plugin/public/datasources/form_based/operations/definitions/column_types';
|
import { ReferenceBasedIndexPatternColumn } from '@kbn/lens-plugin/public/datasources/form_based/operations/definitions/column_types';
|
||||||
import type { FormulaConfig } from '../types';
|
import type { FormulaValueConfig } from './types';
|
||||||
|
|
||||||
const mockDataView = {
|
const mockDataView = {
|
||||||
id: 'mock-id',
|
id: 'mock-id',
|
||||||
|
@ -85,7 +86,7 @@ const REFERENCE_LINE_LAYER: ReferenceBasedIndexPatternColumn = {
|
||||||
scale: 'ratio',
|
scale: 'ratio',
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFormula = (value: string): FormulaConfig => ({
|
const getFormula = (value: string): FormulaValueConfig => ({
|
||||||
value,
|
value,
|
||||||
format: {
|
format: {
|
||||||
id: 'percent',
|
id: 'percent',
|
||||||
|
@ -106,10 +107,10 @@ describe('lens_attributes_builder', () => {
|
||||||
const metriChart = new MetricChart({
|
const metriChart = new MetricChart({
|
||||||
layers: new MetricLayer({
|
layers: new MetricLayer({
|
||||||
data: getFormula(AVERAGE_CPU_USER_FORMULA),
|
data: getFormula(AVERAGE_CPU_USER_FORMULA),
|
||||||
formulaAPI,
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
dataView: mockDataView,
|
dataView: mockDataView,
|
||||||
|
formulaAPI,
|
||||||
});
|
});
|
||||||
const builder = new LensAttributesBuilder({ visualization: metriChart });
|
const builder = new LensAttributesBuilder({ visualization: metriChart });
|
||||||
const {
|
const {
|
||||||
|
@ -148,10 +149,10 @@ describe('lens_attributes_builder', () => {
|
||||||
options: {
|
options: {
|
||||||
showTrendLine: true,
|
showTrendLine: true,
|
||||||
},
|
},
|
||||||
formulaAPI,
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
dataView: mockDataView,
|
dataView: mockDataView,
|
||||||
|
formulaAPI,
|
||||||
});
|
});
|
||||||
const builder = new LensAttributesBuilder({ visualization: metriChart });
|
const builder = new LensAttributesBuilder({ visualization: metriChart });
|
||||||
const {
|
const {
|
||||||
|
@ -204,10 +205,13 @@ describe('lens_attributes_builder', () => {
|
||||||
layers: [
|
layers: [
|
||||||
new XYDataLayer({
|
new XYDataLayer({
|
||||||
data: [getFormula(AVERAGE_CPU_USER_FORMULA)],
|
data: [getFormula(AVERAGE_CPU_USER_FORMULA)],
|
||||||
formulaAPI,
|
options: {
|
||||||
|
buckets: { type: 'date_histogram' },
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
dataView: mockDataView,
|
dataView: mockDataView,
|
||||||
|
formulaAPI,
|
||||||
});
|
});
|
||||||
const builder = new LensAttributesBuilder({ visualization: xyChart });
|
const builder = new LensAttributesBuilder({ visualization: xyChart });
|
||||||
const {
|
const {
|
||||||
|
@ -248,13 +252,23 @@ describe('lens_attributes_builder', () => {
|
||||||
layers: [
|
layers: [
|
||||||
new XYDataLayer({
|
new XYDataLayer({
|
||||||
data: [getFormula(AVERAGE_CPU_USER_FORMULA)],
|
data: [getFormula(AVERAGE_CPU_USER_FORMULA)],
|
||||||
formulaAPI,
|
options: {
|
||||||
|
buckets: { type: 'date_histogram' },
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
new XYReferenceLinesLayer({
|
new XYReferenceLinesLayer({
|
||||||
data: [getFormula('1')],
|
data: [
|
||||||
|
{
|
||||||
|
value: '1',
|
||||||
|
format: {
|
||||||
|
id: 'percent',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
dataView: mockDataView,
|
dataView: mockDataView,
|
||||||
|
formulaAPI,
|
||||||
});
|
});
|
||||||
const builder = new LensAttributesBuilder({ visualization: xyChart });
|
const builder = new LensAttributesBuilder({ visualization: xyChart });
|
||||||
const {
|
const {
|
||||||
|
@ -316,10 +330,13 @@ describe('lens_attributes_builder', () => {
|
||||||
layers: [
|
layers: [
|
||||||
new XYDataLayer({
|
new XYDataLayer({
|
||||||
data: [getFormula(AVERAGE_CPU_USER_FORMULA), getFormula(AVERAGE_CPU_SYSTEM_FORMULA)],
|
data: [getFormula(AVERAGE_CPU_USER_FORMULA), getFormula(AVERAGE_CPU_SYSTEM_FORMULA)],
|
||||||
formulaAPI,
|
options: {
|
||||||
|
buckets: { type: 'date_histogram' },
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
dataView: mockDataView,
|
dataView: mockDataView,
|
||||||
|
formulaAPI,
|
||||||
});
|
});
|
||||||
const builder = new LensAttributesBuilder({ visualization: xyChart });
|
const builder = new LensAttributesBuilder({ visualization: xyChart });
|
||||||
const {
|
const {
|
|
@ -1,15 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
LensAttributes,
|
LensAttributes,
|
||||||
LensVisualizationState,
|
LensVisualizationState,
|
||||||
Chart,
|
Chart,
|
||||||
VisualizationAttributesBuilder,
|
VisualizationAttributesBuilder,
|
||||||
} from '../types';
|
} from './types';
|
||||||
import { DataViewCache } from './data_view_cache';
|
import { DataViewCache } from './data_view_cache';
|
||||||
import { getAdhocDataView } from './utils';
|
import { getAdhocDataView } from './utils';
|
||||||
|
|
||||||
|
@ -17,12 +19,12 @@ export class LensAttributesBuilder<T extends Chart<LensVisualizationState>>
|
||||||
implements VisualizationAttributesBuilder
|
implements VisualizationAttributesBuilder
|
||||||
{
|
{
|
||||||
private dataViewCache: DataViewCache;
|
private dataViewCache: DataViewCache;
|
||||||
constructor(private state: { visualization: T }) {
|
constructor(private lens: { visualization: T }) {
|
||||||
this.dataViewCache = DataViewCache.getInstance();
|
this.dataViewCache = DataViewCache.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
build(): LensAttributes {
|
build(): LensAttributes {
|
||||||
const { visualization } = this.state;
|
const { visualization } = this.lens;
|
||||||
return {
|
return {
|
||||||
title: visualization.getTitle(),
|
title: visualization.getTitle(),
|
||||||
visualizationType: visualization.getVisualizationType(),
|
visualizationType: visualization.getVisualizationType(),
|
||||||
|
@ -34,10 +36,17 @@ export class LensAttributesBuilder<T extends Chart<LensVisualizationState>>
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
internalReferences: visualization.getReferences(),
|
internalReferences: visualization.getReferences(),
|
||||||
|
// EmbeddableComponent receive filters.
|
||||||
filters: [],
|
filters: [],
|
||||||
|
// EmbeddableComponent receive query.
|
||||||
query: { language: 'kuery', query: '' },
|
query: { language: 'kuery', query: '' },
|
||||||
visualization: visualization.getVisualizationState(),
|
visualization: visualization.getVisualizationState(),
|
||||||
adHocDataViews: getAdhocDataView(this.dataViewCache.getSpec(visualization.getDataView())),
|
// Getting the spec from a data view is a heavy operation, that's why the result is cached.
|
||||||
|
adHocDataViews: getAdhocDataView(
|
||||||
|
visualization
|
||||||
|
.getDataViews()
|
||||||
|
.reduce((acc, curr) => ({ ...acc, ...this.dataViewCache.getSpec(curr) }), {})
|
||||||
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { SavedObjectReference } from '@kbn/core/server';
|
||||||
|
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||||
|
import type {
|
||||||
|
FormBasedPersistedState,
|
||||||
|
MetricVisualizationState,
|
||||||
|
PersistedIndexPatternLayer,
|
||||||
|
TypedLensByValueInput,
|
||||||
|
XYState,
|
||||||
|
FormulaPublicApi,
|
||||||
|
XYLayerConfig,
|
||||||
|
} from '@kbn/lens-plugin/public';
|
||||||
|
export type LensAttributes = TypedLensByValueInput['attributes'];
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
export type LensVisualizationState = XYState | MetricVisualizationState;
|
||||||
|
|
||||||
|
export interface VisualizationAttributesBuilder {
|
||||||
|
build(): LensAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Column
|
||||||
|
export interface BaseChartColumn<TValueConfig extends StaticValueConfig | FormulaValueConfig> {
|
||||||
|
getValueConfig(): TValueConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChartColumn extends BaseChartColumn<FormulaValueConfig> {
|
||||||
|
getData(
|
||||||
|
id: string,
|
||||||
|
baseLayer: PersistedIndexPatternLayer,
|
||||||
|
dataView: DataView,
|
||||||
|
formulaAPI: FormulaPublicApi
|
||||||
|
): PersistedIndexPatternLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StaticChartColumn extends BaseChartColumn<StaticValueConfig> {
|
||||||
|
getData(id: string, baseLayer: PersistedIndexPatternLayer): PersistedIndexPatternLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer
|
||||||
|
export type LensLayerConfig = XYLayerConfig | MetricVisualizationState;
|
||||||
|
|
||||||
|
export interface ChartLayer<TLayerConfig extends LensLayerConfig> {
|
||||||
|
getName(): string | undefined;
|
||||||
|
getLayer(
|
||||||
|
layerId: string,
|
||||||
|
accessorId: string,
|
||||||
|
dataView: DataView,
|
||||||
|
formulaAPI: FormulaPublicApi
|
||||||
|
): FormBasedPersistedState['layers'];
|
||||||
|
getReference(layerId: string, dataView: DataView): SavedObjectReference[];
|
||||||
|
getLayerConfig(layerId: string, acessorId: string): TLayerConfig;
|
||||||
|
getDataView(): DataView | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chart
|
||||||
|
export interface Chart<TVisualizationState extends LensVisualizationState> {
|
||||||
|
getTitle(): string;
|
||||||
|
getVisualizationType(): string;
|
||||||
|
getLayers(): FormBasedPersistedState['layers'];
|
||||||
|
getVisualizationState(): TVisualizationState;
|
||||||
|
getReferences(): SavedObjectReference[];
|
||||||
|
getDataViews(): DataView[];
|
||||||
|
}
|
||||||
|
export interface ChartConfig<
|
||||||
|
TLayer extends ChartLayer<LensLayerConfig> | Array<ChartLayer<LensLayerConfig>>
|
||||||
|
> {
|
||||||
|
formulaAPI: FormulaPublicApi;
|
||||||
|
dataView: DataView;
|
||||||
|
layers: TLayer;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formula
|
||||||
|
type LensFormula = Parameters<FormulaPublicApi['insertOrReplaceFormulaColumn']>[1];
|
||||||
|
export type FormulaValueConfig = Omit<LensFormula, 'formula'> & {
|
||||||
|
color?: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type StaticValueConfig = Omit<LensFormula, 'formula'> & {
|
||||||
|
color?: string;
|
||||||
|
value: string;
|
||||||
|
};
|
|
@ -1,10 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
import {
|
|
||||||
|
import type {
|
||||||
DateHistogramIndexPatternColumn,
|
DateHistogramIndexPatternColumn,
|
||||||
PersistedIndexPatternLayer,
|
PersistedIndexPatternLayer,
|
||||||
TermsIndexPatternColumn,
|
TermsIndexPatternColumn,
|
||||||
|
@ -17,12 +19,27 @@ export const DEFAULT_AD_HOC_DATA_VIEW_ID = 'infra_lens_ad_hoc_default';
|
||||||
|
|
||||||
const DEFAULT_BREAKDOWN_SIZE = 10;
|
const DEFAULT_BREAKDOWN_SIZE = 10;
|
||||||
|
|
||||||
|
export function nonNullable<T>(v: T): v is NonNullable<T> {
|
||||||
|
return v != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DateHistogramColumnParams = DateHistogramIndexPatternColumn['params'];
|
||||||
|
|
||||||
|
export type TopValuesColumnParams = Pick<
|
||||||
|
TermsIndexPatternColumn['params'],
|
||||||
|
'size' | 'orderDirection' | 'orderBy'
|
||||||
|
>;
|
||||||
|
|
||||||
export const getHistogramColumn = ({
|
export const getHistogramColumn = ({
|
||||||
columnName,
|
columnName,
|
||||||
overrides,
|
options,
|
||||||
}: {
|
}: {
|
||||||
columnName: string;
|
columnName: string;
|
||||||
overrides?: Partial<Pick<DateHistogramIndexPatternColumn, 'sourceField' | 'params'>>;
|
options?: Partial<
|
||||||
|
Pick<DateHistogramIndexPatternColumn, 'sourceField'> & {
|
||||||
|
params: DateHistogramColumnParams;
|
||||||
|
}
|
||||||
|
>;
|
||||||
}) => {
|
}) => {
|
||||||
return {
|
return {
|
||||||
[columnName]: {
|
[columnName]: {
|
||||||
|
@ -32,32 +49,32 @@ export const getHistogramColumn = ({
|
||||||
operationType: 'date_histogram',
|
operationType: 'date_histogram',
|
||||||
scale: 'interval',
|
scale: 'interval',
|
||||||
sourceField: '@timestamp',
|
sourceField: '@timestamp',
|
||||||
...overrides,
|
...options,
|
||||||
params: { interval: 'auto', ...overrides?.params },
|
params: { interval: 'auto', ...options?.params },
|
||||||
} as DateHistogramIndexPatternColumn,
|
} as DateHistogramIndexPatternColumn,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getTopValuesColumn = ({
|
export const getTopValuesColumn = ({
|
||||||
columnName,
|
columnName,
|
||||||
overrides,
|
field,
|
||||||
|
options,
|
||||||
}: {
|
}: {
|
||||||
columnName: string;
|
columnName: string;
|
||||||
overrides?: Partial<Pick<TermsIndexPatternColumn, 'sourceField'>> & {
|
field: string;
|
||||||
breakdownSize?: number;
|
options?: Partial<TopValuesColumnParams>;
|
||||||
};
|
|
||||||
}): PersistedIndexPatternLayer['columns'] => {
|
}): PersistedIndexPatternLayer['columns'] => {
|
||||||
const { breakdownSize = DEFAULT_BREAKDOWN_SIZE, sourceField } = overrides ?? {};
|
const { size = DEFAULT_BREAKDOWN_SIZE, ...params } = options ?? {};
|
||||||
return {
|
return {
|
||||||
[columnName]: {
|
[columnName]: {
|
||||||
label: `Top ${breakdownSize} values of ${sourceField}`,
|
label: `Top ${size} values of ${field}`,
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
operationType: 'terms',
|
operationType: 'terms',
|
||||||
scale: 'ordinal',
|
scale: 'ordinal',
|
||||||
sourceField,
|
sourceField: field,
|
||||||
isBucketed: true,
|
isBucketed: true,
|
||||||
params: {
|
params: {
|
||||||
size: breakdownSize,
|
size,
|
||||||
orderBy: {
|
orderBy: {
|
||||||
type: 'alphabetical',
|
type: 'alphabetical',
|
||||||
fallback: false,
|
fallback: false,
|
||||||
|
@ -72,6 +89,7 @@ export const getTopValuesColumn = ({
|
||||||
exclude: [],
|
exclude: [],
|
||||||
includeIsRegex: false,
|
includeIsRegex: false,
|
||||||
excludeIsRegex: false,
|
excludeIsRegex: false,
|
||||||
|
...params,
|
||||||
},
|
},
|
||||||
} as TermsIndexPatternColumn,
|
} as TermsIndexPatternColumn,
|
||||||
};
|
};
|
|
@ -1,8 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { XYChart, type XYVisualOptions } from './xy_chart';
|
export { XYChart, type XYVisualOptions } from './xy_chart';
|
|
@ -1,28 +1,30 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaPublicApi, PersistedIndexPatternLayer } from '@kbn/lens-plugin/public';
|
import type { FormulaPublicApi, PersistedIndexPatternLayer } from '@kbn/lens-plugin/public';
|
||||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||||
import type { FormulaConfig, ChartColumn } from '../../../../types';
|
import type { FormulaValueConfig, ChartColumn } from '../../../types';
|
||||||
|
|
||||||
export class FormulaColumn implements ChartColumn {
|
export class FormulaColumn implements ChartColumn {
|
||||||
constructor(private formulaConfig: FormulaConfig, private formulaAPI: FormulaPublicApi) {}
|
constructor(private valueConfig: FormulaValueConfig) {}
|
||||||
|
|
||||||
getFormulaConfig(): FormulaConfig {
|
getValueConfig(): FormulaValueConfig {
|
||||||
return this.formulaConfig;
|
return this.valueConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(
|
getData(
|
||||||
id: string,
|
id: string,
|
||||||
baseLayer: PersistedIndexPatternLayer,
|
baseLayer: PersistedIndexPatternLayer,
|
||||||
dataView: DataView
|
dataView: DataView,
|
||||||
|
formulaAPI: FormulaPublicApi
|
||||||
): PersistedIndexPatternLayer {
|
): PersistedIndexPatternLayer {
|
||||||
const { value, ...rest } = this.getFormulaConfig();
|
const { value, ...rest } = this.getValueConfig();
|
||||||
const formulaLayer = this.formulaAPI.insertOrReplaceFormulaColumn(
|
const formulaLayer = formulaAPI.insertOrReplaceFormulaColumn(
|
||||||
id,
|
id,
|
||||||
{ formula: value, ...rest },
|
{ formula: value, ...rest },
|
||||||
baseLayer,
|
baseLayer,
|
|
@ -1,23 +1,24 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { PersistedIndexPatternLayer } from '@kbn/lens-plugin/public';
|
import type { PersistedIndexPatternLayer } from '@kbn/lens-plugin/public';
|
||||||
import type { ReferenceBasedIndexPatternColumn } from '@kbn/lens-plugin/public/datasources/form_based/operations/definitions/column_types';
|
import type { ReferenceBasedIndexPatternColumn } from '@kbn/lens-plugin/public/datasources/form_based/operations/definitions/column_types';
|
||||||
import type { FormulaConfig, ChartColumn } from '../../../../types';
|
import type { StaticChartColumn, StaticValueConfig } from '../../../types';
|
||||||
|
|
||||||
export class ReferenceLineColumn implements ChartColumn {
|
export class ReferenceLineColumn implements StaticChartColumn {
|
||||||
constructor(private formulaConfig: FormulaConfig) {}
|
constructor(private valueConfig: StaticValueConfig) {}
|
||||||
|
|
||||||
getFormulaConfig(): FormulaConfig {
|
getValueConfig(): StaticValueConfig {
|
||||||
return this.formulaConfig;
|
return this.valueConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(id: string, baseLayer: PersistedIndexPatternLayer): PersistedIndexPatternLayer {
|
getData(id: string, baseLayer: PersistedIndexPatternLayer): PersistedIndexPatternLayer {
|
||||||
const { label, ...params } = this.getFormulaConfig();
|
const { label, ...params } = this.getValueConfig();
|
||||||
return {
|
return {
|
||||||
linkToLayers: [],
|
linkToLayers: [],
|
||||||
columnOrder: [...baseLayer.columnOrder, id],
|
columnOrder: [...baseLayer.columnOrder, id],
|
|
@ -1,13 +1,14 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { MetricLayer, type MetricLayerOptions } from './metric_layer';
|
export { MetricLayer, type MetricLayerOptions } from './metric_layer';
|
||||||
export { XYDataLayer, type XYLayerOptions } from './xy_data_layer';
|
export { XYDataLayer, type XYLayerOptions } from './xy_data_layer';
|
||||||
export { XYReferenceLinesLayer } from './xy_reference_lines_layer';
|
export { XYReferenceLinesLayer } from './xy_reference_lines_layer';
|
||||||
|
|
||||||
export { FormulaColumn as FormulaDataColumn } from './column/formula';
|
export { FormulaColumn as FormulaDataColumn } from './columns/formula';
|
||||||
export { ReferenceLineColumn } from './column/reference_line';
|
export { ReferenceLineColumn } from './columns/reference_line';
|
|
@ -1,8 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { SavedObjectReference } from '@kbn/core/server';
|
import type { SavedObjectReference } from '@kbn/core/server';
|
||||||
|
@ -13,9 +14,9 @@ import type {
|
||||||
MetricVisualizationState,
|
MetricVisualizationState,
|
||||||
PersistedIndexPatternLayer,
|
PersistedIndexPatternLayer,
|
||||||
} from '@kbn/lens-plugin/public';
|
} from '@kbn/lens-plugin/public';
|
||||||
import type { ChartColumn, ChartLayer, FormulaConfig } from '../../../types';
|
import type { ChartColumn, ChartLayer, FormulaValueConfig } from '../../types';
|
||||||
import { getDefaultReferences, getHistogramColumn } from '../../utils';
|
import { getDefaultReferences, getHistogramColumn } from '../../utils';
|
||||||
import { FormulaColumn } from './column/formula';
|
import { FormulaColumn } from './columns/formula';
|
||||||
|
|
||||||
const HISTOGRAM_COLUMN_NAME = 'x_date_histogram';
|
const HISTOGRAM_COLUMN_NAME = 'x_date_histogram';
|
||||||
|
|
||||||
|
@ -27,28 +28,32 @@ export interface MetricLayerOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MetricLayerConfig {
|
interface MetricLayerConfig {
|
||||||
data: FormulaConfig;
|
data: FormulaValueConfig;
|
||||||
options?: MetricLayerOptions;
|
options?: MetricLayerOptions;
|
||||||
formulaAPI: FormulaPublicApi;
|
/**
|
||||||
|
* It is possible to define a specific dataView for the layer. It will override the global chart one
|
||||||
|
**/
|
||||||
|
dataView?: DataView;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MetricLayer implements ChartLayer<MetricVisualizationState> {
|
export class MetricLayer implements ChartLayer<MetricVisualizationState> {
|
||||||
private column: ChartColumn;
|
private column: ChartColumn;
|
||||||
constructor(private layerConfig: MetricLayerConfig) {
|
constructor(private layerConfig: MetricLayerConfig) {
|
||||||
this.column = new FormulaColumn(layerConfig.data, layerConfig.formulaAPI);
|
this.column = new FormulaColumn(layerConfig.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayer(
|
getLayer(
|
||||||
layerId: string,
|
layerId: string,
|
||||||
accessorId: string,
|
accessorId: string,
|
||||||
dataView: DataView
|
chartDataView: DataView,
|
||||||
|
formulaAPI: FormulaPublicApi
|
||||||
): FormBasedPersistedState['layers'] {
|
): FormBasedPersistedState['layers'] {
|
||||||
const baseLayer: PersistedIndexPatternLayer = {
|
const baseLayer: PersistedIndexPatternLayer = {
|
||||||
columnOrder: [HISTOGRAM_COLUMN_NAME],
|
columnOrder: [HISTOGRAM_COLUMN_NAME],
|
||||||
columns: getHistogramColumn({
|
columns: getHistogramColumn({
|
||||||
columnName: HISTOGRAM_COLUMN_NAME,
|
columnName: HISTOGRAM_COLUMN_NAME,
|
||||||
overrides: {
|
options: {
|
||||||
sourceField: dataView.timeFieldName,
|
sourceField: (this.layerConfig.dataView ?? chartDataView).timeFieldName,
|
||||||
params: {
|
params: {
|
||||||
interval: 'auto',
|
interval: 'auto',
|
||||||
includeEmptyRows: true,
|
includeEmptyRows: true,
|
||||||
|
@ -66,23 +71,29 @@ export class MetricLayer implements ChartLayer<MetricVisualizationState> {
|
||||||
columnOrder: [],
|
columnOrder: [],
|
||||||
columns: {},
|
columns: {},
|
||||||
},
|
},
|
||||||
dataView
|
this.layerConfig.dataView ?? chartDataView,
|
||||||
|
formulaAPI
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
...(this.layerConfig.options?.showTrendLine
|
...(this.layerConfig.options?.showTrendLine
|
||||||
? {
|
? {
|
||||||
[`${layerId}_trendline`]: {
|
[`${layerId}_trendline`]: {
|
||||||
linkToLayers: [layerId],
|
linkToLayers: [layerId],
|
||||||
...this.column.getData(`${accessorId}_trendline`, baseLayer, dataView),
|
...this.column.getData(
|
||||||
|
`${accessorId}_trendline`,
|
||||||
|
baseLayer,
|
||||||
|
this.layerConfig.dataView ?? chartDataView,
|
||||||
|
formulaAPI
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
getReference(layerId: string, dataView: DataView): SavedObjectReference[] {
|
getReference(layerId: string, chartDataView: DataView): SavedObjectReference[] {
|
||||||
return [
|
return [
|
||||||
...getDefaultReferences(dataView, layerId),
|
...getDefaultReferences(this.layerConfig.dataView ?? chartDataView, layerId),
|
||||||
...getDefaultReferences(dataView, `${layerId}_trendline`),
|
...getDefaultReferences(this.layerConfig.dataView ?? chartDataView, `${layerId}_trendline`),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +118,10 @@ export class MetricLayer implements ChartLayer<MetricVisualizationState> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
getName(): string | undefined {
|
getName(): string | undefined {
|
||||||
return this.column.getFormulaConfig().label;
|
return this.column.getValueConfig().label;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDataView(): DataView | undefined {
|
||||||
|
return this.layerConfig.dataView;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { SavedObjectReference } from '@kbn/core/server';
|
||||||
|
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||||
|
import type {
|
||||||
|
FormulaPublicApi,
|
||||||
|
FormBasedPersistedState,
|
||||||
|
PersistedIndexPatternLayer,
|
||||||
|
XYDataLayerConfig,
|
||||||
|
SeriesType,
|
||||||
|
TermsIndexPatternColumn,
|
||||||
|
DateHistogramIndexPatternColumn,
|
||||||
|
} from '@kbn/lens-plugin/public';
|
||||||
|
import type { ChartColumn, ChartLayer, FormulaValueConfig } from '../../types';
|
||||||
|
import {
|
||||||
|
getDefaultReferences,
|
||||||
|
getHistogramColumn,
|
||||||
|
getTopValuesColumn,
|
||||||
|
nonNullable,
|
||||||
|
type TopValuesColumnParams,
|
||||||
|
type DateHistogramColumnParams,
|
||||||
|
} from '../../utils';
|
||||||
|
import { FormulaColumn } from './columns/formula';
|
||||||
|
|
||||||
|
const BREAKDOWN_COLUMN_NAME = 'aggs_breakdown';
|
||||||
|
const HISTOGRAM_COLUMN_NAME = 'x_date_histogram';
|
||||||
|
|
||||||
|
interface TopValuesBucketedColumn {
|
||||||
|
type: 'top_values';
|
||||||
|
field: TermsIndexPatternColumn['sourceField'];
|
||||||
|
params?: Partial<TopValuesColumnParams>;
|
||||||
|
}
|
||||||
|
interface DateHistogramBucketedColumn {
|
||||||
|
type: 'date_histogram';
|
||||||
|
field?: DateHistogramIndexPatternColumn['sourceField'];
|
||||||
|
params?: Partial<DateHistogramColumnParams>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface XYLayerOptions {
|
||||||
|
// Add more types as support for them is implemented
|
||||||
|
breakdown?: TopValuesBucketedColumn;
|
||||||
|
// Add more types as support for them is implemented
|
||||||
|
buckets?: DateHistogramBucketedColumn;
|
||||||
|
seriesType?: SeriesType;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface XYLayerConfig {
|
||||||
|
data: FormulaValueConfig[];
|
||||||
|
options?: XYLayerOptions;
|
||||||
|
/**
|
||||||
|
* It is possible to define a specific dataView for the layer. It will override the global chart one
|
||||||
|
**/
|
||||||
|
dataView?: DataView;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class XYDataLayer implements ChartLayer<XYDataLayerConfig> {
|
||||||
|
private column: ChartColumn[];
|
||||||
|
private layerConfig: XYLayerConfig;
|
||||||
|
constructor(layerConfig: XYLayerConfig) {
|
||||||
|
this.column = layerConfig.data.map((dataItem) => new FormulaColumn(dataItem));
|
||||||
|
this.layerConfig = {
|
||||||
|
...layerConfig,
|
||||||
|
options: {
|
||||||
|
...layerConfig.options,
|
||||||
|
buckets: {
|
||||||
|
type: 'date_histogram',
|
||||||
|
...layerConfig.options?.buckets,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getName(): string | undefined {
|
||||||
|
return this.column[0].getValueConfig().label;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBaseLayer(dataView: DataView, options: XYLayerOptions) {
|
||||||
|
return {
|
||||||
|
...(options.buckets?.type === 'date_histogram'
|
||||||
|
? getHistogramColumn({
|
||||||
|
columnName: HISTOGRAM_COLUMN_NAME,
|
||||||
|
options: {
|
||||||
|
...options.buckets.params,
|
||||||
|
sourceField: options.buckets.field ?? dataView.timeFieldName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: {}),
|
||||||
|
...(options.breakdown?.type === 'top_values'
|
||||||
|
? {
|
||||||
|
...getTopValuesColumn({
|
||||||
|
columnName: BREAKDOWN_COLUMN_NAME,
|
||||||
|
field: options?.breakdown.field,
|
||||||
|
options: {
|
||||||
|
...options.breakdown.params,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getLayer(
|
||||||
|
layerId: string,
|
||||||
|
accessorId: string,
|
||||||
|
chartDataView: DataView,
|
||||||
|
formulaAPI: FormulaPublicApi
|
||||||
|
): FormBasedPersistedState['layers'] {
|
||||||
|
const columnOrder: string[] = [];
|
||||||
|
if (this.layerConfig.options?.breakdown?.type === 'top_values') {
|
||||||
|
columnOrder.push(BREAKDOWN_COLUMN_NAME);
|
||||||
|
}
|
||||||
|
if (this.layerConfig.options?.buckets?.type === 'date_histogram') {
|
||||||
|
columnOrder.push(HISTOGRAM_COLUMN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseLayer: PersistedIndexPatternLayer = {
|
||||||
|
columnOrder,
|
||||||
|
columns: {
|
||||||
|
...this.getBaseLayer(
|
||||||
|
this.layerConfig.dataView ?? chartDataView,
|
||||||
|
this.layerConfig.options ?? {}
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
[layerId]: this.column.reduce(
|
||||||
|
(acc, curr, index) => ({
|
||||||
|
...acc,
|
||||||
|
...curr.getData(
|
||||||
|
`${accessorId}_${index}`,
|
||||||
|
acc,
|
||||||
|
this.layerConfig.dataView ?? chartDataView,
|
||||||
|
formulaAPI
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
baseLayer
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getReference(layerId: string, chartDataView: DataView): SavedObjectReference[] {
|
||||||
|
return getDefaultReferences(this.layerConfig.dataView ?? chartDataView, layerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLayerConfig(layerId: string, accessorId: string): XYDataLayerConfig {
|
||||||
|
return {
|
||||||
|
layerId,
|
||||||
|
seriesType: this.layerConfig.options?.seriesType ?? 'line',
|
||||||
|
accessors: this.column.map((_, index) => `${accessorId}_${index}`),
|
||||||
|
yConfig: this.layerConfig.data
|
||||||
|
.map(({ color }, index) =>
|
||||||
|
color ? { forAccessor: `${accessorId}_${index}`, color } : undefined
|
||||||
|
)
|
||||||
|
.filter(nonNullable),
|
||||||
|
layerType: 'data',
|
||||||
|
xAccessor:
|
||||||
|
this.layerConfig.options?.buckets?.type === 'date_histogram'
|
||||||
|
? HISTOGRAM_COLUMN_NAME
|
||||||
|
: undefined,
|
||||||
|
splitAccessor:
|
||||||
|
this.layerConfig.options?.breakdown?.type === 'top_values'
|
||||||
|
? BREAKDOWN_COLUMN_NAME
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getDataView(): DataView | undefined {
|
||||||
|
return this.layerConfig.dataView;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { SavedObjectReference } from '@kbn/core/server';
|
import type { SavedObjectReference } from '@kbn/core/server';
|
||||||
|
@ -12,42 +13,42 @@ import type {
|
||||||
PersistedIndexPatternLayer,
|
PersistedIndexPatternLayer,
|
||||||
XYReferenceLineLayerConfig,
|
XYReferenceLineLayerConfig,
|
||||||
} from '@kbn/lens-plugin/public';
|
} from '@kbn/lens-plugin/public';
|
||||||
import type { ChartColumn, ChartLayer, FormulaConfig } from '../../../types';
|
import type { ChartLayer, StaticValueConfig, StaticChartColumn } from '../../types';
|
||||||
import { getDefaultReferences } from '../../utils';
|
import { getDefaultReferences } from '../../utils';
|
||||||
import { ReferenceLineColumn } from './column/reference_line';
|
import { ReferenceLineColumn } from './columns/reference_line';
|
||||||
|
|
||||||
interface XYReferenceLinesLayerConfig {
|
interface XYReferenceLinesLayerConfig {
|
||||||
data: FormulaConfig[];
|
data: StaticValueConfig[];
|
||||||
|
/**
|
||||||
|
* It is possible to define a specific dataView for the layer. It will override the global chart one
|
||||||
|
**/
|
||||||
|
dataView?: DataView;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class XYReferenceLinesLayer implements ChartLayer<XYReferenceLineLayerConfig> {
|
export class XYReferenceLinesLayer implements ChartLayer<XYReferenceLineLayerConfig> {
|
||||||
private column: ChartColumn[];
|
private column: StaticChartColumn[];
|
||||||
constructor(layerConfig: XYReferenceLinesLayerConfig) {
|
constructor(private layerConfig: XYReferenceLinesLayerConfig) {
|
||||||
this.column = layerConfig.data.map((p) => new ReferenceLineColumn(p));
|
this.column = layerConfig.data.map((p) => new ReferenceLineColumn(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
getName(): string | undefined {
|
getName(): string | undefined {
|
||||||
return this.column[0].getFormulaConfig().label;
|
return this.column[0].getValueConfig().label;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayer(
|
getLayer(layerId: string, accessorId: string): FormBasedPersistedState['layers'] {
|
||||||
layerId: string,
|
|
||||||
accessorId: string,
|
|
||||||
dataView: DataView
|
|
||||||
): FormBasedPersistedState['layers'] {
|
|
||||||
const baseLayer = { columnOrder: [], columns: {} } as PersistedIndexPatternLayer;
|
const baseLayer = { columnOrder: [], columns: {} } as PersistedIndexPatternLayer;
|
||||||
return {
|
return {
|
||||||
[`${layerId}_reference`]: this.column.reduce((acc, curr, index) => {
|
[`${layerId}_reference`]: this.column.reduce((acc, curr, index) => {
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
...curr.getData(`${accessorId}_${index}_reference_column`, acc, dataView),
|
...curr.getData(`${accessorId}_${index}_reference_column`, acc),
|
||||||
};
|
};
|
||||||
}, baseLayer),
|
}, baseLayer),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getReference(layerId: string, dataView: DataView): SavedObjectReference[] {
|
getReference(layerId: string, chartDataView: DataView): SavedObjectReference[] {
|
||||||
return getDefaultReferences(dataView, `${layerId}_reference`);
|
return getDefaultReferences(this.layerConfig.dataView ?? chartDataView, `${layerId}_reference`);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayerConfig(layerId: string, accessorId: string): XYReferenceLineLayerConfig {
|
getLayerConfig(layerId: string, accessorId: string): XYReferenceLineLayerConfig {
|
||||||
|
@ -56,10 +57,14 @@ export class XYReferenceLinesLayer implements ChartLayer<XYReferenceLineLayerCon
|
||||||
layerType: 'referenceLine',
|
layerType: 'referenceLine',
|
||||||
accessors: this.column.map((_, index) => `${accessorId}_${index}_reference_column`),
|
accessors: this.column.map((_, index) => `${accessorId}_${index}_reference_column`),
|
||||||
yConfig: this.column.map((layer, index) => ({
|
yConfig: this.column.map((layer, index) => ({
|
||||||
color: layer.getFormulaConfig().color,
|
color: layer.getValueConfig().color,
|
||||||
forAccessor: `${accessorId}_${index}_reference_column`,
|
forAccessor: `${accessorId}_${index}_reference_column`,
|
||||||
axisMode: 'left',
|
axisMode: 'left',
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDataView(): DataView | undefined {
|
||||||
|
return this.layerConfig.dataView;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormBasedPersistedState, MetricVisualizationState } from '@kbn/lens-plugin/public';
|
import type { FormBasedPersistedState, MetricVisualizationState } from '@kbn/lens-plugin/public';
|
||||||
import type { SavedObjectReference } from '@kbn/core/server';
|
import type { SavedObjectReference } from '@kbn/core/server';
|
||||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||||
|
import type { Chart, ChartConfig, ChartLayer } from '../types';
|
||||||
import { DEFAULT_LAYER_ID } from '../utils';
|
import { DEFAULT_LAYER_ID } from '../utils';
|
||||||
|
|
||||||
import type { Chart, ChartConfig, ChartLayer } from '../../types';
|
|
||||||
|
|
||||||
const ACCESSOR = 'metric_formula_accessor';
|
const ACCESSOR = 'metric_formula_accessor';
|
||||||
|
|
||||||
export class MetricChart implements Chart<MetricVisualizationState> {
|
export class MetricChart implements Chart<MetricVisualizationState> {
|
||||||
|
@ -22,7 +22,12 @@ export class MetricChart implements Chart<MetricVisualizationState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayers(): FormBasedPersistedState['layers'] {
|
getLayers(): FormBasedPersistedState['layers'] {
|
||||||
return this.chartConfig.layers.getLayer(DEFAULT_LAYER_ID, ACCESSOR, this.chartConfig.dataView);
|
return this.chartConfig.layers.getLayer(
|
||||||
|
DEFAULT_LAYER_ID,
|
||||||
|
ACCESSOR,
|
||||||
|
this.chartConfig.dataView,
|
||||||
|
this.chartConfig.formulaAPI
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getVisualizationState(): MetricVisualizationState {
|
getVisualizationState(): MetricVisualizationState {
|
||||||
|
@ -33,8 +38,10 @@ export class MetricChart implements Chart<MetricVisualizationState> {
|
||||||
return this.chartConfig.layers.getReference(DEFAULT_LAYER_ID, this.chartConfig.dataView);
|
return this.chartConfig.layers.getReference(DEFAULT_LAYER_ID, this.chartConfig.dataView);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataView(): DataView {
|
getDataViews(): DataView[] {
|
||||||
return this.chartConfig.dataView;
|
return [this.chartConfig.dataView, this.chartConfig.layers.getDataView()].filter(
|
||||||
|
(x): x is DataView => !!x
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTitle(): string {
|
getTitle(): string {
|
|
@ -1,8 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
* or more contributor license agreements. Licensed under the Elastic License
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
* 2.0.
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
@ -13,8 +14,8 @@ import type {
|
||||||
} from '@kbn/lens-plugin/public';
|
} from '@kbn/lens-plugin/public';
|
||||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||||
import type { SavedObjectReference } from '@kbn/core/server';
|
import type { SavedObjectReference } from '@kbn/core/server';
|
||||||
|
import type { Chart, ChartConfig, ChartLayer } from '../types';
|
||||||
import { DEFAULT_LAYER_ID } from '../utils';
|
import { DEFAULT_LAYER_ID } from '../utils';
|
||||||
import type { Chart, ChartConfig, ChartLayer } from '../../types';
|
|
||||||
|
|
||||||
const ACCESSOR = 'formula_accessor';
|
const ACCESSOR = 'formula_accessor';
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ export interface XYVisualOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class XYChart implements Chart<XYState> {
|
export class XYChart implements Chart<XYState> {
|
||||||
|
private _layers: Array<ChartLayer<XYLayerConfig>> | null = null;
|
||||||
constructor(
|
constructor(
|
||||||
private chartConfig: ChartConfig<Array<ChartLayer<XYLayerConfig>>> & {
|
private chartConfig: ChartConfig<Array<ChartLayer<XYLayerConfig>>> & {
|
||||||
visualOptions?: XYVisualOptions;
|
visualOptions?: XYVisualOptions;
|
||||||
|
@ -37,13 +39,28 @@ export class XYChart implements Chart<XYState> {
|
||||||
return 'lnsXY';
|
return 'lnsXY';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get layers() {
|
||||||
|
if (!this._layers) {
|
||||||
|
this._layers = Array.isArray(this.chartConfig.layers)
|
||||||
|
? this.chartConfig.layers
|
||||||
|
: [this.chartConfig.layers];
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._layers;
|
||||||
|
}
|
||||||
|
|
||||||
getLayers(): FormBasedPersistedState['layers'] {
|
getLayers(): FormBasedPersistedState['layers'] {
|
||||||
return this.chartConfig.layers.reduce((acc, curr, index) => {
|
return this.layers.reduce((acc, curr, index) => {
|
||||||
const layerId = `${DEFAULT_LAYER_ID}_${index}`;
|
const layerId = `${DEFAULT_LAYER_ID}_${index}`;
|
||||||
const accessorId = `${ACCESSOR}_${index}`;
|
const accessorId = `${ACCESSOR}_${index}`;
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
...curr.getLayer(layerId, accessorId, this.chartConfig.dataView),
|
...curr.getLayer(
|
||||||
|
layerId,
|
||||||
|
accessorId,
|
||||||
|
this.chartConfig.dataView,
|
||||||
|
this.chartConfig.formulaAPI
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
@ -59,26 +76,29 @@ export class XYChart implements Chart<XYState> {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
fittingFunction: this.chartConfig.visualOptions?.missingValues ?? 'Zero',
|
fittingFunction: this.chartConfig.visualOptions?.missingValues ?? 'None',
|
||||||
endValue: this.chartConfig.visualOptions?.endValues,
|
endValue: this.chartConfig.visualOptions?.endValues,
|
||||||
curveType: this.chartConfig.visualOptions?.lineInterpolation ?? 'LINEAR',
|
curveType: this.chartConfig.visualOptions?.lineInterpolation,
|
||||||
emphasizeFitting: !this.chartConfig.visualOptions?.showDottedLine,
|
emphasizeFitting: !this.chartConfig.visualOptions?.showDottedLine,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getReferences(): SavedObjectReference[] {
|
getReferences(): SavedObjectReference[] {
|
||||||
return this.chartConfig.layers.flatMap((p, index) => {
|
return this.layers.flatMap((p, index) => {
|
||||||
const layerId = `${DEFAULT_LAYER_ID}_${index}`;
|
const layerId = `${DEFAULT_LAYER_ID}_${index}`;
|
||||||
return p.getReference(layerId, this.chartConfig.dataView);
|
return p.getReference(layerId, this.chartConfig.dataView);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataView(): DataView {
|
getDataViews(): DataView[] {
|
||||||
return this.chartConfig.dataView;
|
return [
|
||||||
|
this.chartConfig.dataView,
|
||||||
|
...this.chartConfig.layers.map((p) => p.getDataView()).filter((x): x is DataView => !!x),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTitle(): string {
|
getTitle(): string {
|
||||||
return this.chartConfig.title ?? this.chartConfig.layers[0].getName() ?? '';
|
return this.chartConfig.title ?? this.layers[0].getName() ?? '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
packages/kbn-lens-embeddable-utils/index.ts
Normal file
27
packages/kbn-lens-embeddable-utils/index.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './attribute_builder/types';
|
||||||
|
|
||||||
|
export type {
|
||||||
|
MetricLayerOptions,
|
||||||
|
XYLayerOptions,
|
||||||
|
XYVisualOptions,
|
||||||
|
} from './attribute_builder/visualization_types';
|
||||||
|
|
||||||
|
export {
|
||||||
|
FormulaDataColumn,
|
||||||
|
MetricChart,
|
||||||
|
MetricLayer,
|
||||||
|
ReferenceLineColumn,
|
||||||
|
XYChart,
|
||||||
|
XYDataLayer,
|
||||||
|
XYReferenceLinesLayer,
|
||||||
|
} from './attribute_builder/visualization_types';
|
||||||
|
|
||||||
|
export { LensAttributesBuilder } from './attribute_builder/lens_attributes_builder';
|
14
packages/kbn-lens-embeddable-utils/jest.config.js
Normal file
14
packages/kbn-lens-embeddable-utils/jest.config.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
preset: '@kbn/test',
|
||||||
|
rootDir: '../..',
|
||||||
|
roots: ['<rootDir>/packages/kbn-lens-embeddable-utils'],
|
||||||
|
setupFiles: ['jest-canvas-mock'],
|
||||||
|
};
|
5
packages/kbn-lens-embeddable-utils/kibana.jsonc
Normal file
5
packages/kbn-lens-embeddable-utils/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type": "shared-browser",
|
||||||
|
"id": "@kbn/lens-embeddable-utils",
|
||||||
|
"owner": "@elastic/infra-monitoring-ui"
|
||||||
|
}
|
6
packages/kbn-lens-embeddable-utils/package.json
Normal file
6
packages/kbn-lens-embeddable-utils/package.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "@kbn/lens-embeddable-utils",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||||
|
}
|
10
packages/kbn-lens-embeddable-utils/tsconfig.json
Normal file
10
packages/kbn-lens-embeddable-utils/tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "target/types",
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"include": ["**/*.ts"],
|
||||||
|
"exclude": ["target/**/*"],
|
||||||
|
"kbn_references": ["@kbn/core", "@kbn/data-plugin", "@kbn/data-views-plugin", "@kbn/lens-plugin"]
|
||||||
|
}
|
|
@ -914,6 +914,8 @@
|
||||||
"@kbn/kubernetes-security-plugin/*": ["x-pack/plugins/kubernetes_security/*"],
|
"@kbn/kubernetes-security-plugin/*": ["x-pack/plugins/kubernetes_security/*"],
|
||||||
"@kbn/language-documentation-popover": ["packages/kbn-language-documentation-popover"],
|
"@kbn/language-documentation-popover": ["packages/kbn-language-documentation-popover"],
|
||||||
"@kbn/language-documentation-popover/*": ["packages/kbn-language-documentation-popover/*"],
|
"@kbn/language-documentation-popover/*": ["packages/kbn-language-documentation-popover/*"],
|
||||||
|
"@kbn/lens-embeddable-utils": ["packages/kbn-lens-embeddable-utils"],
|
||||||
|
"@kbn/lens-embeddable-utils/*": ["packages/kbn-lens-embeddable-utils/*"],
|
||||||
"@kbn/lens-plugin": ["x-pack/plugins/lens"],
|
"@kbn/lens-plugin": ["x-pack/plugins/lens"],
|
||||||
"@kbn/lens-plugin/*": ["x-pack/plugins/lens/*"],
|
"@kbn/lens-plugin/*": ["x-pack/plugins/lens/*"],
|
||||||
"@kbn/license-api-guard-plugin": ["x-pack/plugins/license_api_guard"],
|
"@kbn/license-api-guard-plugin": ["x-pack/plugins/license_api_guard"],
|
||||||
|
|
|
@ -9,14 +9,6 @@ export type {
|
||||||
HostsLensFormulas,
|
HostsLensFormulas,
|
||||||
HostsLensMetricChartFormulas,
|
HostsLensMetricChartFormulas,
|
||||||
HostsLensLineChartFormulas,
|
HostsLensLineChartFormulas,
|
||||||
LensAttributes,
|
|
||||||
FormulaConfig,
|
|
||||||
Chart,
|
|
||||||
LensVisualizationState,
|
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
export { hostLensFormulas } from './constants';
|
export { hostLensFormulas } from './constants';
|
||||||
|
|
||||||
export * from './lens/visualization_types';
|
|
||||||
|
|
||||||
export { LensAttributesBuilder } from './lens/lens_attributes_builder';
|
|
||||||
|
|
|
@ -7,13 +7,10 @@
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
|
import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
|
||||||
import type { Layer } from '../../../../../hooks/use_lens_attributes';
|
import { UseLensAttributesMetricLayerConfig } from '../../../../../hooks/use_lens_attributes';
|
||||||
import { hostLensFormulas } from '../../../constants';
|
import { hostLensFormulas } from '../../../constants';
|
||||||
import { TOOLTIP } from './translations';
|
import { TOOLTIP } from './translations';
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
|
||||||
import type { MetricLayerOptions } from '../../visualization_types';
|
|
||||||
|
|
||||||
export const KPI_CHART_HEIGHT = 150;
|
export const KPI_CHART_HEIGHT = 150;
|
||||||
export const AVERAGE_SUBTITLE = i18n.translate(
|
export const AVERAGE_SUBTITLE = i18n.translate(
|
||||||
'xpack.infra.assetDetailsEmbeddable.overview.kpi.subtitle.average',
|
'xpack.infra.assetDetailsEmbeddable.overview.kpi.subtitle.average',
|
||||||
|
@ -23,7 +20,7 @@ export const AVERAGE_SUBTITLE = i18n.translate(
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface KPIChartProps extends Pick<TypedLensByValueInput, 'id' | 'title' | 'overrides'> {
|
export interface KPIChartProps extends Pick<TypedLensByValueInput, 'id' | 'title' | 'overrides'> {
|
||||||
layers: Layer<MetricLayerOptions, FormulaConfig, 'data'>;
|
layers: UseLensAttributesMetricLayerConfig;
|
||||||
toolTip: string;
|
toolTip: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,12 +33,14 @@ export const KPI_CHARTS: KPIChartProps[] = [
|
||||||
layers: {
|
layers: {
|
||||||
data: {
|
data: {
|
||||||
...hostLensFormulas.cpuUsage,
|
...hostLensFormulas.cpuUsage,
|
||||||
format: {
|
format: hostLensFormulas.cpuUsage.format
|
||||||
...hostLensFormulas.cpuUsage.format,
|
? {
|
||||||
params: {
|
...hostLensFormulas.cpuUsage.format,
|
||||||
decimals: 1,
|
params: {
|
||||||
},
|
decimals: 1,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
layerType: 'data',
|
layerType: 'data',
|
||||||
options: {
|
options: {
|
||||||
|
@ -62,12 +61,14 @@ export const KPI_CHARTS: KPIChartProps[] = [
|
||||||
layers: {
|
layers: {
|
||||||
data: {
|
data: {
|
||||||
...hostLensFormulas.normalizedLoad1m,
|
...hostLensFormulas.normalizedLoad1m,
|
||||||
format: {
|
format: hostLensFormulas.normalizedLoad1m.format
|
||||||
...hostLensFormulas.normalizedLoad1m.format,
|
? {
|
||||||
params: {
|
...hostLensFormulas.normalizedLoad1m.format,
|
||||||
decimals: 1,
|
params: {
|
||||||
},
|
decimals: 1,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
layerType: 'data',
|
layerType: 'data',
|
||||||
options: {
|
options: {
|
||||||
|
@ -85,12 +86,14 @@ export const KPI_CHARTS: KPIChartProps[] = [
|
||||||
layers: {
|
layers: {
|
||||||
data: {
|
data: {
|
||||||
...hostLensFormulas.memoryUsage,
|
...hostLensFormulas.memoryUsage,
|
||||||
format: {
|
format: hostLensFormulas.memoryUsage.format
|
||||||
...hostLensFormulas.memoryUsage.format,
|
? {
|
||||||
params: {
|
...hostLensFormulas.memoryUsage.format,
|
||||||
decimals: 1,
|
params: {
|
||||||
},
|
decimals: 1,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
layerType: 'data',
|
layerType: 'data',
|
||||||
options: {
|
options: {
|
||||||
|
@ -108,12 +111,14 @@ export const KPI_CHARTS: KPIChartProps[] = [
|
||||||
layers: {
|
layers: {
|
||||||
data: {
|
data: {
|
||||||
...hostLensFormulas.diskSpaceUsage,
|
...hostLensFormulas.diskSpaceUsage,
|
||||||
format: {
|
format: hostLensFormulas.diskSpaceUsage.format
|
||||||
...hostLensFormulas.diskSpaceUsage.format,
|
? {
|
||||||
params: {
|
...hostLensFormulas.diskSpaceUsage.format,
|
||||||
decimals: 1,
|
params: {
|
||||||
},
|
decimals: 1,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
layerType: 'data',
|
layerType: 'data',
|
||||||
options: {
|
options: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const cpuUsage: FormulaConfig = {
|
export const cpuUsage: FormulaValueConfig = {
|
||||||
label: 'CPU Usage',
|
label: 'CPU Usage',
|
||||||
value: '(average(system.cpu.user.pct) + average(system.cpu.system.pct)) / max(system.cpu.cores)',
|
value: '(average(system.cpu.user.pct) + average(system.cpu.system.pct)) / max(system.cpu.cores)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const diskIORead: FormulaConfig = {
|
export const diskIORead: FormulaValueConfig = {
|
||||||
label: 'Disk Read IOPS',
|
label: 'Disk Read IOPS',
|
||||||
value: "counter_rate(max(system.diskio.read.count), kql='system.diskio.read.count: *')",
|
value: "counter_rate(max(system.diskio.read.count), kql='system.diskio.read.count: *')",
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const diskReadThroughput: FormulaConfig = {
|
export const diskReadThroughput: FormulaValueConfig = {
|
||||||
label: 'Disk Read Throughput',
|
label: 'Disk Read Throughput',
|
||||||
value: "counter_rate(max(system.diskio.read.bytes), kql='system.diskio.read.bytes: *')",
|
value: "counter_rate(max(system.diskio.read.bytes), kql='system.diskio.read.bytes: *')",
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const diskSpaceAvailability: FormulaConfig = {
|
export const diskSpaceAvailability: FormulaValueConfig = {
|
||||||
label: 'Disk Space Availability',
|
label: 'Disk Space Availability',
|
||||||
value: '1 - average(system.filesystem.used.pct)',
|
value: '1 - average(system.filesystem.used.pct)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const diskSpaceAvailable: FormulaConfig = {
|
export const diskSpaceAvailable: FormulaValueConfig = {
|
||||||
label: 'Disk Space Available',
|
label: 'Disk Space Available',
|
||||||
value: 'average(system.filesystem.free)',
|
value: 'average(system.filesystem.free)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const diskSpaceUsage: FormulaConfig = {
|
export const diskSpaceUsage: FormulaValueConfig = {
|
||||||
label: 'Disk Space Usage',
|
label: 'Disk Space Usage',
|
||||||
value: 'average(system.filesystem.used.pct)',
|
value: 'average(system.filesystem.used.pct)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const diskIOWrite: FormulaConfig = {
|
export const diskIOWrite: FormulaValueConfig = {
|
||||||
label: 'Disk Write IOPS',
|
label: 'Disk Write IOPS',
|
||||||
value: "counter_rate(max(system.diskio.write.count), kql='system.diskio.write.count: *')",
|
value: "counter_rate(max(system.diskio.write.count), kql='system.diskio.write.count: *')",
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const diskWriteThroughput: FormulaConfig = {
|
export const diskWriteThroughput: FormulaValueConfig = {
|
||||||
label: 'Disk Write Throughput',
|
label: 'Disk Write Throughput',
|
||||||
value: "counter_rate(max(system.diskio.write.bytes), kql='system.diskio.write.bytes: *')",
|
value: "counter_rate(max(system.diskio.write.bytes), kql='system.diskio.write.bytes: *')",
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const hostCount: FormulaConfig = {
|
export const hostCount: FormulaValueConfig = {
|
||||||
label: 'Hosts',
|
label: 'Hosts',
|
||||||
value: 'unique_count(host.name)',
|
value: 'unique_count(host.name)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const logRate: FormulaConfig = {
|
export const logRate: FormulaValueConfig = {
|
||||||
label: 'Log Rate',
|
label: 'Log Rate',
|
||||||
value: 'differences(cumulative_sum(count()))',
|
value: 'differences(cumulative_sum(count()))',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const memoryFree: FormulaConfig = {
|
export const memoryFree: FormulaValueConfig = {
|
||||||
label: 'Memory Free',
|
label: 'Memory Free',
|
||||||
value: 'max(system.memory.total) - average(system.memory.actual.used.bytes)',
|
value: 'max(system.memory.total) - average(system.memory.actual.used.bytes)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const memoryUsage: FormulaConfig = {
|
export const memoryUsage: FormulaValueConfig = {
|
||||||
label: 'Memory Usage',
|
label: 'Memory Usage',
|
||||||
value: 'average(system.memory.actual.used.pct)',
|
value: 'average(system.memory.actual.used.pct)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const normalizedLoad1m: FormulaConfig = {
|
export const normalizedLoad1m: FormulaValueConfig = {
|
||||||
label: 'Normalized Load',
|
label: 'Normalized Load',
|
||||||
value: 'average(system.load.1) / max(system.load.cores)',
|
value: 'average(system.load.1) / max(system.load.cores)',
|
||||||
format: {
|
format: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const rx: FormulaConfig = {
|
export const rx: FormulaValueConfig = {
|
||||||
label: 'Network Inbound (RX)',
|
label: 'Network Inbound (RX)',
|
||||||
value:
|
value:
|
||||||
"average(host.network.ingress.bytes) * 8 / (max(metricset.period, kql='host.network.ingress.bytes: *') / 1000)",
|
"average(host.network.ingress.bytes) * 8 / (max(metricset.period, kql='host.network.ingress.bytes: *') / 1000)",
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { FormulaConfig } from '../../../types';
|
import type { FormulaValueConfig } from '@kbn/lens-embeddable-utils';
|
||||||
|
|
||||||
export const tx: FormulaConfig = {
|
export const tx: FormulaValueConfig = {
|
||||||
label: 'Network Outbound (TX)',
|
label: 'Network Outbound (TX)',
|
||||||
value:
|
value:
|
||||||
"average(host.network.egress.bytes) * 8 / (max(metricset.period, kql='host.network.egress.bytes: *') / 1000)",
|
"average(host.network.egress.bytes) * 8 / (max(metricset.period, kql='host.network.egress.bytes: *') / 1000)",
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 type { SavedObjectReference } from '@kbn/core/server';
|
|
||||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
|
||||||
import type {
|
|
||||||
FormulaPublicApi,
|
|
||||||
FormBasedPersistedState,
|
|
||||||
PersistedIndexPatternLayer,
|
|
||||||
XYDataLayerConfig,
|
|
||||||
SeriesType,
|
|
||||||
} from '@kbn/lens-plugin/public';
|
|
||||||
import type { ChartColumn, ChartLayer, FormulaConfig } from '../../../types';
|
|
||||||
import { getDefaultReferences, getHistogramColumn, getTopValuesColumn } from '../../utils';
|
|
||||||
import { FormulaColumn } from './column/formula';
|
|
||||||
|
|
||||||
const BREAKDOWN_COLUMN_NAME = 'aggs_breakdown';
|
|
||||||
const HISTOGRAM_COLUMN_NAME = 'x_date_histogram';
|
|
||||||
|
|
||||||
export interface XYLayerOptions {
|
|
||||||
breakdown?: {
|
|
||||||
size: number;
|
|
||||||
sourceField: string;
|
|
||||||
};
|
|
||||||
seriesType?: SeriesType;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface XYLayerConfig {
|
|
||||||
data: FormulaConfig[];
|
|
||||||
options?: XYLayerOptions;
|
|
||||||
formulaAPI: FormulaPublicApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class XYDataLayer implements ChartLayer<XYDataLayerConfig> {
|
|
||||||
private column: ChartColumn[];
|
|
||||||
constructor(private layerConfig: XYLayerConfig) {
|
|
||||||
this.column = layerConfig.data.map((p) => new FormulaColumn(p, layerConfig.formulaAPI));
|
|
||||||
}
|
|
||||||
|
|
||||||
getName(): string | undefined {
|
|
||||||
return this.column[0].getFormulaConfig().label;
|
|
||||||
}
|
|
||||||
|
|
||||||
getBaseLayer(dataView: DataView, options?: XYLayerOptions) {
|
|
||||||
return {
|
|
||||||
...getHistogramColumn({
|
|
||||||
columnName: HISTOGRAM_COLUMN_NAME,
|
|
||||||
overrides: {
|
|
||||||
sourceField: dataView.timeFieldName,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
...(options?.breakdown
|
|
||||||
? {
|
|
||||||
...getTopValuesColumn({
|
|
||||||
columnName: BREAKDOWN_COLUMN_NAME,
|
|
||||||
overrides: {
|
|
||||||
sourceField: options?.breakdown.sourceField,
|
|
||||||
breakdownSize: options?.breakdown.size,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getLayer(
|
|
||||||
layerId: string,
|
|
||||||
accessorId: string,
|
|
||||||
dataView: DataView
|
|
||||||
): FormBasedPersistedState['layers'] {
|
|
||||||
const baseLayer: PersistedIndexPatternLayer = {
|
|
||||||
columnOrder: [BREAKDOWN_COLUMN_NAME, HISTOGRAM_COLUMN_NAME],
|
|
||||||
columns: {
|
|
||||||
...this.getBaseLayer(dataView, this.layerConfig.options),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
[layerId]: this.column.reduce(
|
|
||||||
(acc, curr, index) => ({
|
|
||||||
...acc,
|
|
||||||
...curr.getData(`${accessorId}_${index}`, acc, dataView),
|
|
||||||
}),
|
|
||||||
baseLayer
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getReference(layerId: string, dataView: DataView): SavedObjectReference[] {
|
|
||||||
return getDefaultReferences(dataView, layerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
getLayerConfig(layerId: string, accessorId: string): XYDataLayerConfig {
|
|
||||||
return {
|
|
||||||
layerId,
|
|
||||||
seriesType: this.layerConfig.options?.seriesType ?? 'line',
|
|
||||||
accessors: this.column.map((_, index) => `${accessorId}_${index}`),
|
|
||||||
yConfig: [],
|
|
||||||
layerType: 'data',
|
|
||||||
xAccessor: HISTOGRAM_COLUMN_NAME,
|
|
||||||
splitAccessor: this.layerConfig.options?.breakdown ? BREAKDOWN_COLUMN_NAME : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,75 +5,7 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { SavedObjectReference } from '@kbn/core/server';
|
|
||||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
|
||||||
import type {
|
|
||||||
FormBasedPersistedState,
|
|
||||||
MetricVisualizationState,
|
|
||||||
PersistedIndexPatternLayer,
|
|
||||||
TypedLensByValueInput,
|
|
||||||
XYState,
|
|
||||||
FormulaPublicApi,
|
|
||||||
XYLayerConfig,
|
|
||||||
} from '@kbn/lens-plugin/public';
|
|
||||||
import { hostLensFormulas } from './constants';
|
import { hostLensFormulas } from './constants';
|
||||||
export type LensAttributes = TypedLensByValueInput['attributes'];
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
export type LensVisualizationState = XYState | MetricVisualizationState;
|
|
||||||
|
|
||||||
export interface VisualizationAttributesBuilder {
|
|
||||||
build(): LensAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Column
|
|
||||||
export interface ChartColumn {
|
|
||||||
getData(
|
|
||||||
id: string,
|
|
||||||
baseLayer: PersistedIndexPatternLayer,
|
|
||||||
dataView: DataView
|
|
||||||
): PersistedIndexPatternLayer;
|
|
||||||
getFormulaConfig(): FormulaConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Layer
|
|
||||||
export type LensLayerConfig = XYLayerConfig | MetricVisualizationState;
|
|
||||||
|
|
||||||
export interface ChartLayer<TLayerConfig extends LensLayerConfig> {
|
|
||||||
getName(): string | undefined;
|
|
||||||
getLayer(
|
|
||||||
layerId: string,
|
|
||||||
accessorId: string,
|
|
||||||
dataView: DataView
|
|
||||||
): FormBasedPersistedState['layers'];
|
|
||||||
getReference(layerId: string, dataView: DataView): SavedObjectReference[];
|
|
||||||
getLayerConfig(layerId: string, acessorId: string): TLayerConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chart
|
|
||||||
export interface Chart<TVisualizationState extends LensVisualizationState> {
|
|
||||||
getTitle(): string;
|
|
||||||
getVisualizationType(): string;
|
|
||||||
getLayers(): FormBasedPersistedState['layers'];
|
|
||||||
getVisualizationState(): TVisualizationState;
|
|
||||||
getReferences(): SavedObjectReference[];
|
|
||||||
getDataView(): DataView;
|
|
||||||
}
|
|
||||||
export interface ChartConfig<
|
|
||||||
TLayer extends ChartLayer<LensLayerConfig> | Array<ChartLayer<LensLayerConfig>>
|
|
||||||
> {
|
|
||||||
dataView: DataView;
|
|
||||||
layers: TLayer;
|
|
||||||
title?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Formula
|
|
||||||
type LensFormula = Parameters<FormulaPublicApi['insertOrReplaceFormulaColumn']>[1];
|
|
||||||
export type FormulaConfig = Omit<LensFormula, 'format' | 'formula'> & {
|
|
||||||
color?: string;
|
|
||||||
format: NonNullable<LensFormula['format']>;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type HostsLensFormulas = keyof typeof hostLensFormulas;
|
export type HostsLensFormulas = keyof typeof hostLensFormulas;
|
||||||
export type HostsLensMetricChartFormulas = Exclude<HostsLensFormulas, 'diskIORead' | 'diskIOWrite'>;
|
export type HostsLensMetricChartFormulas = Exclude<HostsLensFormulas, 'diskIORead' | 'diskIOWrite'>;
|
||||||
|
|
|
@ -11,22 +11,17 @@ import { i18n } from '@kbn/i18n';
|
||||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||||
import type { TimeRange } from '@kbn/es-query';
|
import type { TimeRange } from '@kbn/es-query';
|
||||||
import { FormattedMessage } from '@kbn/i18n-react';
|
import { FormattedMessage } from '@kbn/i18n-react';
|
||||||
import { HostMetricsExplanationContent } from '../../../../lens/metric_explanation/host_metrics_explanation_content';
|
import type { XYVisualOptions } from '@kbn/lens-embeddable-utils';
|
||||||
|
import { UseLensAttributesXYLayerConfig } from '../../../../../hooks/use_lens_attributes';
|
||||||
import { buildCombinedHostsFilter } from '../../../../../utils/filters/build';
|
import { buildCombinedHostsFilter } from '../../../../../utils/filters/build';
|
||||||
import type { Layer } from '../../../../../hooks/use_lens_attributes';
|
import { LensChart, type LensChartProps, HostMetricsExplanationContent } from '../../../../lens';
|
||||||
import { LensChart, type LensChartProps } from '../../../../lens';
|
import { hostLensFormulas } from '../../../../../common/visualizations';
|
||||||
import {
|
|
||||||
type FormulaConfig,
|
|
||||||
hostLensFormulas,
|
|
||||||
type XYLayerOptions,
|
|
||||||
type XYVisualOptions,
|
|
||||||
} from '../../../../../common/visualizations';
|
|
||||||
import { METRIC_CHART_HEIGHT } from '../../../constants';
|
import { METRIC_CHART_HEIGHT } from '../../../constants';
|
||||||
import { Popover } from '../../common/popover';
|
import { Popover } from '../../common/popover';
|
||||||
|
|
||||||
type DataViewOrigin = 'logs' | 'metrics';
|
type DataViewOrigin = 'logs' | 'metrics';
|
||||||
interface MetricChartConfig extends Pick<LensChartProps, 'id' | 'title' | 'overrides'> {
|
interface MetricChartConfig extends Pick<LensChartProps, 'id' | 'title' | 'overrides'> {
|
||||||
layers: Array<Layer<XYLayerOptions, FormulaConfig[]>>;
|
layers: UseLensAttributesXYLayerConfig;
|
||||||
toolTip: string;
|
toolTip: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,10 @@ import type { TimeRange } from '@kbn/es-query';
|
||||||
import { TypedLensByValueInput } from '@kbn/lens-plugin/public';
|
import { TypedLensByValueInput } from '@kbn/lens-plugin/public';
|
||||||
import { css } from '@emotion/react';
|
import { css } from '@emotion/react';
|
||||||
import { useEuiTheme } from '@elastic/eui';
|
import { useEuiTheme } from '@elastic/eui';
|
||||||
|
import { LensAttributes } from '@kbn/lens-embeddable-utils';
|
||||||
import { useKibanaContextForPlugin } from '../../hooks/use_kibana';
|
import { useKibanaContextForPlugin } from '../../hooks/use_kibana';
|
||||||
import { ChartLoadingProgress, ChartPlaceholder } from './chart_placeholder';
|
import { ChartLoadingProgress, ChartPlaceholder } from './chart_placeholder';
|
||||||
import { parseDateRange } from '../../utils/datemath';
|
import { parseDateRange } from '../../utils/datemath';
|
||||||
import { LensAttributes } from '../../common/visualizations';
|
|
||||||
|
|
||||||
export type LensWrapperProps = Omit<
|
export type LensWrapperProps = Omit<
|
||||||
TypedLensByValueInput,
|
TypedLensByValueInput,
|
||||||
|
|
|
@ -57,9 +57,15 @@ describe('useHostTable hook', () => {
|
||||||
data: [normalizedLoad1m],
|
data: [normalizedLoad1m],
|
||||||
layerType: 'data',
|
layerType: 'data',
|
||||||
options: {
|
options: {
|
||||||
|
buckets: {
|
||||||
|
type: 'date_histogram',
|
||||||
|
},
|
||||||
breakdown: {
|
breakdown: {
|
||||||
size: 10,
|
field: 'host.name',
|
||||||
sourceField: 'host.name',
|
type: 'top_values',
|
||||||
|
params: {
|
||||||
|
size: 10,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,13 +12,14 @@ import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||||
import type { Action, ActionExecutionContext } from '@kbn/ui-actions-plugin/public';
|
import type { Action, ActionExecutionContext } from '@kbn/ui-actions-plugin/public';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import useAsync from 'react-use/lib/useAsync';
|
import useAsync from 'react-use/lib/useAsync';
|
||||||
import { FormulaPublicApi, LayerType as LensLayerType } from '@kbn/lens-plugin/public';
|
import { FormulaPublicApi } from '@kbn/lens-plugin/public';
|
||||||
import { InfraClientSetupDeps } from '../types';
|
|
||||||
import {
|
import {
|
||||||
type XYLayerOptions,
|
type XYLayerOptions,
|
||||||
type MetricLayerOptions,
|
type MetricLayerOptions,
|
||||||
type FormulaConfig,
|
type FormulaValueConfig,
|
||||||
type LensAttributes,
|
type LensAttributes,
|
||||||
|
type StaticValueConfig,
|
||||||
|
type LensVisualizationState,
|
||||||
type XYVisualOptions,
|
type XYVisualOptions,
|
||||||
type Chart,
|
type Chart,
|
||||||
LensAttributesBuilder,
|
LensAttributesBuilder,
|
||||||
|
@ -27,48 +28,48 @@ import {
|
||||||
XYChart,
|
XYChart,
|
||||||
MetricChart,
|
MetricChart,
|
||||||
XYReferenceLinesLayer,
|
XYReferenceLinesLayer,
|
||||||
LensVisualizationState,
|
} from '@kbn/lens-embeddable-utils';
|
||||||
} from '../common/visualizations';
|
|
||||||
|
import { InfraClientSetupDeps } from '../types';
|
||||||
import { useLazyRef } from './use_lazy_ref';
|
import { useLazyRef } from './use_lazy_ref';
|
||||||
|
|
||||||
type LayerOptions = XYLayerOptions | MetricLayerOptions;
|
type Options = XYLayerOptions | MetricLayerOptions;
|
||||||
type ChartType = 'lnsXY' | 'lnsMetric';
|
|
||||||
type VisualOptions = XYVisualOptions;
|
|
||||||
export type LayerType = Exclude<LensLayerType, 'annotations' | 'metricTrendline'>;
|
|
||||||
|
|
||||||
export interface Layer<
|
interface StaticValueLayer {
|
||||||
TLayerOptions extends LayerOptions,
|
data: StaticValueConfig[];
|
||||||
TFormulaConfig extends FormulaConfig | FormulaConfig[],
|
layerType: 'referenceLine';
|
||||||
TLayerType extends LayerType = LayerType
|
|
||||||
> {
|
|
||||||
layerType: TLayerType;
|
|
||||||
data: TFormulaConfig;
|
|
||||||
options?: TLayerOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UseLensAttributesBaseParams<
|
interface FormulaValueLayer<
|
||||||
TOptions extends LayerOptions,
|
TOptions extends Options,
|
||||||
TLayers extends Array<Layer<TOptions, FormulaConfig[]>> | Layer<TOptions, FormulaConfig>
|
TData extends FormulaValueConfig[] | FormulaValueConfig
|
||||||
> {
|
> {
|
||||||
|
options?: TOptions;
|
||||||
|
data: TData;
|
||||||
|
layerType: 'data';
|
||||||
|
}
|
||||||
|
|
||||||
|
type XYLayerConfig = StaticValueLayer | FormulaValueLayer<XYLayerOptions, FormulaValueConfig[]>;
|
||||||
|
|
||||||
|
export type UseLensAttributesXYLayerConfig = XYLayerConfig | XYLayerConfig[];
|
||||||
|
export type UseLensAttributesMetricLayerConfig = FormulaValueLayer<
|
||||||
|
MetricLayerOptions,
|
||||||
|
FormulaValueConfig
|
||||||
|
>;
|
||||||
|
|
||||||
|
interface UseLensAttributesBaseParams {
|
||||||
dataView?: DataView;
|
dataView?: DataView;
|
||||||
layers: TLayers;
|
|
||||||
title?: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UseLensAttributesXYChartParams
|
interface UseLensAttributesXYChartParams extends UseLensAttributesBaseParams {
|
||||||
extends UseLensAttributesBaseParams<
|
layers: UseLensAttributesXYLayerConfig;
|
||||||
XYLayerOptions,
|
|
||||||
Array<Layer<XYLayerOptions, FormulaConfig[], 'data' | 'referenceLine'>>
|
|
||||||
> {
|
|
||||||
visualizationType: 'lnsXY';
|
visualizationType: 'lnsXY';
|
||||||
visualOptions?: XYVisualOptions;
|
visualOptions?: XYVisualOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UseLensAttributesMetricChartParams
|
interface UseLensAttributesMetricChartParams extends UseLensAttributesBaseParams {
|
||||||
extends UseLensAttributesBaseParams<
|
layers: UseLensAttributesMetricLayerConfig;
|
||||||
MetricLayerOptions,
|
|
||||||
Layer<MetricLayerOptions, FormulaConfig, 'data'>
|
|
||||||
> {
|
|
||||||
visualizationType: 'lnsMetric';
|
visualizationType: 'lnsMetric';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,13 +77,7 @@ export type UseLensAttributesParams =
|
||||||
| UseLensAttributesXYChartParams
|
| UseLensAttributesXYChartParams
|
||||||
| UseLensAttributesMetricChartParams;
|
| UseLensAttributesMetricChartParams;
|
||||||
|
|
||||||
export const useLensAttributes = ({
|
export const useLensAttributes = ({ dataView, ...params }: UseLensAttributesParams) => {
|
||||||
dataView,
|
|
||||||
layers,
|
|
||||||
title,
|
|
||||||
visualizationType,
|
|
||||||
...extraParams
|
|
||||||
}: UseLensAttributesParams) => {
|
|
||||||
const {
|
const {
|
||||||
services: { lens },
|
services: { lens },
|
||||||
} = useKibana<InfraClientSetupDeps>();
|
} = useKibana<InfraClientSetupDeps>();
|
||||||
|
@ -99,10 +94,7 @@ export const useLensAttributes = ({
|
||||||
visualization: chartFactory({
|
visualization: chartFactory({
|
||||||
dataView,
|
dataView,
|
||||||
formulaAPI,
|
formulaAPI,
|
||||||
layers,
|
...params,
|
||||||
title,
|
|
||||||
visualizationType,
|
|
||||||
...extraParams,
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -163,9 +155,9 @@ export const useLensAttributes = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
const getFormula = () => {
|
const getFormula = () => {
|
||||||
const firstDataLayer = [...(Array.isArray(layers) ? layers : [layers])].find(
|
const firstDataLayer = [
|
||||||
(p) => p.layerType === 'data'
|
...(Array.isArray(params.layers) ? params.layers : [params.layers]),
|
||||||
);
|
].find((p) => p.layerType === 'data');
|
||||||
|
|
||||||
if (!firstDataLayer) {
|
if (!firstDataLayer) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -181,80 +173,70 @@ export const useLensAttributes = ({
|
||||||
return { formula: getFormula(), attributes: attributes.current, getExtraActions, error };
|
return { formula: getFormula(), attributes: attributes.current, getExtraActions, error };
|
||||||
};
|
};
|
||||||
|
|
||||||
const chartFactory = <
|
const chartFactory = ({
|
||||||
TOptions,
|
|
||||||
TLayers extends Array<Layer<TOptions, FormulaConfig[]>> | Layer<TOptions, FormulaConfig>
|
|
||||||
>({
|
|
||||||
dataView,
|
dataView,
|
||||||
formulaAPI,
|
formulaAPI,
|
||||||
layers,
|
...params
|
||||||
title,
|
|
||||||
visualizationType,
|
|
||||||
visualOptions,
|
|
||||||
}: {
|
}: {
|
||||||
dataView: DataView;
|
dataView: DataView;
|
||||||
formulaAPI: FormulaPublicApi;
|
formulaAPI: FormulaPublicApi;
|
||||||
visualizationType: ChartType;
|
} & UseLensAttributesParams): Chart<LensVisualizationState> => {
|
||||||
layers: TLayers;
|
switch (params.visualizationType) {
|
||||||
title?: string;
|
|
||||||
visualOptions?: VisualOptions;
|
|
||||||
}): Chart<LensVisualizationState> => {
|
|
||||||
switch (visualizationType) {
|
|
||||||
case 'lnsXY':
|
case 'lnsXY':
|
||||||
if (!Array.isArray(layers)) {
|
if (!Array.isArray(params.layers)) {
|
||||||
throw new Error(`Invalid layers type. Expected an array of layers.`);
|
throw new Error(`Invalid layers type. Expected an array of layers.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getLayerClass = (layerType: LayerType) => {
|
const xyLayerFactory = (layer: XYLayerConfig) => {
|
||||||
switch (layerType) {
|
switch (layer.layerType) {
|
||||||
case 'data': {
|
case 'data': {
|
||||||
return XYDataLayer;
|
return new XYDataLayer({
|
||||||
|
data: layer.data,
|
||||||
|
options: layer.options,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
case 'referenceLine': {
|
case 'referenceLine': {
|
||||||
return XYReferenceLinesLayer;
|
return new XYReferenceLinesLayer({
|
||||||
|
data: layer.data,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid layerType: ${layerType}`);
|
throw new Error(`Invalid layerType`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return new XYChart({
|
return new XYChart({
|
||||||
dataView,
|
dataView,
|
||||||
layers: layers.map((layerItem) => {
|
formulaAPI,
|
||||||
const Layer = getLayerClass(layerItem.layerType);
|
layers: params.layers.map((layerItem) => {
|
||||||
return new Layer({
|
return xyLayerFactory(layerItem);
|
||||||
data: layerItem.data,
|
|
||||||
formulaAPI,
|
|
||||||
options: layerItem.options,
|
|
||||||
});
|
|
||||||
}),
|
}),
|
||||||
title,
|
title: params.title,
|
||||||
visualOptions,
|
visualOptions: params.visualOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
case 'lnsMetric':
|
case 'lnsMetric':
|
||||||
if (Array.isArray(layers)) {
|
if (Array.isArray(params.layers)) {
|
||||||
throw new Error(`Invalid layers type. Expected a single layer object.`);
|
throw new Error(`Invalid layers type. Expected a single layer object.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MetricChart({
|
return new MetricChart({
|
||||||
dataView,
|
dataView,
|
||||||
|
formulaAPI,
|
||||||
layers: new MetricLayer({
|
layers: new MetricLayer({
|
||||||
data: layers.data,
|
data: params.layers.data,
|
||||||
formulaAPI,
|
options: params.layers.options,
|
||||||
options: layers.options,
|
|
||||||
}),
|
}),
|
||||||
title,
|
title: params.title,
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported chart type: ${visualizationType}`);
|
throw new Error(`Unsupported chart type`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOpenInLensAction = (onExecute: () => void): Action => {
|
const getOpenInLensAction = (onExecute: () => void): Action => {
|
||||||
return {
|
return {
|
||||||
id: 'openInLens',
|
id: 'openInLens',
|
||||||
|
|
||||||
getDisplayName(_context: ActionExecutionContext): string {
|
getDisplayName(_context: ActionExecutionContext): string {
|
||||||
return i18n.translate('xpack.infra.hostsViewPage.tabs.metricsCharts.actions.openInLines', {
|
return i18n.translate('xpack.infra.hostsViewPage.tabs.metricsCharts.actions.openInLines', {
|
||||||
defaultMessage: 'Open in Lens',
|
defaultMessage: 'Open in Lens',
|
||||||
|
|
|
@ -6,15 +6,11 @@
|
||||||
*/
|
*/
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
|
import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
|
||||||
|
import type { XYVisualOptions } from '@kbn/lens-embeddable-utils';
|
||||||
import { LensChart } from '../../../../../../components/lens';
|
import { LensChart } from '../../../../../../components/lens';
|
||||||
import type { Layer } from '../../../../../../hooks/use_lens_attributes';
|
import type { UseLensAttributesXYLayerConfig } from '../../../../../../hooks/use_lens_attributes';
|
||||||
import { useMetricsDataViewContext } from '../../../hooks/use_data_view';
|
import { useMetricsDataViewContext } from '../../../hooks/use_data_view';
|
||||||
import { useUnifiedSearchContext } from '../../../hooks/use_unified_search';
|
import { useUnifiedSearchContext } from '../../../hooks/use_unified_search';
|
||||||
import type {
|
|
||||||
FormulaConfig,
|
|
||||||
XYLayerOptions,
|
|
||||||
XYVisualOptions,
|
|
||||||
} from '../../../../../../common/visualizations';
|
|
||||||
import { useHostsViewContext } from '../../../hooks/use_hosts_view';
|
import { useHostsViewContext } from '../../../hooks/use_hosts_view';
|
||||||
import { buildCombinedHostsFilter } from '../../../../../../utils/filters/build';
|
import { buildCombinedHostsFilter } from '../../../../../../utils/filters/build';
|
||||||
import { useHostsTableContext } from '../../../hooks/use_hosts_table';
|
import { useHostsTableContext } from '../../../hooks/use_hosts_table';
|
||||||
|
@ -23,7 +19,7 @@ import { METRIC_CHART_HEIGHT } from '../../../constants';
|
||||||
|
|
||||||
export interface MetricChartProps extends Pick<TypedLensByValueInput, 'id' | 'overrides'> {
|
export interface MetricChartProps extends Pick<TypedLensByValueInput, 'id' | 'overrides'> {
|
||||||
title: string;
|
title: string;
|
||||||
layers: Array<Layer<XYLayerOptions, FormulaConfig[]>>;
|
layers: UseLensAttributesXYLayerConfig;
|
||||||
visualOptions?: XYVisualOptions;
|
visualOptions?: XYVisualOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,10 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { EuiFlexGrid, EuiFlexItem, EuiText } from '@elastic/eui';
|
import { EuiFlexGrid, EuiFlexItem, EuiText, EuiFlexGroup, EuiSpacer } from '@elastic/eui';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { EuiSpacer } from '@elastic/eui';
|
import type { XYLayerOptions, XYVisualOptions } from '@kbn/lens-embeddable-utils';
|
||||||
import { EuiFlexGroup } from '@elastic/eui';
|
import { hostLensFormulas } from '../../../../../../common/visualizations';
|
||||||
import {
|
|
||||||
hostLensFormulas,
|
|
||||||
type XYVisualOptions,
|
|
||||||
type XYLayerOptions,
|
|
||||||
} from '../../../../../../common/visualizations';
|
|
||||||
import { HostMetricsExplanationContent } from '../../../../../../components/lens';
|
import { HostMetricsExplanationContent } from '../../../../../../components/lens';
|
||||||
import { MetricChart, MetricChartProps } from './metric_chart';
|
import { MetricChart, MetricChartProps } from './metric_chart';
|
||||||
import { Popover } from '../../table/popover';
|
import { Popover } from '../../table/popover';
|
||||||
|
@ -22,8 +17,11 @@ import { Popover } from '../../table/popover';
|
||||||
const DEFAULT_BREAKDOWN_SIZE = 20;
|
const DEFAULT_BREAKDOWN_SIZE = 20;
|
||||||
const XY_LAYER_OPTIONS: XYLayerOptions = {
|
const XY_LAYER_OPTIONS: XYLayerOptions = {
|
||||||
breakdown: {
|
breakdown: {
|
||||||
size: DEFAULT_BREAKDOWN_SIZE,
|
type: 'top_values',
|
||||||
sourceField: 'host.name',
|
field: 'host.name',
|
||||||
|
params: {
|
||||||
|
size: DEFAULT_BREAKDOWN_SIZE,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
"@kbn/logs-shared-plugin",
|
"@kbn/logs-shared-plugin",
|
||||||
"@kbn/licensing-plugin",
|
"@kbn/licensing-plugin",
|
||||||
"@kbn/aiops-utils",
|
"@kbn/aiops-utils",
|
||||||
|
"@kbn/lens-embeddable-utils"
|
||||||
],
|
],
|
||||||
"exclude": ["target/**/*"]
|
"exclude": ["target/**/*"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5984,6 +5984,10 @@
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
|
||||||
|
"@kbn/lens-embeddable-utils@link:packages/kbn-lens-embeddable-utils":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
"@kbn/visualizations-plugin@link:src/plugins/visualizations":
|
"@kbn/visualizations-plugin@link:src/plugins/visualizations":
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue