2016-03-17 99 views
1

我正在使用D3.js直方图布局,并且x轴文本标签未直接对齐到它们各自栏下的正确位置。他们似乎在不同的规模上运行,但我还没有弄清楚他们为什么有不同的时间间隔。 y轴文本标签匹配条的正确高度,但x轴文本标签位于与条宽度不同的位置。为什么会这样呢?x轴文本标签不与D3.js中的条对齐

预先感谢您!

<html> 
 
\t <head> 
 
\t \t <script src="//d3js.org/d3.v3.min.js"></script> 
 
\t \t <script src="//d3js.org/d3-random.v0.2.min.js"></script> 
 
\t \t <style> 
 
\t \t \t html,body{margin:0;padding:0;} 
 
\t \t \t body { 
 
\t \t \t \t background-color: white; 
 
\t \t \t \t font-family: Arial; 
 
\t \t \t \t width: 100%; 
 
\t \t \t } 
 
\t \t \t .title, .axis-text { 
 
\t \t \t \t font-weight: bold; 
 
\t \t \t } 
 
\t \t \t .axis { 
 
\t \t \t \t shape-rendering: crispEdges; 
 
\t \t \t } 
 
\t \t </style> 
 
\t </head> 
 
\t <body> 
 
\t \t \t <svg id="histogram"> 
 
\t \t \t </svg> 
 
\t \t \t <script> 
 
\t \t \t \t function plotHistogram(id, numArray){ 
 
\t \t \t \t \t //Initial variables 
 
\t \t \t \t \t var height = 600; 
 
\t \t \t \t \t var width = 600; 
 
\t \t \t \t \t var margin = 60; 
 
\t \t \t \t \t 
 
\t \t \t \t \t //Format our data into bins 
 
\t \t \t \t \t var bins = d3.layout.histogram() 
 
\t \t \t \t \t \t .bins(numArray.length/5)(numArray); 
 
\t \t \t \t \t 
 
\t \t \t \t \t //Select our SVG and set its attributes 
 
\t \t \t \t \t var svg = d3.select(id) 
 
\t \t \t \t \t \t .attr("height", height) 
 
\t \t \t \t \t \t .attr("width", width); 
 
\t \t \t \t \t 
 
\t \t \t \t \t //Create and format x scale 
 
\t \t \t \t \t var xScale = d3.scale.linear() 
 
\t \t \t \t \t \t .domain(d3.extent(numArray)) 
 
\t \t \t \t \t \t .range([margin, width-margin]); 
 
\t \t \t \t \t 
 
\t \t \t \t \t //Create and format y scale 
 
\t \t \t \t \t var yScale = d3.scale.linear() 
 
\t \t \t \t \t \t .domain([0,d3.max(bins, function (bin) { 
 
\t \t \t \t \t \t \t return bin.y; 
 
\t \t \t \t \t \t })]) 
 
\t \t \t \t \t \t .range([height - margin, margin]); 
 
\t \t \t \t \t 
 
\t \t \t \t \t //Create and format x axis 
 
\t \t \t \t \t var xAxis = d3.svg.axis() 
 
\t \t \t \t \t \t .scale(xScale) 
 
\t \t \t \t \t \t .orient("bottom"); 
 
\t \t \t \t \t svg.append("g") 
 
\t \t \t \t \t \t .attr("class", "axis") 
 
\t \t \t \t \t \t .attr("transform", "translate(0,"+(height-margin)+")") 
 
\t \t \t \t \t \t .call(xAxis); 
 
\t \t \t \t \t svg.append("text") 
 
\t \t \t \t \t \t .attr("text-anchor","middle") 
 
\t \t \t \t \t \t .attr("x",width/2) 
 
\t \t \t \t \t \t .attr("y",height-margin/3) 
 
\t \t \t \t \t \t .text("Data"); 
 
\t \t \t \t \t 
 
\t \t \t \t \t //Create and format y axis 
 
\t \t \t \t \t var yAxis = d3.svg.axis() 
 
\t \t \t \t \t \t .scale(yScale) 
 
\t \t \t \t \t \t .orient("left"); 
 
\t \t \t \t \t svg.append("g") 
 
\t \t \t \t \t \t .attr("transform", "translate(" + margin + ",0)") 
 
\t \t \t \t \t \t .attr("class", "axis") 
 
\t \t \t \t \t \t .call(yAxis); 
 
\t \t \t \t \t svg.append("text") 
 
\t \t \t \t \t \t .attr("text-anchor","middle") 
 
\t \t \t \t \t \t .attr("transform","translate("+(margin/3)+","+(height/2)+")rotate(-90)") 
 
\t \t \t \t \t \t .text("Frequency"); 
 
\t \t \t \t \t 
 
\t \t \t \t \t //For every element of our bins variable, create a new rectangle for it 
 
\t \t \t \t \t var randColors = ["#5c5e58","#af6c6f","#c56b18","#97aedc","#5e8477","#9d291f","#2d3361","#55775a"]; 
 
\t \t \t \t \t bins.forEach(function (curBin) { 
 
\t \t \t \t \t \t //console.log(curBin); 
 
\t \t \t \t \t \t svg.append("rect") 
 
\t \t \t \t \t \t \t .attr("class", "bar") 
 
\t \t \t \t \t \t \t .attr("fill", function() { return randColors[(Math.floor(Math.random() * randColors.length))]}) 
 
\t \t \t \t \t \t \t .attr("height", yScale(0) - yScale(curBin.y)) 
 
\t \t \t \t \t \t \t .attr("stroke","white") 
 
\t \t \t \t \t \t \t .attr("width", xScale(curBin.dx)-xScale(0)) 
 
\t \t \t \t \t \t \t .attr("x", xScale(curBin.x)) 
 
\t \t \t \t \t \t \t .attr("y", yScale(curBin.y)) 
 
\t \t \t \t \t }); \t 
 
\t \t \t \t } 
 
\t \t \t \t 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]; 
 
\t \t \t \t plotHistogram("#histogram",randomNumbers); 
 
\t \t \t </script> 
 
\t </body> 
 
</html>

回答

2

你的数据值在范围从1到20,您的代码被创建10个二进制位在该范围。每个bin有一个dx = 1.9 =(20-1)/ 10。这导致了bin的阈值为1,2.9,4.8,6.7,...,18.1,20。你的代码导致tick值为2,4, 6,...,18,20。由于箱门限以1.9的间隔隔开,并且刻度值间隔为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")); 
+1

工作完美的一点格式(文本标签重叠,但我能够通过抵消其他每个滴答补救)。非常感谢! 对于任何人都好奇我如何解决重叠... 'svg.selectAll(“。tick:nth-​​of-type(odd)text”)。attr(“dy”,30);' –