Inici | Fonaments | Instal·lació | Afegir Elements | Encadenar Mètodes | Asociar Dades | Fent servir les Dades | Desplegar els divs | La funció data() | El primer SVG | Dibuixant SVG's | Tipus de dades | Fent un diagrama de barres | Fent un gràfic de dispersió | Escales | Eixos | Transicions |

Eixos

última actualització 30 de Desembre de 2012
traducció 29 de Maig de 2015

Ara que ja dominem l'ús de les escales de D3, tenim aquest gràfic de dispersió:

gràfic de dispersió, gran i escalat

Afegim l'eix horitzontal i el vertical , per poder treure'ns de sobre aquests horribles nombres vermells que trepitgen els nostres cercles.

Introducció als eixos

Com a les funcions scale(), els eixos de D3 són en realitat funcions, els pàrmetres de les quals has de definir. A diferència d'scales, quan es crida una funció axis(), aquesta no retorna un valor, però si que genera els elements visuals de l'eix, incloent línies, etiquetes i tics.

Recordeu que les funcions d'eix són específiques per a SVG, ja que generen elements SVG. A més, els eixos estan dissenyats per funcionar amb escales quantitatives (no per a ordinals).

Preparant un Eix

Fes serivr d3.svg.axis() per crear una funció axis() genèrica:

            
              var EixX = d3.svg.axis();
            
          

Com a mínim, cada eix necessita que li diguin quina scale() ha de fer servir. Aquí li passarem l'EscalaX del codi del gràfic de dispersió:

            
              EixX.scale(xScale);
            
          

També podem especificar a on han d'aparèixer les etiquetes amb relació a l'eix. El valor per defecte és bottom (a sota), és a dir, les etiquetes apareixeran sota la línia de l'eix. (Tot i que aquest és el valor per defecte, no fa cap mal especificar-lo explícitament.)

            
              EixX.orient("bottom");
            
          

Per descomptat, podem ser més concisos i encadenar tot això en una sola línia:

            
              var EixX = d3.svg.axis()
                            .scale(xScale)
                            .orient("bottom");
            
          

Finalment, per generar realment l'eix i inserir totes aquestes petites línies i etiquetes al nostre SVG, hem de call() la funció EixX .

Posarem el codi al final del nostre script, i així l'eix es genera després que els altres elements en el SVG: (recorda que svg no té layers, i per tant has de tenir en compte la superposició de les formes, per obtenir el resultat que busquis).

            
              svg.append("g")
                  .call(EixX);
            
          

