简体   繁体   English

d3js放大图

[英]d3js zoom into plot

I have made a plot with d3js and because the plot function goes outside the plot I wanted to clip it. 我已经使用d3js进行了绘制,并且由于plot函数超出了绘制的范围,因此我想对其进行裁剪。 At the same time I also thought about zooming. 同时,我还考虑了缩放。 Therefor I started implementing the following example into my code; 因此,我开始在代码中实现以下示例; http://bl.ocks.org/mbostock/3892919 http://bl.ocks.org/mbostock/3892919

Unfortunately however, it seems that my implementation is incorrect. 但是不幸的是,我的实现似乎不正确。 My x- and y-axis labels seem to disappear + the background has turned black + the actual plot is missing until you try to zoom :S. 我的x轴和y轴标签似乎消失了+背景变成了黑色+实际的绘图丢失了,直到您尝试缩放:S为止。

Solution how to fix, ie, correctly implement this is asked. 提出了解决方法,即正确解决该问题的方法。 Further I am also open for improvements of my code. 此外,我也愿意改进我的代码。

Jsfiddle of the version with zoom: http://jsfiddle.net/n3Lndkum/12/ Jsfiddle of the last working version: http://jsfiddle.net/n3Lndkum/9/ 带有缩放版本的Jsfiddle: http : //jsfiddle.net/n3Lndkum/12/上一个工作版本的Jsfiddle: http : //jsfiddle.net/n3Lndkum/9/

Embedded version: 嵌入式版本:

 var margin = {top: 20, right: 20, bottom: 50, left: 50}, width = 250 - margin.left - margin.right, height = 250 - margin.top - margin.bottom, padding = 50; var x = d3.scale.linear() .range([0, width]) .domain([0, 10]); var y = d3.scale.linear() .range([height, 0]) .domain([0, 10]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom") .ticks(5) .innerTickSize(-6) .outerTickSize(0) .tickPadding(7); var yAxis = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .innerTickSize(-6) .outerTickSize(0) .tickPadding(7); var zoom = d3.behavior.zoom() .x(x) .y(y) .scaleExtent([0.1, 32]) .on("zoom", zoomed); var data = []; for (var k = -100; k < 101; k++) { data.push({x: k/10, y: 0.5*k*k/100}); } var line = d3.svg.line() .x(function(d) { return x(dx); }) .y(function(d) { return y(dy); }) .interpolate("linear"); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .call(zoom); svg.append("rect") .attr("width", width) .attr("height", height); // Add x axis svg.append("g") .attr("class","x axis") .attr("transform","translate(0," + height + ")") .call(xAxis); // Add y axis svg.append("g") .attr("class","y axis") .call(yAxis); /* append additional X axis */ svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + [0, 0] + ")") .call(xAxis.innerTickSize(6).tickPadding(-20).tickFormat("")); /* append additional y axis */ svg.append("g") .attr("class","y axis") .attr("transform", "translate(" + [width, 0] + ")") .call(yAxis.innerTickSize(6).tickPadding(-20).tickFormat("")); // Add x axis label svg.append("text") .attr("transform", "translate(" + (width / 2) + "," + (height + margin.bottom) + ")") .style("font-size","15") .style("text-anchor", "middle") .text("x axis"); // Add y axis label svg.append("text") .attr("transform", "rotate(-90)") .attr("y",0 - margin.left) .attr("x",0 - (height / 2)) .attr("dy", "1em") .style("font-size","15") .style("text-anchor", "middle") .text("y axis"); // Add x grid svg.append("g") .attr("class","grid") .attr("transform","translate(0," + height + ")") .call(xAxis .tickSize(-height,-height,0) .tickFormat("") ); // Add y grid svg.append("g") .attr("class","grid") .call(yAxis .tickSize(-width,-width,0) .tickFormat("") ); function zoomed() { svg.select(".x.axis").call(xAxis); svg.select(".y.axis").call(yAxis); // Add data svg.append("path") .attr("class","line") .attr("d",line(data)); } 
 body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } .grid .tick { stroke: lightgrey; opacity: 0.7; } .grid path { stroke-width: 0; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

Few things here: 这里的几件事:

1.) You aren't applying a clip-path to the line. 1.)您没有在行上应用剪切路径。 This is why it overruns the grid. 这就是为什么它会超出网格。

