storybook/stories/metric/6_extra_badge.story.tsx (176 lines of code) (raw):
/*
* 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 { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui';
import { action } from '@storybook/addon-actions';
import { select, boolean, text, color, number } from '@storybook/addon-knobs';
import React from 'react';
import type { MetricWProgress, MetricWTrend, MetricWNumber } from '@elastic/charts';
import { Chart, isMetricElementEvent, Metric, MetricTrendShape, Settings } from '@elastic/charts';
import { KIBANA_METRICS } from '@elastic/charts/src/utils/data_samples/test_dataset_kibana';
import type { ChartsStory } from '../../types';
import { useBaseTheme } from '../../use_base_theme';
import { customKnobs } from '../utils/knobs';
export const Example: ChartsStory = (_, { title: storyTitle, description }) => {
const title = text('title', '21d7f8b7-92ea-41a0-8c03-0db0ec7e11b9');
const subtitle = text('subtitle', 'Cluster CPU usage');
const extraText = text('extra', 'trend');
const trendOptions = select(
'Trend option',
{
None: 'none',
Icon: 'icon',
Value: 'value',
Both: 'both',
},
'both',
);
const breakpointShow = select(
'Show breakpoints',
{
Small: 'small',
Big: 'big',
},
'small',
);
const progressOrTrend = select(
'progress or trend',
{
trend: 'trend',
bar: 'bar',
none: 'none',
},
'trend',
);
const progressBarDirection = select(
'progress bar direction',
{ horizontal: 'horizontal', vertical: 'vertical' },
'vertical',
);
const trendShape = customKnobs.fromEnum('trend shape', MetricTrendShape, MetricTrendShape.Area);
const progressMax = 100;
const value = text('value', '55.23');
const valuePrefix = '';
const valuePostfix = ' %';
const metricColor = color('color', '#3c3c3c');
const useValueColor = boolean('use value color', false);
const valueColor = color('value color', '#3c3c3c');
const showIcon = boolean('show icon', false);
const iconType = 'warning';
const useBlendingBackground = boolean('use blending background', false);
const blendingBackground = color('blending background', 'rgba(255,255,255,1)');
const valueFontSizeMode = select(
'value font mode',
{
Default: 'default',
Fit: 'fit',
Custom: 'custom',
},
'default',
);
const valueFontSize = number('value font size (px)', 40, { min: 0, step: 10 });
const titlesTextAlign = 'left';
const valuesTextAlign = 'right';
const iconAlign = 'right';
const getIcon =
(type: string) =>
({ width, height, color }: { width: number; height: number; color: string }) => (
<EuiIcon type={type} width={width} height={height} fill={color} style={{ width, height }} />
);
const data = {
color: metricColor,
title,
valueColor: useValueColor ? valueColor : undefined,
subtitle,
extra: ({ fontSize, color }: { fontSize: number; color: string }) => (
<>
{extraText}{' '}
{trendOptions === 'none' ? (
'99.99%'
) : (
<EuiBadge
color="success"
style={{ fontSize, lineHeight: `${fontSize}px`, border: `1px solid ${color}` }}
iconType={
['both', 'icon'].includes(trendOptions)
? () => <EuiIcon type="sortUp" style={{ inlineSize: fontSize, blockSize: fontSize }} />
: undefined
}
>
{trendOptions !== 'icon' ? '99.99%' : ''}
</EuiBadge>
)}
</>
),
...(showIcon ? { icon: getIcon(iconType) } : {}),
};
const numericData: MetricWProgress | MetricWNumber | MetricWTrend = {
...data,
value: Number.parseFloat(value),
valueFormatter: (d: number) => `${valuePrefix}${d}${valuePostfix}`,
...(progressOrTrend === 'bar' ? { domainMax: progressMax, progressBarDirection } : {}),
...(progressOrTrend === 'trend'
? {
trend: KIBANA_METRICS.metrics.kibana_os_load.v2.data.slice(0, 30).map(([x, y]) => ({ x, y })),
trendShape,
}
: {}),
};
const onEventClickAction = action('click');
const onEventOverAction = action('over');
const onEventOutAction = action('out');
const configuredData = [[numericData]];
const baseTheme = useBaseTheme();
const breakpoints = breakpointShow === 'small' ? ['200px', '300px', '400px'] : ['500px', '600px', '700px'];
return (
<>
<EuiFlexGroup>
{breakpoints.map((height, i) => (
<EuiFlexItem
key={height}
style={{
height,
width: '200px',
}}
>
<Chart title={storyTitle} description={description}>
<Settings
theme={{
metric: {
blendingBackground: useBlendingBackground ? blendingBackground : undefined,
valueFontSize: valueFontSizeMode === 'custom' ? valueFontSize : valueFontSizeMode,
titlesTextAlign,
valuesTextAlign,
iconAlign,
},
}}
baseTheme={baseTheme}
onElementClick={([d]) => {
if (isMetricElementEvent(d)) {
const { rowIndex, columnIndex } = d;
onEventClickAction(
`row:${rowIndex} col:${columnIndex} value:${configuredData[rowIndex][columnIndex].value}`,
);
}
}}
onElementOver={([d]) => {
if (isMetricElementEvent(d)) {
const { rowIndex, columnIndex } = d;
onEventOverAction(
`row:${rowIndex} col:${columnIndex} value:${configuredData[rowIndex][columnIndex].value}`,
);
}
}}
onElementOut={() => onEventOutAction('out')}
/>
<Metric id={`${i}`} data={configuredData} />
</Chart>
</EuiFlexItem>
))}
</EuiFlexGroup>
</>
);
};
Example.parameters = {
resize: {
height: '700px',
width: '1200px',
},
};