Как я могу продолжать отмечать галочки, когда у меня есть небольшое количество дат на диаграмме nvd3

Ось x любит повторять даты, когда существует ограниченное количество дат. Посмотрите эту скрипту:

http://jsfiddle.net/skilesare/bFfJ2/1/

nv.addGraph(function() {  

    var data = fakeActivityByDate();

    var chart = nv.models.lineChart();




chart.xAxis
       .axisLabel('Date')
       .rotateLabels(-45)
       .tickFormat(function(d) { return d3.time.format('%b %d')(new Date(d)); });

   chart.yAxis
       .axisLabel('Activity')
       .tickFormat(d3.format('d'));

   d3.select('#chart svg')
       .datum(data)
     .transition().duration(500)
       .call(chart);

   nv.utils.windowResize(function() { d3.select('#chart svg').call(chart) });

   return chart;
 });

function days(num) {
  return num*60*60*1000*24
}
 /**************************************
  * Simple test data generator
  */

function fakeActivityByDate() {
   var lineData = [];
   var y=0;
   var start_date = new Date() - days(365); // one year ago

   for (var i = 0; i < 4; i++) {
     lineData.push({x: new Date(start_date + days(i)), y: y});
     y=y+Math.floor((Math.random()*10)-3);
   }

   return [
     {
       values: lineData,
       key: 'Activity',
       color: '#ff7f0e'
     }
   ];
 }`

Если ваш экран достаточно широкий, вы увидите, что даты повторяются. Если вы закроете окно, проблема исчезнет.

Ответ 1

Проблема не связана с размером экрана, как это может показаться и для таких случаев: у вас есть всего 3 дня для отображения, и вместо 3 тиков вы получите 6 или 10 или что-то еще (на самом деле это именно тот случай, который вы делаете если я посмотрю на ваш jsfiddle). Это правда, что nvd3 использует что-то вроде этого, чтобы установить размеры тиков (посмотрите на axis.js):

if (ticks !== null)
    axis.ticks(ticks);
 else if (axis.orient() == 'top' || axis.orient() == 'bottom')
    axis.ticks(Math.abs(scale.range()[1] - scale.range()[0]) / 100);

Существует несколько решений этой проблемы:

  • вы либо реализуете свой собственный компонент оси, либо заменяете nvd3 Ось

  • вы либо напрямую изменяете компонент оси nvd3, либо добавляете некоторые настройки, которые затем будут использоваться специально для этого сценария, вы (вы заметите, что, так как это nvd3, настраиваемый).

  • Hack: вы используете d3 собственный tickValues ​​() и передаете ему массив с датами, которые вы хотите иметь на экране (пример: первая дата, последняя дата и несколько дат между вычисленными по вашему алгоритму). См. Документацию d3: https://github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickValues. В зависимости от случая (какая ось вы хотите изменить и какой график) вам не только нужно прокомментировать код, который я вставил вам, и добавить ваш алгоритм для установки tickValues ​​в компонент диаграммы (например, lineChart), но также вам нужно будет добавить setter для tickValues ​​и перезаписать значения вашими значениями.

Ответ 2

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

    uniqueTicks = [];
    xTickFormat = d3.time.format.multi([
                                        ["%Y", function (d) {
                                        // If tick not applied yet                                            
                                        if (uniqueTicks.indexOf(d.getFullYear()) === -1) {
                                                uniqueTicks.push(d.getFullYear());
                                                return true;
                                            } else {
                                                return false;
                                            }                                        
                                        }],
                                        ["", function () {
                                            return true;
                                        }]
                                    ]);

    d3.svg.axis().tickFormat(xTickFormat );

Этот трюк может быть изменен для любого другого типа тикового формата.