2012-07-04 22 views
7

Attualmente sto lavorando sulla libreria d3.js.Io ho un grafico a linee usando Dynamic Line Graph Qui abbiamo l'opzione di disegnare la potenza lineare e il log. Ma il mio problema è che potrei avere alcuni valori zero nel mio set di dati e il log 0 non è definito, quindi il codice non è in grado di tracciarlo. Qui nel mio codice della scala set Ti piace questaCome evitare il log zero nel grafico usando d3.js

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

e questo è come viene usato

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

So che il suo un question.But strana c'è un modo con cui posso gestire log 0 valore in modo tale che se ho un valore zero singolo il resto di essi viene tracciato correttamente. Posso dare due domini ed intervallo nella stessa istruzione (per gestire il valore 0) se sì rispetto a come si collegherà all'asse y?

Grazie a qualsiasi aiuto sarà apprezzato.

risposta

12

Ho risolto il problema utilizzando la funzione clamp. Questo è il modo che ho cambiato il codice:

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

Se si dispone di un dominio che ha uno dei confini del dominio come scala 0 registro non funzionerà per voi. Anche la scala di registro fornisce una funzione tick() con un numero di tick non modificabile.

Il mio attuale compito è quello di visualizzare dati con domini arbitrari e intervalli su una tabella di dispersione in scala lineare, ma facoltativamente l'utente può passare alla scala logaritmica. Ciò include i domini problematici [0, n] e [n, 0].

Ecco una soluzione che mi è venuta in mente per gestire questi casi: Il problema può essere evitato se si utilizza una scala lineare per proiettare il nostro dominio su un intervallo arbitrario con limiti positivi. Scelgo [1,10] ma può prendere qualsiasi numero positivo. Dopo di ciò possiamo usare una scala di registro normale.

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; 

} 

Usage:

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 

mi serviva solo la gamma(), scala(), zecche() funzioni in modo ho incluso solo questi, ma non dovrebbe prendere più di 5 minuti di attuare tutte gli altri. Inoltre: nota che stavo usando i valori ticks() della scala lineare perché dovevo limitare il numero di tick e questo è più facile con la scala lineare.

EDIT: essere consapevoli A seconda di ciò che si sceglie come PROIEZIONE sarà distorcere la vostra scala logaritmica. L'intervallo più ampio che usi stria più la parte inferiore della tua scala.

Problemi correlati