CSS变换比例下的D3画笔坐标

D3 Brush coordinates under CSS transform scale

D3 笔刷在 css 变换比例下无法正常工作。当 svg 在 div 元素下,并且 div 元素使用 CSS 比例变换时,画笔操作显示错误的坐标。

为了演示这种情况,这里是 jsFiddle

这是Bostock's Brushable Network example的简单修改。

我所做的只是将 SVG 放入 div 元素中,并使用 CSS 变换比例 (0.5) 使 div 元素缩放 50%。并且刷牙坐标不会因为缩放而更新。

#test {
transform: scale(0.5);
}

谢谢。

德克

如果您使用基于 svg 的转换:

transform="scale(0.5)"

然后用笔刷就可以玩的很好了:

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

svg = svg.append("g")
    .attr("transform","scale(0.5)");

已更新 fiddle

要修复计算,您需要做两件事。

1.) 缩放与 div 相对的范围:

.extent {
   transform: scale(2);
}

2.) 修复范围计算:

   .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
      });
   });

新例子here.

如果您使用 CSS 转换,您应该将其应用于所有与节点相关的 类:

 .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);
}

添加transform: scale(0.5);后即可刷全节点。尝试从左到右越过节点位置。

 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];
                });
            }));

完成 jsfiddle here