D3 Brush coordinates under CSS transform scale

无人久伴 提交于 2019-12-08 07:00:50

问题


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


回答1:


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.




回答2:


If you use CSS transform you should apply it to all the classes that related by nodes:

 .node {
  stroke: #fff;
  stroke-width: 1.5px;
  transform: scale(0.5);
 }

 .node .selected {
        stroke: red;
  }

.link {
   stroke: #999;
     transform: scale(0.5);
  }

.brush .extent {
  fill-opacity: .1;
  stroke: #fff;
  shape-rendering: crispEdges;
  transform: scale(0.5);
}

When you add transform: scale(0.5); you can brush all the node. Try from left to right over node position.

 var width = 960,height = 500;
  var svg = d3.select("#body").append("svg")
        .attr("width", width)
        .attr("height", height);


    graph.links.forEach(function(d) {
        d.source = graph.nodes[d.source];
        d.target = graph.nodes[d.target];
    });

    var link = svg.append("g")
        .attr("class", "link")
        .selectAll("line")
        .data(graph.links)
        .enter().append("line")
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    var node = svg.append("g")
        .attr("class", "node")
        .selectAll("circle")
        .data(graph.nodes)
        .enter().append("circle")
        .attr("r", 4)
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });

    var brush = svg.append("g")
        .attr("class", "brush")
        .call(d3.svg.brush()
            .x(d3.scale.identity().domain([0, width]))
            .y(d3.scale.identity().domain([0, height]))
            .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 && d.y < extent[1][1];
                });
            }));

Complete jsfiddle here.



来源:https://stackoverflow.com/questions/31298221/d3-brush-coordinates-under-css-transform-scale

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!