Search code examples
cssd3.jstransformscalebrush

D3 Brush coordinates under CSS transform scale


D3 brush does not function properly under css transform scale. When svg is under div element, and div element is transformed using CSS scale, the brush operation shows wrong coordinates.

To demonstrate this case, here is the jsFiddle.

It is simple modification from Bostock's Brushable Network example.

What I did was simply putting SVG in the div element and made div element zoom 50% using CSS transform scale(0.5). And the brushing coordinates are not updating because of zooming.

#test {
transform: scale(0.5);
}

Thanks.

Deok


Solution

  • If you use an svg based transform:

    transform="scale(0.5)"
    

    Then it'll play nice with the brush:

    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    
    svg = svg.append("g")
        .attr("transform","scale(0.5)");
    

    Updated fiddle.

    To fix the calculations you need two things.

    1.) Scale the extent rect opposite the div:

    .extent {
       transform: scale(2);
    }
    

    2.) Fix the extent calculations:

       .on("brush", function() {
          var extent = d3.event.target.extent();
          node.classed("selected", function(d) {
            return extent[0][0] <= d.x && d.x < extent[1][0] && 
                   extent[0][1] <= (d.y/2) && (d.y/2) < extent[1][1]; // scale y opposite div transform
          });
       });
    

    New example here.