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。
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。