Boost D3.js-diagram med SVG-gradienter

Sep 14, 2025
Hur

Nadieh Bremer kommer att vara på Generera london i september, där hon kommer att visa hur man tar Svg bortom bara former , med JavaScript, CSS och D3.js för att göra data visualiseringar ännu roligare och spännande. Boka din biljett nu !

D3.js har tagit över världen av interaktiv data visualisering. Ett enormt antal exempel kan hittas, var och en visar sin egen roliga och användbara twist på biblioteket. Du ser, D3 är inte ett kartläggningsbibliotek, men något mycket bättre. Det ger dig bara de grundläggande verktygen för att skapa data visualiseringar, och det gör det möjligt för dig att skapa praktiskt taget vad du kan tänka på. Även om vissa idéer kan ta mer tid än andra, kommer du där så småningom. Och denna frihet är exakt vad jag älskar om d3.

Vid kärnan är varje D3 visuell uppbyggd av SVG-element. Till exempel, för varje datapoint i ett scatterplot-diagram, för att skapa ett stapeldiagram, som en axel, parallellkoordinater eller lutningsdiagram, som etiketter och den extremt användbara för praktiskt taget allt annat. Dessutom är SVGs upplösningsoberoende, så ser bra ut på någon bildskärm eller zoomnivå.

Även om du bara använder SVGs för sina former, kan du skapa underbara visualiseringar. Men de kan göra mycket mer - tänk på SVG-filter till exempel. I den här handledningen tar vi ett djupt dyk i en specifik aspekt och tittar på några olika sätt det kan tillämpas för att lysa upp en visualisering. Låt mig presentera dig för SVG-gradienter!

Hitta alla filer du behöver för den här handledningen här .

Linjära gradienter

Ibland när jag skapar ett linjediagram med en enda linje känns det bara lite för tomt och kan gå vilse på den vita bakgrunden. För att få det att stå ut mer, lägger jag en ljusgradient under den med D3: s d3.svg.area Funktion, fylld med en SVG-gradient (se fig 1).

Jag vill att lutningen ska springa vertikalt från toppen (där den är samma färg som linjen men en ljusare nyans) till botten (där den ska bli vit eller transparent). Detta är det som är känt som en linjär gradient; något som ändrar färg längs en rak linje.

Figure 1: A smooth SVG gradient applied to an area chart that lies below the line chart

Figur 1: En slät SVG-gradient applicerad på ett områdesdiagram som ligger under linjediagrammet

Vi börjar med en SVG. Detta är den duk som vårt linjediagram kommer att dras. Vi skapar sedan en defs element på vilket vi kan lägga till a linjära element. Det är väldigt viktigt att ge gradienten ett unikt ID - vi kommer att använda det senare när vi behöver ge området under linjen fyllning.

 Var AreaGradient = SVG.Append ("defs")
.Append ("lineargradient")
.atr ("ID", "AreaGradient")
.atr ("x1", "0%"). ATT ("Y1", "0%")
.atr ("x2", "0%"). ATT ("Y2", "100%"); 

De sista två raderna i koden ovan definierar hur graden ska köras. Tänk på det som en osynlig linje: x1 och y1 är utgångspositionerna för den osynliga linjen och x2 och y2 Ange dess slutpunkt, för att ge gradientens riktning. Det är ofta lättast att definiera dessa i procent, även om det är möjligt att använda exakta pixelplatser. Som standard hänvisar platserna till det avgränsande rutan i det element som gradienten appliceras. Vi vill att gradienten ska springa vertikalt, så x1 och x2 bör vara densamma ( 0% är bra), y1 måste vara 0% och Y2 100% .

Nu kan vi definiera färgerna på gradienten. Minst två färger behövs för en gradient, men du kan använda så många som du vill. För varje färg i den gradient lägger du till en sluta element. Inom detta anger du skuggan med stoppa , och platsen (längs den osynliga linjen) där du vill att den här färgen ska vara ren (den exakta färgen) med offset .

