storybook/stories/interactions/18_null_values.story.tsx (158 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 { action } from '@storybook/addon-actions';
import { boolean, select } from '@storybook/addon-knobs';
import React from 'react';
import type { PointerEvent } from '@elastic/charts';
import {
Axis,
BarSeries,
Chart,
Position,
ScaleType,
Settings,
Placement,
niceTimeFormatter,
TooltipType,
LineSeries,
AreaSeries,
RectAnnotation,
Tooltip,
} from '@elastic/charts';
import { KIBANA_METRICS } from '@elastic/charts/src/utils/data_samples/test_dataset_kibana';
import { palettes } from '@elastic/charts/src/utils/themes/legacy_colors';
import type { ChartsStory } from '../../types';
import { useBaseTheme } from '../../use_base_theme';
const chartTypes: Record<string, any> = {
bar: BarSeries,
line: LineSeries,
area: AreaSeries,
};
const getSeriesKnob = (group?: string) => {
const type =
select<string>(
'Series type',
{
Bar: 'bar',
Line: 'line',
Area: 'area',
},
'area',
group,
) ?? 'area';
return chartTypes[type] ?? BarSeries;
};
export const Example: ChartsStory = (_, { title, description }) => {
const ref1 = React.useRef<Chart>(null);
const ref2 = React.useRef<Chart>(null);
const pointerUpdate = (event: PointerEvent) => {
action('onPointerUpdate')(event);
if (ref1.current) {
ref1.current.dispatchExternalPointerEvent(event);
}
if (ref2.current) {
ref2.current.dispatchExternalPointerEvent(event);
}
};
const { data } = KIBANA_METRICS.metrics.kibana_os_load.v1;
const data1 = KIBANA_METRICS.metrics.kibana_os_load.v1.data;
const data2 = KIBANA_METRICS.metrics.kibana_os_load.v2.data;
const TopSeries = getSeriesKnob();
const BottomSeries = getSeriesKnob();
const showNullValues = boolean('show null values', true);
return (
<>
<Chart
title={title}
description={description}
className="story-chart"
ref={ref1}
size={{ height: '50%' }}
id="chart1"
>
<Settings
baseTheme={useBaseTheme()}
onPointerUpdate={pointerUpdate}
pointerUpdateDebounce={0}
pointerUpdateTrigger="x"
externalPointerEvents={{
tooltip: { visible: true, placement: Placement.Left },
}}
/>
<Tooltip type={TooltipType.VerticalCursor} showNullValues={showNullValues} />
<Axis
id="bottom"
position={Position.Bottom}
tickFormat={niceTimeFormatter([data[0][0], data[data.length - 1][0]])}
/>
<Axis
id="left2"
ticks={3}
position={Position.Left}
tickFormat={(d: any) => (d === null ? 'N/A' : Number(d).toFixed(2))}
/>
<RectAnnotation
dataValues={[
{
coordinates: { x0: data2[10][0], x1: data2[29][0] },
},
]}
id="zoomed"
hideTooltips
/>
<TopSeries
id="Top"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={data1.slice(2, 35).map((d, i) => {
if (i === 7 || i === 11 || i === 12) {
return [d[0], null];
}
return d;
})}
/>
</Chart>
<Chart
title={title}
description={description}
className="story-chart"
ref={ref2}
size={{ height: '50%' }}
id="chart2"
>
<Settings
baseTheme={useBaseTheme()}
onPointerUpdate={pointerUpdate}
externalPointerEvents={{
tooltip: { visible: true, placement: Placement.Left, boundary: 'chart' },
}}
/>
<Tooltip type={TooltipType.VerticalCursor} showNullValues={showNullValues} />
<Axis
id="bottom"
position={Position.Bottom}
tickFormat={niceTimeFormatter([data[0][0], data[data.length - 1][0]])}
/>
<Axis
id="left2"
position={Position.Left}
ticks={3}
tickFormat={(d: any) => (d === null ? 'N/A' : Number(d).toFixed(2))}
domain={{ min: 5, max: 20 }}
/>
<BottomSeries
id="Bottom"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={data2.slice(10, 30).map((d, i) => {
if (i === 4 || i === 10) {
return [d[0], null];
}
return d;
})}
color={palettes.echPaletteForLightBackground.colors[0]}
/>
</Chart>
</>
);
};