多/分组条形图使用D3对齐问题 [英] multi/grouped Bar chart using D3 alignment issue
本文介绍了多/分组条形图使用D3对齐问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用D3创建了一个分组的条形图。我有书面代码和条形图显示,但不正确。有些栏位在x轴下方,其他栏位在图表的顶部,而不是从0开始。我无法找出此问题的原因。
var margin = {top:20,right:30,bottom:30,left:40},width = 960 - margin.left - margin.right,height = 500 - margin.top - bottom; var z = d3.scale.category20c(); 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 +)) ; var parseDate = d3.time.format(%Y-%m-%dT%H:%M:%S.%LZ); var data = [{data:[[2016-01-21T01 :20:00.000Z,1.41818181818182],[2016-01-21T02:28:00.000Z,1.90661764705882],[2016-01-21T03:36:00.000Z,1.66764705882353] 21T04:44:00.000Z,1.51691176470588],[2016-01-21T05:52:00.000Z,1.40955882352941],[2016-01-21T07:00:00.000Z,1.46323529411765],[ -21T08:08:00.000Z,1.48308823529412],[2016-01-21T09:16:00.000Z,1.89384615384615]],label:a},{data:[[2016-01 -21T01:20:00.000Z,4.98701298701299],[2016-01-21T02:28:00.000Z,5.0],[2016-01-21T03:36:00.000Z,4.94852941176471] 01-21T04:44:00.000Z,4.91176470588235],[2016-01-21T05:52:00.000Z,4.81617647058824],[2016-01-21T07:00:00.000Z,5.0] -01-21T08:08:00.000Z,4.94117647058824],[2016-01-21T09:16:00.000Z,4.96969696969697]],label:b}]; var x = d3.scale.ordinal ().rangeRoundBands([0,width],.9); var y = d3.scale.linear().range([height,0]); var xAxis = d3.svg.axis .tickSize(0).orient(bottom)。innerTickSize(-height).outerTickSize(0).tickFormat(d3.time.format(%H:%M)); var yAxis = d3.svg.axis ().scale(y).orient(left)innerTickSize(-width).outerTickSize(0); var ary = []; data.forEach(function(d){ary.push(d.data) }; x.domain(ary [0] .map(function(d){return parseDate.parse(d [0]);})); y.domain([0,d3.max ),function(d){console.log(d.y0 + dy); //这是NaN =不是数字// return d.y0 + d.y; return d [1]; //返回网格线,如果那是你想要的)}); svg.append(g).attr(class,x axis).attr(transform height)).call(xAxis); svg.append(g).attr(class,y axis).call(yAxis); var layer = svg.selectAll .data(data).enter()。append(g).attr(class,layer).style(fill,function(d,i){return z(i);}); layer.selectAll(rect).data(function(d){return d.data;}).enter()。append(rect).attr(x,function(d){return x(parseDate .parse(d [0]));}).attr(y,function(d){console.log(d [1]); return y(d [1]); //注意这是返回数据}; .attr(height,function(d){return y(d [1]); //注意这是返回数据}).attr(width,x.rangeBand() code>
text.inner-circle {font-weight:400; font-size:12px; text-transform:uppercase;} text.inner-text {font-weight:400; font-size:36px; font-family:'Metric Regular','Metric'; text-align:center; font-style:normal; text-transform:uppercase;} path {stroke:steelblue; stroke-width:2; fill:none;}。axis path,.axis line {fill:none;中风:灰色stroke-width:2; shape-rendering:crispEdges;}。grid .tick {stroke:lightgrey;行程不透明度:0.7; shape-rendering:crispEdges;}。grid path {stroke-width:0;}
< script src =https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js>< / script>
请帮我解决这个问题。
解决方案
您错过了这一点:
.attr函数(d){
pre>
return height-y(d [1]); //< - offset y position from height
})
此外,您不会考虑在何处对酒吧进行分组。简单的解决方法是并排放置它们:
...
.enter rect)
.attr(x,function(d,i,j){
// j is the group
if(j === 0)
return x(parseDate.parse(d [0])) - x.rangeBand()/ 2;
else
return x(parseDate.parse(d [0]))+ x.rangeBand / 2;
})
...
b $ b完整代码:
<!DOCTYPE html>< html>< head& < script src =https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js>< / script> < style> text.inner - circle {font - weight:400; font - size:12 px; text - transform:uppercase; } text.inner - text {font - weight:400; font - size:36 px; font-family:'Metric Regular','Metric'; text - align:center; font-style:normal; text - transform:uppercase; } path {stroke:steelblue; stroke-width:2; fill:none; } .axis path,.axis line {fill:none;中风:灰色stroke-width:2;形状 - 渲染:crispEdges; } .grid.tick {stroke:lightgrey;行程 - 不透明度:0.7;形状 - 渲染:crispEdges; } .grid path {stroke-width:0; }< / style>< / head>< body> < script> var margin = {top:20,right:30,bottom:30,left:40},width = 960 - margin.left - margin.right,height = 500 - margin.top - margin.bottom; var z = d3.scale.category20c(); var svg = d3.select(body)。append(svg).attr(width,width + margin.left + margin.right).attr(height,height + margin.top + bottom).append(g).attr(transform,translate(+ margin.left +,+ margin.top +)); var parseDate = d3.time.format(%Y-%m-%dT%H:%M:%S.%LZ); var data = [{data:[[2016-01-21T01:20:00.000Z,1.41818181818182],[2016-01-21T02:28:00.000Z,1.90661764705882],[ 21T03:36:00.000Z,1.66764705882353],[2016-01-21T04:44:00.000Z,1.51691176470588],[2016-01-21T05:52:00.000Z,1.40955882352941],[ -21T07:00:00.000Z,1.46323529411765],[2016-01-21T08:08:00.000Z,1.48308823529412],[2016-01-21T09:16:00.000Z,1.89384615384615] :a},{data:[[2016-01-21T01:20:00.000Z,4.98701298701299],[2016-01-21T02:28:00.000Z,5.0] 01-21T03:36:00.000Z,4.94852941176471],[2016-01-21T04:44:00.000Z,4.91176470588235],[2016-01-21T05:52:00.000Z,4.81617647058824] -01-21T07:00:00.000Z,5.0],[2016-01-21T08:08:00.000Z,4.94117647058824],[2016-01-21T09:16:00.000Z,4.96969696969697] label:b}]; var x = d3.scale.ordinal()。rangeRoundBands([0,width],.9); var y = d3.scale.linear().range([height,0]); var xAxis = d3.svg.axis().scale(x).tickSize(0).orient(bottom)。innerTickSize(-height).outerTickSize(0).tickFormat(d3.time.format(%H :%M)); var yAxis = d3.svg.axis().scale(y).orient(left)。innerTickSize(-width).outerTickSize(0); var ary = []; data.forEach(function(d){ary.push(d.data);}); x.domain(ary [0] .map(function(d){return parseDate.parse(d [0]);})); y.domain([0,d3.max(d3.merge(ary),function(d){console.log(d.y0 + dy); //这是NaN =不是数字// return d.y0 + dy; return d [1]; //返回网格线,如果那是你想要的})]); svg.append(g).attr(class,x axis).attr(transform,translate(0,+ height +)).call(xAxis); svg.append(g).attr(class,y axis).call(yAxis); var layer = svg.selectAll(。layer).data(data).enter()。append(g).attr(class,layer).style i){return z(i);}); layer.selectAll(rect).data(function(d){return d.data;}).enter()。append(rect).attr(x,function(d,i,j){ if(j === 0)return x(parseDate.parse(d [0])) - x.rangeBand()/ 2; else return x(parseDate.parse(d [0]))+ x.rangeBand / 2;}).attr(y,function(d){return height -y(d [1]); //注意这是返回数据}).attr(height,function y(d [1]); //注意这是返回数据}).attr(width,x.rangeBand() - 1); < / script>< / body>< / html>
I am creating a grouped bar chart using D3. I have written code and bar charts are showing but not properly. Some bar are going below the x-axis and other are at the top of the graph instead starting from 0. I am unable to figure out the reason for the this issue.
var margin = { top: 20, right: 30, bottom: 30, left: 40 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var z = d3.scale.category20c(); 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 + ")"); var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ"); var data = [{ "data": [ [ "2016-01-21T01:20:00.000Z", 1.41818181818182 ], [ "2016-01-21T02:28:00.000Z", 1.90661764705882 ], [ "2016-01-21T03:36:00.000Z", 1.66764705882353 ], [ "2016-01-21T04:44:00.000Z", 1.51691176470588 ], [ "2016-01-21T05:52:00.000Z", 1.40955882352941 ], [ "2016-01-21T07:00:00.000Z", 1.46323529411765 ], [ "2016-01-21T08:08:00.000Z", 1.48308823529412 ], [ "2016-01-21T09:16:00.000Z", 1.89384615384615 ] ], "label": "a" }, { "data": [ [ "2016-01-21T01:20:00.000Z", 4.98701298701299 ], [ "2016-01-21T02:28:00.000Z", 5.0 ], [ "2016-01-21T03:36:00.000Z", 4.94852941176471 ], [ "2016-01-21T04:44:00.000Z", 4.91176470588235 ], [ "2016-01-21T05:52:00.000Z", 4.81617647058824 ], [ "2016-01-21T07:00:00.000Z", 5.0 ], [ "2016-01-21T08:08:00.000Z", 4.94117647058824 ], [ "2016-01-21T09:16:00.000Z", 4.96969696969697 ] ], "label": "b" }]; var x = d3.scale.ordinal().rangeRoundBands([0, width], .9); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x).tickSize(0) .orient("bottom").innerTickSize(-height).outerTickSize(0) .tickFormat(d3.time.format("%H:%M")); var yAxis = d3.svg.axis() .scale(y) .orient("left").innerTickSize(-width).outerTickSize(0); var ary = []; data.forEach(function(d) { ary.push(d.data); }); x.domain(ary[0].map(function(d) { return parseDate.parse(d[0]); })); y.domain([0, d3.max(d3.merge(ary), function(d) { console.log(d.y0 + d.y); //This is NaN = Not a number //return d.y0 + d.y; return d[1]; //returns grid lines if that is what you want })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis); var layer = svg.selectAll(".layer") .data(data) .enter().append("g") .attr("class", "layer") .style("fill", function(d, i) { return z(i); }); layer.selectAll("rect") .data(function(d) { return d.data; }) .enter().append("rect") .attr("x", function(d) { return x(parseDate.parse(d[0])); }) .attr("y", function(d) { console.log(d[1]); return y(d[1]); //Note this is returning data }) .attr("height", function(d) { return y(d[1]); //Note this is returning data }) .attr("width", x.rangeBand() - 1);
text.inner-circle { font-weight: 400; font-size: 12px; text-transform: uppercase; } text.inner-text { font-weight: 400; font-size: 36px; font-family: 'Metric Regular', 'Metric'; text-align: center; font-style: normal; text-transform: uppercase; } path { stroke: steelblue; stroke-width: 2; fill: none; } .axis path, .axis line { fill: none; stroke: grey; stroke-width: 2; shape-rendering: crispEdges; } .grid .tick { stroke: lightgrey; stroke-opacity: 0.7; shape-rendering: crispEdges; } .grid path { stroke-width: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Please help me fix this issue.
解决方案You are missing this:
.attr("y", function(d) { return height - y(d[1]); //<-- offset y position from height })
In addition, you aren't taking into account where to group your bars. Simple fix is to place them side-by-side:
... .enter().append("rect") .attr("x", function(d, i, j) { // j is the group if (j === 0) return x(parseDate.parse(d[0])) - x.rangeBand() / 2; else return x(parseDate.parse(d[0])) + x.rangeBand() / 2; }) ...
Full Code:
<!DOCTYPE html> <html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <style> text.inner - circle { font - weight: 400; font - size: 12 px; text - transform: uppercase; } text.inner - text { font - weight: 400; font - size: 36 px; font - family: 'Metric Regular', 'Metric'; text - align: center; font - style: normal; text - transform: uppercase; } path { stroke: steelblue; stroke - width: 2; fill: none; } .axis path, .axis line { fill: none; stroke: grey; stroke - width: 2; shape - rendering: crispEdges; } .grid.tick { stroke: lightgrey; stroke - opacity: 0.7; shape - rendering: crispEdges; } .grid path { stroke - width: 0; } </style> </head> <body> <script> var margin = { top: 20, right: 30, bottom: 30, left: 40 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var z = d3.scale.category20c(); 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 + ")"); var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ"); var data = [{ "data": [ [ "2016-01-21T01:20:00.000Z", 1.41818181818182 ], [ "2016-01-21T02:28:00.000Z", 1.90661764705882 ], [ "2016-01-21T03:36:00.000Z", 1.66764705882353 ], [ "2016-01-21T04:44:00.000Z", 1.51691176470588 ], [ "2016-01-21T05:52:00.000Z", 1.40955882352941 ], [ "2016-01-21T07:00:00.000Z", 1.46323529411765 ], [ "2016-01-21T08:08:00.000Z", 1.48308823529412 ], [ "2016-01-21T09:16:00.000Z", 1.89384615384615 ] ], "label": "a" }, { "data": [ [ "2016-01-21T01:20:00.000Z", 4.98701298701299 ], [ "2016-01-21T02:28:00.000Z", 5.0 ], [ "2016-01-21T03:36:00.000Z", 4.94852941176471 ], [ "2016-01-21T04:44:00.000Z", 4.91176470588235 ], [ "2016-01-21T05:52:00.000Z", 4.81617647058824 ], [ "2016-01-21T07:00:00.000Z", 5.0 ], [ "2016-01-21T08:08:00.000Z", 4.94117647058824 ], [ "2016-01-21T09:16:00.000Z", 4.96969696969697 ] ], "label": "b" }]; var x = d3.scale.ordinal().rangeRoundBands([0, width], .9); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x).tickSize(0) .orient("bottom").innerTickSize(-height).outerTickSize(0) .tickFormat(d3.time.format("%H:%M")); var yAxis = d3.svg.axis() .scale(y) .orient("left").innerTickSize(-width).outerTickSize(0); var ary = []; data.forEach(function(d) { ary.push(d.data); }); x.domain(ary[0].map(function(d) { return parseDate.parse(d[0]); })); y.domain([0, d3.max(d3.merge(ary), function(d) { console.log(d.y0 + d.y); //This is NaN = Not a number //return d.y0 + d.y; return d[1]; //returns grid lines if that is what you want })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis); var layer = svg.selectAll(".layer") .data(data) .enter().append("g") .attr("class", "layer") .style("fill", function(d, i) { return z(i); }); layer.selectAll("rect") .data(function(d) { return d.data; }) .enter().append("rect") .attr("x", function(d, i, j) { if (j === 0) return x(parseDate.parse(d[0])) - x.rangeBand() / 2; else return x(parseDate.parse(d[0])) + x.rangeBand() / 2; }) .attr("y", function(d) { return height -y(d[1]); //Note this is returning data }) .attr("height", function(d) { return y(d[1]); //Note this is returning data }) .attr("width", x.rangeBand() - 1); </script> </body> </html>
这篇关于多/分组条形图使用D3对齐问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文