Tehdään Viivakaavio D3: ssa.js v. 5
on tullut aika tehostaa peliämme ja luoda viivakaavio tyhjästä. Eikä mikä tahansa viivakaavio: monisarjakaavio, johon mahtuu mikä tahansa rivimäärä. Sen lisäksi, että käsittelemme useita linjoja, työskentelemme aika-ja lineaarisilla asteikoilla, akseleilla ja etiketeillä – tai pikemminkin, että ne toimivat meille. On paljon tehtävää, joten ehdotan, että sammutat D3-palvelimesi ja ryhdytään hommiin.
Asiakirjavalmistelu
ensimmäisenä vaiheena on valmisteltava aineisto ja tiedostorakenne visualisointia varten. Luo line_chart.html, styles.css ja data.csv projektikansiossa ja kansoittaa ne pätkiä, jotka seuraavat. Tällä pääsemme alkuun.
liitä tämä rivin_piiriin.html-tiedosto. Koodi määrittelee svg-elementin meille, jotta voimme aloittaa piirtämisen heti. Olen myös luonut perusrakenne etukäteen, joten se on helpompi navigoida asiakirjan työstää sen tiettyjä osia.
jätä tyylit.CSS-asiakirja tyhjä toistaiseksi. Liitä seuraavat rivit dataksi.csv. Viivakaaviossa on useita sarjoja, jotka vastaavat sarakkeita A, B ja C.
date,A,B,C20-Jul-2019,10,20,1621-Jul-2019,11,22,1822-Jul-2019,13,19,2123-Jul-2019,11,17,2224-Jul-2019,15,16,2025-Jul-2019,16,19,1826-Jul-2019,19,21,1827-Jul-2019,22,25,1528-Jul-2019,18,24,1229-Jul-2019,14,20,1630-Jul-2019,14,18,1831-Jul-2019,16,18,2101-Aug-2019,15,20,2202-Aug-2019,14,21,19
tietojen valmistelu
ensimmäinen askel – ja ratkaiseva vaihe koko visualisoinnin kannalta-on lukea tiedot oikein. Olen käyttänyt usean sarjan esimerkki syystä: vaikka se on melko yksinkertainen piirtää yhden polun, käsittely useita rivejä (erityisesti määrittelemätön määrä niitä) vaatii hieman enemmän D3 hienovaraisuutta. Liitä seuraavat tiedot-osioon, lataa html-asiakirja uudelleen ja tarkista konsoliloki selaimessasi:
const timeConv = d3.timeParse("%d-%b-%Y");const dataset = d3.csv("data.csv");dataset.then(function(data) { const slices = data.columns.slice(1).map(function(id) { return { id: id, values: data.map(function(d){ return { date: timeConv(d.date), measurement: +d }; }) }; });console.log("Column headers", data.columns);console.log("Column headers without date", data.columns.slice(1));// returns the sliced datasetconsole.log("Slices",slices); // returns the first sliceconsole.log("First slice",slices);// returns the array in the first sliceconsole.log("A array",slices.values); // returns the date of the first row in the first sliceconsole.log("Date element",slices.values.date); // returns the array's lengthconsole.log("Array length",(slices.values).length);
Kerrataanpa muunnokset, joita kutsutaan tietoaineistollemme yksi kerrallaan: – data.sarakkeet palauttaa csv otsikot-data.sarake.slice (1) palauttaa csv otsikot ilman päivämäärä sarake (siivu alkaa sarakkeessa indeksoitu 1) – kartta () kutsuu funktion jokaisen elementin array (joka koostuu A, B, ja C) – soitetaan kukin näistä elementeistä ”slice” – kartta () määrittää sarakkeen nimi id Elementti kunkin siivu– sitten se määrittää arvot array kunkin siivu– huomaa, miten arvot Elementti herättää funktio. Tässä kartoitamme tietoja alkuperäisestä datajoukosta: array koostuu 2 sarakkeesta, päivämäärästä ja mittauksesta. Päivämäärä johdetaan ensimmäisestä sarakkeesta (ja muunnetaan päivämäärämuotoon), ja mittaus otetaan sarakkeesta, joka vastaa viipaletta id.At lopussa nämä muunnokset saamme 3 taulukot: A, B, ja C, jossa 2 sarakkeet kukin: päivämäärä ja mittaus. Tämä on hämmästyttävän joustava tapa pilkkoa tietoja: riippumatta siitä, kuinka monta saraketta siinä on! Kaikki on tehty niillä riveillä. Olen tulostanut konsoliin tietoja, joiden avulla voit tarkistaa pätkän.
skaalauksen valmistelu
kun tiedot on luettu kohdassa we need to configure the scaling mechanism. Tämä tehdään, jotta kaavio painettaisiin svg: n kiinteistöjen mukaisesti. Vaa ’ at muuttavat datan syötön (päivämäärämme ja arvomme) svg-tason koordinaateiksi. Liitä vaa ’ an osaan seuraavat viivat.
const xScale = d3.scaleTime().range();const yScale = d3.scaleLinear().rangeRound();xScale.domain(d3.extent(data, function(d){ return timeConv(d.date)}));yScale.domain();
piirrämme päivämäärät X-akselilla ja arvot y-akselilla. D3 tarjoaa scaleTime () – menetelmän skaalauspäiville ja scaleLinear () – menetelmän jatkuville arvoille. Ensin päätetään asteikon vaihteluväli: mihin tuloarvot pitäisi kääntää. Tällöin venytämme data-arvot 0: sta svg: n leveyteen ja numeeriset arvot svg: n korkeudesta 0: een. Toisena vaiheena määrittelemme syöttötietoalueen. Toimialue koostuu kaikista määritellyn vähimmäis-ja enimmäisarvon välisistä arvoista, jotka tietojoukko voi ottaa. Sen sijaan manuaalisesti etsiä näitä arvoja, kuljemme sen läpi rakennettu D3 toiminnot: – d3.laajuus () palauttaa array minimi ja maksimi arvo (luonnollisessa järjestyksessä) – tämä toimii täydellisesti meidän päivämäärä asetettu– d3.max () Palauttaa matriisin enimmäisarvon. Huomaa, miten tässä esimerkissä ensin poimia maksimiarvo kustakin array sitten valita enintään kaikki kolme. Lisäsin myös 4 maksimiarvoon puhtaasti subjektiivisista esteettisistä syistä: halusin hieman tilaa kuvaajan yläpuolelle.
vaa ’ at on nyt perustettu. Jos sinulla ei ole tarpeeksi asteikkoja ja haluat nähdä lisää esimerkkejä, tutustu edelliseen opetusohjelmaani.
hyvin konfiguroitu asteikko mahdollistaa arvojen piirtämisen svg: llä. Joka kerta, kun herätämme tietoaineiston, meidän on vain kutsuttava sitä sopivalla mittakaavalla.
kirveet
riittää rupattelu – piirretään jo jotain! Akselit ovat hyvä lähtökohta: oikein piirrettynä ne vakuuttavat, että tieto on luettu odotetusti ja että se skaalautuu niin hienosti kuin olemme kuvitelleet.
liitä tämä akseleihin Valmistusosan alle:
const yaxis = d3.axisLeft().scale(yScale); const xaxis = d3.axisBottom().scale(xScale);
ja tämä akselit alla piirustus osassa:
svg.append("g") .attr("class", "axis") .attr("transform", "translate(0," + height + ")") .call(xaxis);svg.append("g") .attr("class", "axis") .call(yaxis);
ja niin yksinkertaista kuin se on, olemme piirtäneet X-ja y-akselit!
tosin kirveet eivät ole maailman tyylikkäimpiä (nättejä kirveitä on olemassa), mutta ne ovat täällä! On joitakin muita parannuksia voimme hakea tehdä niistä ystävällisempi lukijalle.
katsotaan ensin x-akselia: päivämäärissä on jotain hassua. Vasemmalta lukien saamme ”la 20”, ”heinä 21”, ”ma 22”, ja jossain vaiheessa pääsemme vain ”Elokuu”. Tuntuu, että kuukaudet ja päivät ovat tulleet niskuroivassa variaatioiden sekoituksessa. Meidän täytyy lopettaa tämä freestyle, ja tällä tarkoitan, että meidän pitäisi päättää, minkä päivämäärän formaatin haluamme tulostaa näytölle. D3.axis () – menetelmän avulla voimme säätää kaikenlaisia asioita punkeille-niiden määrä, pisteiden väli, näyttömuoto jne. Määritetään joitakin niistä molemmille akseleille.
korvaa Valmisteluosassa oleva akselimääritelmä seuraavalla pätkällä ja päivitä visualisointi:
const yaxis = d3.axisLeft() .ticks((slices.values).length) .scale(yScale);const xaxis = d3.axisBottom() .ticks(d3.timeDay.every(1)) .tickFormat(d3.timeFormat('%b %d')) .scale(xScale);
yllä oleva koodi määrittää joukon rasteja y-akselille (14 tai niin monta kuin on array-elementtejä / csv-rivejä). X-akselin tapauksessa rasti näkyy päivän rakeisuudella, joka päivä. Se on saavutettu asettamalla rasti ominaisuus D3.timeDay.joka (1). Näytettyjen päivämäärien muoto näyttää päivän ja lyhennetyn kuukauden jokaisen rastin osalta. Näiden muutosten jälkeen päädymme hieman parempiin akseleihin:
tottelemattomat päivämäärät eivät ole enää ongelma!
jotta se olisi vielä parempi (onko se edes mahdollista!!!) voimme lisätä Y-akseliin merkinnän, joka osoittaa, mitä arvot tarkoittavat. Vaikka päivämäärät ovat itsestään selviä, numerot eivät itsessään sisällä mitään tietoa. Lisää etiketti (kutsu sitä miksi haluat – menin taajuus) liittämällä seuraavat Y-akselin piirustus:
//this you hadsvg.append("g") .attr("class", "axis") .call(yaxis)//this you append .append("text") .attr("transform", "rotate(-90)") .attr("dy", ".75em") .attr("y", 6) .style("text-anchor", "end") .text("Frequency");
(etiketille ei ole asetettu tyyliä, joten se ei näy kuvaajassa-mutta uskokaa minua ja Google Chromen kehittäjätyökaluja, se on siellä)
lopuksi parannetaan akselien ulkonäköä. Parannuksella tarkoitan: aseta jokaisen elementin värit, leveydet ja renderöinti ja päätä käytettävä fontti. Liitä seuraavat CSS-tiedostoon ja voit vapaasti tehdä omia tyylipäätöksiä:
/* AXES *//* ticks */.axis line{stroke: #706f6f;stroke-width: 0.5;shape-rendering: crispEdges;}/* axis contour */.axis path {stroke: #706f6f;stroke-width: 0.7;shape-rendering: crispEdges;}/* axis text */.axis text {fill: #2b2929;font-family: Georgia;font-size: 120%;}
punkit ovat hallinnassa .line osa akselin, kun taas todellinen akseli on asetettu kanssa .polkuelementti. Akselit näyttävät teräviltä (kirjoittajan nöyrä mielipide) ja valmiina toivottamaan tervetulleeksi joitakin tietoja:
pitemmittä puheitta, Let ’ s plot the chart!
Viivakaavio
rivit ovat pääosin d3.polut (), jotka yhdistävät joukon (x, y) koordinaatteja 2D-tasolla. Muodostaaksesi rivin sinun täytyy kertoa sille, mistä sen X-ja y-koordinaatit löytyvät, ja sitten liittää se svg: hen. Liitä seuraavat pätkät aiemmin luotuihin paikkamerkintöihin ja tarkastellaan koodia yhdessä.
tämän pitäisi päästä linjoihin Vähän Valmistusosion alla:
const line = d3.line() .x(function(d) { return xScale(d.date); }) .y(function(d) { return yScale(d.measurement); });
tässä pätkässä kutsumme line constructor, d3.viiva (), joka käyttää kahta varustetta: X vaakatason arvoille ja y pystyakselille. Täällä me yksinkertaisesti viitata kaikkein rakeinen arvot meidän array, päivämäärä ja mittaus (tämä ei ole aika huolehtia sisäkkäinen csv rakenne). Kun se on valmis, liitä seuraavat viivat alla piirustus-osassa:
const lines = svg.selectAll("lines") .data(slices) .enter() .append("g"); lines.append("path") .attr("d", function(d) { return line(d.values); });
tämä vaatii jonkin selityksen. Muuttuva viivat valitsee tunnistamattoman määrän viivoja svg: stä – ja kertoo heti D3: lle, että rivejä on 3 osoittamalla rivejä (viivat A, B ja C). Sitten se liittää jokaiseen niistä g-elementin: ryhmittelyelementin, joka helpottaa elämäämme aikanaan. G-Elementti kerää kaiken, mikä liittyy tiettyyn kaaviosarjaan (eli rivistössä olevaan viipaleeseen): viivan (joka esitetään edellä polkuna), sen datapisteet, joiden yli voimme leijua, ja sarjan merkinnät.
ensimmäisenä riveihin (jotka ovat itse asiassa 3 tyhjää g-astiaa) liitetään itse karttaviivoja. Kutsumme sitä D3: ksi.viiva () konstruktori dataan piirtämään polun. Katso, miten ensin pitää päästä käsiksi jokaisen siivun alla oleviin arvoihin. Tämä siirtyy sitten rakentajalle, joka vetää päivämäärät ja mittaukset tarpeen mukaan.
kun muutokset on tallennettu, visualisointi päivittyy tähän:
Okei, tämä ei ole täydellinen, mutta uskokaa minua, me ollaan pääsemässä sinne! Let ’ s soveltaa joitakin esteettisiä korjauksia kaavion ja tarkkailla, miten se muotoutuu. Lisää seuraavat tyylit.css:
/* LINE CHART */path {fill: none;stroke: #ed3700;}
täytön on oltava nolla, jotta muodot näkyvät viivoina. Päivitä kuvaaja:
Mikä erottaa viivakaavion kaaviossa yhteen liimatuista viivoista? Kyky erottaa sarjat toisistaan. Tällä hetkellä meillä on vain edellinen.
alkajaisiksi on tehtävä ero koodin rivien välillä. Lisätään tunnus jokaiseen riviluokkaan-lisää seuraavat rivit Valmistusosan LINJAOSAAN:
let id = 0;const ids = function () { return "line-"+id++;}
tämä pieni koodinpätkä luo laskurin, jonka avulla voimme Automaattisesti määrittää rivitunnuksen jokaiselle lisätylle riville. Katsotaanpa viittaus laskuri luokan omaisuutta polkuja. Säädä koodi LINES-osiossa lisätäksesi luokan ominaisuuden:
const lines = svg.selectAll("lines") .data(slices) .enter() .append("g"); lines.append("path") .attr("class", ids) .attr("d", function(d) { return line(d.values); });
ja maagisesti jokainen polku saa oman luokkansa!
jäljellä on vain viittaaminen näihin luokkiin css: ssä ja antaa jokaiselle suoralle oma ainutlaatuinen luonteensa. Muuta css: n Viivakaavio-osaa sanomaan:
/* LINE CHART */path.line-0 {fill: none;stroke: #ed3700;}path.line-1 {fill: none;stroke: #2b2929;stroke-dasharray: 2;}path.line-2 {fill: none;stroke: #9c9c9c;stroke-dasharray: 6;}
huomaa, että en muuta vain väriä, vaan myös jokaisen viivan iskua. Muista, että noin 10% kaikista ihmisistä kärsii jonkinasteisesta värisokeudesta ja kaiken oikeudenmukaisuuden nimissä värien erottaminen toisistaan voi olla hankalaa kenelle tahansa meistä. Värit vain sulautuvat yhteen, jos tietosarjoja on liikaa ja niiden värisävy näkyy eri tavalla jokaisessa näytössä.
kun muutokset on tehty, rivit erotetaan selvästi toisistaan alla olevassa graafisessa muodossa:
nyt sarjat ovat eriytyneet, mutta on silti mahdotonta sanoa, mikä on kumpi, ellei ole opetellut ulkoa taustalla olevaa tietoa ja omannut aika sairasta visuaalista mielikuvitusta, jolloin ihmettelen, miksi ylipäätään tarvittiin kuvaajaa. Auttaaksemme suurinta osaa meistä sarjan tunnustamisessa ehdotan, että liitämme sarjan nimen kaavion oikeaan laitaan. Lisää rivien piirto-osaan seuraava:
lines.append("text") .attr("class","serie_label") .datum(function(d) { return { id: d.id, value: d.values}; }) .attr("transform", function(d) { return "translate(" + (xScale(d.value.date) + 10) + "," + (yScale(d.value.measurement) + 5 ) + ")";}) .attr("x", 5) .text(function(d) { return ("Serie ") + d.id; });
katkelma paikallistaa jokaisen rivin lopun ja liittää siihen tekstielementin. Teksti painetaan rivistä riippuen Serie A: ksi, Serie B: ksi tai Serie C: ksi. Lisää seuraavat CSS-asiakirjaan säätää sarjan tarroja:
.serie_label {fill: #2b2929;font-family: Georgia;font-size: 80%;}
etiketit ovat liitteenä! Hyviä aikoja.
voimme kaikki olla samaa mieltä tästä on yksi komea viivakaavio! Olen liittänyt koko koodin alla. Muista tarkistaa opetusohjelman toinen osa, joka esittelee kaksi skenaariota interaktiivisuuden lisäämisestä kaavioon.
Seuraa minua Twitterissä saadaksesi lisää datatieteellisyyttä / datan visualisointiprojekteja!
Koodinäytteet
line_chart.html:
styles.css:
/* AXES *//* ticks */.axis line{stroke: #706f6f;stroke-width: 0.5;shape-rendering: crispEdges;}/* axis contour */.axis path {stroke: #706f6f;stroke-width: 0.7;shape-rendering: crispEdges;}/* axis text */.axis text {fill: #2b2929;font-family: Georgia;font-size: 120%;}/* LINE CHART */path.line-0 { fill: none; stroke: #ed3700;}path.line-1 { fill: none; stroke: #2b2929; stroke-dasharray: 2;}path.line-2 { fill: none; stroke: #9c9c9c; stroke-dasharray: 6;}.serie_label { fill: #2b2929; font-family: Georgia; font-size: 80%;}
data.csv: