Plugin to easily make graphs and update them on the fly using Graphite url api on the background, allowing you to easily add:
- Client-side rendered, interactive, canvas-based graphs (relying on Flot)
- Client-side rendered, interactive, svg-based graphs (relying on Rickshaw)
- PNG's rendered by Graphite
Goals:
- easy to use, elegant but powerful api.
- only abstract where it makes sense. Graphite, Flot, and Rickshaw api's are awesome and powerfull, expose them
- aim for some consistency in configuration across backends (to the extent possible and sane)
- provide all interactive features you would expect; so that all graphite dashboards can rely on the same code to render client-side graphs, minimizing redundant work and combining efforts.
Feature comparison table. NA = not available (can't be done to my knowledge), WIP = work in progress (should be possible)
PNG | Flot | Rickshaw | |
---|---|---|---|
description | Static PNG images rendered by graphite server | Interactive client-side rendering using canvas | Interactive client-side rendering using SVG |
speed | quite fast | quite fast. interactive features near-realtime | becomes slow with many datapoints and/or multiple graphs |
hoover over datapoints/graph -> popup with exact data | NA | WIP (flot pull 867) | Y |
events with annotations (using anthracite) | NA | Y | WIP |
interactive zooming and panning | NA | WIP | WIP |
hoover over legend -> hilight on plot | NA | WIP | Y |
reordering items in legend to reorder on stacked plot | NA | WIP | Y |
toggling targets on/off | NA | WIP (flot pull 848, flot pull 869, branch flot-legend-toggle) | Y |
toggling between line vs stack (band) mode | NA | Y | Y |
auto smoothing dense graphs based on datapoints/pixel | NA | NA | WIP |
notes | 1999 called. they want their static images back. you could actually implement interactive features with a JS layer on top. (and some monitoring dashboards do this) but that is/would be soo slow) |
flot seems to have a tad more features than rickshaw | more "generic" (based on D3), all data is accessible in DOM and themeable with CSS |
any web code that can generate graphite urls can use this library with minimal transition work
you'll need a small tweak to allow this app to request data from graphite. (we could use jsonp, but see obfuscurity/tasseo#27) For apache2 this works:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "origin, authorization, accept"
- if you have
scale()
,movingAverage()
and potentially a few more in your targets, be wary of graphite-project/graphite-web#103 and adjust your scales if needed to counter graphite's rewriting of arguments. - don't use function aliases, i.e. use
sumSeries()
, notsum()
You need to check this if you see an error like
internal error: could not figure out which target_option target_graphite '<a target returned from graphite>' comes from
.
You'll probably notice that it looks slightly different from what you configured, and graphite changed it a bit.
see examples
<div id="graph">
$("#graph").graphiteRick({
from: "-24hours",
targets: [
{target: "server.web1.load"},
],
});
See 'examples' directory.
All example files are created so that you can easily diff between png and rickshaw implementations.
There's also a file with both a png and rickshaw graph for easy comparison
(this is used in the screenshot above)
Note that graphite options for visual things (colors, areaMode, legends, etc) will be ignored, but we provide alternatives (work in progress though). There's a bunch of options; for now just look them up in the source code.
- timezone
- zoom, panning
- 'suffixes': false, 'binary' or 'si' (defaults to 'si') automatically show large numbers using a prefix. like graphite does, but configurable
One. Adding a graph to a page:
<img id="graph">
$("#graph").graphite({
from: "-24hours",
target: [
"server.web1.load",
],
});
Two. Setting custom options:
<img id="graph">
$("#graph").graphite({
from: "-24hours",
colorList: "red,green",
target: [
"alias(summarize(stats.site1.auth.login.error,'30min'),'Login Errors')",
"alias(summarize(stats.site1.auth.login.user,'30min'),'Login Success')"
],
title: "Login errors vs Success"
});
Three. Setting global defaults:
$.fn.graphite.defaults.width = "450"
$.fn.graphite.defaults.height = "300"
Four. Updating existing graph:
$.fn.graphite.update($("#graph"), {from: "-3days", lineWidth: "2"});
Five. Setting a custom api url--the default is "/render/":
$.fn.graphite.defaults.url = "http://myserver/render/"
or
$("#graph").graphite({
url: "http://myserver/render/"
});
You should probably specify a target. All other settings are optional. All settings will be passed through to the graphite api.
retaining a familiar 'graphite function api'-feel, easy switching between backends, designing an API on top of flot/rickshaw tailored towards timeseries and making common features easily available, while still providing access to flot/rickshaw internals for deep customisation, is no easy task. But I think I've come up with a solution that's fairly elegant. Here's how it works.
-
the general rule is: each option in the option dict corresponds with a graphite url parameter name
-
instead of
target=<foo>&target=<bar>(...)
we define atargets
list option -
in target definitions:
- don't use
alias()
orcolor()
, we have alternatives (see below) - don't use
colorList
, i didn't even look into how to port this feature to flot/rickshaw cause you can easily avoid it - graphite supports color names like 'green' and hexadecimal RGB codes like '1088ef' (it doesn't allow a
#
prefix) - flot generally uses names or CSS color specifications like "rgb(255, 100, 123)" or '#1088ef', or an integer that specifies which of auto-generated colors to select, e.g. 0 will get color no. 0 it unofficially supports graphite-style color codes (with '#') but only in line mode, so we keep compat with graphite in your config (no '#'), but automatically add the '#' when needed. same for rickshaw which requires the '#'.
- don't use
-
enabling certain interactivity features may set other options which may override specific customisations you did; consult the code and grep for the feature if you want to know more.
-
as a general rule, put all the options that only apply to a specific backend at the bottom of the config