Skip to content

Commit 97d1fa5

Browse files
committed
Fix categorical support for Y and X/Y charts, fix viewer reset plugin bug
Signed-off-by: Andrew Stein <steinlink@gmail.com>
1 parent ed9a645 commit 97d1fa5

20 files changed

Lines changed: 1018 additions & 168 deletions

File tree

packages/viewer-charts/src/ts/axis/bar-axis.ts

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ export type BarCategoryAxis =
142142
| { mode: "category"; domain: CategoricalDomain }
143143
| { mode: "numeric"; domain: AxisDomain; ticks: number[] };
144144

145+
export type BarValueAxis =
146+
| { mode: "category"; domain: CategoricalDomain }
147+
| { mode: "numeric"; domain: AxisDomain; ticks: number[] };
148+
145149
/**
146150
* Render a numeric date-aware axis along the bottom of the plot. Aliases
147151
* the bar-axis bottom variant so heatmap can share the implementation.
@@ -190,13 +194,11 @@ export interface BarAxesFormatters {
190194
export function renderBarAxesChrome(
191195
canvas: Canvas2D,
192196
catAxis: BarCategoryAxis,
193-
valueDomain: AxisDomain,
194-
valueTicks: number[],
197+
valueAxis: BarValueAxis,
195198
layout: PlotLayout,
196199
theme: Theme,
197200
dpr: number,
198-
altDomain?: AxisDomain,
199-
altTicks?: number[],
201+
altAxis: BarValueAxis | undefined,
200202
isHorizontal = false,
201203
formatters: BarAxesFormatters = {},
202204
): void {
@@ -212,7 +214,7 @@ export function renderBarAxesChrome(
212214
ctx.moveTo(plot.x, plot.y);
213215
ctx.lineTo(plot.x, plot.y + plot.height);
214216
ctx.lineTo(plot.x + plot.width, plot.y + plot.height);
215-
if (altDomain) {
217+
if (altAxis) {
216218
if (isHorizontal) {
217219
ctx.moveTo(plot.x, plot.y);
218220
ctx.lineTo(plot.x + plot.width, plot.y);
@@ -238,31 +240,49 @@ export function renderBarAxesChrome(
238240
);
239241
}
240242

241-
drawNumericXAxis(
242-
ctx,
243-
layout,
244-
valueDomain,
245-
valueTicks,
246-
"bottom",
247-
theme,
248-
formatters.value,
249-
);
250-
if (altDomain && altTicks) {
251-
const origMin = layout.paddedXMin;
252-
const origMax = layout.paddedXMax;
253-
layout.paddedXMin = altDomain.min;
254-
layout.paddedXMax = altDomain.max;
243+
if (valueAxis.mode === "category") {
244+
// Categorical value axis on the bottom: reuse the X
245+
// categorical painter. Slot indices on the layout's X
246+
// domain already place each category at its slot pixel.
247+
renderCategoricalXTicks(ctx, layout, valueAxis.domain, theme);
248+
} else {
255249
drawNumericXAxis(
256250
ctx,
257251
layout,
258-
altDomain,
259-
altTicks,
260-
"top",
252+
valueAxis.domain,
253+
valueAxis.ticks,
254+
"bottom",
261255
theme,
262-
formatters.alt,
256+
formatters.value,
263257
);
264-
layout.paddedXMin = origMin;
265-
layout.paddedXMax = origMax;
258+
}
259+
260+
if (altAxis) {
261+
// Alt-axis painter expects the layout's X domain to match
262+
// the alt domain — temporarily swap in `altDomain.min/max`
263+
// for the duration of the call. Categorical alt has no
264+
// top-side painter; render with the bottom-side painter
265+
// (visual overlap with the primary side — documented
266+
// limitation; user-pinned categorical alt is rare).
267+
if (altAxis.mode === "category") {
268+
renderCategoricalXTicks(ctx, layout, altAxis.domain, theme);
269+
} else {
270+
const origMin = layout.paddedXMin;
271+
const origMax = layout.paddedXMax;
272+
layout.paddedXMin = altAxis.domain.min;
273+
layout.paddedXMax = altAxis.domain.max;
274+
drawNumericXAxis(
275+
ctx,
276+
layout,
277+
altAxis.domain,
278+
altAxis.ticks,
279+
"top",
280+
theme,
281+
formatters.alt,
282+
);
283+
layout.paddedXMin = origMin;
284+
layout.paddedXMax = origMax;
285+
}
266286
}
267287
} else {
268288
if (catAxis.mode === "category") {
@@ -278,31 +298,40 @@ export function renderBarAxesChrome(
278298
);
279299
}
280300

281-
drawYAxis(
282-
ctx,
283-
layout,
284-
valueDomain,
285-
valueTicks,
286-
"left",
287-
theme,
288-
formatters.value,
289-
);
290-
if (altDomain && altTicks) {
291-
const origMin = layout.paddedYMin;
292-
const origMax = layout.paddedYMax;
293-
layout.paddedYMin = altDomain.min;
294-
layout.paddedYMax = altDomain.max;
301+
if (valueAxis.mode === "category") {
302+
renderCategoricalYTicks(ctx, layout, valueAxis.domain, theme);
303+
} else {
295304
drawYAxis(
296305
ctx,
297306
layout,
298-
altDomain,
299-
altTicks,
300-
"right",
307+
valueAxis.domain,
308+
valueAxis.ticks,
309+
"left",
301310
theme,
302-
formatters.alt,
311+
formatters.value,
303312
);
304-
layout.paddedYMin = origMin;
305-
layout.paddedYMax = origMax;
313+
}
314+
315+
if (altAxis) {
316+
if (altAxis.mode === "category") {
317+
renderCategoricalYTicks(ctx, layout, altAxis.domain, theme);
318+
} else {
319+
const origMin = layout.paddedYMin;
320+
const origMax = layout.paddedYMax;
321+
layout.paddedYMin = altAxis.domain.min;
322+
layout.paddedYMax = altAxis.domain.max;
323+
drawYAxis(
324+
ctx,
325+
layout,
326+
altAxis.domain,
327+
altAxis.ticks,
328+
"right",
329+
theme,
330+
formatters.alt,
331+
);
332+
layout.paddedYMin = origMin;
333+
layout.paddedYMax = origMax;
334+
}
306335
}
307336
}
308337
}

packages/viewer-charts/src/ts/charts/candlestick/candlestick-render.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,15 @@ export function renderCandlestickChromeOverlay(chart: CandlestickChart): void {
272272
renderBarAxesChrome(
273273
chart._chromeCanvas,
274274
catAxis,
275-
chart._lastYDomain,
276-
chart._lastYTicks,
275+
{
276+
mode: "numeric",
277+
domain: chart._lastYDomain,
278+
ticks: chart._lastYTicks,
279+
},
277280
chart._lastLayout,
278281
theme,
279282
chart._glManager?.dpr ?? 1,
280283
undefined,
281-
undefined,
282284
false,
283285
{
284286
value: chart.getColumnFormatter(valueColumn, "tick"),

0 commit comments

Comments
 (0)