简体   繁体   中英

D3 - how to label x Axis correctly

My goal is to label my x-axis with years from 1960 to 2080 in steps by 10. I have a .csv file which looks like this:

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

So far i got this result (see picture)

Result Picture

I do not know how to label the x-axis correctly. Here is my code so far:

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);
});

I thougth the way to go is to change:

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);
});

Another thing is, that I created an extra array for the years. But I bet there is a better way to get around that. Because the years are already in the csv file. Can I somehow use them without creating an extra array?

Your x axis scale can be thought of in your case as an ordinal scale, so you'll need to use

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

, where min and max are your own values for the x extent, which will map your exact years to pixel x values.

For the "cx" calls you should then use .attr('cx', function(d) {return x(d)})

or more concisely, .attr('cx', x)

which is d3 shorthand for the same thing.

You also have a spelling mistake in your circles variable, you've selected all "cirle"s!

Also, I think your csv data should ideally be in a vertical rather than horizontal format:

Land, Belgien 1960, 9128824

etc.

and then you can access the properties d.Land and d.Belgien wherever you want the corresponding numbers to influence your markup, from within an anonymous function(d,i){} definition, and you can construct your years array for example by using

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

Try this:

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);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM