At StatHat, we make a lot of charts...
Our web app creates dynamic, autoupdating charts using JavaScript, but we also send charts via email and to external services like Campfire and Slack. Plus, we let users embed charts on their own web pages. For these situations, JavaScript charts either won't work, are overkill, or could get messy.
So we made chartd. It allows you to create a chart with just an img tag. These charts:
No JavaScript is required. You can generate SVG or PNG charts. We prefer SVG, but some services (like gmail) won't render SVGs in emails.
<img src="http://chartd.co/a.svg?w=580&h=180&d0=caaageehox301yusuurywwqmjdghhhjmrt0yywwuqrs2yslkgfahnomqux666zzvttv0wsmkgdbhmnlrsz6795420xtvtrnjgdadkopqqv256520zxsssokfdZZbeffjltwzzzxussuywrmgbYWaeefjmu100ywsqqrvuoidb&ymin=0&ymax=160000000&t=1+week+@+1+hour&step=1">
Here's a basic chart. All charts must have these parameters: width (w), height (h), and a dataset (d0).
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst">
When you give chartd the ymin and ymax values, it will draw the y axes.
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3">
Just show the left axis with ol=1 (or just the right with or=1).
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3&ol=1">
You can add a title with the t parameter.
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3&ol=1&t=AAPL+(past+2+months)">
You can put up to 5 datasets (d0..d4) on each chart.
<img src="/a.svg?w=580&h=180&d0=RXZZfhgdURRUYZgfccZXUM&d1=roksqfdcjfKGGMQOSXchUO&d2=y3vuuvljghrgcYZZcdVckg&d3=kdfffcZYbggdfdhkkkgjgk&ymin=45&ymax=90&t=Mean Temperature">
Change any chart to a step chart by adding step=1.
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3&t=AAPL+(past+2+months)&step=1">
Highlight the last point with hl=1. This is the style StatHat uses for automatic anomaly detection emails.
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3&or=1&t=AAPL+(past+2+months)&hl=1">
Provide xmin and xmax as UNIX timestamps and chartd will render the times on the X axis.
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3&t=AAPL+(past+2+months)&xmin=1406260190&xmax=1411444204">
UTC is the default time zone. Change this with the tz parameter.
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3&t=AAPL+(past+2+months)&xmin=1406260190&xmax=1411444204&tz=America/Chicago">
You can change the stroke colors and fills.
<img src="/a.svg?w=580&h=180&d0=SRWfaZHLHEDABKKTUYgpqqvws0138eZfaYtwxxsxyst&ymin=94.48&ymax=103.3&t=AAPL+(past+2+months)&xmin=1406260190&xmax=1411444204&tz=America/Chicago&s0=FF0000&f0=00FF0080">
You can make the lines dashed or dotted.
<img src="/a.svg?w=580&h=180&d0=RXZZfhgdURRUYZgfccZXUM&d1=roksqfdcjfKGGMQOSXchUO&d2=y3vuuvljghrgcYZZcdVckg&ymin=45&ymax=90&s0=4991AE&s1=FF8300.&s2=FF5DAA-">
If you need a PNG chart instead of SVG, use a.png instead of a.svg.
<img src="/a.png?w=580&h=180&d0=RXZZfhgdURRUYZgfccZXUM&d1=roksqfdcjfKGGMQOSXchUO&d2=y3vuuvljghrgcYZZcdVckg&ymin=45&ymax=90&s0=4991AE&s1=FF8300.&s2=FF5DAA-">
The SVG chart images are vectors and can be scaled down for smaller screens. If you're on a desktop browser, go ahead and resize this window to see the charts scale.
To make this happen, wrap the image in an svg-container
class and give the image tag an svg-content
class.
Here's the CSS for svg-container
and svg-content
:
.svg-container { display: inline-block; position: relative; vertical-align: middle; overflow: hidden; width: 100%; padding-bottom: 32%; } .svg-content { display: inline-block; position: absolute; top: 0; left: 0; }
The only tricky thing is that you need the padding-bottom percentage to be at least as great as the ratio of the chart height to its width. The charts on this page are 580px wide by 180px high. So the ratio of height to width is just over 31%, so we rounded up to 32%. You can make it larger to add more padding below the charts.
<div class="svg-container">
<img src="/a.svg?w=580&h=180&d0=ABCDEFGHIJKLMNOPZaz09&ymin=0&ymax=100" class="svg-content">
</div>
While they don't scale as nicely as SVGs, you can make the PNG charts responsive as well. Add the img-responsive class to the PNG img tag and make sure the width you provide as a parameter matches the width of the container.
Here's the CSS for img-responsive
(borrowed from Bootstrap 3):
.img-responsive { display: block; width: 100% \9; max-width: 100%; height: auto; }
<img src="/a.png?w=580&h=180&d0=ABCDEFGHIJKLMNOPZaz09&ymin=0&ymax=100" class="img-responsive">
Then just provide the width and height to the img tag for SVG or PNG. It won't resize when displayed on a smaller screen (but will still look great on retina displays).
<img src="http://chartd.co/a.svg?w=580&h=180&d=ABCDEFGHIJKLMNOPZaz09&ymin=0&ymax=100" width="580" height="180">
All chartd charts look great on retina displays. The SVG charts are vectors and render perfectly. chartd generates all the PNGs @2x the resolution so they scale appropriately.
There are only two URLs: /a.svg and /a.png. Use /a.svg for SVG charts and /a.png for PNG charts.
Here are all the possible chartd parameters:
parameter | description | data type | required? |
---|---|---|---|
w | chart width | integer | yes |
h | chart height | integer | yes |
d0 | dataset 0 | encoded string | yes |
d1 | dataset 1 | encoded string | no |
d2 | dataset 2 | encoded string | no |
d3 | dataset 3 | encoded string | no |
d4 | dataset 4 | encoded string | no |
s0 | color, stroke for d0 | stroke string | no |
s1 | color, stroke for d1 | stroke string | no |
s2 | color, stroke for d2 | stroke string | no |
s3 | color, stroke for d3 | stroke string | no |
s4 | color, stroke for d4 | stroke string | no |
f0 | fill color for d0 | stroke string | no |
f1 | fill color for d1 | stroke string | no |
f2 | fill color for d2 | stroke string | no |
f3 | fill color for d3 | stroke string | no |
f4 | fill color for d4 | stroke string | no |
ymin | y minimum | float | no |
ymax | y maximum | float | no |
xmin | x minimum | UNIX timestamp | no |
xmax | x maximum | UNIX timestamp | no |
tz | timezone for X axis dates | IANA Time Zone location name (e.g. America/New_York or Europe/Berlin) | no |
t | chart title | string | no |
step | step chart | 1 to turn on | no |
hl | highlight last point | 1 to turn on | no |
ol | only left y-axis | 1 to turn on | no |
or | only right y-axis | 1 to turn on | no |
The data is encoded into a base-62 string. Each character in the string is a data point. Each character represents a value of 0 to 61. The characters are A..Za..z0..9. 'A' is 0, '9' is 61. To encode, you map the Y values in your data onto the base-62 characters. Here's what it looks like in Go:
const b62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" func encode(data []float64, min, max float64) string { r := math.Dim(max, min) bs := make([]byte, len(data)) if r == 0 { for i := 0; i < len(data); i++ { bs[i] = b62[0] } return string(bs) } enclen := float64(len(b62) - 1) for i, y := range data { index := int(enclen * (y - min) / r) if index >= 0 && index < len(b62) { bs[i] = b62[index] } else { bs[i] = b62[0] } } return string(bs) }
You can customize the color and the stroke of each dataset with the s0 - s4 parameters and the fill color with the f0 - f4 parameters. Each stroke string is 6-9 characters long. The first 6 characters are your typical CSS hexadecimal RGB values. The next two characters are an optional hexadecimal alpha value. The final character is on optional stroke parameter that determines if the line is solid, dashed, or dotted. The stroke parameter is ignored for fill parameters.
Here's how it looks:
R | R | G | G | B | B | A | A | S |
The RR, GG, BB, and AA fields can go from 00 to FF.
The S field is either - for dashed or . for dotted (anything else, including nothing, will be a solid line).
Some examples:
4991AE blue solid line, no alpha
EFF3F680 red with 50% alpha.
4991AE- blue dashed line, no alpha
FF8300. orange dotted line, no alpha
FF830080. orange dotted line, 50% alpha
All chartd charts are also available over SSL. Just use https://chartd.co.