x轴文本标签未与D3.js中的条对齐 [英] x-axis text labels not aligned with bars in D3.js

查看:93
本文介绍了x轴文本标签未与D3.js中的条对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using a D3.js histogram layout, and the x axis text labels are not aligning to their proper positions directly underneath their respective bar. They seem to be running on different scales, but I haven't been able to figure out why they have different intervals. The y axis text labels match up to the proper height of the bars, but the x axis text labels are at different positions from the widths of the bars. Why might this be?

提前感谢!

<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>

推荐答案

您的数据值范围为1到20.您的代码在该范围内创建了10个bin。每个仓具有dx = 1.9 =(20-1)/ 10。这导致仓阈值为1,2.9,4.8,6.7,...,18.1,20。您的代码导致刻度值为2,4,因为仓阈值以1.9的间隔间隔开,并且刻度值是以2.0的间隔间隔,所以条不与刻度标记对齐。

Your data values were in the range from 1 to 20. Your code was creating 10 bins over that range. Each bin had a dx = 1.9 = (20 - 1) / 10. This result in bin thresholds of 1, 2.9, 4.8, 6.7, ..., 18.1, 20. Your code was resulting in tick values of 2, 4, 6, ..., 18, 20. Since bin thresholds were spaced at intervals of 1.9 and the tick values were spaced intervals of 2.0, the bars did not align with the tick marks.

您可以使用以下代码在每个栏的右边创建刻度线。

You could use the following code to create tick marks at the right edge of each bar.

var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient("bottom")
    .tickValues(bins.map(function (bin) { return bin.x + bin.dx; }))
    .tickFormat(d3.format(".1f"));

这篇关于x轴文本标签未与D3.js中的条对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