Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Add gauges visualization #118616

Merged
merged 51 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
0d81686
add gauge chart expression
mbondyra Nov 23, 2021
ff06e33
excluding staticValue from suggestion for other visualizations
mbondyra Nov 23, 2021
48b0b02
adding prioritized operation for visualization groups (when dropping,…
mbondyra Nov 23, 2021
63eea38
changing the group for metric in chart switcher
mbondyra Nov 23, 2021
9599cd1
only access the activeData if exists (avoids error in console)
mbondyra Nov 23, 2021
1dda8b5
Adding gauge chart
mbondyra Nov 23, 2021
1eb65d8
round nicely the maximum value
mbondyra Nov 23, 2021
3fcfd91
fix warnings
mbondyra Nov 23, 2021
1b6e4d5
fixing rounding
mbondyra Nov 23, 2021
fbdd2fa
fixing tests
mbondyra Nov 24, 2021
a00d0ad
suggestions tests
mbondyra Nov 24, 2021
651a93e
suggestions tbc
mbondyra Nov 24, 2021
577ee78
tests for staticValue limitations
mbondyra Nov 24, 2021
594f93e
added tests to visualization.ts
mbondyra Nov 24, 2021
7e966ec
correct bands
mbondyra Nov 25, 2021
b52b1b2
wip
mbondyra Nov 25, 2021
96f363c
added tests
mbondyra Nov 25, 2021
bc94d66
suggestions
mbondyra Nov 25, 2021
81088a9
palete fixes & tests
mbondyra Nov 26, 2021
909a720
fix magic max
mbondyra Nov 29, 2021
b9ec54d
metric should not overflow
mbondyra Nov 29, 2021
940b5bd
address review
mbondyra Nov 29, 2021
9c74621
[Lens] adding toolbar tests
mbondyra Nov 30, 2021
ba83d44
limit domain to <min, max>
mbondyra Nov 30, 2021
53d3df2
Merge commit 'b8a7370156d51128e75815fde8c328d878d712ab' into lens/gau…
mbondyra Nov 30, 2021
730ce3f
changes the order of experimental badge and dataLoss indicator
mbondyra Nov 30, 2021
f386f6f
fix i18n
mbondyra Nov 30, 2021
c811681
Merge commit '92672187771beee8d8b1b39e1fcfd4d0d43fd354' into lens/gauges
mbondyra Dec 1, 2021
41f6062
address feedback p1
mbondyra Dec 1, 2021
41a7133
don't show required nor optional for max/min dimensions
mbondyra Dec 1, 2021
d0d3b44
fix types
mbondyra Dec 1, 2021
5f0425a
Merge commit 'f4bfd4dfc0cd6b4ba2f6e0a2060b02cdc546ed81' into lens/gauges
mbondyra Dec 1, 2021
6c6cb04
tests fixed
mbondyra Dec 1, 2021
6e94ede
fix types
mbondyra Dec 1, 2021
49baac9
last piece of gauge feedback
mbondyra Dec 1, 2021
8b8d714
Merge commit '42e2e782532dbbf27bbb942b964e43ce65450f62' into lens/gauges
mbondyra Dec 2, 2021
85b7ecb
change naming from title and subtitle to labelMajor and labelMinor
mbondyra Dec 2, 2021
ddddfba
fix bug with percent color bands
mbondyra Dec 2, 2021
68e4483
Merge branch 'main' into lens/gauges
kibanamachine Dec 2, 2021
546420c
Merge commit 'fea14a0da5de5adf4baa54b5cfe4876952afe8d2' into lens/gauges
mbondyra Dec 3, 2021
a9c8a65
functional tests
mbondyra Dec 3, 2021
c10c882
metric shouldn't have static value
mbondyra Dec 3, 2021
a356ce9
pass formatter to metric
mbondyra Dec 3, 2021
bd79625
fake formatter
mbondyra Dec 3, 2021
986ba6f
Merge branch 'main' into lens/gauges
kibanamachine Dec 6, 2021
bbfefa0
fix css and replace emptyPlaceholder
mbondyra Dec 6, 2021
062aa5a
fix tests
mbondyra Dec 6, 2021
95069cf
Merge commit 'ccffda0aea918949888240cc2c20d3f799296b4a' into lens/gauges
mbondyra Dec 7, 2021
f595550
fix static values
mbondyra Dec 7, 2021
7949d0f
name changes
mbondyra Dec 7, 2021
d702bb9
breaking functional
mbondyra Dec 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions x-pack/plugins/lens/common/expressions/gauge_chart/gauge_chart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* 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 { i18n } from '@kbn/i18n';
import type { ExpressionFunctionDefinition } from '../../../../../../src/plugins/expressions/common';
import type { LensMultiTable } from '../../types';
import { GaugeExpressionArgs, GAUGE_FUNCTION, GAUGE_FUNCTION_RENDERER } from './types';

export interface GaugeExpressionProps {
data: LensMultiTable;
args: GaugeExpressionArgs;
}
export interface GaugeRender {
type: 'render';
as: typeof GAUGE_FUNCTION_RENDERER;
value: GaugeExpressionProps;
}

export const gauge: ExpressionFunctionDefinition<
typeof GAUGE_FUNCTION,
LensMultiTable,
GaugeExpressionArgs,
GaugeRender
> = {
name: GAUGE_FUNCTION,
type: 'render',
help: i18n.translate('xpack.lens.gauge.expressionHelpLabel', {
defaultMessage: 'Gauge renderer',
}),
args: {
title: {
types: ['string'],
help: i18n.translate('xpack.lens.gauge.title.help', {
defaultMessage: 'Saved gauge title',
}),
},
shape: {
types: ['string'],
options: ['horizontalBullet', 'verticalBullet'],
help: i18n.translate('xpack.lens.gauge.shape.help', {
defaultMessage: 'Type of gauge chart',
}),
},
description: {
types: ['string'],
help: i18n.translate('xpack.lens.gauge.description.help', {
defaultMessage: 'Saved gauge description',
}),
},
metricAccessor: {
types: ['string'],
help: i18n.translate('xpack.lens.gauge.metricAccessor.help', {
defaultMessage: 'Current value',
}),
},
minAccessor: {
types: ['string'],
help: i18n.translate('xpack.lens.gauge.minAccessor.help', {
defaultMessage: 'Minimum value',
}),
},
maxAccessor: {
types: ['string'],
help: i18n.translate('xpack.lens.gauge.maxAccessor.help', {
defaultMessage: 'Maximum value',
}),
},
goalAccessor: {
types: ['string'],
help: i18n.translate('xpack.lens.gauge.goalAccessor.help', {
defaultMessage: 'Goal Value',
}),
},
colorMode: {
types: ['string'],
default: 'none',
options: ['none', 'palette'],
help: i18n.translate('xpack.lens.gauge.colorMode.help', {
defaultMessage: 'Which part of gauge to color',
}),
},
palette: {
types: ['palette'],
help: i18n.translate('xpack.lens.metric.palette.help', {
defaultMessage: 'Provides colors for the values',
}),
},
ticksPosition: {
types: ['string'],
options: ['auto', 'bands'],
help: i18n.translate('xpack.lens.gaugeChart.config.ticksPosition.help', {
defaultMessage: 'Specifies the placement of ticks',
}),
required: true,
},
labelMajor: {
types: ['string'],
help: i18n.translate('xpack.lens.gaugeChart.config.labelMajor.help', {
defaultMessage: 'Specifies the labelMajor of the gauge chart displayed inside the chart.',
}),
required: false,
},
labelMajorMode: {
types: ['string'],
options: ['none', 'auto', 'custom'],
help: i18n.translate('xpack.lens.gaugeChart.config.labelMajorMode.help', {
defaultMessage: 'Specifies the mode of labelMajor',
}),
required: true,
},
labelMinor: {
types: ['string'],
help: i18n.translate('xpack.lens.gaugeChart.config.labelMinor.help', {
defaultMessage: 'Specifies the labelMinor of the gauge chart',
}),
required: false,
},
},
inputTypes: ['lens_multitable'],
fn(data: LensMultiTable, args: GaugeExpressionArgs) {
return {
type: 'render',
as: GAUGE_FUNCTION_RENDERER,
value: {
data,
args,
},
};
},
};
9 changes: 9 additions & 0 deletions x-pack/plugins/lens/common/expressions/gauge_chart/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export * from './gauge_chart';
export * from './types';
73 changes: 73 additions & 0 deletions x-pack/plugins/lens/common/expressions/gauge_chart/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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 {
PaletteOutput,
CustomPaletteState,
} from '../../../../../../src/plugins/charts/common';
import type { CustomPaletteParams, LayerType } from '../../types';

export const GAUGE_FUNCTION = 'lens_gauge';
export const GAUGE_FUNCTION_RENDERER = 'lens_gauge_renderer';

export const GaugeShapes = {
horizontalBullet: 'horizontalBullet',
verticalBullet: 'verticalBullet',
} as const;

export const GaugeTicksPositions = {
auto: 'auto',
bands: 'bands',
} as const;

export const GaugeLabelMajorModes = {
auto: 'auto',
custom: 'custom',
none: 'none',
} as const;

export const GaugeColorModes = {
palette: 'palette',
none: 'none',
} as const;

export type GaugeType = 'gauge';
export type GaugeColorMode = keyof typeof GaugeColorModes;
export type GaugeShape = keyof typeof GaugeShapes;
export type GaugeLabelMajorMode = keyof typeof GaugeLabelMajorModes;
export type GaugeTicksPosition = keyof typeof GaugeTicksPositions;

export interface SharedGaugeLayerState {
metricAccessor?: string;
minAccessor?: string;
maxAccessor?: string;
goalAccessor?: string;
ticksPosition: GaugeTicksPosition;
labelMajorMode: GaugeLabelMajorMode;
labelMajor?: string;
labelMinor?: string;
colorMode?: GaugeColorMode;
palette?: PaletteOutput<CustomPaletteParams>;
shape: GaugeShape;
}

export type GaugeLayerState = SharedGaugeLayerState & {
layerId: string;
layerType: LayerType;
};

export type GaugeVisualizationState = GaugeLayerState & {
shape: GaugeShape;
};

export type GaugeExpressionArgs = SharedGaugeLayerState & {
title?: string;
description?: string;
shape: GaugeShape;
colorMode: GaugeColorMode;
palette?: PaletteOutput<CustomPaletteState>;
};
1 change: 1 addition & 0 deletions x-pack/plugins/lens/common/expressions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from './rename_columns';
export * from './merge_tables';
export * from './time_scale';
export * from './datatable';
export * from './gauge_chart';
export * from './metric_chart';
export * from './pie_chart';
export * from './xy_chart';
Expand Down
61 changes: 61 additions & 0 deletions x-pack/plugins/lens/public/assets/chart_gauge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* 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 { EuiIconProps } from '@elastic/eui';
import React from 'react';

export const LensIconChartGaugeHorizontal = ({
title,
titleId,
...props
}: Omit<EuiIconProps, 'type'>) => (
<svg
width="30"
height="22"
viewBox="0 0 30 22"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-labelledby={titleId}
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path
className="lensChartIcon__subdued"
d="M1 13a1 1 0 00-1 1v2a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-2a1 1 0 00-1-1H1z"
/>
<path
className="lensChartIcon__accent"
d="M0 6a1 1 0 011-1h24a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1V6z"
/>
</svg>
);

export const LensIconChartGaugeVertical = ({
title,
titleId,
...props
}: Omit<EuiIconProps, 'type'>) => (
<svg
width="30"
height="22"
viewBox="0 0 30 22"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-labelledby={titleId}
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path
className="lensChartIcon__accent"
d="M16 22a1 1 0 01-1-1V4a1 1 0 011-1h4a1 1 0 011 1v17a1 1 0 01-1 1h-4z"
/>
<path
className="lensChartIcon__subdued"
d="M10 0h2a1 1 0 011 1v20a1 1 0 01-1 1h-2a1 1 0 110-2h1v-3h-1a1 1 0 110-2h1v-3h-1a1 1 0 110-2h1V7h-1a1 1 0 010-2h1V2h-1a1 1 0 010-2z"
/>
</svg>
);
2 changes: 2 additions & 0 deletions x-pack/plugins/lens/public/async_services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export * from './xy_visualization/xy_visualization';
export * from './xy_visualization';
export * from './heatmap_visualization/heatmap_visualization';
export * from './heatmap_visualization';
export * from './visualizations/gauge/gauge_visualization';
export * from './visualizations/gauge';

export * from './indexpattern_datasource/indexpattern';
export * from './indexpattern_datasource';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,36 @@ describe('Datatable Visualization', () => {
expect(suggestions.length).toBeGreaterThan(0);
});

it('should reject suggestion with static value', () => {
function staticValueCol(columnId: string): TableSuggestionColumn {
return {
columnId,
operation: {
dataType: 'number',
label: `Static value: ${columnId}`,
isBucketed: false,
isStaticValue: true,
},
};
}
const suggestions = datatableVisualization.getSuggestions({
state: {
layerId: 'first',
layerType: layerTypes.DATA,
columns: [{ columnId: 'col1' }],
},
table: {
isMultiRow: true,
layerId: 'first',
changeType: 'initial',
columns: [staticValueCol('col1'), strCol('col2')],
},
keptLayerIds: [],
});

expect(suggestions).toHaveLength(0);
});

it('should retain width and hidden config from existing state', () => {
const suggestions = datatableVisualization.getSuggestions({
state: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ export const getDatatableVisualization = ({
if (
keptLayerIds.length > 1 ||
(keptLayerIds.length && table.layerId !== keptLayerIds[0]) ||
(state && table.changeType === 'unchanged')
(state && table.changeType === 'unchanged') ||
table.columns.some((col) => col.operation.isStaticValue)
) {
return [];
}
Expand Down
Loading