【问题标题】:d3 v4 Why can't I get my x axis and bars to line up?d3 v4 为什么我的 x 轴和条不能对齐?
【发布时间】:2017-01-06 15:00:20
【问题描述】:

我已经制作了带有 x 轴的条形图,但无法弄清楚为什么我无法让 x 轴上的条形和刻度间距准确对齐。目前刻度线稍微偏右一点。

csv 文件示例:

crop,records
CASSAVA,350
MAIZE,226
TOMATOES,137

代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Abbie's attempt at D3</title>
        <script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
        <style>
        svg {
            background-color: rgba(227, 227, 227, 0.97);
            }
        .bar {
            margin: 20px;
            }
        </style>
    </head>
    <body>
        <script type="text/javascript">
            var margin = {top: 20, right: 30, bottom: 100, left: 40};
            var w = 500 - margin.left - margin.right;
            var h = 500 - margin.top - margin.bottom;
            var barPadding = 5;
            var cropData;

    // load the csv file
    d3.csv("crops.csv", function(error, data) {
        data.forEach(function(d) {
            d.records = +d.records;
        });
        cropData = data;

        var arrayLength = cropData.length;
        var yMax = d3.max(cropData, function(d) {
                return d.records;
        });

        var yScale = d3.scaleLinear()
                            .domain([0, yMax])
                            .range([h, 0]);

        var xScale = d3.scaleBand()
                        .domain(cropData.map(function(d) {
                            return d.crop;
                        }))
                        .rangeRound([0, w]);

        // create the svg
        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 + ")");

        // bars
        svg.selectAll("rect")
            .data(cropData)
            .enter()
            .append("rect")
            .attr("x", function(d, i) {
                return i * xScale.bandwidth() + 5;
                })
            .attr("y", function(d) {
                return yScale(d.records);
                })
            .attr("width", xScale.bandwidth() - 5)
            .attr("height", function(d) {
                return h - yScale(d.records);
                })
            .attr("fill", "teal")
            .attr("class", "bar");

        // x Axis
        var xAxis = d3.axisBottom(xScale);
        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + h + ")")
            .call(xAxis)
            .selectAll("text")
                .style("text-anchor", "end")
                .attr("dx", "-.8em")
                .attr("dy", ".15em")
                .attr("transform", function(d) {
                    return "rotate(-60)"
                    });

        // y Axis
        var yAxis = d3.axisLeft(yScale);
        svg.append("g")
            .call(yAxis);

    </script>
</body>

我在xwidthrect 属性中使用i * xScale.bandwidth() + 5xScale.bandwidth() - 5 是否正确,或者这不是正确的方法吗?如果更改条形,如何更改 x 轴上刻度的间距?他们都使用xScale,所以我觉得这一定与此有关。

【问题讨论】:

    标签: javascript d3.js bar-chart data-visualization


    【解决方案1】:

    我会进行以下更改。

    首先,将padding 介绍给您的xScale

    var xScale = d3.scaleBand()
      .domain(cropData.map(function(d) {
        return d.crop;
      }))
      .rangeRound([0, w])
      .padding(0.1);
    

    这将使条形按带宽的百分比间隔。

    其次,使用您的xScale

    svg.selectAll("rect")
      .data(cropData)
      .enter()
      .append("rect")
      .attr("x", function(d, i) {
        return xScale(d.crop); //<-- place by xScale
      })
      .attr("y", function(d) {
        return yScale(d.records);
      })
      .attr("width", xScale.bandwidth()) //<-- no -5 padding takes care of breaks
    

    可运行代码:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="utf-8">
      <title>Abbie's attempt at D3</title>
      <script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
      <style>
        svg {
          background-color: rgba(227, 227, 227, 0.97);
        }
        
        .bar {
          margin: 20px;
        }
      </style>
    </head>
    
    <body>
      <script type="text/javascript">
        var margin = {
          top: 20,
          right: 30,
          bottom: 100,
          left: 40
        };
        var w = 500 - margin.left - margin.right;
        var h = 500 - margin.top - margin.bottom;
        var barPadding = 5;
        var cropData;
    
        // load the csv file
        //d3.csv("crops.csv", function(error, data) {
    
          var data = [{
            "crop": "CASSAVA",
            "records": "350"
          }, {
            "crop": "MAIZE",
            "records": "226"
          }, {
            "crop": "TOMATOES",
            "records": "137"
          }];
    
          data.forEach(function(d) {
            d.records = +d.records;
          });
          cropData = data;
    
          var arrayLength = cropData.length;
          var yMax = d3.max(cropData, function(d) {
            return d.records;
          });
    
          var yScale = d3.scaleLinear()
            .domain([0, yMax])
            .range([h, 0]);
    
          var xScale = d3.scaleBand()
            .domain(cropData.map(function(d) {
              return d.crop;
            }))
            .rangeRound([0, w])
            .padding(0.1);
    
          // create the svg
          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 + ")");
    
          // bars
          svg.selectAll("rect")
            .data(cropData)
            .enter()
            .append("rect")
            .attr("x", function(d, i) {
              return xScale(d.crop);
            })
            .attr("y", function(d) {
              return yScale(d.records);
            })
            .attr("width", xScale.bandwidth())
            .attr("height", function(d) {
              return h - yScale(d.records);
            })
            .attr("fill", "teal")
            .attr("class", "bar");
    
          // x Axis
          var xAxis = d3.axisBottom(xScale);
          svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + h + ")")
            .call(xAxis)
            .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", ".15em")
            .attr("transform", function(d) {
              return "rotate(-60)"
            });
    
          // y Axis
          var yAxis = d3.axisLeft(yScale);
          svg.append("g")
            .call(yAxis);
            
       // });
      </script>
    </body>

    【讨论】:

    • 谢谢!错误的事情的组合把这一切搞砸了!现在看起来不错:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 2018-01-23
    • 2017-07-31
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多