簡體   English   中英

創建帶有次要和主要刻度d3js的波特圖

[英]Create bode plot with minor and major ticks d3js

我試圖用d3js創建一個典型的波特圖。 使用Matlab創建的典型波特圖如下所示:

Matlab預示着情節

現在我已經相當了解: http//plnkr.co/edit/BpWis5uhC8KM2tRbXMk3或此帖子中嵌入的片段。

我遇到的問題是,我想要,就像在matlab波特圖中一樣,有主要和次要的刻度。 主要蜱是穩固的,而小蜱是點綴的。 不幸的是,我似乎無法做到這一點。 我已經嘗試過各種解決方案:

不同風格的主要和次要蜱,整頁覆蓋D3? D3的V3的主要和次要蜱? d3.js替代axis.tickSubdivide? http://bl.ocks.org/vjpgo/4689130 http://bl.ocks.org/mbostock/4349486

 <!DOCTYPE html> <html lang="en"> <head> <title>LOG</title> <meta charset="utf-8"> <script src="//d3js.org/d3.v3.min.js"></script> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//mathjs.org/js/lib/math.js"></script> <style type="text/css"> 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> <script type="text/javascript"> function linspace(a,b,n) { var every = (ba)/(n-1), range = []; for (i = a; i < b; i += every) range.push(i); return range.length == n ? range : range.concat(b); } function logspace(a,b,n) { return linspace(a,b,n).map(function(x) { return Math.pow(10,x); }); } function isInteger(value) { return typeof value === "number" && isFinite(value) && Math.floor(value) === value; }; function leadlag(f) { w = 2*math.pi*f; s = math.complex(0,w); K = 1; fz = 20; fp = 40; wz = 2*math.pi*fz; wp = 2*math.pi*fp; return math.multiply(K,math.multiply(math.divide(wp,wz),math.divide(math.add(s,wz),(math.add(s,wp))))); }; function angle(f) { return math.atan2(f.im,f.re); }; function deg2rad(deg) { return deg * math.pi / 180; }; function rad2deg(rad) { return rad * 180 / math.pi; }; function mag2db(mag) { return 20 * Math.log10(mag); } function db2mag(db) { return math.pow(10,db / 20); } </script> </head> <body> <div id="plotmagnitude"></div> <div id="plotphase"></div> <script type="text/javascript"> var margin = { top: 20, right: 20, bottom: 35, left: 50 }; var width = 450 - margin.left - margin.right; var height = 250 - margin.top - margin.bottom; var range = logspace(0,3,1000); var x = d3.scale.log() .domain([1, range[range.length-1].toFixed()]) .range([0, width]); var y = d3.scale.linear() .domain([-10, 2]) .range([height, 0]); var xAxis1 = d3.svg.axis() .scale(x) .orient("bottom") .ticks(1,"0.1s") .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) .outerTickSize(0) .tickFormat(""); var yAxis2 = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .innerTickSize(6) .tickPadding(-20) .outerTickSize(0) .tickFormat(""); var xGrid = d3.svg.axis() .scale(x) .orient("bottom") .ticks(5) .tickSize(-height, -height, 0) .tickFormat(""); var yGrid = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .tickSize(-width, -width, 0) .tickFormat(""); var line = d3.svg.line() .x(function(d) { return x(dx); }) .y(function(d) { return y(dy); }) .interpolate("linear"); var zoom = d3.behavior.zoom() .x(x) .y(y) .scaleExtent([1, 1]) .on("zoom",redraw); var plotMagnitude = d3.select("#plotmagnitude").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); // Add x grid plotMagnitude.append("g") .attr("class","x grid") .attr("transform","translate(0," + height + ")") .call(xGrid); // Add y grid plotMagnitude.append("g") .attr("class","y grid") .call(yGrid); plotMagnitude.append("g") .attr("class","x1 axis") .attr("transform","translate(0," + height + ")") .call(xAxis1); plotMagnitude.append("g") .attr("class","y1 axis") .call(yAxis1); /* append additional X axis */ plotMagnitude.append("g") .attr("class","x2 axis") .attr("transform","translate(" + [0, 0] + ")") .call(xAxis2); /* append additional y axis */ plotMagnitude.append("g") .attr("class","y2 axis") .attr("transform","translate(" + [width, 0] + ")") .call(yAxis2); // Add x axis label plotMagnitude.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 plotMagnitude.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"); plotMagnitude.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); plotMagnitude.append("rect") .attr("width", width) .attr("height", height); function redraw() { plotMagnitude.select(".x1.axis").call(xAxis1); plotMagnitude.select(".y1.axis").call(yAxis1); plotMagnitude.select(".x2.axis").call(xAxis2); plotMagnitude.select(".y2.axis").call(yAxis2); plotMagnitude.select(".x.grid").call(xGrid); plotMagnitude.select(".y.grid").call(yGrid); var series = []; var data1 = []; var data2 = []; var data3 = []; for (var i = 0; i < range.length; i++) { data1.push({ x: range[i], y: leadlag(range[i]) }); data2.push({ x: range[i], y: mag2db(math.abs(leadlag(range[i]))) }); data3.push({ x: range[i], y: rad2deg(angle(leadlag(range[i]))) }); } series.push({data: data2, width: 1, color: 'blue', stroke: "0,0", legend: "MAG" }); var series = plotMagnitude.selectAll(".line").data(series); series.enter().append('path'); series.attr("class","line") .attr("d",function(d) { return line(d.data); }) .attr("stroke-width", function(d) { return d.width; }) .style("stroke", function(d) { return d.color; }) .style("stroke-dasharray", function(d) { return d.stroke; }); } $(function() { redraw(); }); </script> </body> </html> 

