Time based x-axis with scaleTime and scaleBand

I would like to create a plot where the x-axis is time in days, and the date range in something that is user input. The plot will have two types of symbols - circles and bars to denote two different types of information.

In order to accomplish this I started using a d3.scaleTime scale, and while the circles were centered on the day, the bars were not (the left hand edge of the bar started on the day, rather than the bar being centered on the day).

After some looking around it seems like I needed to use d3.scaleBand, where the domain is a list of the days in the date range.

So I created a plot where the circles are plotted using the d3.scaleTime scale and the bars are plotted using the d3.scaleBand scale.

This is the notebook with my code so far, and where you can see that while the circles are centered on the days they occur on, the bars are not and in fact drift to the left.

Is there a way to accomplish what I want?

This might work for you:

for the bars, offset the x position by half the bandscale

.attr('x', d => x(new Date(d[0]))-x_band.bandwidth()/2)
2 Likes

That works nicely.

To make sure I understand, you locate the left edge of the bar by first locating the center with x(new Date(d[0])) and then shifting it over by half of the bar width, right?

Correct! Here are some other examples:

https://observablehq.com/@fil/summer-heat (uses half bandwidth to offset labels)

You can also draw a line and set the width of the line to the band width:

Great! Thanks for the other examples, it helps tremendously to look at these other examples and see what is possible.