d3.js - piechart - ¿Cómo puedo evitar que las marcas se repitan cuando tengo un número pequeño de fechas en un gráfico nvd3?
nvd3 piechart (2)
El problema no está relacionado con el tamaño de la pantalla, ya que podría aparecer también en casos como este: solo tienes 3 días para mostrar y en lugar de 3 marcas obtendrás 6 o 10 o lo que sea (en realidad ese es el caso en el que estás si mira tu jsfiddle). Es cierto que nvd3 usa algo así para establecer las dimensiones de los ticks (eche un vistazo a 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);
Hay varias soluciones a este problema:
usted implementa su propio componente de eje y reemplaza el eje de nvd3
usted puede modificar el componente de eje del nvd3 directamente y agregar algunas configuraciones que luego serían utilizadas específicamente para este escenario que está describiendo (notará que como es nvd3 es altamente personalizable).
Hack: utiliza los propios tickValues () de d3 y le pasa una matriz con las fechas que desea tener en la pantalla (ejemplo: primera fecha, última fecha y varias fechas intermedias calculadas por su algoritmo). Consulte la documentación de d3: https://github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickValues . Dependiendo del caso (qué eje quieres modificar y qué gráfico) no solo tienes que comentar el código que te pegué y agregar tu algoritmo para establecer los tickValues al componente del gráfico (lineChart por ejemplo) sino que también debes agregar un colocador para tickValues y sobrescribe los valores con sus valores.
Al eje x le gusta repetir fechas cuando hay un número limitado de fechas. Por favor, mira este violín:
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''
}
];
}`
Si su pantalla es lo suficientemente ancha verá fechas repetidas. Si mire la ventana, el problema desaparece.
Una respuesta tardía, pero podría ser útil para otros. Utilizo una solución alternativa para eliminar los tics duplicados, manteniendo un conjunto de ticks ya aplicados y el especificador de formato múltiple de 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 );
Este truco se puede modificar para cualquier otro tipo de formato de marca.