La funció call() de D3 pren una selecció com a entrada i l'executa dins una altre funció , function() . Així que, en aquest cas, afegim un nou element de grup g per contenir tots els nostres elements d'eix. (El g no és estrictament necessari, però manté els elements organitzats i ens permet aplicar una classe per a tot el grup, que és el que farem d'aquí a uns instants.)

Aquest g es converteix en la selecció per la següent baula de la cadena. call() crida les funcions que es guarden a EixX , per tant el nostre eix es genera dins del nou grup g . El fragment de codi anterior és més agradable, i senzill que el està escrit a continuació, que és exactament equivalent:

            svg.append("g")
                      .call(d3.svg.axis()
                              .scale(EixX)
                              .orient("bottom"));
            
          

Ja veus podries posar tota la funció axis() dins la funció call(), però és més fàcil d'entendre pel nostre cervell primer definir les funcions i cridar-les després quan es necessiten.

en qualsevol cas, així és com es veu fins ara.

Simple, but ugly axis

Polint l'eix

Tècnicament, és un eix, però no és ni bonic ni útil. Per polir-el, primer li assignarem una classe d' eix per al nou g , i axií poder-el apuntar amb CSS:

            
              svg.append("g")
                .attr("class", "eix")  //Asignació de la classe "eix"
                .call(EixX);
          

A continuació, introduirem el nostre primer estil CCS a l'apartat <head> de la nostra pàgina:

            
              .axis path,
              .axis line {
                  fill: none;
                  stroke: black;
                  shape-rendering: crispEdges;
              }

              .axis text {
                  font-family: sans-serif;
                  font-size: 11px;
              }
            
          

La propietat shape-rendering és un atribut SVG, que es fa servir aquí per estar segurs que el nostre eix i les seves marques tenen el nombre de píxels exacte, i evitar que es vegin borrosos o amb difuminats estranys. Prou d'eixos borrosos!

Eix clar

Molt millor, però la part superior de l'eix no es veu, queda tapada. A part també el volem posar a la base del gràfic i no a la part de datl.

Podem transformar transform el grup sencer que forma l'eix portant el a la part de baix:

            
              svg.append("g")
                  .attr("class", "axis")
                  .attr("transform", "translate(0," + (h - padding) + ")")
                  .call(EixX);
            
          

Observa l'ús de (h - padding) , de manera que la vora superior del grup es defineix en h , l'alçada de tota la imatge, menys el valor de padding que hem creat abans.

Eix, bonic i polit

Molt millor! Aquí tens el codi de l'eix.

Comprova els intervals

Uns intervals molt petits et faran embogir, peró els de la lliberia D3 serveixen per a comunicar informació. Definir més intervals no vol dir necessariament que vagi més bé, a partir d'un cert nombre de intervals el gràfic queda massa atapeit. Fixa't que no hem definit quans intervals ha d'incloure l'eix, ni el seu valor. Sense instruccions prèvies, D3 ha auto examinat màgicament la nostra escala, xScale i ha decidit quans intervals hi posava i quin valor tindrien (cada 50, en aquest cas).

Tal com pot suspitar, pots definir qualsevol aspecte de l'eix, com ara el nombre aproximat d'intervals, amb el mètode ticks():

            
              var EixX = d3.svg.axis()
                            .scale(xScale)
                            .orient("bottom")
                            .ticks(5);  //Set rough # of ticks
            
          

Amb menys intervals

Aquí tens el codi

Hauràs notat probablement que, tot i que hem especifiat només cinc intervals, D3 ha pres la decisió de posar-ne set. D3 et dona suport, i ha descobert que incloent només 5 intervals, el valor que tindria per representar tot el domini d'entrada no serien tan clars com - en aquest cas, 0, 150, 300, 450, i 600. D3 intepreta que el valor que dones pels ticks() és una aproximació, un suggeriment, i anul·larà el teu suggeriment amb el que ell determina que són valors més polits i llegibles - en aquest cas, els intervals de 100 - fins i tot quan això requereixi incloure alguns intervals més o menys dels demanats.

Això és realment una característica brillant que augmenta l'escalabilitat del teu disseny; quan el conjunt de dades canvii, i el domini d'entrada s'expandeix o es contregui (nombres més grans o més petits ), D3 t'assegura que les etiquetes senyalitzadores seguiran essent clares i fàcils de llegir.

I l'eix Y?

És hora de posar-nos amb l'eix Y. Copiarem i ajustarem el codi que ja hem escrit per l' EixX, i l'afegirem cap a la part de dalt del nostre codi.

            
              //Defineix l'eix Y 
              var EixY = d3.svg.axis()
                           .scale(EscalaY)
                           .orient("left")
                           .ticks(5);
            
          

i això pro de l final:

            
            //Creem l'eix Y
            svg.append("g")
                .attr("class", "eix")
                .attr("transform", "translate(" + padding + ",0)")
               .call(EixY);
            
          

Fixa't que les etiquetes estan a l'esquerra left i que el grup g de l'EixY l'hem traslladat a la dreta amb un petit marge padding.

Initial Y axis

Això comença a semblar-se a alguna cosa real! Però les etiquetes de l' EixY queden tallades. Per donar-los més espai a l'esquerra, he augmentat el valor de padding de 20 a 30:

            
              var padding = 30;
            
          

Per descomptat, també es pot introduir per separat els marges padding de cada eix, fent servir variables com ara xPadding i yPpadding , per a un major control sobre el disseny.

Aquí tens el codi, i aquí com queda:

Gràfic de dipersió amb l'eix Y

últims retocs

Perque vegis que els nostres nous eixos són dinàmics i escalables, canviaré el conjunt de nombres fixos inicials , per uns d'aleatoris:

            
              //dades aleatòries. eixos dinàmics
              var dataset = [];
              var numDataPoints = 50;
              var xRange = Math.random() * 1000;
              var yRange = Math.random() * 1000;
              for (var i = 0; i < numDataPoints; i++) {
                  var newNumber1 = Math.round(Math.random() * xRange);
                  var newNumber2 = Math.round(Math.random() * yRange);
                  dataset.push([newNumber1, newNumber2]);
              }
            
          

Aquest codi inicialitza una matriu buida, crea un bucle de 50 repetincions, tria dos nombres aleatoris cada cop, i afegeix ("push") al final de la matriu del conjunt de dades la matriu amb el parell de valors aleatoris.

Gràfic de dispersió amb nombres aleatoris

Prova el codi aquí. Cada vegada que tornis a carregar la pàgina, obtindràs diferents valors de dades. Observa com els dos eixos s'escalen per encaixar amb els nous dominis, i els intervals i els valors de les seves etiquetes es trien en conseqüència.

Després d'haver fet el meu punt, crec que per fi podem treue aquestes horribles etiquetes vermelles, comentant les línies rellevants de codi:

Scatterplot with random data and no red labels

Gràfic de dispersió final!

Donant format a les etiquetes dels intervals

Una última cosa: Fins ara, hem estat treballant amb nombres enters - nombres enters - que estan molt bé i son fàcils. Però les dades són sovint més complexes, i en aquests casos, és possible que vulguis més control sobre el format de les etiquetes dels eixos. Posa tickFormat(), que li permet especificar com han de ser els formats dels seus números. Per exemple, és possible que vulgueu incloure 3 llocs després del punt decimal, o valors de visualització com percentatges, o tots dos.

En aquest cas, pots definir una nova funció de format de número. Aquest, per exemple, diu que els valors són percentatges amb un decimal de precisió. (Mira la referència per crear format a la llibreria D3 d3.format() per veure'n altres opcions.)

            
              var formatAsPercentage = d3.format(".1%");
            
          

I ja només qujeda, dir-li a la nostra funció EixX i EixY que la faci servir, per exmeple:

            
              EixX.tickFormat(formatAsPercentage);
            
          

Apunt per desenvolupadors: Em sembla més fàcil de provar aquestes funcions de format a la consola JavaScript. Per exemple, només cal obrir qualsevol pàgina que carrega D3, com el nostre gràfic de dispersió final, i escrigui la seva regla de format a la consola. Després provar un valor, com ho faria amb qualsevol altra funció:

Testant el format a la consola

Pots veure que el valor de 0.54321 es converteix en 54.3% quan es visualitza — perfecte!

Dona-li una oportunitat a aquest codi. Un format de percentatge no té sentit amb el conjunt de dades actual del nostre diagrama de dispersió, sinó és com un exercici. Pots intentar ajustar com es generen els números aleatoris, per, valors de nombres no sencers més apropiades, o experimentar amb la funció de format en si mateix.

Ves al següent capítol: Transicions