[英]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.