d3:应用 scale() 变换时元素移动
d3: Elements move when scale() transform is applied
我希望SVG元素在鼠标悬停时显示得更大。应用 CSS 转换似乎是一种方便的方法,但它也会转换对象。如何使以下示例中的圆保持其原始中心点?我尝试应用position: absolute;
无济于事。
var dataset = [0, 2345786000, 10000000000];
var svg = d3.select("body").append("svg");
var w = 500, h = 200;
var padding = 50;
svg.attr("width", w)
.attr("height", h);
// Background pattern
var patternSize = 5;
svg.append("defs")
.append("pattern")
.attr("id", "dotPattern")
.attr("patternUnits", "userSpaceOnUse")
.attr("width", patternSize)
.attr("height", patternSize)
.append("circle")
.attr("cx", patternSize / 2)
.attr("cy", patternSize / 2)
.attr("r", 2)
.style("stroke", "none")
.style("fill", "lightgrey")
.style("opacity", 0.5);
var xScale = d3.time.scale()
.domain([0, 10000000000])
.range([padding, w-padding]);
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(5);
svg.append("g")
.attr("class","axis")
.attr("transform", "translate(0," + (h-padding) + ")")
.call(xAxis);
var zoom = d3.behavior.zoom()
.on("zoom", build)
.scaleExtent([1, 20]);
zoom.x(xScale);
var clipPath = svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("x", padding)
.attr("y", 0)
.attr("width",w-2*padding)
.attr("height", h-padding);
var zoomArea = svg.append("g")
.attr("class", "zoomArea")
.style("cursor","move")
.attr("clip-path", "url(#clip)");
var zoomRect = zoomArea.append("rect")
.attr("x", padding)
.attr("y", 0)
.attr("width", w-2*padding)
.attr("height", h-padding)
.style("fill", "url(#dotPattern)")
.style("pointer-events", "all")
.style("cursor","move")
.call(zoom);
zoomArea.selectAll("circles")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d){
return xScale(d);
})
.attr("cy", h/2)
.attr("r",10)
.attr("fill","grey")
.on("mouseover", function(){
d3.select(this)
.attr("transform", "scale(1.4)")
})
.on("mouseout", function(){
d3.select(this)
.attr("transform", "scale(1)")
});
function build(){
svg.select("g.axis").call(xAxis);
d3.selectAll("circle")
.attr("cx", function(d){
return xScale(d);
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
有两种可能的方法可以解决此问题。
1.要缩放圆而不更改其位置,请执行以下操作。
平移(-中心X*(因子-1), -中心Y*(因子-1)) 比例(因子)
工作小提琴 1:
var dataset = [0, 2345786000, 10000000000];
var svg = d3.select("body").append("svg");
var w = 500,
h = 200;
var padding = 50;
svg.attr("width", w)
.attr("height", h);
// Background pattern
var patternSize = 5;
svg.append("defs")
.append("pattern")
.attr("id", "dotPattern")
.attr("patternUnits", "userSpaceOnUse")
.attr("width", patternSize)
.attr("height", patternSize)
.append("circle")
.attr("cx", patternSize / 2)
.attr("cy", patternSize / 2)
.attr("r", 2)
.style("stroke", "none")
.style("fill", "lightgrey")
.style("opacity", 0.5);
var xScale = d3.time.scale()
.domain([0, 10000000000])
.range([padding, w - padding]);
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(5);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
var zoom = d3.behavior.zoom()
.on("zoom", build)
.scaleExtent([1, 20]);
zoom.x(xScale);
var clipPath = svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("x", padding)
.attr("y", 0)
.attr("width", w - 2 * padding)
.attr("height", h - padding);
var zoomArea = svg.append("g")
.attr("class", "zoomArea")
.style("cursor", "move")
.attr("clip-path", "url(#clip)");
var zoomRect = zoomArea.append("rect")
.attr("x", padding)
.attr("y", 0)
.attr("width", w - 2 * padding)
.attr("height", h - padding)
.style("fill", "url(#dotPattern)")
.style("pointer-events", "all")
.style("cursor", "move")
.call(zoom);
zoomArea.selectAll("circles")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d);
})
.attr("cy", h / 2)
.attr("r", 10)
.attr("fill", "grey")
.on("mouseover", function(d) {
var x = xScale(d),
y = h / 2,
factor = 2;
var tx = -x * (factor - 1),
ty = -y * (factor - 1);
d3.select(this).transition().duration(50)
.attr("transform", "translate(" + tx + "," + ty + ") scale(" + factor + ")");
})
.on("mouseleave", function(d) {
var x = xScale(d),
y = h / 2,
factor = 1;
var tx = -x * (factor - 1),
ty = -y * (factor - 1);
d3.select(this).transition().duration(50)
.attr("transform", "translate(" + tx + "," + ty + ") scale(" + factor + ")");
});
function build() {
svg.select("g.axis").call(xAxis);
d3.selectAll("circle")
.attr("cx", function(d) {
return xScale(d);
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
2.由于您使用的是圆,因此可以轻松增加圆的半径以缩放它们。
工作小提琴2:
var dataset = [0, 2345786000, 10000000000];
var svg = d3.select("body").append("svg");
var w = 500,
h = 200;
var padding = 50;
svg.attr("width", w)
.attr("height", h);
// Background pattern
var patternSize = 5;
svg.append("defs")
.append("pattern")
.attr("id", "dotPattern")
.attr("patternUnits", "userSpaceOnUse")
.attr("width", patternSize)
.attr("height", patternSize)
.append("circle")
.attr("cx", patternSize / 2)
.attr("cy", patternSize / 2)
.attr("r", 2)
.style("stroke", "none")
.style("fill", "lightgrey")
.style("opacity", 0.5);
var xScale = d3.time.scale()
.domain([0, 10000000000])
.range([padding, w - padding]);
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(5);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
var zoom = d3.behavior.zoom()
.on("zoom", build)
.scaleExtent([1, 20]);
zoom.x(xScale);
var clipPath = svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("x", padding)
.attr("y", 0)
.attr("width", w - 2 * padding)
.attr("height", h - padding);
var zoomArea = svg.append("g")
.attr("class", "zoomArea")
.style("cursor", "move")
.attr("clip-path", "url(#clip)");
var zoomRect = zoomArea.append("rect")
.attr("x", padding)
.attr("y", 0)
.attr("width", w - 2 * padding)
.attr("height", h - padding)
.style("fill", "url(#dotPattern)")
.style("pointer-events", "all")
.style("cursor", "move")
.call(zoom);
zoomArea.selectAll("circles")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d);
})
.attr("cy", h / 2)
.attr("r", 10)
.attr("fill", "grey")
.on("mouseover", function() {
d3.select(this).transition().duration(50).attr("r", 20);
})
.on("mouseleave", function() {
d3.select(this).transition().duration(50).attr("r", 10);
});
function build() {
svg.select("g.axis").call(xAxis);
d3.selectAll("circle")
.attr("cx", function(d) {
return xScale(d);
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
相关文章:
- 远距离变换元素的宽度/高度(以像素为单位)
- 更改已变换元素的变换原点
- 如何向元素添加新的变换样式
- d3:应用 scale() 变换时元素移动
- 获取变换后的宽度:缩放元素
- 在SVG元素中保留变换
- 使用变换的SVG动画正在偏移元素
- 使用“变换”缩放多个元素
- 中心元素css三维变换
- 获取缩放变换元素的实际高度
- 使用动画中的Step函数来变换和旋转元素
- 使用javascript围绕某个点旋转元素(不使用变换原点)
- 拉斐尔元素没有'当传递给循环中的函数时,t变换
- 如何将屏幕坐标转换为z变换元素上的坐标
- 重新计算缩放元素上的变换原点
- CSS通过位置或变换来移动元素
- 将新元素放置在父级中包含的子级之上,并应用CSS缩放变换
- 子元素和父元素的CSS变换比例仍然占用相同的空间
- 我可以重用html5 canvas元素的变换吗?
- 定位并拖动应用了变换的元素