2017-01-06 2 views
1

Я добрался до своей гистограммы с осью x, но не могу понять, почему я не могу получить бары и интервалы между метками по оси x, чтобы точно выровняться. В настоящий момент тики немного правее от центра бара.d3 v4 Почему я не могу заставить оси 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> 

Могу ли я делать это правильно с i * xScale.bandwidth() + 5 и xScale.bandwidth() - 5 в x и width атрибутов rect или это не правильный способ сделать это? Как изменить интервал тиков по оси x, если я изменяю столбцы? Они оба используют xScale, поэтому я чувствую, что это должно быть чем-то связано с этим.

ответ

0

Я бы ввел следующие изменения.

Во-первых, ввести 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 

Runnable код:

<!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>

+0

Спасибо! Сочетание неправильных вещей было испортить все это! Сейчас это выглядит хорошо :-) – Abbie

Смежные вопросы