2013-07-09 16 views

risposta

41

ho finito con uno dei Lars Kotthoff's advices.

Ogni volta che I call(axis) Regolo anche le etichette di testo.
Qui è semplificato codice:

function renderAxis() { 
    axisContainer 
     .transition().duration(300) 
     .call(axis)     // draw the standart d3 axis 
     .call(adjustTextLabels);  // adjusts text labels on the axis 
} 

function adjustTextLabels(selection) { 
    selection.selectAll('.major text') 
     .attr('transform', 'translate(' + daysToPixels(1)/2 + ',0)'); 
} 

// calculate the width of the days in the timeScale 
function daysToPixels(days, timeScale) { 
    var d1 = new Date(); 
    timeScale || (timeScale = Global.timeScale); 
    return timeScale(d3.time.day.offset(d1, days)) - timeScale(d1); 
} 

Aggiornamento:
BTW, ecco un calendario demo che ho finito: http://bl.ocks.org/oluckyman/6199145

enter image description here

5

Non v'è alcun modo semplice (cioè built-in) di farlo, ma puoi ancora realizzarlo. Ci sono alcune opzioni Il più semplice è probabilmente quello di utilizzare tickFormat function per specificare un formato con un numero adeguato di spazi davanti/dopo i numeri. Questo però dovrebbe essere regolato manualmente per ciascuna applicazione.

In alternativa, è possibile selezionare gli elementi dell'etichetta dopo che sono stati disegnati e aggiungere un attributo transform appropriato che li sposta di conseguenza. Ancora una volta, questo dovrebbe essere sintonizzato a mano.

La terza opzione prevede due assi diversi, uno per i segni di graduazione e uno per le etichette. L'idea è che l'asse che fornisce le zecche non ha etichette e l'altra senza zecche. Dovresti impostare i valori di spunta in modo appropriato, ma almeno non dovrai indovinare l'offset corretto.

+0

il primo non avrebbe aiutato nel mio caso, perché l'asse è cartina. – oluckyman

+0

In tutti questi casi è necessario ripristinare i parametri appropriati dopo lo zoom. –

2

È possibile farlo utilizzando axis.tickSize(major[[,minor],end]) e .tickSubdivide(). Le zecche sono impostate per allineare con le zecche principali, ma se si imposta l'altezza di queste zecche su 0 e si imposta un'altezza per le zecche minori e si specifica che vi è un segno di spunta minore tra ogni coppia di zecche principali, terminerà con le etichette di graduazione tra i tick. Il tuo codice sarà simile a questo:

var myAxis = d3.svg.axis() 
    .ticks(15) 
    .tickSubdivide(1) 
    .tickSize(0, 6, 0); 

Nota che è necessario impostare una dimensione finale in modo esplicito. Se si forniscono solo due numeri, saranno interpretati come major e end e minor sarà di default a 0.

Ecco un fiddle.

+0

Bel trucco! Ma a causa di questo hack i dati saranno spostati e invece di "3" otterrai "3.5". Vedere l'immagine: http://i.stack.imgur.com/OmfDN.png – oluckyman

+0

Farei attenzione a non mettere un'etichetta in un posto diverso da quello che rappresenta quel valore. Come utente, suppongo che un segno di spunta tra due etichette rappresenti un valore tra le etichette. Avere rappresenta il numero su un lato di esso o l'altro crea ambiguità. Inoltre, d3 non ha un modo per farlo. – ckersch

+5

C'è un caso speciale: calendario. Nelle date del calendario e nei giorni feriali sono collocati tra le zecche. – oluckyman

0

faccio spesso questo impilando assi multipli, ciascuno con una personalizzazione .tickFormat().

Se sto mettendo etichette tra le date, io spesso fare qualcosa di simile:

@timeDaysAxisLabels = d3.svg.axis() 
    .scale(@timescale) 
    .orient('bottom') 
    .ticks(d3.time.hour.utc, 12) # I want ticks at noon, easiest to just get them ever 12 hours 
    .tickFormat((d) => 
     # only draw labels at noon, between the date boundaries 
     if d.getUTCHours() == 12 
      # draw the label! 
      formatter = d3.time.format.utc('%a %d %b') # "Mon 12 Apr" 
      return formatter(d) 
     else 
      # not noon, don't draw anything 
      return null) 
    .tickSize(0) 
    .tickPadding(30) 

Devo dire anche creare un asse indipendente senza le etichette a tutti, e un non-zero .tickSize() per disegnare effettivamente le zecche, ma questo blocco sopra posiziona le etichette delle date al centro della "colonna".

+0

Wow, perché tutto l'odio per questa risposta? È una tecnica solida. –

1

Già qualche buona risposta ma solo per aggiungerne un'altra. Notare l'uso di text-anchor.

Stessa idea: dopo la chiamata, selezionare il testo, riposizionare.

.call(xAxis)     
.selectAll(".tick text") 
.style("text-anchor", "start") 
.attr("x", axisTextAdjust) 
+1

Esattamente quello di cui avevo bisogno, grazie – James

0
 svg.append("g") 
      .attr("class", "axis axis-years") 
      .attr("transform", "translate(0," + (height + 1) + ")") 
      .call(xAxis) 
     .selectAll("text") 

    .attr("x", "-1.8em") 
    .attr("y", ".00em") 
    .attr("transform", function (d) { 
     return "rotate(-90)"}); 
Problemi correlati