简体   繁体   English

d3-在基于y坐标的位置绘制网格线?

[英]d3-Draw grid line at a location based on the y coordinates?

I am kind a new to d3.js and want to draw a horizontal grid line based on y coordinate value fiddle , i've tried with if condition at y1 and y2 locations but the lines are overlapping at the top of graph. 我是d3.js的新手,想要根据y坐标值fiddle绘制一条水平网格线,我已尝试在y1和y2位置使用if条件,但线条在图形顶部重叠。

Any help is much appreciated. 任何帮助深表感谢。

Your if statement makes little sense to me: 你的if语句对我来说没什么意义:

if (y(d) === thresholdValues.minValue) {
    return y(d);
}

This means that only when the value in the screen is exactly thresholdValues.minValue (which is 40 in your code) the line will be painted. 这意味着只有当屏幕中的值正好是thresholdValues.minValue (代码中为40 )时才会绘制线条。

Solution: drop the if statement. 解决方案:删除if语句。 Actually, I kept the if just to avoid the first gridline, over the x axis: 实际上,我保持if只是为了避开第一个网格线,在x轴上:

if (d != 0) {
    return y(d);
}

Here is your code with that change: 以下是您更改的代码:

 var margin = { top: 30, right: 20, bottom: 30, left: 50 }; var thresholdValues = { minValue: 40, maxValue: 85 }; var width = 600 - margin.left - margin.right; var height = 270 - margin.top - margin.bottom; var parseDate = d3.time.format("%d-%b-%y").parse; var x = d3.time.scale().range([0, width]); var y = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis().scale(x) .orient("bottom").ticks(5); var yAxis = d3.svg.axis().scale(y) .orient("left").ticks(5); var valueline = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.close); }); 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 + ")"); // Get the data var data = [{ date: "1-May-12", close: "58.13" }, { date: "30-Apr-12", close: "53.98" }, { date: "27-Apr-12", close: "67.00" }, { date: "26-Apr-12", close: "89.70" }, { date: "25-Apr-12", close: "99.00" }]; data.forEach(function(d) { d.date = parseDate(d.date); d.close = +d.close; }); // Scale the range of the data x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([0, 100]); svg.append("path") // Add the valueline path. .attr("d", valueline(data)); svg.append("g") // Add the X Axis .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") // Add the Y Axis .attr("class", "y axis") .call(yAxis); svg.selectAll("line.horizontalGrid").data(y.ticks(4)).enter() .append("line") .attr({ "class": "horizontalGrid", "x1": margin.right, "x2": width - margin.right, "y1": function(d) { if (d != 0) { return y(d); } }, "y2": function(d) { if (d != 0) { return y(d); } }, "fill": "none", "shape-rendering": "crispEdges", "stroke": "grey", "stroke-width": "2px", "opacity": 0.4, "stroke-dasharray": 8 }); 
 body { font: 12px Arial; } path { stroke: steelblue; stroke-width: 2; fill: none; } .axis path, .axis line { fill: none; stroke: grey; stroke-width: 1; shape-rendering: crispEdges; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

EDIT: If you want to draw only two lines, at the thresholds, you have to pass their values to data , not the scale ticks: 编辑:如果您只想绘制两条线,在阈值处,您必须将它们的值传递给data ,而不是标尺刻度:

.data(Object.values(thresholdValues))

Here is the demo: 这是演示:

 var margin = { top: 30, right: 20, bottom: 30, left: 50 }; var thresholdValues = { minValue: 40, maxValue: 85 }; var width = 600 - margin.left - margin.right; var height = 270 - margin.top - margin.bottom; var parseDate = d3.time.format("%d-%b-%y").parse; var x = d3.time.scale().range([0, width]); var y = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis().scale(x) .orient("bottom").ticks(5); var yAxis = d3.svg.axis().scale(y) .orient("left").ticks(5); var valueline = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.close); }); 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 + ")"); // Get the data var data = [{ date: "1-May-12", close: "58.13" }, { date: "30-Apr-12", close: "53.98" }, { date: "27-Apr-12", close: "67.00" }, { date: "26-Apr-12", close: "89.70" }, { date: "25-Apr-12", close: "99.00" }]; data.forEach(function(d) { d.date = parseDate(d.date); d.close = +d.close; }); // Scale the range of the data x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([0, 100]); svg.append("path") // Add the valueline path. .attr("d", valueline(data)); svg.append("g") // Add the X Axis .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") // Add the Y Axis .attr("class", "y axis") .call(yAxis); svg.selectAll("line.horizontalGrid").data(Object.values(thresholdValues)).enter() .append("line") .attr({ "class": "horizontalGrid", "x1": margin.right, "x2": width - margin.right, "y1": function(d) { if (d != 0) { return y(d); } }, "y2": function(d) { if (d != 0) { return y(d); } }, "fill": "none", "shape-rendering": "crispEdges", "stroke": "grey", "stroke-width": "2px", "opacity": 0.4, "stroke-dasharray": 8 }); 
 path { stroke: steelblue; stroke-width: 2; fill: none; } .axis path, .axis line { fill: none; stroke: grey; stroke-width: 1; shape-rendering: crispEdges; } 
 <script src="https://d3js.org/d3.v3.js"></script> 

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

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