2014-12-14 2 views
10

У меня проблема с метками, присвоенными значениям моего графика.c3js> Временные значения x не равномерно распределены

График - это время. Я добавляю значения, используя свойство «columns» c3js.

Я использую чистые временные метки (в секундах), а затем преобразовываю их в строки с помощью label.format.

Однако, это то, что происходит:

https://drive.google.com/file/d/0B9GDftIYQFIVb2Z3N2JfS2pzVjg/view?usp=sharing

, как вы можете заметить, пространство не распределяется равномерно между 18-21, 25-28 октября и 1-4, 4-7 ноября как раз два дня, а у всех остальных есть три дня между датами.

Что вызывает это?

Я хотел бы иметь равномерное пространство пробелов (столько же дней).

Вот jfiddle с кодом: http://jsfiddle.net/ok1k6yjo/

var array_times = [1414540800, 1414627200]; 
var array_values = [67, 66.22]; 

var labelWeight = 'weight in kg'; 

var window_period = (30 * 24 * 3600); // last 30 days 

var today = Math.floor(new Date(2014,10,20,0,0,0,0).getTime()/1000); 
var timeEnd = today; 
var timeStart = today - window_period; 

var toShowTime = [1414540800, 1414627200]; 
var toShowValues = [67, 66.22]; 


var minT = Math.min.apply(null, array_times), 
    maxT = Math.max.apply(null, array_times.concat(today)); 

var minV = Math.min.apply(null, array_values), 
    maxV = Math.max.apply(null, array_values); 

function dateToString(e) { 
    var date = new Date(e * 1000); 
    return date.toDateString().substring(4); 
} 


var chart = c3.generate({ 
    bindto: '#chart', 
    data: { 
     x: 'times', 
     columns: [ 
      ['times'].concat(toShowTime), 
      [labelWeight].concat(toShowValues)], 
     labels: { 
      format: { 
       y: d3.format('.2') 
      } 
     }, 
     type: 'scatter' 
    }, 
    point: { 
     r: 6 
    }, 
    legend: { 
     show: false 
    }, 
    grid: { 
     x: { 
      show: true 
     }, 
     y: { 
      show: true 
     } 
    }, 
    axis: { 
     x: { 
      label: { 
       text: 'Time [days]' 
      }, 
      type: 'timeseries', 
      tick: { 
       fit: false, 
       //count: 29, 
       rotate: -75, 
       multiline: false, 
       format: function (e, d) { 
        return dateToString(e); 
       } 
      }, 
      height: 100 
     }, 
     y: { 
      label: { 
       text: 'Weight [kg]', 
       position: 'outer', 
       min: minV - 10, 
       max: maxV + 10 
      }, 
      tick: { 
       format: function (e, d) { 
        return parseFloat(e).toFixed(2); 
       } 
      }, 
     } 
    } 
}); 

chart.axis.range({min: {x:timeStart, y:minV-10}, max: {x:timeEnd, y:maxV+10}}); 

Небольшое различие связано с различной начальной даты.

Вот еще одна скрипка с аналогичными проблемами. http://jsfiddle.net/hfznh45w/5/

var d = (24 * 3600); // last 30 days 


//var array_times = [1414540800-8*d, 1414540800-d, 1414540800, 1414627200, 1414627200 + d, 1414627200 + 2 * d, 1414627200 + 3 * d]; 
//var array_values = [61, 60, 67, 66.22, 68, 68, 68]; 

var array_times = []; 
var array_values = []; 

for (var i = -8; i < 30; i++) { 
    array_times.push(1414540800 + (i * d)); 
    array_values.push(60 + i); 
} 

console.log(array_times); 
console.log(array_values); 

var labelWeight = 'weight in kg'; 

var window_period = (30 * 24 * 3600); // last 30 days 

var today = Math.floor(new Date(2014, 10, 20, 0, 0, 0, 0).getTime()/1000); 
var timeEnd = today; 
var timeStart = today - window_period; 


