2012-07-02 21 views
17

Tengo un conjunto de datos Estoy graficando con d3.js. El eje x representa el tiempo (en minutos). Me gustaría mostrar este eje en un formato hh:mm, y no puedo encontrar una manera de hacerlo limpiamente en d3.¿Cómo puedo crear un formateador de ejes personalizado para horas y minutos en d3.js?

Mi código eje se ve así:

svg.append('g') 
    .attr('class', 'x axis') 
    .attr('transform', 'translate(0,' + height + ')') 
    .call(d3.svg.axis() 
    .scale(x) 
    .orient('bottom')); 

que genera etiquetas en minutos que se parece a [100, 115, 130, 140], etc.

Mi solución actual es seleccionar los elementos text después de que hayan sido generados y anularlos con una función:

svg.selectAll('.x.axis text') 
    .text(function(d) { 
     d = d.toFixed(); 
     var hours = Math.floor(d/60); 
     var minutes = pad((d % 60), 2); 
     return hours + ":" + minutes; 
    }); 

Este eje de salidas ticks como [1:40, 1:55, 2:10], etc.

Pero esto parece janky y evita el uso de d3.format. ¿Hay una mejor manera de hacer estas etiquetas?

Respuesta

52

Si tiene tiempo absoluto, es probable que desee convertir sus datos x tener JavaScript Date objects en lugar de números simples, y luego desea utilizar d3.time.scale y d3.time.format. Un ejemplo de "hh: mm" formato para un eje sería:

d3.svg.axis() 
    .scale(x) 
    .orient("bottom") 
    .tickFormat(d3.time.format("%H:%M")); 

Y, de hecho, puede que no necesite especificar un formato de señal en absoluto; Dependiendo del dominio de su escala y el número de tics, el default time scale format podría ser suficiente para sus necesidades. Alternativamente, si desea un control completo, también puede especificar los intervalos de tic en la escala. Por ejemplo, la presencia de garrapatas cada quince minutos, se podría decir:

d3.svg.axis() 
    .scale(x) 
    .orient("bottom") 
    .ticks(d3.time.minutes, 15) 
    .tickFormat(d3.time.format("%H:%M")); 

Si tiene tiempo relativo, es decir duraciones, (y por lo tanto tienen números que representan minutos en lugar de fechas absolutas), puede dar formato a estos como fechas seleccionando una época arbitraria y convirtiendo sobre la marcha. De esa forma, puede dejar los datos en sí mismos como números. Por ejemplo:

var formatTime = d3.time.format("%H:%M"), 
    formatMinutes = function(d) { return formatTime(new Date(2012, 0, 1, 0, d)); }; 

Dado que solo se mostrarán los minutos y las horas, no importa qué época elija. Aquí hay un ejemplo usando esta técnica para dar formato a una distribución de las duraciones:

+0

supongo que debería haber mencionado, mi caso de uso es un histograma (con los objetos que representan el tiempo agrupadas). Como estoy bastante seguro de que esto establece una escala ordinal, no he podido hacer que esto funcione. Tal vez solo estoy mezclando conceptos incompatibles? Aquí está mi código (eje en la parte inferior): http://pastebin.com/Wkcexcgr – matthewsteele

+3

Edité mi respuesta y agregué un ejemplo que muestra cómo usar la segunda técnica junto con un histograma de duraciones. – mbostock

+2

Esto lo hizo. ¡Gracias por toda tu ayuda! Realmente sorprendido de lo que has construido. – matthewsteele

Cuestiones relacionadas