AyKarsi AyKarsi - 3 months ago 41
Javascript Question

d3: drawing multiple rectangles using areas

I need to draw draw many filled rectangles inside a graph and would like to achieve this using svg paths.
(I'm not using the rect tag because perfomance will suffer over time.)

My current approach uses the d3.svg.area to generate the path for each area, but the rectangles are not being drawn properly.

As far as I understand the rendered path attribute, it seems that path is missing a moveTo per rectangle.

The following is my simplified code of the problem.

var data = [
{x0:0,x1:50,y0:0,y1:10},
{x10:0,x1:60,y0:20,y1:30},
];

var width = 500;
var barHeight = 20;

var areaFunc = d3.svg.area()
//.interpolate('step')
.x0(function(d){return d.x0;})
.x1(function(d){return d.x1;})
.y0(function(d){return d.y0;})
.y1(function(d){return d.y1;});

var chart = d3.select('#chart')
.attr('width', width)
.attr('height', barHeight * data.length);

chart.append('path')
//.data(data)
.attr('d', areaFunc(data))
.attr('class', 'absences area')
.attr('style', 'fill:blue;stroke:black;stroke-width:1');


JSFiddle: http://jsfiddle.net/3kLdkgz8/

Answer

If you want several rectangles, you need to define your data like that

var data = [
    [{x0:10,x1:60,y0:0,y1:0},{x0:10,x1:60,y0:20,y1:20}], // rect 1
    [{x0:100,x1:600,y0:20,y1:20},{x0:100,x1:600,y0:200,y1:200}]// rect 2
];

And call it like that

chart.selectAll('path')
        .data(data)
        .enter()
        .append('path')
        .attr('d', areaFunc)
        .attr('class', 'absences area')
        .attr('style', 'fill:blue;stroke:black;stroke-width:1');  

See http://jsfiddle.net/zh1vqfos/2/