我正在使用D3.js直方图布局,并且x轴文本标签未直接对齐到其各自条形下方的正确位置。他们似乎在不同的规模上运行,但我还没能弄清楚为什么他们有不同的间隔。 y轴文本标签与条的适当高度匹配,但x轴文本标签与条的宽度位于不同的位置。为什么会这样?
提前谢谢!
<html>
<head>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/d3-random.v0.2.min.js"></script>
<style>
html,body{margin:0;padding:0;}
body {
background-color: white;
font-family: Arial;
width: 100%;
}
.title, .axis-text {
font-weight: bold;
}
.axis {
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<svg id="histogram">
</svg>
<script>
function plotHistogram(id, numArray){
//Initial variables
var height = 600;
var width = 600;
var margin = 60;
//Format our data into bins
var bins = d3.layout.histogram()
.bins(numArray.length/5)(numArray);
//Select our SVG and set its attributes
var svg = d3.select(id)
.attr("height", height)
.attr("width", width);
//Create and format x scale
var xScale = d3.scale.linear()
.domain(d3.extent(numArray))
.range([margin, width-margin]);
//Create and format y scale
var yScale = d3.scale.linear()
.domain([0,d3.max(bins, function (bin) {
return bin.y;
})])
.range([height - margin, margin]);
//Create and format x axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,"+(height-margin)+")")
.call(xAxis);
svg.append("text")
.attr("text-anchor","middle")
.attr("x",width/2)
.attr("y",height-margin/3)
.text("Data");
//Create and format y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
svg.append("g")
.attr("transform", "translate(" + margin + ",0)")
.attr("class", "axis")
.call(yAxis);
svg.append("text")
.attr("text-anchor","middle")
.attr("transform","translate("+(margin/3)+","+(height/2)+")rotate(-90)")
.text("Frequency");
//For every element of our bins variable, create a new rectangle for it
var randColors = ["#5c5e58","#af6c6f","#c56b18","#97aedc","#5e8477","#9d291f","#2d3361","#55775a"];
bins.forEach(function (curBin) {
//console.log(curBin);
svg.append("rect")
.attr("class", "bar")
.attr("fill", function() { return randColors[(Math.floor(Math.random() * randColors.length))]})
.attr("height", yScale(0) - yScale(curBin.y))
.attr("stroke","white")
.attr("width", xScale(curBin.dx)-xScale(0))
.attr("x", xScale(curBin.x))
.attr("y", yScale(curBin.y))
});
}
var randomNumbers = [3, 3, 4, 19, 14, 14, 8, 3, 5, 9,
8, 5, 18, 15, 1, 6, 18, 20, 6, 19,
14, 1, 10, 14, 6, 2, 19, 3, 20, 1,
2, 11, 9, 6, 14, 15, 11, 5, 19, 5,
17, 16, 9, 12, 19, 13, 20, 20, 13, 6];
plotHistogram("#histogram",randomNumbers);
</script>
</body>
</html>
&#13;
答案 0 :(得分:2)
您的数据值介于1到20之间。您的代码在该范围内创建了10个分区。每个bin都有一个dx = 1.9 =(20 - 1)/ 10.这个结果是bin阈值为1,2.9,4.8,6.7,...,18.1,20。你的代码导致2,4的滴答值, 6,...,18,20。由于bin阈值间隔为1.9,而tick值间隔为2.0,因此条形与刻度线不对齐。
您可以使用以下代码在每个条形的右边缘创建刻度线。
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickValues(bins.map(function (bin) { return bin.x + bin.dx; }))
.tickFormat(d3.format(".1f"));