Hand rulle diagram med D3 som du faktiskt vet vad du gör

0
26

Diagram! Min minst favorit ämne förutom Sociala Studier. Men du kommer inte komma långt i den här branschen innan någon vill att du ska göra ett diagram. Jag vet inte vad det är med människor och diagram, men tydligen kan vi inte ha en civilisation utan ett stapeldiagram som visar Maggie försäljning för förra månaden så med ALLA MEDEL — låt oss göra ett diagram.

Ja, jag vet att det inte är hur du kan visa denna information. Jag försöker göra en poäng här.

För att förbereda dig för att förestående “OMG jag kommer att behöva för att göra ett diagram som” existentiell kris, mycket som döden, vi gillar att låtsas aldrig kommer att hända, jag kommer att visa dig hur hand-rulla dina egna scatter plot diagram med D3.js. Denna artikel är tung på den kod sidan och din första blick på den färdiga koden kommer att leda till att din “kamp eller flykt” reaktion. Men om du kan få genom denna artikel, jag tror att du kommer att bli förvånad över hur väl du förstår D3 och hur säker du är på att du kan gå och göra lite andra diagram som du helst inte skulle göra.

Innan vi gör det, men det är viktigt att tala om VARFÖR du någonsin skulle vilja rulla dina egna diagram.

Bygga vs. Köpa

När du behöver diagram, kommer du sannolikt nå för något som kommer “out of the box.” Du skulle aldrig hand-rulla ett diagram. På samma sätt som du skulle aldrig sitta och slå dig på tummen med en hammare, det är ganska smärtsamt och det är mer produktiva sätt att använda din hammare. Diagram är ganska komplexa objekt i användargränssnittet. Det är inte som du är center-rikta lite text i ett div här. Bibliotek som Chart.js eller Kendo UI har färdiga diagram som du kan bara peka på dina data. Utvecklare har tillbringat tusentals timmar på att finslipa dessa diagram skulle Du aldrig någonsin kommer att bygga en av dessa själv.

Eller skulle du?

Kartläggning bibliotek är fantastiska, men de gör införa en viss mängd restriktioner på dig…och ibland är de faktiskt göra det svårare att göra även enkla saker. Som Peter Parker morfar sa innan han över-handlat hans döende scenen i Spiderman, “Med stor kartläggning bibliotek, kommer stora trade-off på flexibilitet.”

Toby aldrig borde ha varit Spiderman. FITE MIG.

Detta är exakt det scenario jag befann mig i när min kollega Jasmine Greenaway, och jag bestämde mig för att vi skulle kunna använda diagram för att lista ut vem @horse_js är. I fall du inte redan ett stort @horse_js fan, det är en parodi konto som människor citat ur sitt sammanhang. Det är extremt häftigt.

Vi drog varje tweet från @horse_js för de senaste två åren. Vi fastnat som i en Kosmos DB-databas och sedan skapat ett Azurblått Funktion endpoint att exponera data.

Och sedan, med en sjunkande känsla i magen när vi insåg att vi behövde ett diagram. Vi ville kunna se vad de data som såg ut som det skett över tid. Vi trodde att kunna se data visuellt i en tidsserieanalys kan hjälpa oss att identifiera några mönster eller få insikt om konto. Och faktiskt, det gjorde det.

Vi kartlagt alla twittrar som @horse_js har skrivit under de senaste två åren. När vi ser till att data i ett punktdiagram, det ser ut så här:

Se Pennan wYxYNd av Burke Holland (@burkeholland) på CodePen.

Som av en slump, detta är något vi kommer att bygga i denna artikel.

Varje tweet är visas med datum på x-axeln och tiden på dagen på y. Jag trodde att detta skulle vara lätt att göra med en kartläggning bibliotek, men alla de jag försökte egentligen inte utrustade för att hantera scenariot av ett datum i hela x-och en gång på y. Jag kunde inte hitta några exempel på att folk gör det på nätet. Jag bryter ny mark här? Är jag en data visualisering pionjär?

Förmodligen. Definitivt.

Så, låt oss ta en titt på hur vi kan bygga denna hisnande scatter plot med D3.

Komma igång med D3

Här är den sak om D3: det ser ganska hemskt. Jag vill bara få ut det så kan vi sluta låtsas som D3-kod är kul att titta på. Det är det inte. Det finns ingen skam i att säga det. Nu när vi har bjudit in som elefanten i rummet för att tea party, tillåt mig att insinuera att även om D3 koden ser ganska dåligt, det är faktiskt inte. Det är bara en del av det.

