2013-09-17 2 views
3

У меня есть следующий набор данных:D3.js: рассчитать шкалу времени оси x для гистограммы?

var data = [ 
    { 
    "air_used": 0.660985, 
    "datestr": "2012-12-01 00:00:00", 
    "energy_used": 0.106402 
    }, 
    { 
    "air_used": 0.824746, 
    "datestr": "2013-01-01 00:00:00", 
    "energy_used": 0.250462 
    } ... 
] 

И я хочу нарисовать гистограмму (для air_used) и линейный график (для energy_used), которые выглядят так:

enter image description here

Моя проблема заключается в том, что на данный момент с использованием x-scale, который я использую, график выглядит следующим образом: в основном, бары находятся в неправильном положении, а последний стержень падает с графика:

enter image description here

Вот JSFiddle с полным кодом и рабочим графиком: http://jsfiddle.net/aWJtJ/4/

Чтобы достичь того, чего я хочу, я думаю мне нужно изменить й-масштаб, так что есть дополнительная ширина до первой точки данных и после последней точки данных и так, чтобы полосы сдвигались влево на половину ширины каждого бара.

Может ли кто-нибудь помочь мне разобраться, что мне нужно сделать с помощью x-scale?

Я попытался добавить дополнительный месяц в домен, который останавливает последний бар, падающий с конца графика, но он также добавляет дополнительный тик, который я не хочу, и он не исправляет положение линейного графика и тиков.

Если возможно, я хочу продолжить шкалу времени для оси x, а не порядковый масштаб, потому что я хочу использовать умные форматы титров D3 и синтаксические анализаторы даты, например. xAxis.ticks(d3.time.weeks, 2).

+0

У меня есть базовое исправление, но (1) оно кажется довольно взломанным и (2) линия оси х теперь не идет туда, где она должна: http://jsfiddle.net/aWJtJ/5/ – Richard

+0

Кроме того, месяцы отличаются по ширине, так как в этом вопросе: http://stackoverflow.com/questions/12186366/d3-js-evenly-spaced-bars-on-a-time-scale – Richard

+2

Чтобы исправить месяцы, widths, вы должны подумать о создании порядкового номера оси в зависимости от месячной/месячной части метки времени, а затем с помощью настраиваемого форматирования указать метку тика. Затем вы можете использовать диапазоны диапазонов для обработки ширины полосы: https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-ordinal_rangeBands – reblace

ответ

3

Разверните свой домен на +1 и -1 месяц с фактической протяженности ваших данных. Это позволит заполнить график дополнительными месяцами с каждой стороны, а затем обновить ширину полосы, чтобы добавить 2 к количеству элементов данных.

var barRawWidth = width/(data.length + 2); 

Смотрите эту скрипку: http://jsfiddle.net/reblace/aWJtJ/6/

Если вы хотите, чтобы скрыть нижнюю и верхнюю границу месяцев, вы можете взломать его, как это: http://jsfiddle.net/reblace/aWJtJ/7/, просто добавляя и вычитая 20 дней вместо целого месяца, но есть, вероятно, более элегантные способы сделать это.

var xExtent = d3.extent(data, function(d) { return d.date; }); 
var nxExtent = [d3.time.day.offset(xExtent[0], -20), d3.time.day.offset(xExtent[1], 20)]; 
x.domain(nxExtent); 
0

Как было отмечено в комментариях, я думаю, что лучший подход состоит в использовании d3.scale.ordinal. Обратите внимание, что использование этого не мешает вам использовать парсеры d3.time, но вам нужно учесть ширину полосы, чтобы выровнять линию с полосками.

Пример решения здесь: http://jsfiddle.net/jcollado/N8tuR/

Соответствующий код из приведенного выше решения заключается в следующем:

// Map data set to dates to provide the whole domain information 
var x = d3.scale.ordinal() 
    .domain(data.map(function(d) { 
     return d.date; 
    })) 
    .rangeRoundBands([0, width], 0.1); 

... 

// Use x.rangeBand() to align line with bars 
var line = d3.svg.line() 
    .x(function(d) { return x(d.date) + x.rangeBand()/2; }) 
    .y(function(d) { return y(d.energy_used); }); 

... 

// Use x.rangeBand() to set bar width 
bars.enter().append("rect") 
    .attr("class", "air_used") 
    .attr("width", x.rangeBand()) 
    ... 

Обратите внимание, что дата разбора код был перемещен, чтобы иметь d.date доступные при создании х масштаб. Кроме того, заявления d3.time не были изменены вообще.

+1

Не имеет ли этого большого недостатка, что отсутствующие значения не учитываются в шкале? Например, если я удалю февраль из данных вашего примера, график будет идти с января по март. – explunit

+0

@explunit Да, это правильно. С порядковой шкалой вам нужно передать все данные, даже если значение равно 0. – jcollado

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