为什么最后一个刻度没有值 - D3.js

时间:2016-02-10 12:08:21

标签: javascript d3.js

x轴和y轴的最后一个刻度不会在它们旁边绘制值。我无法弄清楚为什么缺少这些值。

这是JS代码:

var xAxisScale = d3.scale.linear()
         .domain([0, d3.max(data, function(d) { return d.x; })])
       .range([padding, containerWidth - padding * 2]);

    var xAxis = d3.svg.axis().scale(xAxisScale).orient("bottom");

    var xGuide = chartContainer.append('g')
      .attr("class", "xAxis")
      .call(xAxis)
      .attr('transform', 'translate(0 ,' + (containerHeight -padding) + ')');


    /* Code for adding y axis in chart
     * 
     * */
    var yAxisScale = d3.scale.linear()
      .domain([0, d3.max(data, function(d){return d.y})])
      .range([containerHeight-padding, padding ]);

    var yAxis = d3.svg.axis().scale(yAxisScale).orient("left");

    var yGuide = chartContainer.append('g')
      .attr("class", "yAxis")
      .call(yAxis)
      .attr('transform', 'translate('+padding + ',0)');

这是我的live demo

3 个答案:

答案 0 :(得分:1)

这可以通过使用axis.tickValues()覆盖默认行为来确定刻度值来完成:

var yAxis = d3.svg.axis().scale(yAxisScale).orient("left")
  .tickValues(yAxisScale.ticks().concat(yAxisScale.domain()));

这仍然通过调用yAxisScale.ticks()来自动生成的刻度值,这是D3轴的默认行为。然后使用数据值的外边界(即yAxisScale.ticks()返回的数组)补充这些值。要设置上限,if是否足以指定yAxisScale.domain()[1],尽管它不会影响在提供给.tickValues()的数组中有重复值。

这样做可以使您免受刻度值的任何硬编码。

看看这个工作示例:

var padding = 70;

    	//Width and height
    	var containerWidth = 1000;
    	var containerHeight = 500;
    	var data = [{
    	  "x": 82,
    	  "y": 1730
    	}, {
    	  "x": 533,
    	  "y": 16385
    	}, {
    	  "x": 41,
    	  "y": 783
    	}, {
    	  "x": 20.5,
    	  "y": 5873
    	}, {
    	  "x": 553.5,
    	  "y": 25200
    	}, {
    	  "x": 61.5,
    	  "y": 30000
    	}, {
    	  "x": 184.5,
    	  "y": 2853
    	}, {
    	  "x": 1476,
    	  "y": 83775
    	}];
    	//Create scale functions
			var xScale = d3.scale.linear()
				
								 
    	var chartContainer = d3.select("body")
    	  .append("svg")
    	  .attr("class", "chartContainer")
    	  .attr("width", containerWidth)
    	  .attr("height", containerHeight);

    	$(".chartContainer").css({
    	  "background-color": "",
    	  "position": "absolute",
    	  "top": 50,
    	  "left": 15
    	});
      
								 
    	var xAxisScale = d3.scale.linear()
  			 .domain([0, d3.max(data, function(d) { return d.x; })])
    	   .range([padding, containerWidth - padding * 2]);

    	var xAxis = d3.svg.axis().scale(xAxisScale).orient("bottom")
    	  .tickValues(xAxisScale.ticks().concat(xAxisScale.domain()));
 
    	var xGuide = chartContainer.append('g')
    	  .attr("class", "xAxis")
    	  .call(xAxis)
    	  .attr('transform', 'translate(0 ,' + (containerHeight -padding) + ')');

xGuide.selectAll('path')
	  		.style({ fill: 'none', stroke: "#000"});
	  	xGuide.selectAll('line')
	  		.style({ stroke: "#000"});
    	/* Code for adding y axis in chart
    	 * 
    	 * */
    	var yAxisScale = d3.scale.linear()
    	  .domain([0, d3.max(data, function(d){return d.y})])
    	  .range([containerHeight-padding, padding ]);

    	var yAxis = d3.svg.axis().scale(yAxisScale).orient("left")
    	  .tickValues(yAxisScale.ticks().concat(yAxisScale.domain()[1]));

    	var yGuide = chartContainer.append('g')
    	  .attr("class", "yAxis")
    	  .call(yAxis)
    	  .attr('transform', 'translate('+padding + ',0)');

    	chartContainer.selectAll("circle")
    	  .data(data)
    	  .enter()
    	  .append("circle")
    	  .attr("cx", function(d) {
    	    return xAxisScale(d.x);
    	  })
    	  .attr("cy", function(d) {
    	    return yAxisScale(d.y);
    	  })
    	  .attr("r", 4)
    	  .attr("fill", "red")
    	  .attr({
    	    "z-index": "9999"
    	  });
    	  
    	  yGuide.selectAll('path')
	  		.style({ fill: 'none', stroke: "#000"});
	  	yGuide.selectAll('line')
	  		.style({ stroke: "#000"});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

答案 1 :(得分:0)

您正在使用d3的自动刻度生成器,它可以根据图表中的数据最佳地猜测如何最佳地绘制轴。

您有两种方法可以覆盖它:

  1. 设置要显示的刻度值数。例如:

    var xAxis = d3.svg.axis()               .scale(xAxisScale)               。东方(“底部”)               .ticks(10);

  2. 传递一个刻度值数组,明确告诉d3你想要在x或y轴上有什么值;像这样:

    var xAxis = d3.svg.axis()               .scale(xAxisScale)               。东方(“底部”)               .tickValues([0,100,200,300,400]);

  3. 如果你想摆脱缺失值的刻度(在你的情况下,外部刻度),只需在x或y轴上设置.outerTickSize(0)。

    您还应该阅读d3的轴API here

答案 2 :(得分:0)

在您的live demo.的第69行中添加.nice()将解决此问题。最终结果请参见下图。

有关更多详细信息和说明,请参阅d3比例尺库上的this已解决问题。 mbostock在2016年12月6日对此进行了评论并提供了解决方案。

enter image description here