d3.js 4.0 - 具有中心轴的线图的网格线 [英] d3.js 4.0 — Gridlines for linechart with centered axis
问题描述
我几天前开始熟悉d3.js。幸运的是,图书馆在几个星期前进行了一次重大更新,现有的许多资源现在已过时。我已经设法做了我计划的大部分,但现在被困在网格线上部分。
我试图使用tick方法来绘制新行,用网格线搜索图表来查看它们是如何工作的等等都没有效果。方法改变了名字,我不总是很好地理解文档,所以这有点困难。我真的很感激,如果有人可以这么善良,指出我的方向正确。 :)
我把我的代码放在下面来说明中心轴的意思(两者都是)。
h1 {color:darkgreen;}。lineHighRange {fill:none;中风:钢蓝stroke-width:2px;}。lineLowRange {fill:none;中风:钢蓝stroke-width:2px;}。lineMiddleRange {fill:none;中风:橙色; stroke-width:2px;}。exteriorCircle {fill:darkred;}。contractPointsText {text-anchor:middle; font-family:sans-serif; font-size:12px;}。yAxisName {text-anchor:middle; transform:rotate(-90deg);}。xAxisName {text-anchor:middle;}
< script src =https://d3js.org/d3.v4.min.js>< / script>< title> Linechart< / title>< body& < h1> Demo-d3 4.0< / h1> < script src =js / chart.js>< / script>< / body>< / html>
>解决方案代替更改D3轴刻度,我们可以为每个刻度添加行。
首先,我们为每个轴设置类(
xAxis
和yAxis
)。然后,我们选择刻度(d3.selectAll(g.yAxis g.tick)
和d3.selectAll(g.xAxis g。
我为每一个轴添加了一行gridline。使用CSS更改其不透明度,颜色,样式等。
检查下面的代码段。
//数据//路径datavar contractHighRange = [{x:-6,y:0.5},{x:-5 ,y:0.1},{x:-4,y:0.1},{x:-2,y:0.2} 0.1,{x:0,y:-0.1},{x:1,y:-0.2} x:3,y:-0.2},{x:4,y:0.2},{x:5,y:0.4} :0.5}]; var contractLowRange = [{x:-6,y:0.3},{x:-5,y:-0.1} y:-0.1},{x:-2,y:0},{x:-1,y 0.3,{x:1,y:-0.4},{x:2,y:-0.3} x:4,y:0},{x:5,y:0.2},{x:6,y:0.3}]; var contractMiddleRange = -6,y:0.4},{x:-5,y:0},{x:-4,y:0} :0.1},{x:-1,y:0},{x:0,y:-0.2} {x:2,y:-0.2},{x:3,y:-0.3},{x:4,y:0.1} ,y:0.3},{x:6,y:0.4}]; // Axis definitionvar contractInformationForAxis = [{name:abscissa,x:-6,y 6},{name:ordinate,x:-0.8,y:0.8}]; var contractInformationForScatterpoints = [{name:qM,x:-5.25,y :0.1},{name:uM,x:5,y:-3.5},{name:uSMi,x:-2.75,y:0} {var:name =top:{name:uSMa,x:3.75,y:0} 1000 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; // Main SVGvar svgContainer = 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.top +); //轴创建var xAxisScale = d3.scaleLinear().domain([contractInformationForAxis [0] .x,contractInformationForAxis [0] .y]).range width]); var yAxisScale = d3.scaleLinear().domain([contractInformationForAxis [1] .x,contractInformationForAxis [1] .y]).range([height,0]); //轴generationvar xAxisGroup = svgContainer .append (g).attr(class,xAxis).attr(transform,translate(0,+(height / 2)+)).call(d3.axisBottom(xAxisScale)) ; var yAxisGroup = svgContainer .append(g).attr(class,yAxis).attr(transform,translate(+ width / 2 +,0))。 axisLeft(yAxisScale)); d3.selectAll(g.yAxis g.tick).append(line).attr(class,gridline).attr(x1, - (width / 2)).attr(y1 ,0).attr(x2,width / 2).attr(y2,0); d3.selectAll(g.xAxis g.tick).append(line).attr(class,gridline).attr(x1,0).attr(y1,height / 2 ).attr(x2,0).attr(y2,-height / 2); // Noms des axesvar xAxisName = svgContainer .append(text).attr(transform,translate (xAxisName).text(xAxis); var yAxisName = svgContainer .append(text / ).attr(y,0 - margin.left).attr(x,0 - (height / 2)).attr(dy,1em).attr(class,yAxisName ).text(yAxis); // Lines creationvar lineFunction = d3.line().x(function(d){return xAxisScale(dx);})。 ;}).curve(d3.curveLinear); //行generationvar contractHighRangePath = svgContainer .append(path).attr(d,lineFunction(contractHighRange)).attr(class,lineHighRange); var contractLowRangePath = svgContainer .append(path).attr(d,lineFunction(contractLowRange)).attr(class,lineLowRange); var contractMiddleRangePath = svgContainer .append(path).attr ; lineFunction(contractMiddleRange)).attr(class,lineMiddleRange); // SCATTERPOINTSvar contractPointsCreation = svgContainer .selectAll(dot).data(contractInformationForScatterpoints).enter().append(g); / Generate scatterplotsvar contractPointsGeneration = contractPointsCreation .append(circle).attr(r,10).attr(cx,function(d){return xAxisScale(dx); } .attr(cy,function(d){return yAxisScale(dy);}).attr(class,exteriorCircle); var contractPointsText = contractPointsCreation .selectAll(text).data(contractInformationForScatterpoints) .attr(y,function(d){return yAxisScale(x),function(d) (dy)+ margin.top / 2.5;}).attr(class,contractPointsText).text(function(d){return(+ d.name ++ dx +,+ dy +)});
h1 {color:darkgreen ;}。lineHighRange {fill:none;中风:钢蓝stroke-width:2px;}。lineLowRange {fill:none;中风:钢蓝stroke-width:2px;}。lineMiddleRange {fill:none;中风:橙色; stroke-width:2px;}。exteriorCircle {fill:darkred;}。contractPointsText {text-anchor:middle; font-family:sans-serif; font-size:12px;}。yAxisName {text-anchor:middle; transform:-h(-90deg);}。xAxisName {text-anchor:middle;} gridline {stroke:black; shape-rendering:crispEdges; stroke-opacity:.2;}
< script src =https://d3js.org/d3.v4.min.js >< / script>< title> Linechart< / title>< body> < h1> Demo-d3 4.0< / h1> < script src =js / chart.js>< / script>< / body>< / html>
>I've started familiarizing myself with d3.js a few days ago. As luck would have it, the library underwent a major update a few weeks ago, and a lot of the existing resources are now out of date. I've managed to do most of what I had planned, but am now stuck on the "putting gridlines on it" part.
I've tried to use the "tick methods," to draw new lines, to search graphs with gridlines to see how they worked, etc. to no avail. Methods have changed names, and I don't always understand the documentation well, so it's a bit hard. I would really appreciate if someone could be so kind as to point me in the right direction. :)
I've put my code below to illustrate what I mean by "centered axis" (both are, actually).
// Data // Path data var contractHighRange = [ { "x" : -6, "y" : 0.5 }, { "x" : -5, "y" : 0.1 }, { "x" : -4, "y" : 0.1 }, { "x" : -2, "y" : 0.2 }, { "x" : -1, "y" : 0.1 }, { "x" : 0, "y" : -0.1 }, { "x" : 1, "y" : -0.2 }, { "x" : 2, "y" : -0.1 }, { "x" : 3, "y" : -0.2 }, { "x" : 4, "y" : 0.2 }, { "x" : 5, "y" : 0.4 }, { "x" : 6, "y" : 0.5 } ]; var contractLowRange = [ { "x" : -6, "y" : 0.3 }, { "x" : -5, "y" : -0.1 }, { "x" : -4, "y" : -0.1 }, { "x" : -2, "y" : 0 }, { "x" : -1, "y" : -0.1 }, { "x" : 0, "y" : -0.3 }, { "x" : 1, "y" : -0.4 }, { "x" : 2, "y" : -0.3 }, { "x" : 3, "y" : -0.4 }, { "x" : 4, "y" : 0 }, { "x" : 5, "y" : 0.2 }, { "x" : 6, "y" : 0.3 } ]; var contractMiddleRange = [ { "x" : -6, "y" : 0.4 }, { "x" : -5, "y" : 0 }, { "x" : -4, "y" : 0 }, { "x" : -2, "y" : 0.1 }, { "x" : -1, "y" : 0 }, { "x" : 0, "y" : -0.2 }, { "x" : 1, "y" : -0.3 }, { "x" : 2, "y" : -0.2 }, { "x" : 3, "y" : -0.3 }, { "x" : 4, "y" : 0.1 }, { "x" : 5, "y" : 0.3 }, { "x" : 6, "y" : 0.4 } ]; // Axis definition var contractInformationForAxis = [ { "name" : "abscissa", "x" : -6, "y" : 6}, { "name" : "ordinate", "x" : -0.8, "y" : 0.8} ]; var contractInformationForScatterpoints = [ { "name" : "qM", "x" : -5.25, "y" : 0.1 }, { "name" : "uM", "x" : 5, "y" : -3.5 }, { "name" : "uSMi", "x" : -2.75, "y" : 0 }, { "name" : "uSMa", "x" : 3.75, "y" : 0 } ]; // General appearance var margin = { top: 50, right: 50, bottom: 50, left: 50 }; var width = 1000 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; // Main SVG var svgContainer = 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 + ")"); // Axis creation var xAxisScale = d3.scaleLinear() .domain([ contractInformationForAxis[0].x, contractInformationForAxis[0].y]) .range([0, width]); var yAxisScale = d3.scaleLinear() .domain([ contractInformationForAxis[1].x, contractInformationForAxis[1].y]) .range([height, 0]); // Axis generation var xAxisGroup = svgContainer .append("g") .attr("transform", "translate(0," + (height / 2) + ")") .call(d3.axisBottom(xAxisScale)); var yAxisGroup = svgContainer .append("g") .attr("transform", "translate(" + width / 2 + ", 0)") .call(d3.axisLeft(yAxisScale)); // Noms des axes var xAxisName = svgContainer .append("text") .attr("transform", "translate(" + (width / 2) + " ," + (height + margin.top) + ")") .attr("class", "xAxisName") .text("xAxis"); var yAxisName = svgContainer .append("text") .attr("y", 0 - margin.left) .attr("x", 0 - (height / 2)) .attr("dy", "1em") .attr("class", "yAxisName") .text("yAxis"); // Lines creation var lineFunction = d3.line() .x(function(d) { return xAxisScale(d.x); }) .y(function(d) { return yAxisScale(d.y); }) .curve(d3.curveLinear); // Lines generation var contractHighRangePath = svgContainer .append("path") .attr("d", lineFunction(contractHighRange)) .attr("class", "lineHighRange"); var contractLowRangePath = svgContainer .append("path") .attr("d", lineFunction(contractLowRange)) .attr("class", "lineLowRange"); var contractMiddleRangePath = svgContainer .append("path") .attr("d", lineFunction(contractMiddleRange)) .attr("class", "lineMiddleRange"); // SCATTERPOINTS var contractPointsCreation = svgContainer .selectAll("dot") .data(contractInformationForScatterpoints) .enter() .append("g"); // Generate scatterplots var contractPointsGeneration = contractPointsCreation .append("circle") .attr("r", 10) .attr("cx", function(d) { return xAxisScale(d.x); }) .attr("cy", function(d) { return yAxisScale(d.y); }) .attr("class", "exteriorCircle"); var contractPointsText = contractPointsCreation .selectAll("text") .data(contractInformationForScatterpoints) .enter(); var contractPointsTextAttributes = contractPointsText .append("text") .attr("x", function(d) { return xAxisScale(d.x); }) .attr("y", function(d) { return yAxisScale(d.y) + margin.top / 2.5; }) .attr("class", "contractPointsText") .text(function(d) { return "(" + d.name + " " + d.x + ", " + d.y + ")"});
h1 { color: darkgreen; } .lineHighRange { fill: none; stroke: steelblue; stroke-width: 2px; } .lineLowRange { fill: none; stroke: steelblue; stroke-width: 2px; } .lineMiddleRange { fill: none; stroke: orange; stroke-width: 2px; } .exteriorCircle { fill: darkred; } .contractPointsText{ text-anchor: middle; font-family: sans-serif; font-size: 12px; } .yAxisName { text-anchor: middle; transform: rotate(-90deg); } .xAxisName { text-anchor: middle; }
<script src="https://d3js.org/d3.v4.min.js"></script> <title>Linechart</title> <body> <h1>Demo - d3 4.0</h1> <script src="js/chart.js"></script> </body> </html>
解决方案Instead of changing D3 axis ticks, we can append lines to each tick.
First, we set classes to each axis (
xAxis
andyAxis
). Then, we select the ticks(d3.selectAll("g.yAxis g.tick")
andd3.selectAll("g.xAxis g.tick")
) of each axis and append a line to each tick.I set a class "gridline" to these lines. Use the CSS to change their opacity, color, style etc.
Check the snippet below.
// Data // Path data var contractHighRange = [ { "x" : -6, "y" : 0.5 }, { "x" : -5, "y" : 0.1 }, { "x" : -4, "y" : 0.1 }, { "x" : -2, "y" : 0.2 }, { "x" : -1, "y" : 0.1 }, { "x" : 0, "y" : -0.1 }, { "x" : 1, "y" : -0.2 }, { "x" : 2, "y" : -0.1 }, { "x" : 3, "y" : -0.2 }, { "x" : 4, "y" : 0.2 }, { "x" : 5, "y" : 0.4 }, { "x" : 6, "y" : 0.5 } ]; var contractLowRange = [ { "x" : -6, "y" : 0.3 }, { "x" : -5, "y" : -0.1 }, { "x" : -4, "y" : -0.1 }, { "x" : -2, "y" : 0 }, { "x" : -1, "y" : -0.1 }, { "x" : 0, "y" : -0.3 }, { "x" : 1, "y" : -0.4 }, { "x" : 2, "y" : -0.3 }, { "x" : 3, "y" : -0.4 }, { "x" : 4, "y" : 0 }, { "x" : 5, "y" : 0.2 }, { "x" : 6, "y" : 0.3 } ]; var contractMiddleRange = [ { "x" : -6, "y" : 0.4 }, { "x" : -5, "y" : 0 }, { "x" : -4, "y" : 0 }, { "x" : -2, "y" : 0.1 }, { "x" : -1, "y" : 0 }, { "x" : 0, "y" : -0.2 }, { "x" : 1, "y" : -0.3 }, { "x" : 2, "y" : -0.2 }, { "x" : 3, "y" : -0.3 }, { "x" : 4, "y" : 0.1 }, { "x" : 5, "y" : 0.3 }, { "x" : 6, "y" : 0.4 } ]; // Axis definition var contractInformationForAxis = [ { "name" : "abscissa", "x" : -6, "y" : 6}, { "name" : "ordinate", "x" : -0.8, "y" : 0.8} ]; var contractInformationForScatterpoints = [ { "name" : "qM", "x" : -5.25, "y" : 0.1 }, { "name" : "uM", "x" : 5, "y" : -3.5 }, { "name" : "uSMi", "x" : -2.75, "y" : 0 }, { "name" : "uSMa", "x" : 3.75, "y" : 0 } ]; // General appearance var margin = { top: 50, right: 50, bottom: 50, left: 50 }; var width = 1000 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; // Main SVG var svgContainer = 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 + ")"); // Axis creation var xAxisScale = d3.scaleLinear() .domain([ contractInformationForAxis[0].x, contractInformationForAxis[0].y]) .range([0, width]); var yAxisScale = d3.scaleLinear() .domain([ contractInformationForAxis[1].x, contractInformationForAxis[1].y]) .range([height, 0]); // Axis generation var xAxisGroup = svgContainer .append("g") .attr("class", "xAxis") .attr("transform", "translate(0," + (height / 2) + ")") .call(d3.axisBottom(xAxisScale)); var yAxisGroup = svgContainer .append("g") .attr("class", "yAxis") .attr("transform", "translate(" + width / 2 + ", 0)") .call(d3.axisLeft(yAxisScale)); d3.selectAll("g.yAxis g.tick") .append("line") .attr("class", "gridline") .attr("x1", -(width/2)) .attr("y1", 0) .attr("x2", width/2) .attr("y2", 0); d3.selectAll("g.xAxis g.tick") .append("line") .attr("class", "gridline") .attr("x1", 0) .attr("y1", height/2) .attr("x2", 0) .attr("y2", -height/2); // Noms des axes var xAxisName = svgContainer .append("text") .attr("transform", "translate(" + (width / 2) + " ," + (height + margin.top) + ")") .attr("class", "xAxisName") .text("xAxis"); var yAxisName = svgContainer .append("text") .attr("y", 0 - margin.left) .attr("x", 0 - (height / 2)) .attr("dy", "1em") .attr("class", "yAxisName") .text("yAxis"); // Lines creation var lineFunction = d3.line() .x(function(d) { return xAxisScale(d.x); }) .y(function(d) { return yAxisScale(d.y); }) .curve(d3.curveLinear); // Lines generation var contractHighRangePath = svgContainer .append("path") .attr("d", lineFunction(contractHighRange)) .attr("class", "lineHighRange"); var contractLowRangePath = svgContainer .append("path") .attr("d", lineFunction(contractLowRange)) .attr("class", "lineLowRange"); var contractMiddleRangePath = svgContainer .append("path") .attr("d", lineFunction(contractMiddleRange)) .attr("class", "lineMiddleRange"); // SCATTERPOINTS var contractPointsCreation = svgContainer .selectAll("dot") .data(contractInformationForScatterpoints) .enter() .append("g"); // Generate scatterplots var contractPointsGeneration = contractPointsCreation .append("circle") .attr("r", 10) .attr("cx", function(d) { return xAxisScale(d.x); }) .attr("cy", function(d) { return yAxisScale(d.y); }) .attr("class", "exteriorCircle"); var contractPointsText = contractPointsCreation .selectAll("text") .data(contractInformationForScatterpoints) .enter(); var contractPointsTextAttributes = contractPointsText .append("text") .attr("x", function(d) { return xAxisScale(d.x); }) .attr("y", function(d) { return yAxisScale(d.y) + margin.top / 2.5; }) .attr("class", "contractPointsText") .text(function(d) { return "(" + d.name + " " + d.x + ", " + d.y + ")"});
h1 { color: darkgreen; } .lineHighRange { fill: none; stroke: steelblue; stroke-width: 2px; } .lineLowRange { fill: none; stroke: steelblue; stroke-width: 2px; } .lineMiddleRange { fill: none; stroke: orange; stroke-width: 2px; } .exteriorCircle { fill: darkred; } .contractPointsText{ text-anchor: middle; font-family: sans-serif; font-size: 12px; } .yAxisName { text-anchor: middle; transform: rotate(-90deg); } .xAxisName { text-anchor: middle; } .gridline{ stroke: black; shape-rendering: crispEdges; stroke-opacity: .2; }
<script src="https://d3js.org/d3.v4.min.js"></script> <title>Linechart</title> <body> <h1>Demo - d3 4.0</h1> <script src="js/chart.js"></script> </body> </html>
这篇关于d3.js 4.0 - 具有中心轴的线图的网格线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文