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 metric Viz config options, title position and sizing #124124

Merged
merged 24 commits into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
dbdc290
Add lens config options
shahzad31 Jan 31, 2022
b093f5e
Merge branch 'main' of github.com:elastic/kibana into lens-metric
shahzad31 Feb 1, 2022
ba3448e
Merge branch 'main' of github.com:elastic/kibana into lens-metric
shahzad31 Feb 1, 2022
932545d
wip
shahzad31 Feb 1, 2022
b3329c2
Pr feedback
shahzad31 Feb 1, 2022
e1b2643
simplify align
shahzad31 Feb 1, 2022
c1934ed
improve typing
shahzad31 Feb 1, 2022
b0aaec6
update typing
shahzad31 Feb 1, 2022
00328a7
Merge branch 'main' of github.com:elastic/kibana into lens-metric
shahzad31 Feb 3, 2022
da64340
PR feedback
shahzad31 Feb 3, 2022
5ebd718
Design PR feedback
shahzad31 Feb 4, 2022
9384fa1
snapshot
shahzad31 Feb 8, 2022
a0514f8
Merge branch 'main' of github.com:elastic/kibana into lens-metric
shahzad31 Feb 8, 2022
b9f7a61
Merge branch 'main' of github.com:elastic/kibana into lens-metric
shahzad31 Feb 9, 2022
3bfdf0b
update snap
shahzad31 Feb 9, 2022
159ffd0
Merge branch 'main' of github.com:elastic/kibana into lens-metric
shahzad31 Feb 11, 2022
05c8b50
Merge branch 'main' into lens-metric
kibanamachine Feb 11, 2022
56c0bb4
design suggestions
shahzad31 Feb 11, 2022
71c3162
Merge branch 'lens-metric' of github.com:shahzad31/kibana into lens-m…
shahzad31 Feb 11, 2022
321f8f3
Merge branch 'main' into lens-metric
kibanamachine Feb 15, 2022
b139f93
Use bottom as default position for title and some other small refacto…
VladLasitsa Feb 15, 2022
e4d3b03
Fix test
VladLasitsa Feb 15, 2022
cd89b4e
Fix shapshot
VladLasitsa Feb 15, 2022
8726fb8
Fix shapshot
VladLasitsa Feb 15, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,24 @@ export const metricChart: ExpressionFunctionDefinition<
defaultMessage: 'The chart title.',
}),
},
size: {
types: ['string'],
help: i18n.translate('xpack.lens.metric.size.help', {
defaultMessage: 'The chart size.',
shahzad31 marked this conversation as resolved.
Show resolved Hide resolved
}),
},
titlePosition: {
types: ['string'],
help: i18n.translate('xpack.lens.metric.titlePosition.help', {
defaultMessage: 'The chart title position.',
shahzad31 marked this conversation as resolved.
Show resolved Hide resolved
}),
},
MichaelMarcialis marked this conversation as resolved.
Show resolved Hide resolved
textAlign: {
types: ['string'],
help: i18n.translate('xpack.lens.metric.textAlignPosition.help', {
defaultMessage: 'The chart text align position.',
shahzad31 marked this conversation as resolved.
Show resolved Hide resolved
}),
},
description: {
types: ['string'],
help: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export interface MetricState {
layerType: LayerType;
colorMode?: ColorMode;
palette?: PaletteOutput<CustomPaletteParams>;
titlePosition?: 'top' | 'bottom';
size?: string;
textAlign?: 'left' | 'right' | 'center';
}

export interface MetricConfig extends Omit<MetricState, 'palette' | 'colorMode'> {
Expand Down
13 changes: 12 additions & 1 deletion x-pack/plugins/lens/public/metric_visualization/auto_scale.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@

import React from 'react';
import { throttle } from 'lodash';
import classNames from 'classnames';
import { EuiResizeObserver } from '@elastic/eui';

interface Props extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode | React.ReactNode[];
minScale?: number;
size?: string;
titlePosition?: string;
textAlign?: string;
}

interface State {
Expand Down Expand Up @@ -56,7 +60,7 @@ export class AutoScale extends React.Component<Props, State> {
};

render() {
const { children, minScale, ...rest } = this.props;
const { children, minScale, size, textAlign, titlePosition, ...rest } = this.props;
const { scale } = this.state;
const style = this.props.style || {};

Expand Down Expand Up @@ -85,6 +89,13 @@ export class AutoScale extends React.Component<Props, State> {
style={{
transform: `scale(${scale})`,
}}
className={classNames('lnsMetricExpression_container_scale', {
shahzad31 marked this conversation as resolved.
Show resolved Hide resolved
rowDirection: ['left', 'right'].includes(titlePosition ?? ''),
alignStart: ['left', 'top'].includes(textAlign ?? ''),
alignEnd: ['right', 'bottom'].includes(textAlign ?? ''),
shahzad31 marked this conversation as resolved.
Show resolved Hide resolved
alignCenter: ['center', 'middle'].includes(textAlign ?? ''),
[`titleSize${(size ?? 'xl').toUpperCase()}`]: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why the default size isn't handled on the toExpression level like position and alignment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed default here because we use default font size in class lnsMetricExpression__value and don't needed to add this class if size is not defained.

})}
>
{children}
</div>
Expand Down
77 changes: 73 additions & 4 deletions x-pack/plugins/lens/public/metric_visualization/expression.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,83 @@
text-align: center;

.lnsMetricExpression__value {
font-size: $euiSizeXXL * 2;
font-size: $euiFontSizeXXL * 2;
font-weight: $euiFontWeightSemiBold;
border-radius: $euiBorderRadius;
padding: 0 $euiSize;
}

.lnsMetricExpression__title {
font-size: $euiSizeXL;
font-size: $euiFontSizeXXL;
color: $euiTextColor;
&.reverseOrder {
order: 1;
}
}
}

.lnsMetricExpression_container_scale {
display: flex;
align-items: center;
flex-direction: column;
&.rowDirection {
flex-direction: row;
}
MichaelMarcialis marked this conversation as resolved.
Show resolved Hide resolved
&.alignStart {
align-items: start;
}
&.alignEnd {
align-items: end;
}
&.alignCenter {
align-items: center;
}
&.titleSizeXS {
.lnsMetricExpression__title {
font-size: $euiFontSizeS;
shahzad31 marked this conversation as resolved.
Show resolved Hide resolved
}
.lnsMetricExpression__value {
font-size: $euiFontSizeXS * 2;
}
}
&.titleSizeS {
.lnsMetricExpression__title {
font-size: $euiFontSizeS;
}
.lnsMetricExpression__value {
font-size: $euiFontSizeM * 2.25;
}
}
&.titleSizeM {
.lnsMetricExpression__title {
font-size: $euiFontSizeM;
}
.lnsMetricExpression__value {
font-size: $euiFontSizeL * 2;
}
}
&.titleSizeL {
.lnsMetricExpression__title {
font-size: $euiFontSizeL;
}
.lnsMetricExpression__value {
font-size: $euiFontSizeXL * 2;
}
}
&.titleSizeXL {
.lnsMetricExpression__title {
font-size: $euiFontSizeXL;
}
.lnsMetricExpression__value {
font-size: $euiFontSizeXXL * 2;
}
}

&.titleSizeXXL {
.lnsMetricExpression__title {
font-size: $euiFontSizeXXL;
}
.lnsMetricExpression__value {
font-size: $euiFontSizeXXL * 3;
}
}
}
}
15 changes: 9 additions & 6 deletions x-pack/plugins/lens/public/metric_visualization/expression.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import './expression.scss';
import { I18nProvider } from '@kbn/i18n-react';
import React from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import { IUiSettingsClient, ThemeServiceStart } from 'kibana/public';
import { KibanaThemeProvider } from '../../../../../src/plugins/kibana_react/public';
import type {
Expand Down Expand Up @@ -109,7 +110,7 @@ export function MetricChart({
formatFactory,
uiSettings,
}: MetricChartProps & { formatFactory: FormatFactory; uiSettings: IUiSettingsClient }) {
const { metricTitle, accessor, mode, colorMode, palette } = args;
const { metricTitle, accessor, mode, colorMode, palette, titlePosition, textAlign, size } = args;
const firstTable = Object.values(data.tables)[0];

const getEmptyState = () => (
Expand Down Expand Up @@ -144,19 +145,21 @@ export function MetricChart({

return (
<VisualizationContainer className="lnsMetricExpression__container" style={color}>
<AutoScale key={value}>
<div data-test-subj="lns_metric_value" className="lnsMetricExpression__value">
{value}
</div>
<AutoScale key={value} titlePosition={titlePosition} textAlign={textAlign} size={size}>
{mode === 'full' && (
<div
data-test-subj="lns_metric_title"
className="lnsMetricExpression__title"
className={classNames('lnsMetricExpression__title', {
reverseOrder: ['bottom', 'right'].includes(titlePosition ?? ''),
})}
style={colorMode === ColorMode.Background ? color : undefined}
>
{metricTitle}
</div>
)}
<div data-test-subj="lns_metric_value" className="lnsMetricExpression__value">
{value}
</div>
</AutoScale>
</VisualizationContainer>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiFormRow, EuiButtonGroup } from '@elastic/eui';
import { MetricState } from '../../../common/expressions';

export interface TitlePositionProps {
state: MetricState;
setState: (newState: MetricState) => void;
}

const alignButtonIcons = [
{
id: `left`,
label: i18n.translate('xpack.lens.metricChart.alignLabel.left', {
defaultMessage: 'Align left',
}),
iconType: 'editorAlignLeft',
},
{
id: `center`,
label: i18n.translate('xpack.lens.metricChart.alignLabel.center', {
defaultMessage: 'Align center',
}),
iconType: 'editorAlignCenter',
},
{
id: `right`,
label: i18n.translate('xpack.lens.metricChart.alignLabel.right', {
defaultMessage: 'Align right',
}),
iconType: 'editorAlignRight',
},
];

export const AlignOptions: React.FC<TitlePositionProps> = ({ state, setState }) => {
return (
<EuiFormRow
display="columnCompressed"
label={
<>
{i18n.translate('xpack.lens.metricChart.titleAlignLabel', {
defaultMessage: 'Align',
})}
</>
}
>
<EuiButtonGroup
legend={i18n.translate('xpack.lens.metricChart.titleAlignLabel', {
defaultMessage: 'Align',
})}
options={alignButtonIcons}
idSelected={state.textAlign ?? 'center'}
onChange={(id) => {
setState({ ...state, textAlign: id as MetricState['textAlign'] });
}}
isIconOnly
/>
</EuiFormRow>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { ToolbarPopover, TooltipWrapper } from '../../shared_components';
import { TitlePositionOptions } from './title_position_option';
import { FramePublicAPI } from '../../types';
import { MetricState } from '../../../common/expressions';
import { AlignOptions } from './align_options';
import { SizeOptions } from './size_options';

export interface VisualOptionsPopoverProps {
state: MetricState;
setState: (newState: MetricState) => void;
datasourceLayers: FramePublicAPI['datasourceLayers'];
}

export const AppearanceOptionsPopover: React.FC<VisualOptionsPopoverProps> = ({
state,
setState,
}) => {
return (
<TooltipWrapper
tooltipContent={i18n.translate('xpack.lens.shared.AppearanceLabel', {
defaultMessage: 'Appearance',
})}
condition={true}
>
<ToolbarPopover
title={i18n.translate('xpack.lens.shared.metric.appearanceLabel', {
defaultMessage: 'Appearance',
})}
type="visualOptions"
groupPosition="none"
buttonDataTestSubj="lnsMetricAppearanceButton"
>
<AlignOptions state={state} setState={setState} />
<SizeOptions state={state} setState={setState} />
<TitlePositionOptions state={state} setState={setState} />
</ToolbarPopover>
</TooltipWrapper>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React, { memo } from 'react';
import { EuiFlexGroup, EuiFlexItem, htmlIdGenerator } from '@elastic/eui';
import type { VisualizationToolbarProps } from '../../types';

import { AppearanceOptionsPopover } from './appearance_options_popover';
import { MetricState } from '../../../common/expressions';

export const MetricToolbar = memo(function MetricToolbar(
props: VisualizationToolbarProps<MetricState>
) {
const { state, setState, frame } = props;

return (
<EuiFlexGroup gutterSize="m" justifyContent="spaceBetween" responsive={false}>
<EuiFlexItem>
<EuiFlexGroup gutterSize="none" responsive={false}>
<AppearanceOptionsPopover
state={state}
setState={setState}
datasourceLayers={frame.datasourceLayers}
/>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
);
});

export const idPrefix = htmlIdGenerator()();
Loading