我有一个条形图,它由JSON变量的值填充。该图表是动态的,因为通过计数从SQL查询中检索值。所以我的数据反馈如下:
[{"Fruit":"Apple","COUNT( Fruit )":"12"},{"Fruit":"Orange","COUNT( Fruit )":"6"},{"Fruit":"Pear","COUNT( Fruit )":"1"},{"Fruit":"Blank","COUNT( Fruit )":"1"},{"Fruit":"Pineapple","COUNT( Fruit )":"1"},{"Fruit":"Kiwi","COUNT( Fruit )":"1"}]
在大多数情况下,我的图表似乎正常显示。然而有些人返回超过Y轴的值,我不认为是导致问题的值我认为它的轴不计算正确的高度。例如
如果橙色计数为14,有时Y轴会停在一个小于此值的数字处,并且该列会扩展图形。
通过在谷歌浏览器开发者控制台中查看,我可以看到栏的高度为
<rect id="Orange" y="-520px" x="94px" height="1040px" width="162"></rect>
远远超出我的SVG高度600px - 边距(顶部+底部)80px!
有谁知道为什么我的Y轴没有获得正确的最大值?
代码在这里:
var canv = document.getElementById("exportCanvas");
canv.width = screen.width;
var margin ={top:40, right:0, bottom:40, left:40},
width=screen.width - 250,
height=600-margin.top-margin.bottom;
var jsplit = jdata.split('"');
var keyX = jsplit[1];
var keyY = "";
var data = JSON.parse(jdata);
for (k in data[0]) {
if (k!=keyX) keyY=k;
}
console.log("keyX = " + keyX);
console.log(keyY);
console.log(data[0]);
// scale to ordinal because x axis is not numerical
var x = d3.scale.ordinal()
.domain(['Orange','Apple','Pear']) //Added this in temporarilly. this should be calculated from the data.
.rangeRoundBands([0, width], 0.25,0.25);
//scale to numerical value by height
// var y = d3.scale.linear().range([height, 0]);
var y = d3.scale.linear()
.range([height, 0]);
console.log(data);
x.domain(data.map(function(d){ return d[keyX]}));
y.domain([0, d3.max(data, function(d){return d[keyY]})]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width+ margin.left+margin.right) //set width
// .attr("width", width+(2*margin.left)+margin.right) //set width
.attr("height", height+margin.top+margin.bottom); //set height
// .attr("transform", "translate(" + Math.min(width,height) / 2 + "," + Math.min(width,height) / 2 + ")");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom"); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10).tickFormat(function(d) {
if (d % 1 == 0) {
return d3.format('.f')(d)
} else {
return ""
}
});
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g");
//you're moving the group and then moving the rect below as well
//one or the other not both need to be moved.
//.attr("transform", function(d, i){
// return "translate("+x(d[keyX])+", 0)";
//});
bar.append("rect")
.attr("id", function(d) {
return d[keyX];
})
.attr("y", function(d) {
return y(d[keyY]) + "px";
})
.attr("x", function(d,i){
//AB - Adjusted this so it correcly places the bar along the X
//x.range is an array of x values for each bar
//calculated in the var x = line above , with the .rangeRoundBands([0, width], 0.25,0.25);
//setting the width of the bars (an equal division of width) with margins of 0.25 at the start
//and end of the graph and 0.25 between each bar.
return x.range()[i] + margin.left + "px";
})
.attr("height", function(d) {
return height - y(d[keyY]) +"px";
})
.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x",function(d,i){
//similar to above but adding half the width of the bar to the x position
//to roughly center it on the bar. only rough as doesnt take account of length of text.
return x.range()[i] + margin.left + (x.rangeBand()/2)+ "px";
})
.attr("y", function(d) { return y(d[keyY]) +20; })
.attr("dy", ".75em")
.style("fill","white")
.style("font-weight", "bold")
.text(function(d) { return d[keyY]; });
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+margin.left+","+ height+")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate("+margin.left+",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(keyY);
对于已注释掉的代码表示道歉,我一直在尝试使用它,并尝试将其解决。
答案 0 :(得分:0)
您需要在数据集刷新时重新计算y.domain()。因此,当您更新数据时,可以尝试以下方法:
y.domain([0, d3.max(data, function(d){return d[keyY]})]);
chart.select(".y.axis")
.call(yAxis.scale(y));