GraphNG: stats in legend (#30251)

* StatsPickerEditor - add more config to the options ui

* Show calcs in the legend

* Refactor the way legend items are created

* Progress on refresh

* Migration update

* Use human-readable names in the legend stats

* Disable pointer cursor in table header
This commit is contained in:
Dominik Prokop
2021-01-15 09:14:50 +01:00
committed by GitHub
parent 61b9d811cb
commit f5dfb3b24b
19 changed files with 336 additions and 59 deletions

View File

@@ -1,5 +1,5 @@
import { ApplyFieldOverrideOptions, DataTransformerConfig, dateMath, FieldColorModeId, PanelData } from '@grafana/data';
import { GraphNG, Table } from '@grafana/ui';
import { GraphNG, LegendDisplayMode, Table } from '@grafana/ui';
import { config } from 'app/core/config';
import React, { FC, useMemo, useState } from 'react';
import { useObservable } from 'react-use';
@@ -54,7 +54,14 @@ export const TestStuffPage: FC = () => {
{data && (
<div style={{ padding: '16px' }}>
<GraphNG width={1200} height={300} data={data.series} timeRange={data.timeRange} timeZone="browser" />
<GraphNG
width={1200}
height={300}
data={data.series}
legend={{ displayMode: LegendDisplayMode.List, placement: 'bottom', calcs: [] }}
timeRange={data.timeRange}
timeZone="browser"
/>
<hr></hr>
<Table data={data.series[0]} width={1200} height={300} />
</div>

View File

@@ -1,5 +1,60 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Graph Migrations legend 1`] = `
Object {
"fieldConfig": Object {
"defaults": Object {
"custom": Object {
"axisPlacement": "auto",
"drawStyle": "line",
"fillOpacity": 50,
"lineInterpolation": "stepAfter",
"lineWidth": 5,
"pointSize": 6,
"showPoints": "never",
"spanNulls": true,
},
"nullValueMode": "null",
"unit": "short",
},
"overrides": Array [
Object {
"matcher": Object {
"id": "byName",
"options": "A-series",
},
"properties": Array [
Object {
"id": "color",
"value": Object {
"fixedColor": "red",
"mode": "fixed",
},
},
],
},
],
},
"options": Object {
"graph": Object {},
"legend": Object {
"calcs": Array [
"mean",
"lastNotNull",
"max",
"min",
"sum",
],
"displayMode": "table",
"placement": "bottom",
},
"tooltipOptions": Object {
"mode": "single",
},
},
}
`;
exports[`Graph Migrations simple bars 1`] = `
Object {
"fieldConfig": Object {
@@ -16,6 +71,7 @@ Object {
"options": Object {
"graph": Object {},
"legend": Object {
"calcs": Array [],
"displayMode": "list",
"placement": "bottom",
},
@@ -50,7 +106,14 @@ Object {
"options": Object {
"graph": Object {},
"legend": Object {
"displayMode": "list",
"calcs": Array [
"mean",
"lastNotNull",
"max",
"min",
"sum",
],
"displayMode": "table",
"placement": "bottom",
},
"tooltipOptions": Object {
@@ -98,6 +161,7 @@ Object {
"options": Object {
"graph": Object {},
"legend": Object {
"calcs": Array [],
"displayMode": "list",
"placement": "bottom",
},
@@ -179,6 +243,7 @@ Object {
"options": Object {
"graph": Object {},
"legend": Object {
"calcs": Array [],
"displayMode": "list",
"placement": "bottom",
},

View File

@@ -39,6 +39,15 @@ describe('Graph Migrations', () => {
panel.options = graphPanelChangedHandler(panel, 'graph', old);
expect(panel).toMatchSnapshot();
});
it('legend', () => {
const old: any = {
angular: legend,
};
const panel = {} as PanelModel;
panel.options = graphPanelChangedHandler(panel, 'graph', old);
expect(panel).toMatchSnapshot();
});
});
const stairscase = {
@@ -306,3 +315,97 @@ const stepedColordLine = {
timeShift: null,
datasource: null,
};
const legend = {
aliasColors: {
'A-series': 'red',
},
dashLength: 10,
fieldConfig: {
defaults: {
custom: {},
},
overrides: [],
},
fill: 5,
gridPos: {
h: 9,
w: 12,
x: 0,
y: 0,
},
id: 2,
legend: {
avg: true,
current: true,
max: false,
min: false,
show: true,
total: true,
values: true,
alignAsTable: true,
},
lines: true,
linewidth: 5,
maxDataPoints: 20,
nullPointMode: 'null',
options: {
alertThreshold: true,
},
pluginVersion: '7.4.0-pre',
pointradius: 2,
renderer: 'flot',
seriesOverrides: [],
spaceLength: 10,
steppedLine: true,
thresholds: [],
timeRegions: [],
title: 'Panel Title',
tooltip: {
shared: true,
sort: 0,
value_type: 'individual',
},
type: 'graph',
xaxis: {
buckets: null,
mode: 'time',
name: null,
show: true,
values: [],
},
yaxes: [
{
$$hashKey: 'object:38',
format: 'short',
label: null,
logBase: 1,
max: null,
min: null,
show: true,
},
{
$$hashKey: 'object:39',
format: 'short',
label: null,
logBase: 1,
max: null,
min: null,
show: true,
},
],
yaxis: {
align: false,
alignLevel: null,
},
bars: false,
dashes: false,
fillGradient: 0,
hiddenSeries: false,
percentage: false,
points: false,
stack: false,
timeFrom: null,
timeShift: null,
datasource: null,
};

View File

@@ -1,20 +1,20 @@
import {
ConfigOverrideRule,
DynamicConfigValue,
FieldColorModeId,
FieldConfig,
FieldConfigProperty,
FieldConfigSource,
FieldMatcherID,
fieldReducers,
NullValueMode,
PanelModel,
fieldReducers,
ConfigOverrideRule,
FieldMatcherID,
DynamicConfigValue,
FieldConfigProperty,
FieldColorModeId,
} from '@grafana/data';
import { GraphFieldConfig, LegendDisplayMode } from '@grafana/ui';
import {
FillGradientMode,
AxisPlacement,
DrawStyle,
FillGradientMode,
LineInterpolation,
LineStyle,
PointVisibility,
@@ -256,15 +256,29 @@ export function flotToGraphOptions(angular: any): { fieldConfig: FieldConfigSour
legend: {
displayMode: LegendDisplayMode.List,
placement: 'bottom',
calcs: [],
},
tooltipOptions: {
mode: 'single',
},
};
if (angular.legend?.values) {
const show = getReducersFromLegend(angular.legend?.values);
console.log('Migrate Legend', show);
// Legend config migration
const legendConfig = angular.legend;
if (legendConfig) {
if (legendConfig.show) {
options.legend.displayMode = legendConfig.alignAsTable ? LegendDisplayMode.Table : LegendDisplayMode.List;
} else {
options.legend.displayMode = LegendDisplayMode.Hidden;
}
if (legendConfig.rightSide) {
options.legend.placement = 'right';
}
if (angular.legend.values) {
options.legend.calcs = getReducersFromLegend(angular.legend);
}
}
return {

View File

@@ -1,9 +1,9 @@
import { PanelPlugin } from '@grafana/data';
import { PanelPlugin, standardEditorsRegistry, StatsPickerConfigSettings } from '@grafana/data';
import { GraphFieldConfig, LegendDisplayMode } from '@grafana/ui';
import { TimeSeriesPanel } from './TimeSeriesPanel';
import { graphPanelChangedHandler } from './migrations';
import { Options } from './types';
import { getGraphFieldConfig, defaultGraphConfig } from './config';
import { defaultGraphConfig, getGraphFieldConfig } from './config';
export const plugin = new PanelPlugin<Options, GraphFieldConfig>(TimeSeriesPanel)
.setPanelChangeHandler(graphPanelChangedHandler)
@@ -48,5 +48,17 @@ export const plugin = new PanelPlugin<Options, GraphFieldConfig>(TimeSeriesPanel
],
},
showIf: c => c.legend.displayMode !== LegendDisplayMode.Hidden,
})
.addCustomEditor<StatsPickerConfigSettings, string[]>({
id: 'legend.calcs',
path: 'legend.calcs',
name: 'Legend calculations',
description: 'Choose a reducer functions / calculations to include in legend',
editor: standardEditorsRegistry.get('stats-picker').editor as any,
defaultValue: [],
settings: {
allowMultiple: true,
},
showIf: currentConfig => currentConfig.legend.displayMode !== LegendDisplayMode.Hidden,
});
});