【问题标题】:D3 - how to label x Axis correctlyD3 - 如何正确标记 x 轴
【发布时间】:2016-09-09 16:13:59
【问题描述】:

我的目标是将我的 x 轴标记为从 1960 年到 2080 年的年份,步长为 10。 我有一个 .csv 文件,如下所示:

Land,1960,1970,1980,1990,2000,2010,2020,2030,2040,2050,2060,2070,2080
Belgien,9128824,9660154,9855110,9947782,10239085,10839905,11824225,12885338,13918014,14758714,15400272,16027593,16614305

到目前为止,我得到了这个结果(见图)

Result Picture

我不知道如何正确标记 x 轴。到目前为止,这是我的代码:

d3.csv("/Data/temp_eu_popul.csv", function(e, eu_popul) {
console.log(eu_popul);


var years = [1960,1970,1980,1990,2000,2010,2020,2030,2040,2050,2060,2070,2080];
    console.log(years);

var population = [];
  for(var i = 1960; i<=2080; i+= 10){
    population.push(parseFloat(eu_popul[0][i]));
  }
console.log(population);

var svg = d3.select("body")
  .append("svg")
    .attr("width", 500)
    .attr("height", 500);

var y = d3.scaleLinear()
  .domain(d3.extent(population))
  .range([250, -50]);

var x = d3.scaleLinear()
  .domain([0,years.length])
  .range([100, 450]);

var yAxis = d3.axisLeft(y);
    svg.append('g')
        .attr("transform", "translate(75,150)")
        .attr('class', 'y axis')
        .call(yAxis);

var xAxis = d3.axisBottom(x);
svg.append('g')
  .attr("transform", "translate(0,450)")
  .attr('class', 'x axis')
  .call(xAxis);

var circles = svg.selectAll("cirle").data(population).enter().append("circle")
.attr("cx", function(d,i){ return x(i); })
.attr("cy", function(d,i){ return 350-y(d); })
    .attr("r", 2);
});

我认为要走的路就是改变:

var x = d3.scaleLinear()
  .domain(d3.extent(years))
  .range([100, 450]);

var circles = svg.selectAll("cirle").data(population).enter().append("circle")
.attr("cx", years)
.attr("cy", function(d,i){ return 350-y(d); })
    .attr("r", 2);
});

另一件事是,多年来我创建了一个额外的数组。但我敢打赌,有更好的方法来解决这个问题。因为年份已经在 csv 文件中。我可以在不创建额外数组的情况下以某种方式使用它们吗?

【问题讨论】:

    标签: javascript arrays json csv d3.js


    【解决方案1】:

    在您的情况下,您的 x 轴刻度可以被认为是一个序数刻度,因此您需要使用

    x = d3.scaleOrdinal().domain(years).range([min, max])

    ,其中 min 和 max 是您自己的 x 范围值,它将您的确切年份映射到像素 x 值。

    对于“cx”调用,您应该使用 .attr('cx', function(d) {return x(d)})

    或更简洁地说, .attr('cx', x)

    这是同一事物的 d3 简写。

    您的circles 变量也有拼写错误,您选择了所有“圆”!

    另外,我认为你的 csv 数据最好是垂直而不是水平格式:

    Land, Belgien 1960, 9128824

    等等

    然后您可以在匿名的function(d,i){} 定义中访问属性d.Landd.Belgien,只要您希望相应的数字影响您的标记,您就可以构造您的years 数组,例如使用

    var years = eu_popul.map(function(d) {return d.Land});

    【讨论】:

    • hm,当我将代码更改为 x = d3.scaleOrdinal().domain(years).range([min, max]) 时,我得到一个空页面。将 range([min,max]) 更改回 .range([100, 450]);我得到一个输出,但它看起来很奇怪。 min, max 是在 d3 中预定义的吗?那么我的代码知道最小值和最大值是多少吗?
    • 对不起,我应该说 min 和 max 应该用你自己的值代替!
    • 已编辑,见上文
    • 奇怪在哪里?不,max 和 min 没有在 d3 中预定义 - d3 知道的几乎所有内容(不是常规的 javascript 函数)都由 d3 作为前缀/命名空间,例如 d3.scaleLinear、d3.select 等
    【解决方案2】:

    试试这个:

    var x = d3.scaleLinear()
      .domain(d3.extent(years)) // or .domain(d3.extent(eu_popul[1]))
      .range([100, 450]);
    
    var xAxis = d3.axisBottom(x);
    svg.append('g')
      .attr("transform", "translate(0,450)")
      .attr('class', 'x axis')
      .call(xAxis); 
    
    var circles = svg.selectAll("circle").data(population).enter().append("circle")
    .attr("cx", function(d,i){ return x(years[i]); })
    .attr("cy", function(d,i){ return 350-y(d); })
        .attr("r", 2);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      相关资源
      最近更新 更多