diff --git a/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx b/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx index 628ef871852..1fb68e60dd0 100755 --- a/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx +++ b/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx @@ -210,7 +210,7 @@ export class GraphNG extends React.Component { render() { const { width, height, children, timeRange, renderLegend } = this.props; - const { config, alignedFrame } = this.state; + const { config, alignedFrame, alignedData } = this.state; if (!config) { return null; @@ -220,8 +220,8 @@ export class GraphNG extends React.Component { {(vizWidth: number, vizHeight: number) => ( { this.reinitPlot(); } else if (!sameData(prevProps, this.props)) { plot?.setData(this.props.data); + + // this is a uPlot cache-busting hack for bar charts in case x axis labels changed + // since the x scale's "range" doesnt change, the axis size doesnt get recomputed, which is where the tick labels are regenerated & cached + // the more expensive, more proper/thorough way to do this is to force all axes to recalc: plot?.redraw(false, true); + if (plot && typeof this.props.data[0][0] === 'string') { + //@ts-ignore + plot.axes[0]._values = this.props.data[0]; + } } else if (!sameTimeRange(prevProps, this.props)) { plot?.setScale('x', { min: this.props.timeRange.from.valueOf(), diff --git a/public/app/plugins/panel/barchart/BarChart.tsx b/public/app/plugins/panel/barchart/BarChart.tsx index 4cd8e3d2f0c..5f4be6566b2 100644 --- a/public/app/plugins/panel/barchart/BarChart.tsx +++ b/public/app/plugins/panel/barchart/BarChart.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useRef } from 'react'; import { cloneDeep } from 'lodash'; import { DataFrame, TimeRange } from '@grafana/data'; import { GraphNG, GraphNGProps, PlotLegend, UPlotConfigBuilder, usePanelContext, useTheme2 } from '@grafana/ui'; @@ -27,6 +27,9 @@ export const BarChart: React.FC = (props) => { const theme = useTheme2(); const { eventBus } = usePanelContext(); + const frame0Ref = useRef(); + frame0Ref.current = props.frames[0]; + const renderLegend = (config: UPlotConfigBuilder) => { if (!config || props.legend.displayMode === LegendDisplayMode.Hidden) { return null; @@ -35,6 +38,8 @@ export const BarChart: React.FC = (props) => { return ; }; + const rawValue = (seriesIdx: number, valueIdx: number) => frame0Ref.current!.fields[seriesIdx].values.get(valueIdx); + const prepConfig = (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => { const { timeZone, orientation, barWidth, showValue, groupWidth, stacking, legend, tooltip, text } = props; @@ -52,6 +57,7 @@ export const BarChart: React.FC = (props) => { legend, tooltip, text, + rawValue, allFrames: props.frames, }); }; diff --git a/public/app/plugins/panel/barchart/types.ts b/public/app/plugins/panel/barchart/types.ts index b80cab51265..ff8a6476595 100644 --- a/public/app/plugins/panel/barchart/types.ts +++ b/public/app/plugins/panel/barchart/types.ts @@ -19,6 +19,7 @@ export interface BarChartOptions extends OptionsWithLegend, OptionsWithTooltip, showValue: BarValueVisibility; barWidth: number; groupWidth: number; + rawValue: (seriesIdx: number, valueIdx: number) => number; } /** diff --git a/public/app/plugins/panel/barchart/utils.test.ts b/public/app/plugins/panel/barchart/utils.test.ts index 7d233d8cd64..4df56dd2111 100644 --- a/public/app/plugins/panel/barchart/utils.test.ts +++ b/public/app/plugins/panel/barchart/utils.test.ts @@ -94,6 +94,7 @@ describe('BarChart utils', () => { text: { valueSize: 10, }, + rawValue: (seriesIdx: number, valueIdx: number) => frame.fields[seriesIdx].values.get(valueIdx), }; it.each([VizOrientation.Auto, VizOrientation.Horizontal, VizOrientation.Vertical])('orientation', (v) => { diff --git a/public/app/plugins/panel/barchart/utils.ts b/public/app/plugins/panel/barchart/utils.ts index de8f19793a6..d4ddf052ec9 100644 --- a/public/app/plugins/panel/barchart/utils.ts +++ b/public/app/plugins/panel/barchart/utils.ts @@ -45,6 +45,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ barWidth, stacking, text, + rawValue, }) => { const builder = new UPlotConfigBuilder(); const defaultValueFormatter = (seriesIdx: number, value: any) => @@ -67,7 +68,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ groupWidth, barWidth, stacking, - rawValue: (seriesIdx: number, valueIdx: number) => frame.fields[seriesIdx].values.get(valueIdx), + rawValue, formatValue, text, showValue,