0

I am trying to create a graph like this:

http://bl.ocks.org/cmdoptesc/6228457

or like this

http://raphaeljs.com/polar-clock.html

But I want it to be able to scale (preferably without javascript) according to the browser width. I would love to be able to do this with CSS only, and if not with CSS, preferably without a library like raphael or d3 (though I'll take what I can get). Anybody know how to accomplish this in a way that scales down / up?

UPDATE

I made a JS Fiddle - this is exactly the graph I want:

http://jsfiddle.net/Q9hb5/

But I need it to resize. I am using Raphael, and I read about SVG resizing here:

http://bertanguven.com/?tag=raphael-js

and here:

http://www.justinmccandless.com/blog/Making+Sense+of+SVG+viewBox%27s+Madness

but I don't want to have to resize with JS - I'd really like to be able to do this with svg properties such as viewBox and preserveAspectRatio, but I still haven't seen an example that accomplishes this.

Any ideas?

mheavers
  • 29,530
  • 58
  • 194
  • 315

1 Answers1

3

Since you say you don't want to use Javascript libraries, I assume you are creating the SVG image ahead of time and/or on the server, and are just transmitting static SVG code to the user. Canvas images, in contrast, are always made with Javascript.

(If you want to dynamically create the graph with Javascript, but not use a library, the hard part will be drawing the graph, not getting it to resize! As @Lars Kotthoff notes, with Javascript it is easy to find out the size of the window and scale everything accordingly.)

To make SVG scale up and down, you need to include a viewBox attribute on your SVG element, and it will scale automatically. A warning, though, that sizing the image dynamically while maintaining aspect ratio can be a bit frustrating. The preserveAspectRatio attribute prevents distortion, but only by leaving empty space, not by scaling down. In Firefox, using height:auto; will cause the SVG height to scale down to match the width and viewBox aspect ratio, but not in webkit browsers.

Example here:
http://fiddle.jshell.net/9dSbL/

A somewhat indirect solution is to + Set the svg height to a negligible (but not zero) amount, such as 1px; + Set overflow:visible; on the svg; + Use a slice option for preserveAspectRatio, so that the image scales to the larger dimension of height or width; + Hard-code a bottom padding style on the svg element that matches the aspect ratio of the viewBox; + Wrap the entire svg in a <div> with style overflow:hidden;.

Example here:
http://fiddle.jshell.net/9dSbL/1/

AmeliaBR
  • 27,344
  • 6
  • 86
  • 119
  • And in response to @mheavers' edit. Yes, you can use a viewBox attribute on a dynamically created SVG to make it responsive without listening to window events. The first example in [this answer](http://stackoverflow.com/a/21418197/3128209) makes a graph responsive by adding a viewBox attribute with d3; you could just as easily do so with Raphael. My other comments about getting the scale and aspect ratio correct still hold, you just have to add all the correct attributes onto the SVG in your code. – AmeliaBR Jan 31 '14 at 21:34
  • This is awesome, thanks. I think the only thing I'm confused in your example is how you derived the viewbox. Viewbox numbers seem so arbitrary to me (-3 -1 16 16) – mheavers Jan 31 '14 at 21:42
  • Sorry, that *is* confusing and they *are* arbitrary; I re-used the drawing from something else, and it had been easier to change the viewBox than change all the curve coordinates when the edges of the shape were getting cut off. Here's [the same example with a more standard viewBox](http://fiddle.jshell.net/9dSbL/2/). When creating the viewBox dynamically, just remember that the first two numbers will be the coordinates of the top left corner, and the last two numbers will be the width and height, for all the drawing and layout commands. – AmeliaBR Jan 31 '14 at 21:59
  • 1
    A less arbitrary example showing why you might use non-zero values for the first two numbers: In order to show a 100*100 square with 30 units padding on each side, I use the viewBox "-30 -30 160 160": http://codepen.io/AmeliaBR/pen/pIder – AmeliaBR Jan 31 '14 at 22:08