Search code examples
javascriptcsvsvgd3.jsrect

Add rectangles over dates D3


I have the csv;

start_dt,end_dt
2012-08-01 00:00:00,2012-08-02 06:30:00
2012-09-02 13:00:00,2012-09-02 15:00:00
2012-09-12 00:00:00,2012-09-12 06:00:00
2012-11-06 05:00:00,2012-11-06 16:00:00

I require to add a transparent rectangle over each span (start_dt - end_dt) to a D3 chart which alrady contains a line path with datetime x-axis.

I get the data from the csv via;

d3.csv("{% static 'historicaldata/csv/bad_data.csv' %}", function(error, data) {
    data.forEach(function(d) {
    d.start_dt = parseDate(d.start_dt);
    d.end_dt = pareseDate(d.end_dt);
});

How do I create these rectangles in the context of time, relative to the line path that is already present, and add them to my svg container?

I have already defined dimensions;

height = 275 - margin.top - margin.bottom;

EDIT:

fiddle with js function concerned http://jsfiddle.net/3emn74yr/2/


Solution

  • You just need to use your x-scale to set the x-coordinate of the rects based on the start date, and set the width to be the difference in the x-scaled values of the end and start dates.

    For example, if you want your rects to span the full height of your chart, you could do this:

    svg.selectAll('.time-span-rect')
      .data(data)
      .enter().append('rect')
        .attr('class', 'time-span-rect')
        .attr('x', function(d) { return x(d.start_dt); })
        .attr('y', 0)
        .attr('width', function(d) { return x(d.end_dt) - x(d.start_dt); })
        .attr('height', height);
    

    Then if you want them to be transparent, you can either set

    .attr('fill', 'transparent')
    

    or target the class in your css:

    .time-span-rect {
      fill: transparent;
    }
    

    HERE is an example you can look at using your time-span data and a random line graph. I've made the x-scale a d3.time.scale rather than a linear scale, since it makes working with the axes quite a bit simpler. You might want to consider doing the same. Also, I've made the rects' fill cyan just so they show up. Simply change the css fill to transparent. Hope that helps.