#javascript #arrays #d3.js
#javascript #массивы #d3.js
Вопрос:
Я пытаюсь написать функцию для метода .tickValues на моей оси X, чтобы первый год в моем массиве данных записывался как полный год (2000), а остальные годы записывались как: ’01, ’02, ’03.. и так далее
вот масштаб, ось и данные:
var xScale = d3.time.scale()
.range([0, width])
.domain(d3.extent(dataset, function(d) { return d.year }));
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var dataset = [
{ year: "2000", age1: 31, age2: 10, age3: 32, age4: 27 },
{ year: "2001", age1: 32, age2: 12, age3: 30, age4: 26 },
{ year: "2002", age1: 24, age2: 19, age3: 32, age4: 25 },
{ year: "2003", age1: 26, age2: 18, age3: 31, age4: 25 },
{ year: "2004", age1: 22, age2: 17, age3: 34, age4: 27 },
{ year: "2004", age1: 24, age2: 17, age3: 33, age4: 26 },
{ year: "2006", age1: 31, age2: 15, age3: 32, age4: 22 },
{ year: "2007", age1: 30, age2: 15, age3: 35, age4: 20 },
{ year: "2008", age1: 27, age2: 18, age3: 31, age4: 24 },
{ year: "2009", age1: 25, age2: 15, age3: 35, age4: 25 },
{ year: "2010", age1: 34, age2: 12, age3: 33, age4: 21 },
{ year: "2011", age1: 31, age2: 14, age3: 32, age4: 23 },
{ year: "2012", age1: 27, age2: 18, age3: 30, age4: 25 },
{ year: "2013", age1: 25, age2: 20, age3: 35, age4: 20 }
];
// convert years to dates
var parseDate = d3.time.format("%Y").parse;
dataset.forEach(function(d) {
d.year = parseDate(d.year);
});
У меня есть функция для форматирования лет как ’01’, ’02 и т.д.:
var formatYear = d3.time.format("'" "%y");
Но когда я применяю к нему свою функцию в методе .tickValues(), это не работает:
xAxis.tickValues( function(d){ if(d==dataset[0].year){return d;}else{return formatYear(d);} } );
Комментарии:
1. Похоже, вы пытаетесь установить домен вашего масштаба до того, как вы назначили массив данных своей переменной
dataset
. Переместитьvar dataset =
… и т.д. В начало вашего блока кода здесь. Решает ли это проблему?2. да, если я перемещу домен так, чтобы он находился после переменной dataset, то у меня все еще будет проблема
Ответ №1:
.tickValues()
Метод используется для присвоения, какие значения получают отметки на оси, а не для присвоения, как они форматируются. Для этого вам следует использовать .tickFormat()
метод.
Для начала, похоже, что вы делаете все в точности наоборот в опубликованном вами блоке кода. Вы должны определить свои данные и преобразовать свои значения в даты, прежде чем создавать домен вашей шкалы.
Поскольку вы превращаете значения года в своих данных в Date
объекты, при создании вашей шкалы вы можете использовать унарный
оператор, чтобы принудительно преобразовать их в количество мс…
var xScale = d3.time.scale()
.range([0, width])
.domain(d3.extent(dataset, function(d) { return d.year; }));
…который затем можно использовать в функции, которую вы передаете .tickFormat()
:
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(function(d) {
// if the year ends in 00 then display the full year
if (d3.time.format('%Y')(d).slice(-2) === '00') {
return d3.time.format('%Y')(d);
} else {
// otherwise shorten it to the final 2 digits
return d3.time.format(''%y')(d);
}
})
.ticks(d3.time.year, 1);
В последней строке показано преимущество использования объектов фактической даты, а не строки года для шкалы, поскольку вы можете точно контролировать временной интервал ваших тиков. В этом случае я указал, что для каждого года должна быть отметка.
Вот демонстрационный JSFiddle