Alpha panel: new Timeline/Discrete panel (#31973)

This commit is contained in:
Leon Sorokin
2021-04-06 18:06:46 -05:00
committed by GitHub
parent ea202513cd
commit 6082a9360e
15 changed files with 1389 additions and 5 deletions

View File

@@ -0,0 +1,56 @@
import React, { useCallback } from 'react';
import { PanelProps } from '@grafana/data';
import { Timeline, GraphNGLegendEvent, TimelineOptions } from '@grafana/ui';
import { changeSeriesColorConfigFactory } from '../timeseries/overrides/colorSeriesConfigFactory';
import { hideSeriesConfigFactory } from '../timeseries/overrides/hideSeriesConfigFactory';
interface TimelinePanelProps extends PanelProps<TimelineOptions> {}
/**
* @alpha
*/
export const TimelinePanel: React.FC<TimelinePanelProps> = ({
data,
timeRange,
timeZone,
options,
width,
height,
fieldConfig,
onFieldConfigChange,
}) => {
const onLegendClick = useCallback(
(event: GraphNGLegendEvent) => {
onFieldConfigChange(hideSeriesConfigFactory(event, fieldConfig, data.series));
},
[fieldConfig, onFieldConfigChange, data.series]
);
const onSeriesColorChange = useCallback(
(label: string, color: string) => {
onFieldConfigChange(changeSeriesColorConfigFactory(label, color, fieldConfig));
},
[fieldConfig, onFieldConfigChange]
);
if (!data || !data.series?.length) {
return (
<div className="panel-empty">
<p>No data found in response</p>
</div>
);
}
return (
<Timeline
data={data.series}
timeRange={timeRange}
timeZone={timeZone}
width={width}
height={height}
onLegendClick={onLegendClick}
onSeriesColorChange={onSeriesColorChange}
{...options}
/>
);
};

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 81 80.91"><defs><style>.cls-1{fill:#3865ab;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:url(#linear-gradient-2);}.cls-4{fill:#84aff1;}.cls-5{fill:url(#linear-gradient-3);}.cls-6{fill:url(#linear-gradient-4);}.cls-7{fill:url(#linear-gradient-5);}.cls-8{fill:url(#linear-gradient-6);}</style><linearGradient id="linear-gradient" x1="8" y1="4" x2="70" y2="4" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f2cc0c"/><stop offset="1" stop-color="#ff9830"/></linearGradient><linearGradient id="linear-gradient-2" x1="30" y1="18.58" x2="51" y2="18.58" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-3" x1="0" y1="33.16" x2="37" y2="33.16" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-4" x1="20" y1="47.74" x2="45" y2="47.74" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-5" x1="49" y1="62.33" x2="60" y2="62.33" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-6" x1="13" y1="76.91" x2="73.5" y2="76.91" xlink:href="#linear-gradient"/></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" width="81" height="8" rx="1"/><rect class="cls-1" y="72.91" width="81" height="8" rx="1"/><rect class="cls-1" y="58.33" width="81" height="8" rx="1"/><rect class="cls-1" y="43.74" width="81" height="8" rx="1"/><rect class="cls-1" y="29.16" width="81" height="8" rx="1"/><rect class="cls-1" y="14.58" width="81" height="8" rx="1"/><path class="cls-2" d="M39,8H8V0H39ZM70,0H59V8H70Z"/><rect class="cls-3" x="30" y="14.58" width="21" height="8"/><rect class="cls-4" x="57.93" y="14.58" width="6" height="8"/><rect class="cls-4" x="11.17" y="14.58" width="6" height="8"/><path class="cls-5" d="M37,37.16H1a1,1,0,0,1-1-1v-6a1,1,0,0,1,1-1H37Z"/><rect class="cls-4" x="62.5" y="29.16" width="11" height="8"/><rect class="cls-6" x="20" y="43.74" width="25" height="8"/><path class="cls-4" d="M80,51.74H52v-8H80a1,1,0,0,1,1,1v6A1,1,0,0,1,80,51.74Z"/><rect class="cls-7" x="49" y="58.33" width="11" height="8"/><path class="cls-4" d="M30,66.33H1a1,1,0,0,1-1-1v-6a1,1,0,0,1,1-1H30Z"/><path class="cls-8" d="M24,80.91H13v-8H24Zm49.5-8h-33v8h33Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,107 @@
import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data';
import { TimelinePanel } from './TimelinePanel';
import { TimelineOptions, TimelineFieldConfig, BarValueVisibility } from '@grafana/ui';
//import { addHideFrom, addLegendOptions } from '../timeseries/config';
//import { defaultBarChartFieldConfig } from '@grafana/ui/src/components/BarChart/types';
import { TimelineMode } from '@grafana/ui/src/components/Timeline/types';
export const plugin = new PanelPlugin<TimelineOptions, TimelineFieldConfig>(TimelinePanel)
.useFieldConfig({
standardOptions: {
[FieldConfigProperty.Color]: {
settings: {
byValueSupport: true,
},
defaultValue: {
mode: FieldColorModeId.PaletteClassic,
},
},
},
/*
useCustomConfig: (builder) => {
const cfg = defaultBarChartFieldConfig;
builder
.addSliderInput({
path: 'lineWidth',
name: 'Line width',
defaultValue: cfg.lineWidth,
settings: {
min: 0,
max: 10,
step: 1,
},
})
.addSliderInput({
path: 'fillOpacity',
name: 'Fill opacity',
defaultValue: cfg.fillOpacity,
settings: {
min: 0,
max: 100,
step: 1,
},
})
.addRadio({
path: 'gradientMode',
name: 'Gradient mode',
defaultValue: graphFieldOptions.fillGradient[0].value,
settings: {
options: graphFieldOptions.fillGradient,
},
});
// addAxisConfig(builder, cfg, true);
addHideFrom(builder);
},
*/
})
.setPanelOptions((builder) => {
builder
.addRadio({
path: 'mode',
name: 'Mode',
defaultValue: TimelineMode.Spans,
settings: {
options: [
{ label: 'Spans', value: TimelineMode.Spans },
{ label: 'Grid', value: TimelineMode.Grid },
],
},
})
.addRadio({
path: 'showValue',
name: 'Show values',
settings: {
options: [
//{ value: BarValueVisibility.Auto, label: 'Auto' },
{ value: BarValueVisibility.Always, label: 'Always' },
{ value: BarValueVisibility.Never, label: 'Never' },
],
},
defaultValue: BarValueVisibility.Always,
})
.addSliderInput({
path: 'rowHeight',
name: 'Row height',
defaultValue: 0.9,
settings: {
min: 0,
max: 1,
step: 0.01,
},
})
.addSliderInput({
path: 'colWidth',
name: 'Column width',
defaultValue: 0.9,
settings: {
min: 0,
max: 1,
step: 0.01,
},
showIf: ({ mode }) => mode === TimelineMode.Grid,
});
//addLegendOptions(builder);
});

View File

@@ -0,0 +1,18 @@
{
"type": "panel",
"name": "Timeline",
"id": "timeline",
"state": "alpha",
"info": {
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
},
"logos": {
"small": "img/timeline.svg",
"large": "img/timeline.svg"
}
}
}

View File

@@ -24,6 +24,7 @@ import {
GraphGradientMode,
LegendDisplayMode,
AxisConfig,
HideableFieldConfig,
} from '@grafana/ui';
import { SeriesConfigEditor } from './HideSeriesConfigEditor';
import { ScaleDistributionEditor } from './ScaleDistributionEditor';
@@ -185,7 +186,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig): SetFieldConfigOption
};
}
export function addHideFrom(builder: FieldConfigEditorBuilder<AxisConfig>) {
export function addHideFrom(builder: FieldConfigEditorBuilder<HideableFieldConfig>) {
builder.addCustomEditor({
id: 'hideFrom',
name: 'Hide in area',