Search code examples
javascriptd3.jschartszooming

d3 stacking and zoom


I created a chart that I manually stack/overlay areas on top of each other. Long story but I needed more control that the usual stacking that comes with d3.

Below is just a snippet of how I add each area to the chart:

let backlogGen = d3.svg.area()
            .x(function(d) { return x(d.projectDate); })
            .y0(height)
            .interpolate("cardinal")
            .y1(function(d) { return y(d.backlog); });

let reviewGen = d3.svg.area()
            .x(function(d) { return x(d.projectDate); })
            .y0(height)
            .interpolate("cardinal")
            .y1(function(d) { return y(d.uxreview); });

svg.append('syg:path')
            .attr('d', backlogGen(data))
            .attr("fill-opacity","1")
            .attr('fill', 'rgb(49, 130, 189)')

svg.append('svg:path')
            .attr('d', reviewGen(data))
            .attr("fill-opacity",".9")
            .attr('fill', 'rgb(230, 85, 13)')

Now I have a zoom function that zooms the x and y:

function zoomed() {
            console.log(d3.event.translate);
            console.log(d3.event.scale);

            svg.select("g.x.axis").call(xAxis);
            svg.select("g.y.axis").call(yAxis);

        }

My question is how do I make the actual area zoom as well? Do I somehow group them? Any help would be lovely!!


Solution

  • You need to update each layer. First you should save references to each layer, changing:

    svg.append('svg:path')
                .attr('d', backlogGen(data))
    

    and

    svg.append('svg:path')
                .attr('d', reviewGen(data))
    

    to

    let backlogLayer = svg.append('svg:path')
                .attr('d', backlogGen(data))
    

    and

    let reviewLayer = svg.append('svg:path')
                .attr('d', reviewGen(data))
    

    then in the end of zoomed(), refresh the data.

    backlogLayer.attr('d', backlogGen(data));
    reviewLayer.attr('d', reviewGen(data));
    

    What's happening is that zooming changes the x and y scales, and by calling backlogGen/reviewGen it updates the layer data based on the new scales.

    Also, depending on your scope, you might need to change all instances of let to var.