var minT = Math.min.apply(null, array_times), 
    maxT = Math.max.apply(null, array_times.concat(today)); 

var minV = Math.min.apply(null, array_values), 
    maxV = Math.max.apply(null, array_values); 

function dateToString(e) { 
    var date = new Date(e * 1000); 
    return date.toDateString().substring(4); 
} 


var chart = c3.generate({ 
    bindto: '#chart', 
    data: { 
     x: 'times', 
     columns: [ 
      ['times'].concat(array_times), [labelWeight].concat(array_values)], 
     labels: { 
      format: { 
       y: d3.format('.2') 
      } 
     }, 
     type: 'scatter' 
    }, 
    point: { 
     r: 6 
    }, 
    legend: { 
     show: false 
    }, 
    grid: { 
     x: { 
      show: true 
     }, 
     y: { 
      show: true 
     } 
    }, 
    axis: { 
     x: { 
      padding: { 
       left: 0, 
       right: 0, 
      }, 
      label: { 
       text: 'Time [days]' 
      }, 
      type: 'timeseries', 
      tick: { 
       fit: false, 
       rotate: -75, 
       multiline: false, 
       format: function (e, d) { 
        return dateToString(e); 
       } 
      }, 
      height: 100 
     }, 
     y: { 
      padding: { 
       top: 0, 
       bottom: 0 
      }, 
      label: { 
       text: 'Weight [kg]', 
       position: 'outer', 
       min: minV - 10, 
       max: maxV + 10 
      }, 
      tick: { 
       format: function (e, d) { 
        return parseFloat(e).toFixed(2); 
       } 
      } 
     } 
    } 
}); 

chart.axis.range({ 
    min: { 
     x: timeStart, 
     y: minV - 10 
    }, 
    max: { 
     x: timeEnd, 
     y: maxV + 10 
    } 
}); 

Любой ключ/исправление более чем приветствуется. Спасибо!

+0

вы должны держать ось й в таймсериях ли? Можно ли присвоить имена меток по оси х отдельно? – JasTonAChair

+0

Если вы хотите сохранить соответствие между построенными данными и соответствующей меткой оси x: мне это не нужно, и, как правило, для таймсеров никому это не нужно. Поведение c3js для временных рядов кажется немного странным. – 2dvisio

ответ

7

c3js позволяет указать, какие тики появятся на оси х.

Под осью/х/тик Я добавил это -

values: [1413936000, 1414195200,1414454400,1414713600,1414972800,1415232000], 

я преобразовал свои даты в течение трех интервалов день с epoch converter.

Here's the reference for solution.

Я могу только предположить, если линии сетки не совпадают эти три дня клещей, то они толкали в новый день каждый энный клеща - значит, ваш вопрос. Кроме того, вы можете разместить gridlines manually.

Код для оси x.

 x: { 
      label: { 
       text: 'Time [days]' 
      }, 
      type: 'timeseries', 
      tick: { 
       values: [1413936000, 1414195200,1414454400,1414713600,1414972800,1415232000], 
       fit: false, 
       //count: 29, 
       rotate: -75, 
       multiline: false, 
       format: function (e, d) { 
        return dateToString(e); 
       } 
      }, 
      height: 100 
     }, 
0

Я также столкнулся с problem.Here, как я решил.Используйте ось x как категорию, а не временные ряды, и манипулируйте соответствующим тиковым форматом, чтобы выглядеть так, как если бы он был временным.

Я упростил проблему, чтобы сделать ее общей.

Проблема (нерегулярное интервал):

