mirror of
https://github.com/grafana/grafana.git
synced 2025-09-23 01:43:36 +08:00
BarChart: refactor x tick label placement logic (#43256)
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
import uPlot, { Axis, AlignedData } from 'uplot';
|
import uPlot, { Axis, AlignedData, Scale } from 'uplot';
|
||||||
import { pointWithin, Quadtree, Rect } from './quadtree';
|
import { pointWithin, Quadtree, Rect } from './quadtree';
|
||||||
import { distribute, SPACE_BETWEEN } from './distribute';
|
import { distribute, SPACE_BETWEEN } from './distribute';
|
||||||
import { DataFrame, GrafanaTheme2 } from '@grafana/data';
|
import { DataFrame, GrafanaTheme2 } from '@grafana/data';
|
||||||
@ -75,24 +75,42 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
|||||||
barMark.style.background = 'rgba(255,255,255,0.4)';
|
barMark.style.background = 'rgba(255,255,255,0.4)';
|
||||||
|
|
||||||
const xSplits: Axis.Splits = (u: uPlot) => {
|
const xSplits: Axis.Splits = (u: uPlot) => {
|
||||||
const dim = isXHorizontal ? u.bbox.width : u.bbox.height;
|
|
||||||
const _dir = dir * (isXHorizontal ? 1 : -1);
|
const _dir = dir * (isXHorizontal ? 1 : -1);
|
||||||
|
|
||||||
let splits: number[] = [];
|
// for distr: 2 scales, the splits array should contain indices into data[0] rather than values
|
||||||
|
let splits = u.data[0].map((v, i) => i);
|
||||||
distribute(u.data[0].length, groupWidth, groupDistr, null, (di, leftPct, widPct) => {
|
|
||||||
let groupLftPx = (dim * leftPct) / devicePixelRatio;
|
|
||||||
let groupWidPx = (dim * widPct) / devicePixelRatio;
|
|
||||||
|
|
||||||
let groupCenterPx = groupLftPx + groupWidPx / 2;
|
|
||||||
|
|
||||||
splits.push(u.posToVal(groupCenterPx, 'x'));
|
|
||||||
});
|
|
||||||
|
|
||||||
return _dir === 1 ? splits : splits.reverse();
|
return _dir === 1 ? splits : splits.reverse();
|
||||||
};
|
};
|
||||||
|
|
||||||
const xValues: Axis.Values = (u) => u.data[0].map((x) => formatValue(0, x));
|
// the splits passed into here are data[0] values looked up by the indices returned from splits()
|
||||||
|
const xValues: Axis.Values = (u, splits) => {
|
||||||
|
return splits.map((v) => formatValue(0, v));
|
||||||
|
};
|
||||||
|
|
||||||
|
// this expands the distr: 2 scale so that the indicies of each data[0] land at the proper justified positions
|
||||||
|
const xRange: Scale.Range = (u, min, max) => {
|
||||||
|
min = 0;
|
||||||
|
max = u.data[0].length - 1;
|
||||||
|
|
||||||
|
let pctOffset = 0;
|
||||||
|
|
||||||
|
// how far in is the first tick in % of full dimension
|
||||||
|
distribute(u.data[0].length, groupWidth, groupDistr, 0, (di, lftPct, widPct) => {
|
||||||
|
pctOffset = lftPct + widPct / 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
// expand scale range by equal amounts on both ends
|
||||||
|
let rn = max - min; // TODO: clamp to 1?
|
||||||
|
|
||||||
|
let upScale = 1 / (1 - pctOffset * 2);
|
||||||
|
let offset = (upScale * rn - rn) / 2;
|
||||||
|
|
||||||
|
min -= offset;
|
||||||
|
max += offset;
|
||||||
|
|
||||||
|
return [min, max];
|
||||||
|
};
|
||||||
|
|
||||||
let distrTwo = (groupCount: number, barCount: number) => {
|
let distrTwo = (groupCount: number, barCount: number) => {
|
||||||
let out = Array.from({ length: barCount }, () => ({
|
let out = Array.from({ length: barCount }, () => ({
|
||||||
@ -335,6 +353,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
|||||||
points: { show: false },
|
points: { show: false },
|
||||||
},
|
},
|
||||||
// scale & axis opts
|
// scale & axis opts
|
||||||
|
xRange,
|
||||||
xValues,
|
xValues,
|
||||||
xSplits,
|
xSplits,
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptions> = ({
|
|||||||
builder.addScale({
|
builder.addScale({
|
||||||
scaleKey: 'x',
|
scaleKey: 'x',
|
||||||
isTime: false,
|
isTime: false,
|
||||||
|
range: config.xRange,
|
||||||
distribution: ScaleDistribution.Ordinal,
|
distribution: ScaleDistribution.Ordinal,
|
||||||
orientation: vizOrientation.xOri,
|
orientation: vizOrientation.xOri,
|
||||||
direction: vizOrientation.xDir,
|
direction: vizOrientation.xDir,
|
||||||
|
Reference in New Issue
Block a user