Thursday, May 26, 2016

Make Your Own Responsive SVG Graphs & Infographics

A few weeks ago I talked about making this Star Trek vs. Star Wars chart in SVG using the free Boxy SVG vector editor.

Star Trek Vs Star Wars SVG

We also talked about the power of clean, well-written SVG. I want to take that idea a step further today. I know this is the design and UX channel, but sometimes to design something better, we need to take 'code-level' control. We're going to poke around in the SVG markup but there will be a worthwhile design payoff.

One of the best ways I've found to experiment with SVG is to:

  1. Draw something simple in Boxy SVG and save it,
  2. Open that SVG file in your favorite text editor (Brackets, Atom, Sublime, whatever)
  3. Copy and paste that SVG code directly into the HTML panel at Codepen.io. It should render in the results panel.

From there you can start making changes and see what happens. Here's my original Star Trek vs. Star Wars chart pasted into Codepen.

Tidy SVGs are Happy SVGs

Switching back to the code editor for a second, let's look at the basic structure of our SVG chart. At the top, you'll see a set of <defs> tags that contain reusable resources we call on later in this document – specifically you'll see:

  • a gray background gradient 'glow', and
  • the grid pattern we use in the back

Beneath the <defs>, the rest of the document is fairly easy to follow.

  1. A background rectangle (<rect>) with glow makes a backing canvas
  2. The chart body with the grid pattern (<rect>)
  3. The chart title (<text>)
  4. The 'Star Wars' yellow chart line (<path>)
  5. The 'Star Trek' blue chart line (<path>)
  6. 2 x labels for the chart lines (<text>)
  7. A group (<g>) containing the y-axis number markers (<text>)
  8. A group (<g>) containing the x-axis number markers (<text>)

There's not a lot to it, right?

But if you look closely at those two groups of axis numbers, you're probably seeing a lot of repetition.

[html]
<text y="430" x="40" style="text-anchor: middle; fill: rgb(103, 102, 102); font-size: 12px;">1960</text>
<text y="430" x="118" style="text-anchor: middle; fill: rgb(103, 102, 102); font-size: 12px;">1965</text>
<text y="430" x="196" style="text-anchor: middle; fill: rgb(103, 102, 102); font-size: 12px;">1970</text>
[/html]

If this was HTML we wouldn't stand for this many repeated inline properties – we'd strip them out into the CSS and replace them with a class. There's no reason not to do exactly the same in SVG.

In <defs> section at the top of we already have <style> block. We can add a new CSS rule to that block like this:

[code language="css"]
.y-axis text {
text-anchor: middle;
fill: rgb(103, 102, 102);
font-size: 12px;
}
[/code]

And that allows us to strip those text nodes down to something much more compact like this:

[code language="html"]
<text y="430" x="40">1960</text>
<text y="430" x="118">1965</text>
<text y="430" x="196">1970</text>
[/code]

Not only is this code MUCH easier to read and navigate through but it also makes the file smaller while allowing us to change the color of all the y-axis numbers from a single point. Win:win:win.

With the help of your code editor's find-and-replace, you should be able to tidy up your file nicely. We can put the chart line label styling into the <style> too. We'll create new CSS class and add it to the label text.

[css]
.label-starwars {
white-space: pre;
font-size: 15px;
fill: rgb(253, 200, 39);
word-spacing: 0px;
}
[/css]

Be aware that you can't move the 'x' and 'y' values of an SVG element into the CSS. But all other properties can be transferred to a class even including properties that aren't in the CSS spec such as 'fill' or 'stroke' (as shown above).

Here's that same SVG file tidied up with some new CSS classes.

But this article isn't just about cleaning – let's do something cooler and more useful with our chart.

Making Smarter SVGs

If there's one benefit of SVG that is trumpeted the most, surely it is 'scalability'? After all, that IS what the 'S' in 'SVG' stands for. We can effortlessly scale an icon from 40px to 400px and expect it to stay laser-sharp and crisp.

But this has its limitations.

[caption id="attachment_131242" align="alignright" width="411"]Scaled down SVGs Crisp text has no value if it's too small to read.[/caption]

Just because I can scale down our chart to fit onto a smaller screen, doesn't mean that it's of any practical use at that size. It doesn't matter how laser-sharp our labels are if they're simply too small to read.

As you can see above, the text quickly becomes illegible when we scale our chart below about 500 pixels wide.

Can we fix it? Responsive SVG can!

In HTML and CSS, we would tackle this kind of problem with CSS media queries – which is exactly what we'll do in our SVG. We spent time CSS-ifying our SVG and now we reap the benefits.

Back in our <style> block we can add a CSS media query that dials up the font-size of our text when our chart has less than 500px to work with. Something like this:

[code language="css"]
@media (max-width: 500px) {
.label-startrek, .label-starwars{
font-size: 170%;
}
.y-axis text {
font-size: 130%;
}
.x-axis text {
font-size: 130%;
}
}
[/code]

Which gives us a result like this:

[caption id="attachment_131244" align="alignright" width="406"]Upscaling the text in an SVG graph below a preset breakpoint Our axis labels up-size themselves when the graphic breaks 500px – but it's a bit ugly.[/caption]

Great! So, now the numbers on our axis are more readable at smaller scales – but they are also a little crowded and ugly too.

Continue reading %Make Your Own Responsive SVG Graphs & Infographics%


by Alex Walker via SitePoint

No comments:

Post a Comment