var chart = c3.generate({ 
 
      data: { 
 
       x: 'xtime', 
 
       xFormat: '%Y-%m-%d-%H-%M-%S', 
 
       columns: [ 
 
        ['xtime', '2015-05-20-05-10-13', '2015-05-20-05-11-13', '2015-05-21-06-10-13'], 
 
        ['value', 30, 50, 20] 
 
       ] 
 
      }, 
 
      size: { 
 
       height: 300, 
 
       width: 600 
 
      }, 
 
      axis: { 
 
       x: { 
 
        type: 'timeseries', 
 
        // type: 'category', 
 
        tick: { 
 
         // format: function(x) { 
 
         //  var dateSubs = this.api.categories()[x].split('-'), 
 
         //   newDate = new Date(dateSubs[0], dateSubs[1], dateSubs[2], dateSubs[3], dateSubs[4], dateSubs[5], 0); 
 
         // 
 
         //  return newDate.toLocaleString(); 
 
         // } 
 

 
         format: '%e-%b-%Y %H:%M' 
 
        } 
 
       } 
 
      } 
 
     });
<link href="https://rawgit.com/masayuki0812/c3/master/c3.css" rel="stylesheet"/> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script> 
 
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
 

 
<div id="chart"></div>

Решение:

var chart = c3.generate({ 
 
      data: { 
 
       x: 'xtime', 
 
       xFormat: '%Y-%m-%d-%H-%M-%S', 
 
       columns: [ 
 
        ['xtime', '2015-05-20-05-10-13', '2015-05-20-05-11-13', '2015-05-21-06-10-13'], 
 
        ['value', 30, 50, 20] 
 
       ] 
 
      }, 
 
      size: { 
 
       height: 300, 
 
       width: 600 
 
      }, 
 
      axis: { 
 
       x: { 
 
        // type: 'timeseries', 
 
        type: 'category', 
 
        tick: { 
 
         format: function(x) { 
 
          var dateSubs = this.api.categories()[x].split('-'), 
 
           newDate = new Date(dateSubs[0], dateSubs[1], dateSubs[2], dateSubs[3], dateSubs[4], dateSubs[5], 0); 
 
         
 
          return newDate.toLocaleString(); 
 
         } 
 

 
         // format: '%e-%b-%Y %H:%M' 
 
        } 
 
       } 
 
      } 
 
     });
<link href="https://rawgit.com/masayuki0812/c3/master/c3.css" rel="stylesheet"/> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script> 
 
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
 

 
<div id="chart"></div>

1

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

Решение, которое сработало лучше всего для меня, заключалось в том, чтобы исключить ярлыки из моего графика и вместо этого работать с графиком indexed. Оттуда я вручную отформатирую каждый индекс до нужной даты с помощью функции format.

Вот упрощенная версия коды оригинального плаката:

var d = (30 * 24 * 3600); // last 30 days 

var array_times = [1414540800, 1414627200, 1414627200 + d, 1414627200 + 2 * d, 1414627200 + 3 * d, 1456528117]; 
var array_values = [67, 66.22, 68, 68, 68, 77]; 

var labelWeight = 'weight in kg'; 

var window_period = (30 * 24 * 3600); // last 30 days 


function dateToString(e) { 
    var date = new Date(e * 1000); 
    return date.toDateString().substring(4); 
} 


var chart = c3.generate({ 
    bindto: '#chart', 
    data: { 
     columns: [ 
      // Notice that I removed the datetimes from here 
      [labelWeight].concat(array_values) 
     ], 
     type: 'area' 
    }, 
    point: { 
     r: 6 
    }, 
    legend: { 
     show: false 
    }, 
    grid: { 
     x: { 
      show: true 
     }, 
     y: { 
      show: true 
     } 
    }, 
    axis: { 
     x: { 
      label: { 
       text: 'Time [days]' 
      }, 
      type: 'indexed', 
      tick: { 
       rotate: 90, 
       // I reference array_times manually here to 
       // convert the index to a user-friendly label 
       format: function (index) { 
        return dateToString(array_times[index]); 
       } 
      } 
     } 
    } 
}); 

Работа скрипка: http://jsfiddle.net/uop61zLc/1/

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