För att komma igång, vi behöver D3. Jag använder CDN har för D3 5 för dessa exempel. Jag är också med Nu att arbeta med datum, som vi kommer till senare.

https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js
https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js

D3 fungerar med SVG. Det är vad den gör. Det är i grunden gifter sig med SVG med data och ger några praktiska inbyggda mekanismer för visualisering — saker som axis. Eller Axees? Axlarna? Vad plural av “axel” är. Men för nu, vet bara att det är som jQuery för SVG.

Så, det första vi behöver är en SVG-element att arbeta med.

<svg id=”sjökort”></svg>

OK. Nu är vi redo att börja D3 ‘ ing vårt sätt att data visualisering vanära. Det första vi ska göra är att göra vår punktdiagram en klass. Vi vill göra den här saken så allmän som möjligt så att vi kan återanvända det med andra uppsättningar av data. Vi kommer att börja med en konstruktor som tar två parametrar. Den första kommer att vara den klass eller id för det element som vi ska jobba med (i vårt fall att det är, #diagrammet) och den andra är ett objekt som kommer att tillåta oss att gå i alla parametrar som kan variera från diagram-att-diagram (till exempel uppgifter, bredd, etc.).

klass ScatterPlot {
konstruktör(el, val) {
}
}

Diagrammet själva koden kommer att gå i en render funktion, vilket också kommer att kräva att de uppgifter som vi arbetar med för att vara godkänd.

klass ScatterPlot {
konstruktör(el, val) {
detta.render(alternativ.data);
}

render(data) {
}
}

Det första vi ska göra i vår render-metoden ligger en storlek värderingar och marginaler för våra diagram.

klass ScatterPlot {
konstruktör(el, val) {
detta.data = alternativ.data – | | [];
detta.bredd = alternativ.bredd || 500;
detta.höjd = alternativ.höjd || 400;

detta.render();
}

render() {
låt marginal = { top: 20, höger: 20, botten: 50, vänster: 60 };
låt height = detta.höjd || 400;
låt width = (.höjd || 400) – marginal.topp – marginal.botten;
låt data = detta.uppgifter.
}
}

Jag nämnde att D3 är som jQuery för SVG, och jag tror att analogt pinnar. Så du kan se vad jag menar, låt oss göra en enkel SVG-ritning med D3.

Till att börja med, du behöver för att välja det DOM element som SVG kommer att arbeta med. När du gör det, kan du börja lägga till saker och ställa sina attribut. D3, precis som jQuery, är byggt på konceptet av kedja, så att varje funktion som du kallar returnerar en instans av element som du kallade det. På detta sätt kan du hålla på att lägga till element och attribut tills korna kommer hem.

Till exempel, låt oss säga att vi ville rita en kvadrat. Med D3, kan vi dra en rektangel (SVG-det är en rect), att lägga till de nödvändiga attribut längs vägen.

Se Pennan zmdpJZ av Burke Holland (@burkeholland) på CodePen.

NU. Vid denna punkt kommer du att säga, “Men jag vet inte SVG.” Tja, som jag inte heller. Men jag vet hur Google och det är ingen brist på artiklar om hur man gör i stort sett allt i SVG.

Så, hur ska vi få från en rektangel till ett diagram? Det är där D3 blir så mycket mer än bara “jQuery för att rita.”

Första, låt oss skapa ett diagram. Vi börjar med en tom SVG-element i vår kod. Vi använder D3 för att välja den tomma svg-element (som heter #diagrammet) och definiera dess bredd och höjd samt marginaler.

// skapa diagrammet
detta.diagram = d3.välj(det här.el)
.attr(‘width’, bredd + marginal.höger + marginal.vänster)
.attr(‘höjd’, höjd + marginal.topp + marginal.botten);

Och här är vad det ser ut:

Se Pennan EdpOqy av Burke Holland (@burkeholland) på CodePen.

FANTASTISKT! Inget där. Om du öppnar dev verktyg, kommer du att se att det finns något där. Det är bara en tom något. Typ som att min själ.

Som diagrammet! Låt oss gå om att lägga vissa uppgifter i det. För att, som vi kommer att behöva för att definiera vår x-och y-axeln.

Det är ganska lätt i D3. Du kallar axisBottom metod. Här är jag också formatering skalstrecken med rätt datum format för att visa.

låt xAxis = d3.axisBottom(x).tickFormat(d3.timeFormat(‘%b%y’));

Jag är också passerar ett “x” – parametern till axisBottom metod. Vad är det? Det kallas en skala.

D3 skalor

D3 har något som kallas fjäll. Skalor är bara ett sätt att berätta D3 var du ska lägga dina data och D3 har en hel del olika typer av skalor. Den vanligaste typen skulle vara linjär som en skala av data från 1 till 10. Den innehåller också en skala bara för tidsserier — vilket är vad vi behöver för detta diagram. Vi kan använda scaleTime metod för att definiera en “skala” för vår x-axeln.

// ange x-axeln
låt minDateValue = d3.min(data, d => {
återgå nya Datum(ögonblick(d.created_at).format(‘MM-DD-ÅÅÅÅ’));
});

låt maxDateValue = d3.max(data, d => {
återgå nya Datum(ögonblick(d.created_at).format(‘MM-DD-ÅÅÅÅ’));
});

låt x = d3.scaleTime()
.domän([minDateValue, maxDateValue])
.utbud([0, width]);

låt xAxis = d3.axisBottom(x).tickFormat(d3.timeFormat(‘%b%y’));

D3 vågar använda vissa termer som är något skrämmande. Det finns två huvudsakliga begrepp för att förstå här: domäner och serier.

  • Domän: intervallet av möjliga värden i dina data set. I mitt fall, jag får den minsta datum från matrisen, och den maximala datum från matrisen. Alla andra värden i de uppgifter som faller mellan dessa två ändpunkter — så “endpoints” definiera min domän.
  • Utbud: Det intervall som används för att visa data. Med andra ord, hur utspritt vill du att din data ska vara? I vårt fall vill vi att det begränsas till bredden av diagrammet, så vi bara passera bredd som andra parameter. Om vi gått ett värde som, säg, 10000, data ut över 10 000 pixlar bred. Om vi passerat inget värde alls, det skulle dra alla data på toppen av sig alla på den vänstra sidan av diagrammet… som på följande bild.

Y-axeln är byggd på samma sätt. Bara för det, vi kommer att vara formatering våra data för tiden, inte datum.

// ange y-axeln
låt minTimeValue = new Date().setHours(0, 0, 0, 0);
låt maxTimeValue = new Date().setHours(23, 59, 59, 999);

låt y = d3.scaleTime()
.domän([minTimeValue, maxTimeValue])
.nice(d3.timeDay)
.utbud([höjd, 0]);

låt yAxis = d3.axisLeft(y).fästingar(24).tickFormat(d3.timeFormat(‘%H:%M”));

Den extra trevlig metod för samtal på y-skala berättar y-axeln för att formatera den här gången skala fint. Om vi inte har det, kommer det inte att ha en etikett för den översta kryssa på vänster sida eftersom det går bara till 11:59:59, snarare än hela vägen fram till midnatt. Det är en sarkasm, men vi gör inte skit här. Vi behöver etiketter på alla våra fästingar.

Nu är vi redo att dra vårt axeln i diagrammet. Kom ihåg att vår diagrammet har några marginaler på det. För att korrekt placera objekt på insidan av våra sjökort, vi kommer att skapa en grupp (g) del och som dess bredd och höjd. Då kan vi dra alla våra element i behållaren.

låt huvudsakliga = detta.diagrammet.lägga till (“g”)
.attr (“förvandla”, ” översätta(${marginal.vänster}, ${marginal.övre})`)
.attr(‘width’, bredd)
.attr(‘höjd’, height)
.attr(‘class’, ‘main’);

Vi ritar våra container, som står för marginal och att ange dess bredd och höjd. Ja. Jag vet. Det är tråkigt. Men så är det staten för att lägga ut saker i en webbläsare. När var sista gången du försökte horisontellt och vertikalt centrum innehållet i en div? Ja, inte så häftigt före Flexbox och CSS Nätet.

Nu kan vi dra vårt x-axeln:

main.diagrammet.lägga till (“g”)
.attr (“förvandla”, ” översätta(0, ${höjd})`)
.attr(‘class’, ‘main axel datum’)
.samtal(xAxis);

Vi gör en behållare element, och sedan “call” xAxis som vi definierade tidigare. D3 drar saker och ting börjar längst upp till vänster, så använder vi omvandla attribut för att kompensera för x-axeln från toppen så att det visas längst ned. Om vi inte gör det, vår diagrammet ser ut så här…

Genom att ange förändra, vi driva det till botten. Nu för y-axeln:

main.lägga till (“g”)
.attr(‘class’, ‘main axel datum’)
.samtal(yAxis);

Låt oss titta på all kod som vi har så långt, och sedan får vi se vad denna utgångar till tv.

klass ScatterPlot {
konstruktör(el, val) {
detta.el = el;

om (val) {
detta.data = alternativ.data – | | [];
detta.tooltip = alternativ.tooltip;
detta.pointClass = alternativ.pointClass || “;

detta.data = alternativ.data – | | [];
detta.bredd = alternativ.bredd || 500;
detta.höjd = alternativ.höjd || 400;

detta.render();
}
}

render() {
låt marginal = { top: 20, höger: 15, botten: 60, vänster: 60 };
låt height = detta.höjd || 400;
låt width = (.bredd || 500) – marginal.höger marginal.vänster;
låt data = detta.uppgifter.

// skapa diagrammet
låt diagram = d3.välj(det här.el)
.attr(‘width’, bredd + marginal.höger + marginal.vänster)
.attr(‘höjd’, höjd + marginal.topp + marginal.botten);

// ange x-axeln
låt minDateValue = d3.min(data, d => {
återgå nya Datum(ögonblick(d.created_at).format(‘MM-DD-ÅÅÅÅ’));
});

låt maxDateValue = d3.max(data, d => {
återgå nya Datum(ögonblick(d.created_at).format(‘MM-DD-ÅÅÅÅ’));
});

låt x = d3.scaleTime()
.domän([minDateValue, maxDateValue])
.utbud([0, width]);

låt xAxis = d3.axisBottom(x).tickFormat(d3.timeFormat(‘%b%y’));

// ange y-axeln
låt minTimeValue = new Date().setHours(0, 0, 0, 0);
låt maxTimeValue = new Date().setHours(23, 59, 59, 999);

låt y = d3.scaleTime()
.domän([minTimeValue, maxTimeValue])
.nice(d3.timeDay)
.utbud([höjd, 0]);

låt yAxis = d3.axisLeft(y).fästingar(24).tickFormat(d3.timeFormat(‘%H:%M”));

// definera vårt innehåll
låt huvudsakliga = diagrammet.lägga till (“g”)
.attr (“förvandla”, ” översätta(${marginal.vänster}, ${marginal.övre})`)
.attr(‘width’, bredd)
.attr(‘höjd’, height)
.attr(‘class’, ‘main’);

// rita x-axeln
main.lägga till (“g”)
.attr (“förvandla”, ” översätta(0, ${höjd})`)
.attr(‘class’, ‘main axel datum’)
.samtal(xAxis);

// rita y-axeln
main.lägga till (“g”)
.attr(‘class’, ‘main axel datum’)
.samtal(yAxis);
}
}

Se Pennan oaeybM av Burke Holland (@burkeholland) på CodePen.

Vi har fått ett diagram! Ring dina vänner! Ring dina föräldrar! OMÖJLIGT ÄR INGENTING!

Etiketter för kategoriaxel

Låt oss nu lägga till några diagram etiketter. Nu har du kanske har räknat ut att när det kommer till D3, du gör det mesta för hand. Lägga till etiketter för kategoriaxel är inte annorlunda. Alla vi kommer att göra är att lägga till en svg text-element anger du det värde och position. Det är allt.
​​
För x-axeln, kan vi lägga till texten etiketten och placera det använda översätta. Vi sätter det x-position till mitten (bredd / 2) i diagrammet. Då kan vi subtrahera den vänstra marginal för att se till att vi är centrerade under diagrammet. Jag är också med hjälp av en CSS-klass för axis-märkningen som en text-anchor: middle att se till att vår text är med ursprung från mitten av text element.
​​

// text label för x-axeln
diagrammet.lägga till(“text”)
.attr(“transform”,
“översätta(” + ((bredd/2) + marginal.vänster) + ” ,” +
(höjd + marginal.topp + marginal.längst ned) + “)”)
.attr(‘class’, ‘axel-label”)
.sms: a (Datum För Tweet”);

​​
Y-axeln är samma koncept — en text-element som vi manuellt läge. Denna är placerad med absoluta x-och y-attribut. Detta beror på att våra omvandla används för att rotera etiketten, så att vi använder x-och y-egenskaper för att positionera den.
​​
Kom ihåg: När du roterar ett element, x-och y-rotera med det. Det innebär att när text-element på sidan som det är här, y nu skjuter det åt vänster och höger och x skjuter det upp och ner. Förvirrad än? Det är OK, du är i gott sällskap.
​​

// text label för y-axeln
diagrammet.lägga till(“text”)
.attr(“förändra”, “rotera(-90)”)
.attr(“y”, 10)
.attr(“x”,0 – ((höjd / 2) + (marginal.topp + marginal.längst ner))
.attr(‘class’, ‘axel-label”)
.text(“Tid för Tweet – CST (-6)”);

​​
​​

Se Pennan oaeybM av Burke Holland (@burkeholland) på CodePen.

Nu, som sagt — det är en HEL del kod. Det är onekligen. Men det är inte super komplex kod. Det är som LEGO: LEGO block är enkelt, men du kan bygga ganska komplexa saker med dem. Vad jag försöker säga är att det är en mycket sofistikerad samverkande tegel system.

Nu har vi en tabell, är det dags att göra våra uppgifter.
​​

Dra datapunkter

Detta är ganska enkelt. Som vanligt kan vi skapa en grupp för att sätta alla våra cirklar. Då har vi en slinga på varje objekt i våra data och dra en SVG-cirkel. Vi har för att ställa in positionen för varje cirkel (cx och cy) baserat på aktuella data artikel datum och tid värde. Slutligen, vi satt sin radie (r), som styr hur stor cirkeln är.

låt cirklar = main.lägga till (“g”);

uppgifter.forEach(artikel => {
cirklar.append(‘svg:circle”)
.attr(‘class’, detta.pointClass)
.attr(‘cx’, d => {
tillbaka x(new Date(objekt.created_at));
})
.attr(‘cy’, d => {
låt idag = new Date();
låt tiden = new Date(objekt.created_at);
tillbaka y(i dag.setHours(tid.getHours(), tid.getMinutes(), tid.getSeconds(), tid.getMilliseconds()));
})
.attr (“r”, 5);
});

När vi satte cx och cy värden, vi använder skalan (x eller y) som vi definierade tidigare. Vi klarar att skala datum eller tid-värdet av de aktuella uppgifterna punkt och skala kommer att ge oss tillbaka den korrekta ställningen på diagrammet för denna artikel.

Och, min gode vän, vi har en riktig diagram med några riktiga data i det.

Se Pennan VEzdrR av Burke Holland (@burkeholland) på CodePen.

Slutligen, låt oss lägga till några animeringar till det här diagrammet. D3 har några trevliga lättnader funktioner som vi kan använda här. Vad vi gör är att definiera en övergång på var och en av våra cirklar. I grund och botten, allt som kommer efter övergången metod blir animerad. Eftersom D3 drar allt från överst till vänster, vi kan ställa in x-position först och sedan animera y. Resultatet är prickarna ser ut som de faller på plats. Vi kan använda D3 är tjusig easeBounce lättnader funktion för att göra dessa punkter studsa när de faller.

uppgifter.forEach(artikel => {
cirklar.append(‘svg:circle”)
.attr(‘class’, detta.pointClass)
.attr(‘cx’, d => {
tillbaka x(new Date(objekt.created_at));
})
.övergången()
.varaktighet(Matematik.våningen(Matematik.random() * (3000-2000) + 1000))
.lätthet(d3.easeBounce)
.attr(‘cy’, d => {
låt idag = new Date();
låt tiden = new Date(objekt.created_at);
tillbaka y(i dag.setHours(tid.getHours(), tid.getMinutes(), tid.getSeconds(), tid.getMilliseconds()));
})
.attr (“r”, 5);

OK, så en gång till, alla tillsammans nu…

klass ScatterPlot {
konstruktör(el, val) {
detta.el = el;
detta.data = alternativ.data – | | [];
detta.bredd = alternativ.bredd || 960;
detta.höjd = alternativ.höjd || 500;

detta.render();
}

render() {
låt marginal = { top: 20, höger: 20, botten: 50, vänster: 60 };
låt height = detta.höjd – marginal.nedre marginal.top;
låt width = detta.bredd – marginal.höger marginal.vänster;
låt data = detta.uppgifter.

// skapa diagrammet
låt diagram = d3.välj(det här.el)
.attr(‘width’, bredd + marginal.höger + marginal.vänster)
.attr(‘höjd’, höjd + marginal.topp + marginal.botten);

// ange x-axeln
låt minDateValue = d3.min(data, d => {
återgå nya Datum(ögonblick(d.created_at).format(‘MM-DD-ÅÅÅÅ’));
});

låt maxDateValue = d3.max(data, d => {
återgå nya Datum(ögonblick(d.created_at).format(‘MM-DD-ÅÅÅÅ’));
});

låt x = d3.scaleTime()
.domän([minDateValue, maxDateValue])
.utbud([0, width]);

låt xAxis = d3.axisBottom(x).tickFormat(d3.timeFormat(‘%b%y’));

// ange y-axeln
låt minTimeValue = new Date().setHours(0, 0, 0, 0);
låt maxTimeValue = new Date().setHours(23, 59, 59, 999);

låt y = d3.scaleTime()
.domän([minTimeValue, maxTimeValue])
.nice(d3.timeDay)
.utbud([höjd, 0]);

låt yAxis = d3.axisLeft(y).fästingar(24).tickFormat(d3.timeFormat(‘%H:%M”));

// definera vårt innehåll
låt huvudsakliga = diagrammet.lägga till (“g”)
.attr (“förvandla”, ” översätta(${marginal.vänster}, ${marginal.övre})`)
.attr(‘width’, bredd)
.attr(‘höjd’, height)
.attr(‘class’, ‘main’);

// rita x-axeln
main.lägga till (“g”)
.attr (“förvandla”, ” översätta(0, ${höjd})`)
.attr(‘class’, ‘main axel datum’)
.samtal(xAxis);

// rita y-axeln
main.lägga till (“g”)
.attr(‘class’, ‘main axel datum’)
.samtal(yAxis);

// text label för y-axeln
diagrammet.lägga till(“text”)
.attr(“förändra”, “rotera(-90)”)
.attr(“y”, 10)
.attr(“x”,0 – ((höjd / 2) + marginal.topp + marginal.längst ner)
.attr(‘class’, ‘axel-label”)
.text(“Tid för Tweet – CST (-6)”);

// rita data poäng
låt cirklar = main.lägga till (“g”);

uppgifter.forEach(artikel => {
cirklar.append(‘svg:circle”)
.attr(‘class’, detta.pointClass)
.attr(‘cx’, d => {
tillbaka x(new Date(objekt.created_at));
})
.övergången()
.varaktighet(Matematik.våningen(Matematik.random() * (3000-2000) + 1000))
.lätthet(d3.easeBounce)
.attr(‘cy’, d => {
låt idag = new Date();
låt tiden = new Date(objekt.created_at);
tillbaka y(i dag.setHours(tid.getHours(), tid.getMinutes(), tid.getSeconds(), tid.getMilliseconds()));
})
.attr (“r”, 5);
});
}
}

Vi kan nu ringa ett samtal för vissa uppgifter och göra detta diagram…

// hämta data
låt data = fetch(‘https://s3-us-west-2.amazonaws.com/s.cdpn.io/4548/time-series.json’).då(d => d.json()).sedan(data => {

// massage data lite för att få det i rätt format
låt horseData = data.karta(artikel => {
returnera varan.häst;
})

// skapa diagrammet
låt diagram = new ScatterPlot(‘#diagram’, {
data: horseData,
bredd: 960
});
});

Och här är hela grejen, komplett med ett samtal till vår Azure Funktion för att returnera data från Kosmos DB. Det är MASSOR av uppgifter, så ha tålamod medan vi tuggar upp hela din bandbredd.

Se Pennan GYvGep av Burke Holland (@burkeholland) på CodePen.

Om du har gjort det här långt, jag…ja, jag är imponerad. D3 är inte en lätt sak att komma in. Det är helt enkelt inte ut som det kommer att vara kul. MEN, nej tummen krossades här, och vi har nu fullständig kontroll av detta diagram. Vi kan göra vad vi vill med det.

Kolla in några av dessa ytterligare resurser för D3, och lycka till med ditt diagram. Du kan göra det! Eller så kan du inte. Hursomhelst, någon har för att göra ett diagram, och det kan lika gärna vara du.

För din data och API:

  • Komma igång med Kosmos DB
  • Komma Igång Med Azure Funktioner

Mer på D3:

  • Låt oss göra ett stapeldiagram
  • Enkel D3 verktygstips
  • Att bygga interaktiva stapeldiagram med D3