diff --git a/docs/sources/panels-visualizations/visualizations/state-timeline/index.md b/docs/sources/panels-visualizations/visualizations/state-timeline/index.md index 1ef99435336..a6916eb1f83 100644 --- a/docs/sources/panels-visualizations/visualizations/state-timeline/index.md +++ b/docs/sources/panels-visualizations/visualizations/state-timeline/index.md @@ -149,6 +149,10 @@ The **Page size** option lets you paginate the state timeline visualization to l {{< docs/shared lookup="visualizations/tooltip-options-1.md" source="grafana" version="" leveloffset="+1" >}} +### Axis options + +{{< docs/shared lookup="visualizations/axis-options-state-status.md" source="grafana" version="" leveloffset="+1" >}} + ### Standard options {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} diff --git a/docs/sources/panels-visualizations/visualizations/status-history/index.md b/docs/sources/panels-visualizations/visualizations/status-history/index.md index b7825b94b82..3ca5df864e6 100644 --- a/docs/sources/panels-visualizations/visualizations/status-history/index.md +++ b/docs/sources/panels-visualizations/visualizations/status-history/index.md @@ -131,6 +131,10 @@ Controls the opacity of state regions. {{< docs/shared lookup="visualizations/tooltip-options-1.md" source="grafana" version="" >}} +## Axis options + +{{< docs/shared lookup="visualizations/axis-options-state-status.md" source="grafana" version="" leveloffset="+1" >}} + ## Standard options {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} diff --git a/docs/sources/panels-visualizations/visualizations/time-series/index.md b/docs/sources/panels-visualizations/visualizations/time-series/index.md index e7f21000554..e54509d5aeb 100644 --- a/docs/sources/panels-visualizations/visualizations/time-series/index.md +++ b/docs/sources/panels-visualizations/visualizations/time-series/index.md @@ -209,21 +209,7 @@ The following example shows three series: Min, Max, and Value. The Min and Max s ### Axis options -Options under the **Axis** section control how the x- and y-axes are rendered. Some options don't take effect until you click outside of the field option box you're editing. You can also press `Enter`. - -| Option | Description | -| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Time zone | Set the desired time zones to display along the x-axis. | -| [Placement](#placement) | Select the placement of the y-axis. | -| Label | Set a y-axis text label. If you have more than one y-axis, then you can assign different labels using an override. | -| Width | Set a fixed width of the axis. By default, Grafana dynamically calculates the width of an axis. By setting the width of the axis, data with different axes types can share the same display proportions. This setting makes it easier for you to compare more than one graph’s worth of data because the axes aren't shifted or stretched within visual proximity to each other. | -| Show grid lines | Set the axis grid line visibility.
| -| Color | Set the color of the axis. | -| Show border | Set the axis border visibility. | -| Scale | Set the y-axis values scale.
| -| Centered zero | Set the y-axis so it's centered on zero. | -| [Soft min](#soft-min-and-soft-max) | Set a soft min to better control the y-axis limits. zero. | -| [Soft max](#soft-min-and-soft-max) | Set a soft max to better control the y-axis limits. zero. | +{{< docs/shared lookup="visualizations/axis-options-all.md" source="grafana" version="" leveloffset="+1" >}} #### Placement diff --git a/docs/sources/shared/visualizations/axis-options-all.md b/docs/sources/shared/visualizations/axis-options-all.md new file mode 100644 index 00000000000..e2c833ab9e2 --- /dev/null +++ b/docs/sources/shared/visualizations/axis-options-all.md @@ -0,0 +1,21 @@ +--- +title: Axis options +comments: | + This file is used in the following visualizations: time series. +--- + +Options under the **Axis** section control how the x- and y-axes are rendered. Some options don't take effect until you click outside of the field option box you're editing. You can also press `Enter`. + +| Option | Description | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| Time zone | Set the desired time zones to display along the x-axis. | +| [Placement](#placement) | Select the placement of the y-axis. | +| Label | Set a y-axis text label. If you have more than one y-axis, then you can assign different labels using an override. | +| Width | Set a fixed width for the axis. By default, Grafana dynamically calculates the width of an axis. | +| Show grid lines | Set the axis grid line visibility.
| +| Color | Set the color of the axis. | +| Show border | Set the axis border visibility. | +| Scale | Set the y-axis values scale.
| +| Centered zero | Set the y-axis so it's centered on zero. | +| [Soft min](#soft-min-and-soft-max) | Set a soft min to better control the y-axis limits. zero. | +| [Soft max](#soft-min-and-soft-max) | Set a soft max to better control the y-axis limits. zero. | diff --git a/docs/sources/shared/visualizations/axis-options-state-status.md b/docs/sources/shared/visualizations/axis-options-state-status.md new file mode 100644 index 00000000000..8b1bacfd78c --- /dev/null +++ b/docs/sources/shared/visualizations/axis-options-state-status.md @@ -0,0 +1,10 @@ +--- +title: Axis options +comments: | + This file is used in the following visualizations: state timeline, status history. +--- + +| Option | Description | +| --------- | ------------------------------------------------------------------------------------------------ | +| Placement | Control the visibility of series names along the y-axis or time values along the x-axis. | +| Width | Set a fixed width for the axis. By default, Grafana dynamically calculates the width of an axis. | diff --git a/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts index 72c3097c014..a62b8181e42 100644 --- a/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts @@ -43,7 +43,7 @@ export const defaultOptions: Partial = { showValue: ui.VisibilityMode.Auto, }; -export interface FieldConfig extends ui.HideableFieldConfig { +export interface FieldConfig extends ui.AxisConfig, ui.HideableFieldConfig { fillOpacity?: number; lineWidth?: number; } diff --git a/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts index 8b0b21a3723..1efeeb3dec4 100644 --- a/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts @@ -33,7 +33,7 @@ export const defaultOptions: Partial = { showValue: ui.VisibilityMode.Auto, }; -export interface FieldConfig extends ui.HideableFieldConfig { +export interface FieldConfig extends ui.AxisConfig, ui.HideableFieldConfig { fillOpacity?: number; lineWidth?: number; } diff --git a/packages/grafana-ui/src/options/builder/axis.tsx b/packages/grafana-ui/src/options/builder/axis.tsx index 2e08654298c..304dc78268a 100644 --- a/packages/grafana-ui/src/options/builder/axis.tsx +++ b/packages/grafana-ui/src/options/builder/axis.tsx @@ -14,49 +14,32 @@ import { Stack } from '../../components/Layout/Stack/Stack'; import { Select } from '../../components/Select/Select'; import { graphFieldOptions } from '../../components/uPlot/config'; +const category = ['Axis']; + /** * @alpha */ -export function addAxisConfig( - builder: FieldConfigEditorBuilder, - defaultConfig: AxisConfig, - hideScale?: boolean -) { - const category = ['Axis']; - +export function addAxisConfig(builder: FieldConfigEditorBuilder, defaultConfig: AxisConfig) { // options for axis appearance + addAxisPlacement(builder); + + builder.addTextInput({ + path: 'axisLabel', + name: 'Label', + category, + defaultValue: '', + settings: { + placeholder: 'Optional text', + expandTemplateVars: true, + }, + showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden, + // Do not apply default settings to time and string fields which are used as x-axis fields in Time series and Bar chart panels + shouldApply: (f) => f.type !== FieldType.time && f.type !== FieldType.string, + }); + + addAxisWidth(builder); + builder - .addRadio({ - path: 'axisPlacement', - name: 'Placement', - category, - defaultValue: graphFieldOptions.axisPlacement[0].value, - settings: { - options: graphFieldOptions.axisPlacement, - }, - }) - .addTextInput({ - path: 'axisLabel', - name: 'Label', - category, - defaultValue: '', - settings: { - placeholder: 'Optional text', - expandTemplateVars: true, - }, - showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden, - // Do not apply default settings to time and string fields which are used as x-axis fields in Time series and Bar chart panels - shouldApply: (f) => f.type !== FieldType.time && f.type !== FieldType.string, - }) - .addNumberInput({ - path: 'axisWidth', - name: 'Width', - category, - settings: { - placeholder: 'Auto', - }, - showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden, - }) .addRadio({ path: 'axisGridShow', name: 'Show grid lines', @@ -209,3 +192,32 @@ export const ScaleDistributionEditor = ({ value, onChange }: StandardEditorProps ); }; + +/** @internal */ +export function addAxisWidth(builder: FieldConfigEditorBuilder) { + builder.addNumberInput({ + path: 'axisWidth', + name: 'Width', + category, + settings: { + placeholder: 'Auto', + }, + showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden, + }); +} + +/** @internal */ +export function addAxisPlacement( + builder: FieldConfigEditorBuilder, + optionsFilter = (placement: AxisPlacement) => true +) { + builder.addRadio({ + path: 'axisPlacement', + name: 'Placement', + category, + defaultValue: graphFieldOptions.axisPlacement[0].value, + settings: { + options: graphFieldOptions.axisPlacement.filter((placement) => optionsFilter(placement.value!)), + }, + }); +} diff --git a/public/app/core/components/TimelineChart/utils.ts b/public/app/core/components/TimelineChart/utils.ts index 0057b21331d..5a727990631 100644 --- a/public/app/core/components/TimelineChart/utils.ts +++ b/public/app/core/components/TimelineChart/utils.ts @@ -51,6 +51,7 @@ interface UPlotConfigOptions { mergeValues?: boolean; getValueColor: (frameIdx: number, fieldIdx: number, value: unknown) => string; hoverMulti: boolean; + axisWidth?: number; } /** @@ -161,25 +162,32 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ( range: coreConfig.yRange, }); + const xAxisHidden = frame.fields[0].config.custom.axisPlacement === AxisPlacement.Hidden; + builder.addAxis({ + show: !xAxisHidden, scaleKey: xScaleKey, isTime: true, splits: coreConfig.xSplits!, placement: AxisPlacement.Bottom, timeZone: timeZones[0], theme, - grid: { show: true }, }); + const yCustomConfig = frame.fields[1].config.custom; + const yAxisWidth = yCustomConfig.axisWidth; + const yAxisHidden = yCustomConfig.axisPlacement === AxisPlacement.Hidden; + builder.addAxis({ scaleKey: FIXED_UNIT, // y isTime: false, placement: AxisPlacement.Left, splits: coreConfig.ySplits, - values: coreConfig.yValues, + values: yAxisHidden ? (u, splits) => splits.map((v) => null) : coreConfig.yValues, grid: { show: false }, ticks: { show: false }, - gap: 16, + gap: yAxisHidden ? 0 : 16, + size: yAxisHidden ? 0 : yAxisWidth, theme, }); diff --git a/public/app/plugins/panel/barchart/module.tsx b/public/app/plugins/panel/barchart/module.tsx index 35d1f095828..5b5ae542531 100644 --- a/public/app/plugins/panel/barchart/module.tsx +++ b/public/app/plugins/panel/barchart/module.tsx @@ -103,7 +103,7 @@ export const plugin = new PanelPlugin(BarChartPanel) shouldApply: () => true, }); - commonOptionsBuilder.addAxisConfig(builder, cfg, false); + commonOptionsBuilder.addAxisConfig(builder, cfg); commonOptionsBuilder.addHideFrom(builder); }, }) diff --git a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx index 81e272a6b98..4c57d757a05 100644 --- a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx +++ b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx @@ -4,6 +4,7 @@ import { useMeasure } from 'react-use'; import { DashboardCursorSync, DataFrame, PanelProps } from '@grafana/data'; import { + AxisPlacement, EventBusPlugin, Pagination, TooltipDisplayMode, @@ -209,15 +210,16 @@ export const StateTimelinePanel = ({ maxWidth={options.tooltip.maxWidth} /> )} - {/* Renders annotations */} - + {alignedFrame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden && ( + + )} ); diff --git a/public/app/plugins/panel/state-timeline/module.tsx b/public/app/plugins/panel/state-timeline/module.tsx index 972194fc52d..024d1e883ac 100644 --- a/public/app/plugins/panel/state-timeline/module.tsx +++ b/public/app/plugins/panel/state-timeline/module.tsx @@ -5,7 +5,7 @@ import { identityOverrideProcessor, PanelPlugin, } from '@grafana/data'; -import { VisibilityMode } from '@grafana/schema'; +import { AxisPlacement, VisibilityMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; import { InsertNullsEditor } from '../timeseries/InsertNullsEditor'; @@ -76,6 +76,11 @@ export const plugin = new PanelPlugin(StateTimelinePanel) }); commonOptionsBuilder.addHideFrom(builder); + commonOptionsBuilder.addAxisPlacement( + builder, + (placement) => placement === AxisPlacement.Auto || placement === AxisPlacement.Hidden + ); + commonOptionsBuilder.addAxisWidth(builder); }, }) .setPanelOptions((builder) => { diff --git a/public/app/plugins/panel/state-timeline/panelcfg.cue b/public/app/plugins/panel/state-timeline/panelcfg.cue index a186f5e12e8..5a9c34e2a28 100644 --- a/public/app/plugins/panel/state-timeline/panelcfg.cue +++ b/public/app/plugins/panel/state-timeline/panelcfg.cue @@ -41,6 +41,7 @@ composableKinds: PanelCfg: { perPage?: number & >=1 | *20 } @cuetsy(kind="interface") FieldConfig: { + ui.AxisConfig ui.HideableFieldConfig lineWidth?: uint32 & <=10 | *0 fillOpacity?: uint32 & <=100 | *70 diff --git a/public/app/plugins/panel/state-timeline/panelcfg.gen.ts b/public/app/plugins/panel/state-timeline/panelcfg.gen.ts index 0fc25fe65b8..5ea1b58af54 100644 --- a/public/app/plugins/panel/state-timeline/panelcfg.gen.ts +++ b/public/app/plugins/panel/state-timeline/panelcfg.gen.ts @@ -41,7 +41,7 @@ export const defaultOptions: Partial = { showValue: ui.VisibilityMode.Auto, }; -export interface FieldConfig extends ui.HideableFieldConfig { +export interface FieldConfig extends ui.AxisConfig, ui.HideableFieldConfig { fillOpacity?: number; lineWidth?: number; } diff --git a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx index fd1164c85f3..237f1469723 100644 --- a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx +++ b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx @@ -1,7 +1,14 @@ import { useMemo, useState } from 'react'; import { DashboardCursorSync, PanelProps } from '@grafana/data'; -import { EventBusPlugin, TooltipDisplayMode, TooltipPlugin2, usePanelContext, useTheme2 } from '@grafana/ui'; +import { + AxisPlacement, + EventBusPlugin, + TooltipDisplayMode, + TooltipPlugin2, + usePanelContext, + useTheme2, +} from '@grafana/ui'; import { TimeRange2, TooltipHoverMode } from '@grafana/ui/src/components/uPlot/plugins/TooltipPlugin2'; import { TimelineChart } from 'app/core/components/TimelineChart/TimelineChart'; import { @@ -141,14 +148,16 @@ export const StatusHistoryPanel = ({ maxWidth={options.tooltip.maxWidth} /> )} - + {alignedFrame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden && ( + + )} ); diff --git a/public/app/plugins/panel/status-history/module.tsx b/public/app/plugins/panel/status-history/module.tsx index 8d42b1c4d1b..58ff47be783 100644 --- a/public/app/plugins/panel/status-history/module.tsx +++ b/public/app/plugins/panel/status-history/module.tsx @@ -1,5 +1,5 @@ import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; -import { VisibilityMode } from '@grafana/schema'; +import { AxisPlacement, VisibilityMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; import { StatusHistoryPanel } from './StatusHistoryPanel'; @@ -42,6 +42,11 @@ export const plugin = new PanelPlugin(StatusHistoryPanel) }); commonOptionsBuilder.addHideFrom(builder); + commonOptionsBuilder.addAxisPlacement( + builder, + (placement) => placement === AxisPlacement.Auto || placement === AxisPlacement.Hidden + ); + commonOptionsBuilder.addAxisWidth(builder); }, }) .setPanelOptions((builder) => { diff --git a/public/app/plugins/panel/status-history/panelcfg.cue b/public/app/plugins/panel/status-history/panelcfg.cue index ec5ab6c4fc7..55a96b501d2 100644 --- a/public/app/plugins/panel/status-history/panelcfg.cue +++ b/public/app/plugins/panel/status-history/panelcfg.cue @@ -37,6 +37,7 @@ composableKinds: PanelCfg: { colWidth?: float & <=1 | *0.9 } @cuetsy(kind="interface") FieldConfig: { + ui.AxisConfig ui.HideableFieldConfig lineWidth?: uint32 & <=10 | *1 fillOpacity?: uint32 & <=100 | *70 diff --git a/public/app/plugins/panel/status-history/panelcfg.gen.ts b/public/app/plugins/panel/status-history/panelcfg.gen.ts index 8bc46e363d0..fac1c7e19df 100644 --- a/public/app/plugins/panel/status-history/panelcfg.gen.ts +++ b/public/app/plugins/panel/status-history/panelcfg.gen.ts @@ -31,7 +31,7 @@ export const defaultOptions: Partial = { showValue: ui.VisibilityMode.Auto, }; -export interface FieldConfig extends ui.HideableFieldConfig { +export interface FieldConfig extends ui.AxisConfig, ui.HideableFieldConfig { fillOpacity?: number; lineWidth?: number; }