Scalable Vector Graphics

Jeg har nå laget mitt første SVG-diagram! Hvis man ikke regner med et enkelt kakediagram jeg har tegnet opp tidligere...

Scalable Vector Graphics, eller SVG, er et XML-basert språk, noe lignende HTML, som kan brukes for å tegne opp grafikk, som for eksempel diagrammer.

SVG er vektorgrafikk, i likhet med for eksempel flash og PDF, som gjør at det kan skaleres opp (zoomes inn) i det «uendelige» uten at kvaliteten forringes. Dette er i motsetning til rene bildefiler, slik som JPEG, GIF eller PNG.

I likhet med masse annen funksjonalitet som er i ferd med å bli støttet i flere og flere nettlesere (f. eks. HTML5) har SVG tidligere ikke stått så sterkt. I dag støtter alle moderne browsere SVG i en eller annen form.

Og da er altså tiden inne for å lære seg hvordan dette fungerer.

Og SVG viser seg å være overraskende enkelt å forstå når man allerede kan HTML. Problemet er bare at man må holde tunga VELDIG rett i munnen når man jobber med det!

Norges riksvåpen

Norges riksvåpen

Mange flagg, kommunevåpen, bysegl og lignende på Wikipedia har blitt laget i SVG-format, og stadig flere blir konvertert til dette formatet fortløpende.

Et eksempel er Norges riksvåpen.

Dette «bildet», som har relativt mange detaljer, er altså bygget opp av mer eller mindre leselig kode.

For å se denne koden kan du åpne selve SVG-filen i nettleseren din (jeg forutsetter at du har en nettleser som kan vise SVG): Coat_of_Arms_of_Norway.svg

Deretter er det bare å høyreklikke og velge «Vis kilde», «Show source» eller hvilket begrep din nettleser måtte bruke.

Akkurat dette bildet er laget i programmet Inkscape, som spytter ut ferdig vektorbaserte bilder. Man kan selvfølgelig kode det «for hånd» også, men det vil være en veldig tidkrevende og komplisert oppgave.

Skalering

Som nevnt innledningsvis er SVG vektorgrafikk. Det betyr at alt innhold er basert på kode som sier hvor og hvordan de forskjellige tingene skal være plassert (i forhold til hverandre), i motsetning til rastergrafikk som for eksempel JPEG hvor størrelsen er forhåndsdefinert og selve filen sier hvilke farger som skal være på hvilken piksel.

Nedenfor forsøker jeg å illustrere dette med et utsnitt av riksvåpenet. Til venstre har jeg zoomet inn 400 % på våpenet vist som et PNG-bilde, mens til høyre har jeg samme utsnitt og zoom vist som SVG-bilde:

svg-skalering.png
(Innrømmelse: Faktisk er begge disse to bildene vist som ett PNG-bilde her på bloggen...)

Som du kan se kommer det tydelig frem at SVG-bildet er like klart og tydelig ved høy zoom, mens PNG-bildet blir veldig kornete.

Det samme eksempelet gjelder for flashfiler, men her kan det gjerne være en kombinasjon av vektor- og rastergrafikk. For eksempel er gjerne et foto som blir vist i en flashannonse rastergrafikk, mens logo og tekst er vektorgrafikk. I enkelte flashannonser kan du høyreklikke og velge «Zoom in» for å se dette i praksis.

Nedenfor er et utsnitt av en flashannonse:

ball1.png

Hvis vi zoomer inn på et lite område av denne annonsen kan vi tydelig se at skriften er vektorgrafikk, mens bildet av fotballen er rastergrafikk:

ball2.png

Lag din egen SVG

Denne enkle, og noen vil kanskje si stygge, grafikken består av et rektangel med avrundede kanter og en strek:

Beklager, nettleseren din støtter ikke SVG

Koden som ligger til grunn for denne grafikken er som følger:

<svg width="560" height="170">
<rect x="10" y="10" rx="30" ry="30" width="540" height="150" style="fill: #6f7a86; stroke:black; stroke-width: 5;" />
<line x1="50" y1="25" x2="400" y2="120" style="stroke: red; stroke-width: 10" />
Beklager, nettleseren din støtter ikke SVG
</svg>

Rektangelet har x- og y-koordinatene som egne attributter, og origo er alltid øverst til venstre. Så hvis x=10 og y=10 betyr det 10 piksler ut fra venstre kant og 10 piksler ned fra øvre kant.

Det samme gjelder for linjen, men her har vi to sett med koordinater; x1 og y1 for koordinatene hvor linjen starter og x2 og y2 for koordinatene hvor linjen slutter.

I tillegg har rektangelet attributtene rx og ry som angir avrundingen i hjørnene.

Style-delen sier seg selv, gjør det ikke?

Inline eller embedded

En SVG kan både legges direkte inn i HTML-koden til en HTML-side (inline) eller lagres som en *.svg og settes inn med en vanlig <img> tag (embedded).

Lage diagrammer som SVG

Dette diagrammet har jeg laget denne uken: Statistikk for Hardcode.no

diagram-screenshot.png
Diagrammet vist overfor er bare en skjermdump av dette SVG-diagrammet

Det var egentlig litt komplisert å få til, men jeg regner med at det er mye enklere når man først har lært seg teknikken litt bedre. Den største utfordringen var at jeg måtte endre tankesettet litt, siden alle koordinatene tar utgangspunkt i øvre venstre hjørne.

I praksis betyr det at et punkt høyt oppe kan ha koordinatene (100,10), mens et punkt langt nede kan ha koordinatene (100,300). I sammenheng med diagrammer virker det litt bakvendt, men med litt matematikk er det overkommelig.

En annen utfordring var skaleringen av selve diagrammet. Jeg er ikke sikker på om jeg har den mest optimale løsningen nå, som innebærer at bredden er satt til 100 % (responsivt design), mens høyden på selve SVG-elementet blir justert av jQuery når siden lastes og når størrelsen på nettleservinduet justeres. Sannsynligvis hadde jeg kommet bedre ut av det hvis jeg hadde bildet som en egen SVG-fil som ble hentet inn med en <img> tag.

Og bare for å ha nevnt det: Diagrammet er dynamisk og viser oppdaterte data fra Google Analytics. Det måtte derfor en del ekstra kode til for å sørge for at skalaene og støttelinjene ble riktig og vil støtte andre inndata. Men hva som skjer hvis tallene på y-aksen blir firesifret gjenstår å se...

Svend Asbjørn Sylling, 17. desember 2013

Bloggen fra Sylling Hardcode