/graphitejs

A jQuery plugin for displaying graphite graphs

Primary LanguageJavaScriptBSD 2-Clause "Simplified" LicenseBSD-2-Clause

graphite.js

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

Screenshot Screenshot

Notes for client-side graph rendering / troubleshooting

Configuration of graphite server / If you don't seem to get any actual data

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"

The code needs to be able to map targets returned from graphite back to your configuration, so:

  • 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(), not sum()

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.

Flot client-side canvas graphs

see examples

Rickshaw client-side svg graphs

Minimal config

<div id="graph">
$("#graph").graphiteRick({
    from: "-24hours",
    targets: [
        {target: "server.web1.load"},
    ],
});

Advanced examples

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.

TODO

  • timezone
  • zoom, panning

Optional keys for flot/rickshaw

  • 'suffixes': false, 'binary' or 'si' (defaults to 'si') automatically show large numbers using a prefix. like graphite does, but configurable

Graphite PNG's

How it works

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/"
});

$(img).graphite(options)

You should probably specify a target. All other settings are optional. All settings will be passed through to the graphite api.

Configuration

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 a targets list option

  • in target definitions:

    • don't use alias() or color(), 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 '#'.
  • 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