Eventuellt kan vi också ställa in opaciteten hos varje färg med stoppa opacitet . Här gör jag skuggan lite lättare på toppen och helt transparent i botten.

AreaGradient.Append ("Stop")
.atr ("offset", "0%")
.atr ("Stop-Color", "# 21825C")
.attr ("stopp-opacitet", 0,6);
AreaGradient.Append ("Stop")
.attr ("offset", "80%")
.attr ("Stop-Color", "White")
.atr ("Stop-opacity", 0); 

Nu är den linjära gradienten inrättad, vi kan skapa ett områdesdiagram och fylla det med gradienten. För att göra detta, använd URL (# Gradient-ID) I fyllstilen, tillsammans med det unika ID som vi satte sig tidigare.

 SVG.Append ("Path")
.style ("fyll", "URL (#AreAgrad)")
.atr ("D", områdesfunktion (dataset)); 

Därefter rita linjen ovanpå detta område i diagrammet så att tittaren kan läsa resultat från din graf. I mitt diagram har jag också placerat cirklar för att betona placeringen av specifika datapunkter.

Don't miss Nadieh and other top web names at Generate London

Missa inte Nadieh och andra toppwebbnamn på Generera London

En jämn legend

Legender är mycket vanliga i data visualiseringar. När du använder färger för att representera en viss aspekt av dina data måste du förklara vad varje färg betyder. Det är här en legend kommer in.

I vissa diagram kommer du att använda färg för att diskriminera mellan diskreta fall (till exempel olika länder), i vilket fall färgerna ofta är alla väldigt olika. Du kan dock också använda färg för att ange ett kvantitativt värde.

Här representerar vi temperaturen utanför (se fig 2). Färgen ändras gradvis för att indikera att temperaturen går från låg till hög. För att visa detta i en legend ska vi skapa en lång rektangel och fylla den med en gradient som går från vänster till höger. Vi kan återanvända den gradient vi skapade för vårt linjediagram, men vänds med 90 grader (så x2 kör nu till 100% , hellre än y2 ). Även om det i allmänhet en regnbågspalett inte rekommenderas i datavisualisering, används människor för att se färgglada temperaturkartor, och jag har valt nio färger att använda i vårt exempel.

Figure 2: The gradient of different colours represents the temperature in a location, explained in a legend below

Figur 2: Gradienten i olika färger representerar temperaturen på en plats, förklaras i en legend nedanför

Istället för att skriva ut var och en sluta För att lägga till kan vi lägga alla färgerna i en dataset och använda D3: s nifty data steg för att göra processen snabbare. Med D3 är det möjligt att få tillgång till någon egenskap hos datasetet i de efterföljande kedjestegen med användning av en anonym funktion, vilket gör det möjligt för oss att ställa in färgen och offset på bara två linjer.

 SVG.Append ("defs")
.Append ("lineargradient")
.attr ("id", "legendgradientmulti")
.atr ("x1", "0%"). ATT ("Y1", "0%")
.attr ("x2", "100%"). ATT ("Y2", "0%")
.selektall ("stop")
.data([
{offset: "0%", färg: "# 2c7bb6"},
{Offset: "12,5%", Färg: "# 00A6CA"},
{Offset: "25%", Färg: "# 00ccbc"},
{Offset: "37,5%", Färg: "# 90eb9d"},
{Offset: "50%", Färg: "# ffff8c"},
{kompense: "62,5%", färg: "# f9d057"},
{Offset: "75%", Färg: "# f29e2e"},
{Offset: "87,5%", Färg: "# e76818"},
{Offset: "100%", Färg: "# d7191c"}])
.enter (). Lägg till ("stop")
.atr ("offset", funktion (d) {return d.offset;})
.atr ("Stop-color", funktion (d) {retur d.color;}); 

Liksom tidigare är det sista steget att skapa en rekt och fyll i detta med det unika gradient-ID.

 SVG.Append ("rect")
.attr ("x", 0) .ATTR ("Y", 0)
.atr ("Bredd", 500) .ATTR ("Höjd", 20)
.style ("fyll", "URL (#legendGradientmulti)"); 

Diagrammen som dessa legender går med återskapas efter det fantastiska arbetet med www.weather-radials.com Visar temperaturen i New York eller Peking 2015. Den genomsnittliga temperaturen varje dag indikeras av en färgad linje, och dessa linjer är anordnade att bilda ett cirkulärt diagram. Legenden nedan förklarar vad varje färg betyder. Ett diagram använder en gradient från en färg till en annan, och den andra fortskrider genom alla nio färger.

Databaserade gradienter

På ett sätt som liknar det föregående exemplet kan vi också skapa flera gradienter. Vi kunde göra en unik gradient för varje datapunkt, baserat på en viss aspekt av data. Jag använde detta tillvägagångssätt i en Exoplanet visualisering , där varje planet fick en gradient baserad på stellärklassen av stjärnan IT-banor. Jag använde en subtil sfär effekt för att ge intrycket vart tänds av stjärnan i mitten.

Figure 3: In this exoplanet visualisation, each planet has its own data-based gradient, creating the look of a sphere

Figur 3: I denna exoplanet visualisering har varje planet sin egen databaserade gradient, vilket skapar utseendet på en sfär

Så låt oss gå tillbaka till 90-talet och vända en samling av platta cirklar som representerar planeterna i vårt eget solsystem i 3D-ser sfärer med radiella gradienter (fig 4). Jag har skapat ett litet dataset som innehåller planetens namn och diameter. Var och en kommer generaliserad med en färg, som vi använder för att skapa en unik gradient för varje planet.

 Var Gradientradial = Svg.Append ("defs")
.selektall ("radialgradient")
.Data (planeter)
.Enter (). Lägg till ("radialgradient")
.atr ("ID", funktion (d) {return "gradient-" + d.planet;})
.attr ("cx", "15%")
.atr ("Cy", "50%")
.atr ("r", "85%"); 

Koden är något annorlunda här: I stället för att först lägga till ett gradientelement, bifogar vi nu planeter dataset och först efter stiga på Skapar vi ett gradientelement (i det här fallet radialgradient ). På detta sätt skapas en gradient för varje punkt i datasetet. Håll varje Points ID unikt genom att basera det på data. Indexet jag Vanligtvis fungerar, men här är planetnamnet säkrare. Detta säkerställer att vi kan komma åt rätt gradient senare.

En radiell gradient är något annorlunda än en linjär. Vi skapar det på ett liknande sätt som en SVG-cirkel: leverera gradientens centrum med avseende på de objekt som den kommer att appliceras med användning av cx och cykel . Dessa värden är standard till 50% , vilket är mitten av objektet.

Figure 4: Each planet's gradient has been set to make it look like a sphere. Here, the four giant planets are clearly visible

Figur 4: Varje planetens gradient har blivit inställd för att det ska se ut som en sfär. Här är de fyra jätte planeterna tydligt synliga

För att simulera utseendet på en stjärna som lyser på planeterna från ena sidan flyttar vi centrum av gradienten till vänster genom att ställa in cx till 15% . Gradientens radie (där ett gradientstopp av 100% bör sluta) indikeras av r . Det är också standard till 50% , men på grund av vårt cx Offset, det här är nu 85% Så fyller den hela cirkeln.

Vi kan använda planetdata för att lägga till färgstopparna. För att skapa utseendet på en sfär som skinns på, färgen på 0% bör vara lättare. Genom att använda d3.rgb (). ljusare (k) Jag behöver inte ange en separat färg, eftersom D3 kommer att göra den beräkningen för mig. Värdet k Definierar hur mycket lättare jag vill att färgen ska bli. På omkring 50% Jag satte den sanna färgen i datasetet. Vid kanten vill jag ha en färg som är lite mörkare, vilket ger utseendet på skuggan. Logiskt, det finns också en d3.rgb (). mörkare (k) som vi kan använda.

 Gradientradial.Append ("Stop")
.atr ("offset", "0%")
.atr ("Stop-color", funktion (d) {
returnera d3.rgb (d.color). Butter (1); });
Gradientradial.append ("Stop")
.atr ("offset", "50%")
.ATTR ("STOP-COLOR", funktion (d) {retur d.color;});
Gradientradial.append ("Stop")
.attr ("offset", "100%")
.atr ("Stop-color", funktion (d) {
returnera d3.rgb (d.color) .darker (2,5); }); 

Om du skulle inspektera HTML efter att ha kört detta, skulle det finnas åtta olika radiella gradienter närvarande. Sist, måste vi skapa åtta cirklar, ge dem en radie som definieras av data och fyll dem med rätt gradient.

 svg.selectall (". Planeter")
.Data (planeter)
.Enter (). Lägg till ("cirkel")
/ * Ställ in klassen, platsen och radieattributen ... * /
.style ("fyll", funktion (d) {
returnera "URL (# Gradient-" + D.Planet + ")"; }); 

Jag har också lagt till solen, som har sin egen radialgradient, men jag har lämnat cx , cykel och r med standardinställningen av 50% För att få det att se ut som solen är glödande från mitten utåt.

En ansvarsfriskrivning: Även om diametrarna för alla sfärer är korrekta i förhållande till varandra, är avstånden naturligtvis helt svåra. Och jag är ledsen att Saturnus inte har några ringar

Spelar med orienteringarna

Vi har nu utforskat hur man ställer in färgaspekter baserat på data, men det finns många fler möjligheter. Vi kan ställa in praktiskt taget allt baserat på data - även de orienteringar av varje gradient.

För att prova det här, låt oss göra ett D3-ackorddiagram som visar samarbetet mellan Avengers i Marvel Cinematic Universe (fig 5). De ackord som går mellan de sex avengersna är dimensionerade enligt antalet filmer där de båda visas. Vi ska fylla dessa ackord med en enkel linjär gradient, byte från en avgerens färg till en annan.

Ett ackord är vanligtvis inte exakt horisontellt eller vertikalt. Så vi måste ställa in X1, x2 , y1 och y2 värden baserade på platserna för varje avgerens yttre båge. Dessa data är inte i vår ursprungliga dataset, men efter att vi har levererat det till D3 d3.layout.chord Funktion, vi kommer tillbaka en ny dataset som innehåller start- och slutvinklarna i varje båge (som d.source.startangle och d.target.endangel ). Detta är den dataset vi levererar samtidigt som vi skapar gradienterna.

Figure 5 Each chord has its own unique gradient, where the orientations (and colour) are defined by the data

Figur 5 Varje ackord har sin egen unika gradient, där orienteringarna (och färg) definieras av data

Vi behöver veta pixelpositionerna för den osynliga linjen som går från ena änden av ett ackord till den andra. Dessa används sedan för att ge x1, .., y2 attribut för varje gradient. Vi kan tillämpa lite trigonometri med hjälp av ackorddiagrammets radie och platsen halvvägs längs varje avger båge för att komma tillbaka dessa positioner. Den fullständiga trigonometriska formeln har tagits bort från följande kod, men du hittar den i Github repo som följer med den här artikeln .

För att göra ett unikt ID för varje ackord skapar vi en strängkombination av Avengerens indexvärde i varje ände av ett ackord. D3 s d3.layout.chord ställer alltid en (av Avengers) till källa och den andra till mål , vilket gör ett unikt par. Senare, när vi ritar ackorden, kan vi använda samma teknik för att ringa rätt gradient.

 Var Grads = SVG.Append ("defs"). SelectAll ("LineArGradient")
.Data (ackord.chords ())
.Enter (). Lägg till ("lineargradient")
.atr ("ID", funktion (d) {return "gradientchord-" + d.source.
Index + "-" + d.target.index; })
.attr ("gradientunits", "userspaceonuse")
// pixelplatsen för ena änden av ett ackord
.attr ("x1", funktion (d, i) {returnera / * ... trigonometri baserad på
D.Source Värden ... * /; })
.atr ("y1", funktion (d, i) {returnera / * ... * /})
// pixelplatsen för den andra änden av ett ackord
.atr ("x2", funktion (d, i) {returnera / * ... * /})
.ATTR ("Y2", funktion (d, i) {returnera / * ... * /}); 

Eftersom varje avger definieras av sitt eget indexnummer kan vi göra en färgfunktion, färger , som returnerar varje avgerens färg per indexvärde. Detta gör det enkelt att hänvisa till rätt färg medan du lägger till de två färgstopparna.

 Grads.Append ("Stop")
.atr ("offset", "0%")
.attr ("Stop-Color", funktion (d) {Returfärgad färg (d.source.index);
});
Grads.Append ("Stop")
.attr ("offset", "100%")
.ATTR ("Stop-Color", Funktion (D) {Returfärgat (d.Target.index);
}); 

Allt som återstår är att ringa rätt gradient-ID när du ställer in ackordens fyllningsstil (med samma funktion som vi använde för att ställa in lutnings-ID).

Runda upp

Under den här handledningen har vi tittat på fyra olika sätt att använda SVG-gradienter i data visualiseringar, men det finns alltid fler saker du kan göra. Med gradient animationer kan du simulera ett flöde från en del av datavisualiseringen till en annan, till exempel.

Så nästa gång du utformar en data visualisering, låt din kreativitet springa fri. Med d3.js behöver du inte begränsas av det du tycker är gränserna för verktyget. Med lite out-of-the-box tänkande och ansträngning kan du göra de mest fantastiska sakerna.

Missa inte Nadiehs session, SVG bortom bara former, på Generera London, 21-23 september. Boka nu !

Denna artikel uppträdde ursprungligen i nätmagasin utgåva 280; köp det här !


Hur - Mest populära artiklar

4 steg för att använda variabla teckensnitt

Hur Sep 14, 2025

(Bildkredit: Framtida) Variabel typsnitt Aktivera teckensnittsdesigners för att definiera typvariationer inom själv..


Hur man skapar en Alexa-skicklighet för din webbplats

Hur Sep 14, 2025

Många av oss har nu någon form av röstassistent runt hemmet, oavsett om det är ett Amazon Echo, Apple Homepod eller ett Googl..


Skapa speciella utskriftsfinisher i InDesign

Hur Sep 14, 2025

Sida 1 av 4: Folieblockering Folieblockering ..


Hur man använder Adobe Capture CC

Hur Sep 14, 2025

Adobe Capture CC är en fantastisk app som gör att du kan hitta teckensnitt och färger helt enkelt genom att ta ett foto. Du kanske undrar vilka teckensnitt som har använts i din favoritma..


Hur man ritar med affinitetsfoto för iPad

Hur Sep 14, 2025

Affinitetsfoto för iPad är en bra bildredigering , men hur kostar Serifs app när det gäller att sk..


Hur smälter du ett 3D-objekt med tre.js

Hur Sep 14, 2025

Webben som vi vet det, förändras och utvecklas ständigt. Det vi fortfarande kan komma ihåg som ett enkelt och enkelt medium f..


Ålder ett fotografi i Photoshop CC

Hur Sep 14, 2025

Åldrande ett fotografi i Photoshop är en klassisk teknik som kan vända jämn en ho-hum, full färgbild till något slående. O..


Hur man bygger världar för biografen

Hur Sep 14, 2025

När du blir ombedd att göra en workshop om att skapa en fantasimiljö, trodde jag att det skulle vara roligt att hylla en av de..


Kategorier