2.) Your grid is black because you've appended a rect to it (so it can receive the pan/zoom mouse events) but you aren't setting it's fill to something (it's black by default). 2)您的网格是黑色的,因为您已经在其上附加了一个rect (因此它可以接收平移/缩放鼠标事件),但是您没有将其填充设置为某种颜色(默认情况下为黑色)。 Note, you can't set it's fill to none since then it won't get the mouse events. 请注意,您不能将其填充设置为none,否则将不会获得鼠标事件。

3.) You shouldn't share the axis definition like you are doing: 3)您不应该像现在那样共享轴定义:

.call(xAxis.innerTickSize(6).tickPadding(-20).tickFormat(""));

The pan and zoom functionality is going to need to redraw the axis(es) and grid(s), keep a reference to each one you create. 平移和缩放功能将需要重绘轴和网格,并保留对创建的每个轴的引用。

4.) In your zoom event, don't re-append a new line. 4.)在缩放事件中,请勿重新添加新行。 Select the existing one and update it's data: 选择现有的一个并更新其数据:

d3.select(".line")
  .attr("d", line(data));

Putting this all together: 全部放在一起:

 <!DOCTYPE html> <meta charset="utf-8"> <title>Zoom + Pan</title> <style> svg { font: 10px sans-serif; shape-rendering: crispEdges; } rect { fill: transparent; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; clip-path: url(#clip); } .grid .tick { stroke: lightgrey; opacity: 0.7; } .grid path { stroke-width: 0; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var margin = { top: 20, right: 20, bottom: 30, left: 40 }, width = 600 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var x = d3.scale.linear() .domain([0, 10]) .range([0, width]); var y = d3.scale.linear() .domain([0, 10]) .range([height, 0]); var zoom = d3.behavior.zoom() .x(x) .y(y) .scaleExtent([1, 32]) .on("zoom", zoomed); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .call(zoom); var xAxis1 = d3.svg.axis() .scale(x) .orient("bottom") .ticks(5) .innerTickSize(-6) .outerTickSize(0) .tickPadding(7); var yAxis1 = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .innerTickSize(-6) .outerTickSize(0) .tickPadding(7); var xAxis2 = d3.svg.axis() .scale(x) .orient("top") .ticks(5) .innerTickSize(6) .tickPadding(-20) .tickFormat(""); var yAxis2 = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .innerTickSize(6) .tickPadding(-20) .tickFormat(""); var xGrid = d3.svg.axis() .scale(x) .orient("bottom") .tickSize(-height, -height, 0) .tickFormat(""); var yGrid = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .tickSize(-width, -width, 0) .tickFormat(""); // Add x grid svg.append("g") .attr("class", "x grid") .attr("transform", "translate(0," + height + ")") .call(xGrid); // Add y grid svg.append("g") .attr("class", "y grid") .call(yGrid); svg.append("g") .attr("class", "x1 axis") .attr("transform", "translate(0," + height + ")") .call(xAxis1); svg.append("g") .attr("class", "y1 axis") .call(yAxis1); /* append additional X axis */ svg.append("g") .attr("class", "x2 axis") .attr("transform", "translate(" + [0, 0] + ")") .call(xAxis2); /* append additional y axis */ svg.append("g") .attr("class", "y2 axis") .attr("transform", "translate(" + [width, 0] + ")") .call(yAxis2); svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); svg.append("rect") .attr("width", width) .attr("height", height); var data = []; for (var k = -100; k < 101; k++) { data.push({ x: k / 10, y: 0.5 * k * k / 100 }); } var line = d3.svg.line() .x(function(d) { return x(dx); }) .y(function(d) { return y(dy); }) .interpolate("linear"); svg.append("path") .attr("class", "line") .attr("d", line(data)) function zoomed() { svg.select(".x1.axis").call(xAxis1); svg.select(".y1.axis").call(yAxis1); svg.select(".x2.axis").call(xAxis2); svg.select(".y2.axis").call(yAxis2); svg.select(".x.grid").call(xGrid); svg.select(".y.grid").call(yGrid); d3.select(".line") .attr("d", line(data)); } </script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM