基于D3的条形图中的轴域不正确

时间:2016-11-21 11:36:40

标签: javascript d3.js

我试图做一个简单的条形图,其中y轴具有Band标度,x轴具有线性标度。

我面临以下问题 -

  1. 无法显示字符串以及上的标记 Y轴
  2. 根据数据
  3. ,X轴的域不同步
  4. 不确定矩形的宽度是否正确(可能会反转)
  5. 是否适合使用Y轴的带刻度而不是Ordinal刻度?
  6. 我会指出任何指向错误或缺少部分的帮助。谢谢!

    我已将代码与底部的JsFiddle链接一起附加。

    
    
    function addBarGraph() {
      var margin = {
          top: 20,
          right: 20,
          bottom: 30,
          left: 50
        },
        width = 600 - margin.left - margin.right,
        height = 400 - margin.top - margin.bottom;
    
      var x = d3.scaleLinear()
        .rangeRound([0, width]);
    
      var y = d3.scaleBand()
        .rangeRound([height, 0]).padding(0.1);
    
      var xAxis = d3.axisBottom(x);
    
      var yAxis = d3.axisLeft(y);
    
      var svg = d3.select('#barGraph').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 + ")");
    
      var max = d3.max(data, function(datum) {
        return datum.distribution;
      });
    
      svg.append("g")
        .attr("class", "xAxis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);
    
      svg.append("g")
        .attr("class", "yAxis")
        .call(yAxis);
    
      data.forEach(function(d) {
        d.distribution = +d.distribution;
      });
    
      y.domain(data.map(function(d) {
        return d.nv;
      }));
      x.domain([max, 0]);
    
      svg.selectAll(".bar")
        .data(data)
        .enter().append("rect")
        .attr("class", "bar")
        .attr("y", function(d) {
          return y(d.nv);
        })
        .attr("width", function(d) {
          return width - x(d.distribution);
        })
        .attr("height", y.bandwidth());
    
    }
    
    function getData() {
      data = JSON.parse('[{"nv":"Channel1","distribution":60},{"nv":"channel2","distribution":30}]');
    }
    
    $(document).ready(function() {
      getData();
      addBarGraph();
    });
    
    .bar {
      fill: steelblue;
    }
    
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <span id="barGraph"></span>
    &#13;
    &#13;
    &#13;

    链接https://jsfiddle.net/6esyv0os/

1 个答案:

答案 0 :(得分:2)

让我们一步一步走。

  
      
  1. 无法显示字符串以及Yaxis上的刻度
  2.   

这是因为您在设置<g>域之前附加了轴的y元素。

  
      
  1. 根据数据
  2. ,X轴的域不同步   

那是因为数组中的顺序是反转的。它应该是:

x.domain([0, max]);
  
      
  1. 不确定矩形的宽度是否正确(可能会反转)
  2.   

是的,它被倒置了。这是正确的功能:

.attr("width", function (d) {
        return x(d.distribution);
    })
  
      
  1. 是否适合使用Y轴的带刻度而不是Ordinal刻度?
  2.   

带尺 一个序数尺度。是的,它是合适的。实际上,对于条形图(直方图),它是正确的预期。

这是您更新的小提琴:https://jsfiddle.net/58fo16s9/

甚至比小提琴更好,这里有一个SO片段:

&#13;
&#13;
function addBarGraph() {
    var margin = {
            top: 20,
            right: 20,
            bottom: 30,
            left: 60
        },
        width = 500 - margin.left - margin.right,
        height = 300 - margin.top - margin.bottom;

    var x = d3.scaleLinear()
        .rangeRound([0, width]);

    var y = d3.scaleBand()
        .rangeRound([height, 0]).padding(0.1);

    var xAxis = d3.axisBottom(x);

    var yAxis = d3.axisLeft(y).ticks();

    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 + ")");

    var max = d3.max(data, function(datum) {
        return datum.distribution;
    });



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


    y.domain(data.map(function(d) {
        return d.nv;
    }));
    x.domain([0, max]);



    svg.selectAll(".bar")
        .data(data)
        .enter().append("rect")
        .attr("fill", "steelblue")
        .attr("y", function(d) {
            return y(d.nv);
        })
        .attr("width", function(d) {
            return x(d.distribution);
        })
        .attr("height", y.bandwidth());

    svg.append("g")
        .attr("class", "xAxis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.append("g")
        .attr("class", "yAxis")
        .call(yAxis);

}

function getData() {
    data = JSON.parse('[{"nv":"Channel1","distribution":60},{"nv":"Channel2","distribution":30}]');
}

getData();
addBarGraph();
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;