簡體   English   中英

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.要縮放圓圈而不更改其位置,請執行以下操作。

translate(-centerX *(factor-1), - centerY *(factor-1))scale(factor)

工作小提琴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> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM