Centering a rect on the axis tick when using a utc scale #2353
Replies: 2 comments
-
|
You can use a band scale with the “day” interval if your data represents days rather than exact times. Documentation: https://observablehq.com/plot/transforms/interval |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for the quick response! I had been doing that originally, but it didn't work because of the way the rest of the chart is set up. I left a bit of that out to hopefully make my question simpler, but I'll elaborate here. The idea of the chart is that it shows how many words a set of people wrote each day (rect mark), versus a daily par (line mark). There's also a tooltip to show details about each person's writing and the par that day.
In this question, I had asked how to keep the par and words from stacking together when rendering the tooltip (since I only want one tooltip on screen at once), and the response was to offset the par data points by a millisecond, which would prevent them from stacking but would not be visible. That works great, but requires a Here's an expanded version of my config: const words: { series: string; date: Date; value: number } = [ /* ... */ ];
const wordsMark = Plot.rectY(words, {
x: 'date',
y: 'value',
z: 'series',
fill: 'series',
order: seriesOrder,
// we have to move the x position back half a day so it's centered on the axis tick
x1: d => addHours(d.date, -12),
x2: d => addHours(d.date, 12),
insetLeft: 1,
insetRight: 1,
}),
const par: { series: string; date: Date; value: number } = [ /* ... */ ].map(el => ({
...el,
series: 'Par',
date: addMilliseconds(el.date, 1)
});
const parMark = Plot.lineY(par, {
x: 'date',
y: 'value',
stroke: chartColors.par,
strokeDasharray: 8,
}),
const tooltipData = [...words, ...par];
const tipMark = Plot.tip(tooltipData, Plot.pointer(Plot.stackY2({
x: 'date',
y: 'value',
z: 'series',
channels: {
date: { label: '', value: 'date' },
value: { label: '', value: 'value' },
series: { label: '', value: 'series', scale: 'color' },
},
format: {
date: d => formatDate(d, true),
value: d => formatCountForChart(d),
series: d => getSeriesName(seriesInfo, d),
x: false,
y: false,
z: false,
},
fill: chartColors.background,
order: seriesOrder,
})));
const chart = Plot.plot({
/* lots of plot config omitted */
x: {
type: 'utc',
tickFormat: (d: Date) => (d.getUTCHours() === 0) ? utcFormat('%-d\n%b')(d) : '',
},
y: {
grid: true,
nice: true,
zero: true,
tickFormat: /* ... */,
},
color: {
type: 'categorical',
domain: ['Par', ...seriesOrder],
range: [chartColors.par, ...colorOrder],
legend: true,
},
marks: [ parMark, wordsMark, tipMark ],
});
// then render the chartIf the answer is, "yep, that's how I'd do it", then great! But it felt like I might be missing a formatting or offset option in the axis or tick config somewhere. |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
Hello! I'll start by saying that I've figured out a way to do what I need, but I want to ask if I have missed an easier way to do it. Here's what I've got.
My data is of the form
{ series: string; value: number; date: Date }but only the actual day, month, and year matter, so the time on the dates is all 00:00:00Z. I want to display this as a stacked bar graph, and am using a rect mark to do that. However, when I do this, the left side of the rect aligns with the day's tick mark on the axis:And I would like the center of the rect to align with that tick mark1:
Here's how I'm currently achieving this (with styling config removed):
Changing
x1andx2by 12 hours just seems... kinda fiddly. So: is there a simpler way to do this that I've missed? Or is this how you'd suggest doing it?Footnotes
The reason for this is because I also have a line mark and a tooltip on this graph, and those are behaving — their data points are right over the tick mark, exactly where I want them. This is more-or-less the same configuration from https://github.com/observablehq/plot/discussions/2206, but with rects instead of area, and it's the width of the rects that's screwing things up here. ↩
Beta Was this translation helpful? Give feedback.
All reactions