mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TimeSeries/BarChart/XYChart: Allow hiding x axis (#44107)
* TimeSeries/BarChart/XYChart: Allow hiding x axis * Update public/app/plugins/panel/barchart/utils.ts Co-authored-by: Oscar Kilhed <oscar.kilhed@grafana.com> * Migrations Co-authored-by: Oscar Kilhed <oscar.kilhed@grafana.com>
This commit is contained in:
@@ -67,6 +67,10 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursor
|
|||||||
let xScaleUnit = '_x';
|
let xScaleUnit = '_x';
|
||||||
let yScaleKey = '';
|
let yScaleKey = '';
|
||||||
|
|
||||||
|
const xFieldAxisPlacement =
|
||||||
|
xField.config.custom?.axisPlacement !== AxisPlacement.Hidden ? AxisPlacement.Bottom : AxisPlacement.Hidden;
|
||||||
|
const xFieldAxisShow = xField.config.custom?.axisPlacement !== AxisPlacement.Hidden;
|
||||||
|
|
||||||
if (xField.type === FieldType.time) {
|
if (xField.type === FieldType.time) {
|
||||||
xScaleUnit = 'time';
|
xScaleUnit = 'time';
|
||||||
builder.addScale({
|
builder.addScale({
|
||||||
@@ -83,7 +87,8 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursor
|
|||||||
builder.addAxis({
|
builder.addAxis({
|
||||||
scaleKey: xScaleKey,
|
scaleKey: xScaleKey,
|
||||||
isTime: true,
|
isTime: true,
|
||||||
placement: AxisPlacement.Bottom,
|
placement: xFieldAxisPlacement,
|
||||||
|
show: xFieldAxisShow,
|
||||||
label: xField.config.custom?.axisLabel,
|
label: xField.config.custom?.axisLabel,
|
||||||
timeZone,
|
timeZone,
|
||||||
theme,
|
theme,
|
||||||
@@ -103,7 +108,8 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursor
|
|||||||
|
|
||||||
builder.addAxis({
|
builder.addAxis({
|
||||||
scaleKey: xScaleKey,
|
scaleKey: xScaleKey,
|
||||||
placement: AxisPlacement.Bottom,
|
placement: xFieldAxisPlacement,
|
||||||
|
show: xFieldAxisShow,
|
||||||
label: xField.config.custom?.axisLabel,
|
label: xField.config.custom?.axisLabel,
|
||||||
theme,
|
theme,
|
||||||
grid: { show: xField.config.custom?.axisGridShow },
|
grid: { show: xField.config.custom?.axisGridShow },
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ describe('DashboardModel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('dashboard schema version should be set to latest', () => {
|
it('dashboard schema version should be set to latest', () => {
|
||||||
expect(model.schemaVersion).toBe(34);
|
expect(model.schemaVersion).toBe(35);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('graph thresholds should be migrated', () => {
|
it('graph thresholds should be migrated', () => {
|
||||||
@@ -1839,6 +1839,43 @@ describe('DashboardModel', () => {
|
|||||||
expect(model.panels[3].panels[0].datasource).toEqual({ type: 'prometheus', uid: 'mock-ds-2' });
|
expect(model.panels[3].panels[0].datasource).toEqual({ type: 'prometheus', uid: 'mock-ds-2' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when migrating time series axis visibility', () => {
|
||||||
|
test('preserves x axis visibility', () => {
|
||||||
|
const model = new DashboardModel({
|
||||||
|
panels: [
|
||||||
|
{
|
||||||
|
type: 'timeseries',
|
||||||
|
fieldConfig: {
|
||||||
|
defaults: {
|
||||||
|
custom: {
|
||||||
|
axisPlacement: 'hidden',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(model.panels[0].fieldConfig.overrides).toMatchInlineSnapshot(`
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"matcher": Object {
|
||||||
|
"id": "byType",
|
||||||
|
"options": "time",
|
||||||
|
},
|
||||||
|
"properties": Array [
|
||||||
|
Object {
|
||||||
|
"id": "custom.axisPlacement",
|
||||||
|
"value": "auto",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function createRow(options: any, panelDescriptions: any[]) {
|
function createRow(options: any, panelDescriptions: any[]) {
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import {
|
|||||||
DataQuery,
|
DataQuery,
|
||||||
DataSourceRef,
|
DataSourceRef,
|
||||||
DataTransformerConfig,
|
DataTransformerConfig,
|
||||||
|
FieldConfigSource,
|
||||||
|
FieldMatcherID,
|
||||||
|
FieldType,
|
||||||
getActiveThreshold,
|
getActiveThreshold,
|
||||||
getDataSourceRef,
|
getDataSourceRef,
|
||||||
isDataSourceRef,
|
isDataSourceRef,
|
||||||
@@ -41,7 +44,7 @@ import { VariableHide } from '../../variables/types';
|
|||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
import { plugin as statPanelPlugin } from 'app/plugins/panel/stat/module';
|
import { plugin as statPanelPlugin } from 'app/plugins/panel/stat/module';
|
||||||
import { plugin as gaugePanelPlugin } from 'app/plugins/panel/gauge/module';
|
import { plugin as gaugePanelPlugin } from 'app/plugins/panel/gauge/module';
|
||||||
import { getStandardFieldConfigs, getStandardOptionEditors } from '@grafana/ui';
|
import { AxisPlacement, getStandardFieldConfigs, getStandardOptionEditors, GraphFieldConfig } from '@grafana/ui';
|
||||||
import { getDataSourceSrv } from '@grafana/runtime';
|
import { getDataSourceSrv } from '@grafana/runtime';
|
||||||
import { labelsToFieldsTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/labelsToFields';
|
import { labelsToFieldsTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/labelsToFields';
|
||||||
import { mergeTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/merge';
|
import { mergeTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/merge';
|
||||||
@@ -67,7 +70,7 @@ export class DashboardMigrator {
|
|||||||
let i, j, k, n;
|
let i, j, k, n;
|
||||||
const oldVersion = this.dashboard.schemaVersion;
|
const oldVersion = this.dashboard.schemaVersion;
|
||||||
const panelUpgrades: PanelSchemeUpgradeHandler[] = [];
|
const panelUpgrades: PanelSchemeUpgradeHandler[] = [];
|
||||||
this.dashboard.schemaVersion = 34;
|
this.dashboard.schemaVersion = 35;
|
||||||
|
|
||||||
if (oldVersion === this.dashboard.schemaVersion) {
|
if (oldVersion === this.dashboard.schemaVersion) {
|
||||||
return;
|
return;
|
||||||
@@ -724,6 +727,10 @@ export class DashboardMigrator {
|
|||||||
this.migrateCloudWatchAnnotationQuery();
|
this.migrateCloudWatchAnnotationQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldVersion < 35) {
|
||||||
|
panelUpgrades.push(ensureXAxisVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
if (panelUpgrades.length === 0) {
|
if (panelUpgrades.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1205,3 +1212,35 @@ function migrateTooltipOptions(panel: PanelModel) {
|
|||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This migration is performed when there is a time series panel with all axes configured to be hidden
|
||||||
|
// To avoid breaking dashboards we add override that persists x-axis visibility
|
||||||
|
function ensureXAxisVisibility(panel: PanelModel) {
|
||||||
|
if (panel.type === 'timeseries') {
|
||||||
|
if (
|
||||||
|
(panel.fieldConfig as FieldConfigSource<GraphFieldConfig>)?.defaults.custom?.axisPlacement ===
|
||||||
|
AxisPlacement.Hidden
|
||||||
|
) {
|
||||||
|
panel.fieldConfig = {
|
||||||
|
...panel.fieldConfig,
|
||||||
|
overrides: [
|
||||||
|
...panel.fieldConfig.overrides,
|
||||||
|
{
|
||||||
|
matcher: {
|
||||||
|
id: FieldMatcherID.byType,
|
||||||
|
options: FieldType.time,
|
||||||
|
},
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
id: 'custom.axisPlacement',
|
||||||
|
value: AxisPlacement.Auto,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,10 +131,18 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
direction: vizOrientation.xDir,
|
direction: vizOrientation.xDir,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const xFieldAxisPlacement =
|
||||||
|
frame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden
|
||||||
|
? vizOrientation.xOri === ScaleOrientation.Horizontal
|
||||||
|
? AxisPlacement.Bottom
|
||||||
|
: AxisPlacement.Left
|
||||||
|
: AxisPlacement.Hidden;
|
||||||
|
const xFieldAxisShow = frame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden;
|
||||||
|
|
||||||
builder.addAxis({
|
builder.addAxis({
|
||||||
scaleKey: 'x',
|
scaleKey: 'x',
|
||||||
isTime: false,
|
isTime: false,
|
||||||
placement: vizOrientation.xOri === 0 ? AxisPlacement.Bottom : AxisPlacement.Left,
|
placement: xFieldAxisPlacement,
|
||||||
label: frame.fields[0].config.custom?.axisLabel,
|
label: frame.fields[0].config.custom?.axisLabel,
|
||||||
splits: config.xSplits,
|
splits: config.xSplits,
|
||||||
values: config.xValues,
|
values: config.xValues,
|
||||||
@@ -143,6 +151,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
gap: 15,
|
gap: 15,
|
||||||
tickLabelRotation: xTickLabelRotation * -1,
|
tickLabelRotation: xTickLabelRotation * -1,
|
||||||
theme,
|
theme,
|
||||||
|
show: xFieldAxisShow,
|
||||||
});
|
});
|
||||||
|
|
||||||
let seriesIndex = 0;
|
let seriesIndex = 0;
|
||||||
|
|||||||
@@ -566,3 +566,28 @@ Object {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`Graph Migrations x axis should hide x axis 1`] = `
|
||||||
|
Object {
|
||||||
|
"defaults": Object {
|
||||||
|
"custom": Object {
|
||||||
|
"drawStyle": "points",
|
||||||
|
"spanNulls": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"overrides": Array [
|
||||||
|
Object {
|
||||||
|
"matcher": Object {
|
||||||
|
"id": "byType",
|
||||||
|
"options": "time",
|
||||||
|
},
|
||||||
|
"properties": Array [
|
||||||
|
Object {
|
||||||
|
"id": "custom.axisPlacement",
|
||||||
|
"value": "hidden",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -390,6 +390,22 @@ describe('Graph Migrations', () => {
|
|||||||
expect(panel4.options.tooltip.sort).toBe(SortOrder.None);
|
expect(panel4.options.tooltip.sort).toBe(SortOrder.None);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('x axis', () => {
|
||||||
|
test('should hide x axis', () => {
|
||||||
|
const old: any = {
|
||||||
|
angular: {
|
||||||
|
xaxis: {
|
||||||
|
show: false,
|
||||||
|
mode: 'time',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const panel = {} as PanelModel;
|
||||||
|
panel.options = graphPanelChangedHandler(panel, 'graph', old, prevFieldConfig);
|
||||||
|
expect(panel.fieldConfig).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const customColor = {
|
const customColor = {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
FieldConfigSource,
|
FieldConfigSource,
|
||||||
FieldMatcherID,
|
FieldMatcherID,
|
||||||
fieldReducers,
|
fieldReducers,
|
||||||
|
FieldType,
|
||||||
NullValueMode,
|
NullValueMode,
|
||||||
PanelTypeChangedHandler,
|
PanelTypeChangedHandler,
|
||||||
Threshold,
|
Threshold,
|
||||||
@@ -434,6 +435,20 @@ export function flotToGraphOptions(angular: any): { fieldConfig: FieldConfigSour
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (angular.xaxis && angular.xaxis.show === false && angular.xaxis.mode === 'time') {
|
||||||
|
overrides.push({
|
||||||
|
matcher: {
|
||||||
|
id: FieldMatcherID.byType,
|
||||||
|
options: FieldType.time,
|
||||||
|
},
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
id: 'custom.axisPlacement',
|
||||||
|
value: AxisPlacement.Hidden,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
fieldConfig: {
|
fieldConfig: {
|
||||||
defaults: omitBy(y1, isNil),
|
defaults: omitBy(y1, isNil),
|
||||||
|
|||||||
@@ -548,7 +548,9 @@ const prepConfig = (
|
|||||||
|
|
||||||
builder.addAxis({
|
builder.addAxis({
|
||||||
scaleKey: 'x',
|
scaleKey: 'x',
|
||||||
placement: AxisPlacement.Bottom,
|
placement:
|
||||||
|
xField.config.custom?.axisPlacement !== AxisPlacement.Hidden ? AxisPlacement.Bottom : AxisPlacement.Hidden,
|
||||||
|
show: xField.config.custom?.axisPlacement !== AxisPlacement.Hidden,
|
||||||
theme,
|
theme,
|
||||||
label: xField.config.custom.axisLabel,
|
label: xField.config.custom.axisLabel,
|
||||||
});
|
});
|
||||||
@@ -571,12 +573,15 @@ const prepConfig = (
|
|||||||
range: (u, min, max) => [min, max],
|
range: (u, min, max) => [min, max],
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.addAxis({
|
if (field.config.custom?.axisPlacement !== AxisPlacement.Hidden) {
|
||||||
scaleKey,
|
builder.addAxis({
|
||||||
theme,
|
scaleKey,
|
||||||
label: field.config.custom.axisLabel,
|
theme,
|
||||||
values: (u, splits) => splits.map((s) => field.display!(s).text),
|
placement: field.config.custom?.axisPlacement,
|
||||||
});
|
label: field.config.custom.axisLabel,
|
||||||
|
values: (u, splits) => splits.map((s) => field.display!(s).text),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
builder.addSeries({
|
builder.addSeries({
|
||||||
facets: [
|
facets: [
|
||||||
|
|||||||
Reference in New Issue
Block a user