2012-07-04 14 views
7

Estoy trabajando actualmente en la biblioteca d3.js.Tengo un gráfico de líneas usando Dynamic Line Graph Aquí tenemos la opción de dibujar líneas lineales y log. Pero mi problema es que podría tener algunos valores cero en mi conjunto de datos y como log 0 no está definido, por lo que el código no puede trazarlo. Aquí en mi código de la escala establecida como estoCómo evitar el registro cero en el gráfico usando d3.js

y = d3.scale.log().domain([0.1, max_y _value]).range([h, 0]).nice(); 

y esta es la forma en que se utiliza

lineFunction = d3.svg.line() 
     .y(function(d) { 
      return y(d); 
     }); 

Sé que su question.But un curioso es que hay un camino por el cual puedo manejar registro 0 valor de modo que si tengo valor de cero único el resto de ellos se trazan correctamente. ¿Puedo dar dos dominios y rango en la misma instrucción (para manejar el valor de 0) si es así que cómo se unirá al eje y?

Gracias, cualquier ayuda será apreciada.

Respuesta

12

Resolví mi problema utilizando la función clamp. Esta es la forma en que he cambiado el código:

y = d3.scale.log().clamp(true).domain([0.1, max_y _value]).range([h, 0]).nice(); 
2

Si usted tiene un dominio que tiene uno de los límites del dominio como escala de 0 registro no va a funcionar para usted. También la escala de registro le proporciona una función de marcar() con una cantidad de marcas no configurable.

Mi tarea actual es mostrar datos con dominios arbitrarios y rangos en un gráfico de dispersión escalado lineal PERO, opcionalmente, el usuario puede cambiar a escala logarítmica. Esto incluye los dominios problemáticos [0, n] y [n, 0].

Aquí hay una solución que surgió para manejar estos casos: El problema se puede evitar si estamos usando una escala lineal para proyectar nuestro dominio a un rango arbitrario con límites positivos. Elijo [1,10] pero puede tomar cualquier número positivo. Después de eso, podemos usar una escala de registro normal.

d3.scale.genericLog = function() { 
    return GenericLog(); 
}; 
function GenericLog() { 
    var PROJECTION=[1,10]; 
    var linearScale, logScale; 

    linearScale=d3.scale.linear(); 
    linearScale.range(PROJECTION); 

    logScale=d3.scale.log(); 
    logScale.domain(PROJECTION); 

    function scale(x) { 
     return logScale(linearScale(x)); 
    } 
    scale.domain = function(x) { 
     if (!arguments.length) return linearScale.domain(); 
     linearScale.domain(x); 
     return scale; 
    }; 
    scale.range = function(x) { 
     if (!arguments.length) return logScale.range(); 
     logScale.range(x); 
     return scale; 
    }; 
    scale.ticks = function(m) { 
     return linearScale.ticks(m); 
    }; 
    return scale; 

} 

Uso:

var scale1 = d3.scale.genericLog().domain([0,1]).range([500,1000]); 
var scale2 = d3.scale.genericLog().domain([-10,0]).range([500,1000]); 
scale1(0) //500 
scale2(-10) //500 
scale2(0) //100 

sólo se necesitaba la gama(), scale(), garrapatas() funciones, así que sólo se incluyeron éstos pero no debería tardar más de 5 minutos para poner en práctica todos los demás. Además: tenga en cuenta que estaba usando los valores de ticks() de la escala lineal porque tuve que limitar el número de tics y eso es más fácil con la escala lineal.

EDIT: ser consciente Dependiendo de lo que elija como PROYECCIÓN distorsionará su escala logarítmica. El intervalo más amplio que use aumentará más la parte inferior de la escala.