d3.js将底部轴线延伸到原点

时间:2017-12-29 19:29:01

标签: javascript d3.js svg

我希望从原点开始划分第一个刻度线,但也希望有一条连接它们的线。我想我可以附加一个svg为我做这个,但必须有一个更简单的方法,我在文档中遗漏。我可以找到我所瞄准的图像示例here

以下是我遇到问题的一个例子:



var margin = {
      top: 20,
      right: 10,
      bottom: 40,
      left: 40
     };
    
     var padding = 20;
    
     var height = 100;
     var width = 400
    
      var xAxisTimeScale = [];
    
      for(var i = 8; i < 21; i++) {
       xAxisTimeScale.push(i);
      }
    
      // scales
      var xScale = d3.scaleLinear()
      .domain([0, 12])
      .range([padding, width - padding]);
    
      var yScale = d3.scaleLinear()
      .domain([0, 10])
      .range([height, 0]);
    
     function convertTimeToString(time) {
      if(time > 12) {
       return (time - 12) + "PM";
      } else {
       return time + "AM";
      }
     }
    
     var xAxis = d3.axisBottom(xScale)
     .ticks(13)
     .tickFormat(function(d,i){ return convertTimeToString(xAxisTimeScale[i]);});
    
     var yAxis = d3.axisLeft(yScale);
    
     var svg = d3.select("body").append("svg")
     .attr('width', width + margin.left + margin.right)
     .attr('height', height + margin.top + margin.bottom)
     .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
     // add axes
     svg.append('g')
     .call(yAxis);
    
     svg.append('g')
     .attr('transform', 'translate(0, ' + height + ')')
     .call(xAxis);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.min.js"></script>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

以下是我提出的方法:

  1. 将x轴的path的{​​{1}}属性更改为d。相关代码更改:

    'M0,0.5V0.5H'+(width-padding)

    我是如何在那里提出svg.select('.x.axis path.domain').attr('d', function() { return 'M0,0.5V0.5H'+(width-padding); }); 的?我分析了d3.js并遇到0.5(用于创建X轴域的 d3-version3 中的V0.5。有关如何路径的详细信息已经形成,请查看SVG path d attribute。使用此偏移量,这是一个实现相同的代码片段:

    V0
    var margin = {
          top: 20,
          right: 10,
          bottom: 40,
          left: 40
         };
        
         var padding = 20;
        
         var height = 100;
         var width = 400
        
          var xAxisTimeScale = [];
        
          for(var i = 8; i < 21; i++) {
           xAxisTimeScale.push(i);
          }
        
          // scales
          var xScale = d3.scaleLinear()
          .domain([0, 12])
          .range([padding, width - padding]);
        
          var yScale = d3.scaleLinear()
          .domain([0, 10])
          .range([height, 0]);
        
         function convertTimeToString(time) {
          if(time > 12) {
           return (time - 12) + "PM";
          } else {
           return time + "AM";
          }
         }
        
         var xAxis = d3.axisBottom(xScale)
         .ticks(13)
         .tickFormat(function(d,i){ return convertTimeToString(xAxisTimeScale[i]);});
        
         var yAxis = d3.axisLeft(yScale);
        
         var svg = d3.select("body").append("svg")
         .attr('width', width + margin.left + margin.right)
         .attr('height', height + margin.top + margin.bottom)
         .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        
         // add axes
         svg.append('g')
         .call(yAxis);
        
         svg.append('g').classed('x axis', true)
         .attr('transform', 'translate(0, ' + height + ')')
         .call(xAxis);
         
         svg.select('.x.axis path.domain').attr('d', function() {
         		return 'M0,0.5V0.5H'+(width-padding);
         });

  2. 使用简单的线路代码从原点明确添加一行到X轴的起点。相关代码更改:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.min.js"></script>

    svg.append('line').classed('connecting-line', true) .attr('y1', height+0.5).attr('y2', height+0.5).attr('x1', 0).attr('x2', padding).style('stroke', '#000'); 与上述原因相同。 Rest属性仅基于高度和宽度。以下是实现此功能的代码段:

    0.5
    var margin = {
          top: 20,
          right: 10,
          bottom: 40,
          left: 40
         };
        
         var padding = 20;
        
         var height = 100;
         var width = 400
        
          var xAxisTimeScale = [];
        
          for(var i = 8; i < 21; i++) {
           xAxisTimeScale.push(i);
          }
        
          // scales
          var xScale = d3.scaleLinear()
          .domain([0, 12])
          .range([padding, width - padding]);
        
          var yScale = d3.scaleLinear()
          .domain([0, 10])
          .range([height, 0]);
        
         function convertTimeToString(time) {
          if(time > 12) {
           return (time - 12) + "PM";
          } else {
           return time + "AM";
          }
         }
        
         var xAxis = d3.axisBottom(xScale)
         .ticks(13)
         .tickFormat(function(d,i){ return convertTimeToString(xAxisTimeScale[i]);});
        
         var yAxis = d3.axisLeft(yScale);
        
         var svg = d3.select("body").append("svg")
         .attr('width', width + margin.left + margin.right)
         .attr('height', height + margin.top + margin.bottom)
         .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        
         // add axes
         svg.append('g')
         .call(yAxis);
        
         svg.append('g').classed('x axis', true)
         .attr('transform', 'translate(0, ' + height + ')')
         .call(xAxis);
      
      	svg.append('line').classed('connecting-line', true)
        	.attr('y1', height+0.5).attr('y2', height+0.5).attr('x1', 0).attr('x2', padding).style('stroke', '#000');

  3. 将叠加矩形添加为或作为使用<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.min.js"></script>设置的矩形。但我认为这不会有用,因为它会有点压倒一切。

  4. 希望上述任何一种方法都能达到目的。我真的很抱歉没有准时回来(星期五晚上有我):)。

答案 1 :(得分:0)

鉴于您将线性比例伪装成时间尺度,此处的解决方案将是 ad hoc 。否则,解决方案可能会更加惯用。

首先,增加xAxisTimeScale

var xAxisTimeScale = d3.range(7, 23, 1)

然后,增加你的域名......

.domain([0, 13])

...并删除第一个勾号:

.tickFormat(function(d, i) {
    return i ? convertTimeToString(xAxisTimeScale[i]) : null;
});

以下是包含这些更改的代码:

var margin = {
  top: 20,
  right: 10,
  bottom: 40,
  left: 40
};

var padding = 20;

var height = 100;
var width = 400

var xAxisTimeScale = d3.range(7, 23, 1)

// scales
var xScale = d3.scaleLinear()
  .domain([0, 13])
  .range([0, width - padding]);

var yScale = d3.scaleLinear()
  .domain([0, 10])
  .range([height, 0]);

function convertTimeToString(time) {
  if (time > 12) {
    return (time - 12) + "PM";
  } else {
    return time + "AM";
  }
}

var xAxis = d3.axisBottom(xScale)
  .ticks(13)
  .tickFormat(function(d, i) {
    return i ? convertTimeToString(xAxisTimeScale[i]) : null;
  });

var yAxis = d3.axisLeft(yScale);

var svg = d3.select("body").append("svg")
  .attr('width', width + margin.left + margin.right)
  .attr('height', height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// add axes
svg.append('g')
  .call(yAxis);

svg.append('g')
  .attr('transform', 'translate(0, ' + height + ')')
  .call(xAxis);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.min.js"></script>