如何在d3中显示顺序轴

时间:2018-03-18 15:09:00

标签: d3.js scale axis

我是d3的新手,并且在显示序数轴的标签方面存在问题:

<!DOCTYPE html>
<html lang="en">
	<head>
      <script src="https://d3js.org/d3.v4.min.js"></script>
		<meta charset="utf-8">
		<title>D3: Loading data from a CSV file</title>
  </head>
	<body>
		<script type="text/javascript">

      var margin = {top: 20, right: 20, bottom: 30, left: 40},
    		w = 600 - margin.left - margin.right,
    		h = 300 - margin.top - margin.bottom;
      var padding = 40;
      
      var data = [
        { "Food": "Apples", "Deliciousness": 9 },
        { "Food": "Green Beans", "Deliciousness": 5 },
        { "Food": "Egg Salad Sandwich", "Deliciousness": 4 },
        { "Food": "Cookies", "Deliciousness": 10 },
        { "Food": "Liver", "Deliciousness": 2 },
        { "Food": "Burrito", "Deliciousness": 7 },
      ];

      data.forEach(function(d) {
        d.Deliciousness = +d.Deliciousness;
      });

      var svg = d3.select("body")
						.append("svg")
						.attr("width", w + margin.left + margin.right)
						.attr("height", h + margin.top + margin.bottom)
      			.append("g")
      			.attr("transform", "translate(" + margin.left+"," +
                 margin.top+")");
        
      var xScale = d3.scaleBand()
      	.domain(d=>d.Food)
      	.range([0,w])
      	.paddingInner(0.2);
     xScale.domain(data.map(function(d) { return d.Food; }));
        
      var xAxis = d3.axisBottom()
      	.scale(xScale)
      	.ticks(5);
      
      var yScale = d3.scaleLinear()
      	.domain([0, d3.max(data, d=>d.Deliciousness)])
      	.rangeRound([h,0]);
        
      var yAxis = d3.axisLeft()
      	.scale(yScale)
      	.ticks(5);
      
      svg.selectAll('rect')
        .data(data)
        .enter()
        .append('rect')
        .attr('x',(d,i) => margin.left + i*w/data.length)
        .attr('y',d=>yScale(d.Deliciousness))
        .attr('width', xScale.bandwidth())
        .attr('height',d =>h-yScale(d.Deliciousness))
        .attr('fill',function(d){
          if (d===30) return "red";
          return "rgb(0,0,"+d.Deliciousness*10+")" ;});
       
      svg.selectAll("text")
      	.data(data)
      	.enter()
      	.append("text")
      	.text(d=>d.Deliciousness)
      	.attr("x", (d,i)=>(padding + i*w/data.length))
        .attr("y", d=>yScale(d.Deliciousness)+15)
      	.attr("fill","white");
      
      svg.append("g")
      	.attr("class", "axis")
	   		.attr("transform", "translate(" + padding + ",0)")
      	.call(yAxis);
        
			svg.append("g")
      	.attr("class", "axis")
	   		.attr("transform", "translate(0," + (h-margin.bottom) + ")")
      	.call(xAxis);
        
		</script>
	</body>
</html>

x轴在某种程度上与图表重叠,如何正确使用边距?

就顺序轴而言,除了在.domain()中手动列出所有类别之外,在.domain()。range()调用中使用特殊xScale的其他方法是什么?感谢

1 个答案:

答案 0 :(得分:1)

它来自x轴的位置定义。

您可以更改:

player.loadVideo("video_id");

使用:

svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0," + (h-margin.bottom) + ")")
  .call(xAxis);

以下是演示:

svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + margin.left + "," + h + ")")
  .call(xAxis);

与其容器(此处为<!DOCTYPE html> <html lang="en"> <head> <script src="https://d3js.org/d3.v4.min.js"></script> <meta charset="utf-8"> <title>D3: Loading data from a CSV file</title> </head> <body> <script type="text/javascript"> var margin = {top: 20, right: 20, bottom: 30, left: 40}, w = 600 - margin.left - margin.right, h = 300 - margin.top - margin.bottom; var padding = 40; var data = [ { "Food": "Apples", "Deliciousness": 9 }, { "Food": "Green Beans", "Deliciousness": 5 }, { "Food": "Egg Salad Sandwich", "Deliciousness": 4 }, { "Food": "Cookies", "Deliciousness": 10 }, { "Food": "Liver", "Deliciousness": 2 }, { "Food": "Burrito", "Deliciousness": 7 }, ]; data.forEach(function(d) { d.Deliciousness = +d.Deliciousness; }); var svg = d3.select("body") .append("svg") .attr("width", w + margin.left + margin.right + padding) .attr("height", h + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left+"," + margin.top+")"); var xScale = d3.scaleBand() .domain(d=>d.Food) .range([0,w]) .paddingInner(0.2); xScale.domain(data.map(function(d) { return d.Food; })); var xAxis = d3.axisBottom() .scale(xScale) .ticks(5); var yScale = d3.scaleLinear() .domain([0, d3.max(data, d=>d.Deliciousness)]) .rangeRound([h,0]); var yAxis = d3.axisLeft() .scale(yScale) .ticks(5); svg.selectAll('rect') .data(data) .enter() .append('rect') .attr('x',(d,i) => margin.left + i * ((w + 20 ) / data.length)) .attr('y',d=>yScale(d.Deliciousness)) .attr('width', xScale.bandwidth()) .attr('height',d =>h-yScale(d.Deliciousness)) .attr('fill',function(d){ if (d===30) return "red"; return "rgb(0,0,"+d.Deliciousness*10+")" ;}); svg.selectAll("text") .data(data) .enter() .append("text") .text(d=>d.Deliciousness) .attr('x',(d,i) => margin.left + i * ((w + 20 ) / data.length)) .attr("y", d=>yScale(d.Deliciousness)+15) .attr("fill","white"); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + padding + ",0)") .call(yAxis); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + margin.left + "," + h + ")") .call(xAxis); </script> </body> </html>)相比的

x-axis位置由svg属性定义。在这种情况下,这是一个翻译。要定义翻译,我们为transform属性赋予此值:transform

dx :当translate(dx,dy)被赋予rectmargin.left)的轴偏移时,我们还需要将x轴水平平移{{1 }}

dy :由于.attr('x',(d,i) => margin.left + i*w/data.length)的基数从margin.leftrect)开始,我们还需要将x轴垂直翻译为{ {1}}。

我还使用以下方法修改了条形和标签的x位置

h

而不是:

.rangeRound([h, 0]);

最后,由于最后一个条形图在图形外面一半,您可以通过替换以下内容来增加svg容器的宽度:

h

使用:

.attr('x',(d,i) => margin.left + i * ((w + margin.right ) / data.length))

关于你的最后一个问题,这个https://github.com/d3/d3-axis可能会为你提供有关如何使用d3轴的更多细节。