mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
State-timeline: support migrating from discrete panel (#35071)
This commit is contained in:
parent
f7893ca5cf
commit
a9b5aa1088
@ -0,0 +1,67 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Timeline Migrations from discrete panel 1`] = `
|
||||||
|
Object {
|
||||||
|
"fieldConfig": Object {
|
||||||
|
"defaults": Object {
|
||||||
|
"custom": Object {
|
||||||
|
"fillOpacity": 100,
|
||||||
|
"lineWidth": 0,
|
||||||
|
},
|
||||||
|
"mappings": Array [
|
||||||
|
Object {
|
||||||
|
"options": Object {
|
||||||
|
"1": Object {
|
||||||
|
"color": "#7EB26D",
|
||||||
|
},
|
||||||
|
"111": Object {
|
||||||
|
"text": "ONE",
|
||||||
|
},
|
||||||
|
"20": Object {
|
||||||
|
"color": "#EAB839",
|
||||||
|
},
|
||||||
|
"222": Object {
|
||||||
|
"text": "TWO",
|
||||||
|
},
|
||||||
|
"30": Object {
|
||||||
|
"color": "#EF843C",
|
||||||
|
},
|
||||||
|
"5": Object {
|
||||||
|
"color": "#E24D42",
|
||||||
|
},
|
||||||
|
"90": Object {
|
||||||
|
"color": "#6ED0E0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": "value",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"options": Object {
|
||||||
|
"from": 1,
|
||||||
|
"result": Object {
|
||||||
|
"text": "AAA",
|
||||||
|
},
|
||||||
|
"to": 3,
|
||||||
|
},
|
||||||
|
"type": "range",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"options": Object {
|
||||||
|
"from": 4,
|
||||||
|
"result": Object {
|
||||||
|
"text": "BBB",
|
||||||
|
},
|
||||||
|
"to": 5,
|
||||||
|
},
|
||||||
|
"type": "range",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"unit": "currencyGBP",
|
||||||
|
},
|
||||||
|
"overrides": Array [],
|
||||||
|
},
|
||||||
|
"options": Object {
|
||||||
|
"mergeValues": true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
154
public/app/plugins/panel/state-timeline/migrations.test.ts
Normal file
154
public/app/plugins/panel/state-timeline/migrations.test.ts
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
|
import { timelinePanelChangedHandler } from './migrations';
|
||||||
|
|
||||||
|
describe('Timeline Migrations', () => {
|
||||||
|
it('from discrete panel', () => {
|
||||||
|
const panel = {} as PanelModel;
|
||||||
|
panel.options = timelinePanelChangedHandler(panel, 'natel-discrete-panel', { angular: discreteInV8 });
|
||||||
|
expect(panel).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const discreteInV8 = {
|
||||||
|
id: 23763571993,
|
||||||
|
gridPos: {
|
||||||
|
h: 8,
|
||||||
|
w: 12,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
type: 'natel-discrete-panel',
|
||||||
|
title: 'Panel Title',
|
||||||
|
backgroundColor: 'rgba(128,128,128,0.1)',
|
||||||
|
colorMaps: [
|
||||||
|
{
|
||||||
|
$$hashKey: 'object:365',
|
||||||
|
color: '#7EB26D',
|
||||||
|
text: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$$hashKey: 'object:366',
|
||||||
|
color: '#EAB839',
|
||||||
|
text: '20',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$$hashKey: 'object:367',
|
||||||
|
color: '#6ED0E0',
|
||||||
|
text: '90',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$$hashKey: 'object:368',
|
||||||
|
color: '#EF843C',
|
||||||
|
text: '30',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$$hashKey: 'object:369',
|
||||||
|
color: '#E24D42',
|
||||||
|
text: '5',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
crosshairColor: '#8F070C',
|
||||||
|
display: 'timeline',
|
||||||
|
extendLastValue: true,
|
||||||
|
highlightOnMouseover: true,
|
||||||
|
legendSortBy: '-ms',
|
||||||
|
lineColor: 'rgba(0,0,0,0.1)',
|
||||||
|
metricNameColor: '#000000',
|
||||||
|
rangeMaps: [
|
||||||
|
{
|
||||||
|
$$hashKey: 'object:267',
|
||||||
|
from: '1',
|
||||||
|
text: 'AAA',
|
||||||
|
to: '3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: '4',
|
||||||
|
to: '5',
|
||||||
|
text: 'BBB',
|
||||||
|
$$hashKey: 'object:544',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rowHeight: 50,
|
||||||
|
showLegend: true,
|
||||||
|
showLegendNames: true,
|
||||||
|
showLegendPercent: true,
|
||||||
|
showLegendValues: true,
|
||||||
|
showTimeAxis: true,
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
refId: 'A',
|
||||||
|
scenarioId: 'csv_metric_values',
|
||||||
|
stringInput: '1,20,90,30,5,0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenarioId: 'csv_metric_values',
|
||||||
|
refId: 'B',
|
||||||
|
stringInput: '1,20,30,5,0',
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
textSize: 24,
|
||||||
|
textSizeTime: 12,
|
||||||
|
timeOptions: [
|
||||||
|
{
|
||||||
|
name: 'Years',
|
||||||
|
value: 'years',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Months',
|
||||||
|
value: 'months',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Weeks',
|
||||||
|
value: 'weeks',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Days',
|
||||||
|
value: 'days',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hours',
|
||||||
|
value: 'hours',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Minutes',
|
||||||
|
value: 'minutes',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Seconds',
|
||||||
|
value: 'seconds',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Milliseconds',
|
||||||
|
value: 'milliseconds',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
timePrecision: {
|
||||||
|
name: 'Minutes',
|
||||||
|
value: 'minutes',
|
||||||
|
},
|
||||||
|
timeTextColor: '#d8d9da',
|
||||||
|
units: 'currencyGBP',
|
||||||
|
valueMaps: [
|
||||||
|
{
|
||||||
|
$$hashKey: 'object:265',
|
||||||
|
op: '=',
|
||||||
|
text: 'ONE',
|
||||||
|
value: '111',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '222',
|
||||||
|
op: '=',
|
||||||
|
text: 'TWO',
|
||||||
|
$$hashKey: 'object:546',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
valueTextColor: '#000000',
|
||||||
|
writeLastValue: true,
|
||||||
|
expandFromQueryS: 0,
|
||||||
|
use12HourClock: false,
|
||||||
|
useTimePrecision: false,
|
||||||
|
writeAllValues: false,
|
||||||
|
writeMetricNames: false,
|
||||||
|
datasource: null,
|
||||||
|
};
|
80
public/app/plugins/panel/state-timeline/migrations.ts
Normal file
80
public/app/plugins/panel/state-timeline/migrations.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { FieldConfigSource, MappingType, PanelModel, ValueMap } from '@grafana/data';
|
||||||
|
import { TimelineFieldConfig, TimelineOptions } from './types';
|
||||||
|
import { isArray } from 'lodash';
|
||||||
|
|
||||||
|
// This is called when the panel changes from another panel
|
||||||
|
export const timelinePanelChangedHandler = (
|
||||||
|
panel: PanelModel<Partial<TimelineOptions>> | any,
|
||||||
|
prevPluginId: string,
|
||||||
|
prevOptions: any
|
||||||
|
) => {
|
||||||
|
let options = (panel.options ?? {}) as TimelineOptions;
|
||||||
|
|
||||||
|
// Changing from angular singlestat
|
||||||
|
if (prevPluginId === 'natel-discrete-panel' && prevOptions.angular) {
|
||||||
|
const oldOptions = prevOptions.angular;
|
||||||
|
const fieldConfig: FieldConfigSource = panel.fieldConfig ?? { defaults: {}, overrides: [] };
|
||||||
|
|
||||||
|
if (oldOptions.units) {
|
||||||
|
fieldConfig.defaults.unit = oldOptions.units;
|
||||||
|
}
|
||||||
|
|
||||||
|
const custom: TimelineFieldConfig = {
|
||||||
|
fillOpacity: 100,
|
||||||
|
lineWidth: 0,
|
||||||
|
};
|
||||||
|
fieldConfig.defaults.custom = custom;
|
||||||
|
options.mergeValues = true;
|
||||||
|
|
||||||
|
// Convert mappings
|
||||||
|
const valuemap: ValueMap = { type: MappingType.ValueToText, options: {} };
|
||||||
|
fieldConfig.defaults.mappings = [valuemap];
|
||||||
|
|
||||||
|
if (isArray(oldOptions.colorMaps)) {
|
||||||
|
for (const p of oldOptions.colorMaps) {
|
||||||
|
const color = p.color as string;
|
||||||
|
if (color) {
|
||||||
|
valuemap.options[p.text as string] = { color };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isArray(oldOptions.valueMaps)) {
|
||||||
|
for (const p of oldOptions.valueMaps) {
|
||||||
|
const text = p.text as string;
|
||||||
|
const value = p.value as string;
|
||||||
|
if (text && value) {
|
||||||
|
let old = valuemap.options[value];
|
||||||
|
if (old) {
|
||||||
|
old.text = text;
|
||||||
|
} else {
|
||||||
|
valuemap.options[value] = { text };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isArray(oldOptions.rangeMaps)) {
|
||||||
|
for (const p of oldOptions.rangeMaps) {
|
||||||
|
let from = +p.from;
|
||||||
|
let to = +p.to;
|
||||||
|
const text = p.text as string;
|
||||||
|
if (text) {
|
||||||
|
fieldConfig.defaults.mappings.push({
|
||||||
|
type: MappingType.RangeToText,
|
||||||
|
options: {
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
result: { text },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mutates the input
|
||||||
|
panel.fieldConfig = fieldConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
};
|
@ -3,8 +3,10 @@ import { StateTimelinePanel } from './StateTimelinePanel';
|
|||||||
import { TimelineOptions, TimelineFieldConfig, defaultPanelOptions, defaultTimelineFieldConfig } from './types';
|
import { TimelineOptions, TimelineFieldConfig, defaultPanelOptions, defaultTimelineFieldConfig } from './types';
|
||||||
import { BarValueVisibility } from '@grafana/ui';
|
import { BarValueVisibility } from '@grafana/ui';
|
||||||
import { addLegendOptions } from '@grafana/ui/src/options/builder';
|
import { addLegendOptions } from '@grafana/ui/src/options/builder';
|
||||||
|
import { timelinePanelChangedHandler } from './migrations';
|
||||||
|
|
||||||
export const plugin = new PanelPlugin<TimelineOptions, TimelineFieldConfig>(StateTimelinePanel)
|
export const plugin = new PanelPlugin<TimelineOptions, TimelineFieldConfig>(StateTimelinePanel)
|
||||||
|
.setPanelChangeHandler(timelinePanelChangedHandler)
|
||||||
.useFieldConfig({
|
.useFieldConfig({
|
||||||
standardOptions: {
|
standardOptions: {
|
||||||
[FieldConfigProperty.Color]: {
|
[FieldConfigProperty.Color]: {
|
||||||
|
Loading…
Reference in New Issue
Block a user