看起來您的“主要”刻度被定義為帶有標簽的刻度,因此難以找到它們然后找到相應的網格線。

怎么樣:

d3.selectAll('.x1.axis>.tick')  // find all the x axis ticks and loop
  .each(function(d,i){
    if (d3.select(this).select('text').text() === ""){ // if they have no label
      d3.select('.x.grid>.tick:nth-child(' + (i + 1) + ')') // get the corresponding grid line
        .style("stroke-dasharray", "3,3"); // and make it dashed
      }
  });

完整代碼:

 <!DOCTYPE html> <html lang="en"> <head> <title>LOG</title> <meta charset="utf-8"> <script src="//d3js.org/d3.v3.min.js"></script> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//mathjs.org/js/lib/math.js"></script> <style type="text/css"> 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> <script type="text/javascript"> function linspace(a,b,n) { var every = (ba)/(n-1), range = []; for (i = a; i < b; i += every) range.push(i); return range.length == n ? range : range.concat(b); } function logspace(a,b,n) { return linspace(a,b,n).map(function(x) { return Math.pow(10,x); }); } function isInteger(value) { return typeof value === "number" && isFinite(value) && Math.floor(value) === value; }; function leadlag(f) { w = 2*math.pi*f; s = math.complex(0,w); K = 1; fz = 20; fp = 40; wz = 2*math.pi*fz; wp = 2*math.pi*fp; return math.multiply(K,math.multiply(math.divide(wp,wz),math.divide(math.add(s,wz),(math.add(s,wp))))); }; function angle(f) { return math.atan2(f.im,f.re); }; function deg2rad(deg) { return deg * math.pi / 180; }; function rad2deg(rad) { return rad * 180 / math.pi; }; function mag2db(mag) { return 20 * Math.log10(mag); } function db2mag(db) { return math.pow(10,db / 20); } </script> </head> <body> <div id="plotmagnitude"></div> <div id="plotphase"></div> <script type="text/javascript"> var margin = { top: 20, right: 20, bottom: 35, left: 50 }; var width = 450 - margin.left - margin.right; var height = 250 - margin.top - margin.bottom; var range = logspace(0,3,1000); var x = d3.scale.log() .domain([1, range[range.length-1].toFixed()]) .range([0, width]); var y = d3.scale.linear() .domain([-10, 2]) .range([height, 0]); var xAxis1 = d3.svg.axis() .scale(x) .orient("bottom") .ticks(1,"0.1s") .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) .outerTickSize(0) .tickFormat(""); var yAxis2 = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .innerTickSize(6) .tickPadding(-20) .outerTickSize(0) .tickFormat(""); var xGrid = d3.svg.axis() .scale(x) .orient("bottom") .ticks(5) .tickSize(-height, -height, 0) .tickFormat(""); var yGrid = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .tickSize(-width, -width, 0) .tickFormat(""); var line = d3.svg.line() .x(function(d) { return x(dx); }) .y(function(d) { return y(dy); }) .interpolate("linear"); var zoom = d3.behavior.zoom() .x(x) .y(y) .scaleExtent([1, 1]) .on("zoom",redraw); var plotMagnitude = d3.select("#plotmagnitude").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); // Add x grid plotMagnitude.append("g") .attr("class","x grid") .attr("transform","translate(0," + height + ")") .call(xGrid); // Add y grid plotMagnitude.append("g") .attr("class","y grid") .call(yGrid); plotMagnitude.append("g") .attr("class","x1 axis") .attr("transform","translate(0," + height + ")") .call(xAxis1); plotMagnitude.append("g") .attr("class","y1 axis") .call(yAxis1); /* append additional X axis */ plotMagnitude.append("g") .attr("class","x2 axis") .attr("transform","translate(" + [0, 0] + ")") .call(xAxis2); /* append additional y axis */ plotMagnitude.append("g") .attr("class","y2 axis") .attr("transform","translate(" + [width, 0] + ")") .call(yAxis2); // Add x axis label plotMagnitude.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 plotMagnitude.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"); plotMagnitude.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); plotMagnitude.append("rect") .attr("width", width) .attr("height", height); function redraw() { plotMagnitude.select(".x1.axis").call(xAxis1); plotMagnitude.select(".y1.axis").call(yAxis1); plotMagnitude.select(".x2.axis").call(xAxis2); plotMagnitude.select(".y2.axis").call(yAxis2); plotMagnitude.select(".x.grid").call(xGrid); plotMagnitude.select(".y.grid").call(yGrid); var series = []; var data1 = []; var data2 = []; var data3 = []; for (var i = 0; i < range.length; i++) { data1.push({ x: range[i], y: leadlag(range[i]) }); data2.push({ x: range[i], y: mag2db(math.abs(leadlag(range[i]))) }); data3.push({ x: range[i], y: rad2deg(angle(leadlag(range[i]))) }); } series.push({data: data2, width: 1, color: 'blue', stroke: "0,0", legend: "MAG" }); var series = plotMagnitude.selectAll(".line").data(series); series.enter().append('path'); series.attr("class","line") .attr("d",function(d) { return line(d.data); }) .attr("stroke-width", function(d) { return d.width; }) .style("stroke", function(d) { return d.color; }) .style("stroke-dasharray", function(d) { return d.stroke; }); d3.selectAll('.x1.axis>.tick') .each(function(d,i){ if (d3.select(this).select('text').text() === ""){ d3.select('.x.grid>.tick:nth-child(' + (i + 1) + ')') .style("stroke-dasharray", "3,3"); } }); } $(function() { redraw(); }); </script> </body> </html> 

暫無
暫無

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

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