Skip to content

Commit

Permalink
Merge branch 'master' of github.com:kenhub/giraffe
Browse files Browse the repository at this point in the history
  • Loading branch information
Yoav committed Jan 18, 2014
2 parents 59d7a16 + aa068a2 commit 7b6cc04
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 30 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog for Giraffe

* Version 1.0.2 - more configuration options
- Stroke color in area renderer can be a function that takes the graph color
as a d3.rgb color and returns the color of the stroke
- Format y axis ticks and totals values with a formatting function,
`ticks_formatter` and `totals_formatter` respectively,
just like `summary_formatter`
- Totals fields can be selected by passing an array of strings, e.g.
`"totals_fields": ["max", "min"]`
* Version 1.0.1 - min default set to `auto` (#49)
* Version 1.0.0
- first tagged version

## commits

[github commit log](https://github.com/kenhub/giraffe/commits)
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ Need a quick way to install and play with graphite? try [graphite-fabric](https:
Giraffe is based on a number of amazing open-source projects and libraries, to name a few:

* The [Rickshaw](http://code.shutterstock.com/rickshaw/) charting library (based on [d3](http://mbostock.github.com/d3/))
* [HTML5 Boilerplate](http://html5boilerplate.com/) and [Twitter Bootstrap](https://github.com/twitter/bootstrap)
* [HTML5 Boilerplate](http://html5boilerplate.com/) and [Bootstrap](https://github.com/twbs/bootstrap)
* Written in (but does not require) [Coffeescript](http://coffeescript.org)
* Other libraries such as [jQuery](http://jquery.com), [underscore.js](http://underscorejs.org), [jQuery BBQ](http://benalman.com/projects/jquery-bbq-plugin/), [pagedown](), [{{mustache}}](https://github.com/janl/mustache.js/) and more

##Inspiration

Giraffe is heavily inspired by several existing graphite dashboards. Primarily:

* [GDash](https://github.com/ripienaar/gdash) - it uses twitter bootstrap and allows multiple dashboards to be configured. However, it requires running a sinatra server, and the graphs are pulled directly from graphite rather than rendered via a js charting library.
* [GDash](https://github.com/ripienaar/gdash) - it uses Bootstrap and allows multiple dashboards to be configured. However, it requires running a sinatra server, and the graphs are pulled directly from graphite rather than rendered via a js charting library.
* [Tasseo](https://github.com/obfuscurity/tasseo) - also allows multiple dashboards, but still relies on a server component. Tasseo also uses Rickshaw, but charts only a single data series. Giraffe started as a tasseo fork, but eventually got refactored (almost) beyond recognition.
* [Graphene](https://github.com/jondot/graphene) - a d3-based relatime dashboard with different widgets. Supports a single dashboard, and its charting functionality is not as extensive as with Richshaw.

Expand Down Expand Up @@ -162,6 +162,8 @@ The core code lives in `js/src/giraffe.coffee`.
Since the `dashboards.js` configuration needs easy access to everything inside `giraffe.js`, please compile the coffeescript
using the `--bare` option.
* To submit a pull request, please make sure your changes are going into the original `giraffe.coffee`. Patches to the compiled `js` file cannot be merged on their own.
##Who is behind Giraffe?
Giraffe was developed at [kenHub](https://www.kenhub.com). We are not much of techie startup, but we hope to build the
Expand Down Expand Up @@ -205,3 +207,4 @@ Check out the different [demo dashboards](http://kenhub.github.com/giraffe/) for
##Links, Plugins and 3rd party tools

* [giraffe-collectd](https://github.com/bflad/giraffe-collectd) - A simple Giraffe configuration generator for collectd metrics in Graphite (created by @bflad)
* [giraffe-web](https://github.com/jedi4ever/giraffe-web.js) - a node.js server wrapper and cli - also allows proxying your graphite server (created by @jedi4ever)
10 changes: 10 additions & 0 deletions dashboards.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var dashboards =
"description": "New signups to the website", // enter your metric description here
"summary": "sum", // available options: [sum|min|max|avg|last|<function>]
"summary_formatter": d3.format(",f") // customize your summary format function. see d3 formatting docs for more options
// also supported are tick_formatter to customize y axis ticks, and totals_formatter to format the values in the legend
},
{
"alias": "signup breakdown",
Expand Down Expand Up @@ -99,7 +100,13 @@ var dashboards =
"description": "cpu utilization on production (using linear interpolation). Summary displays the average across all series",
"interpolation": "linear", // you can use different rickshaw interpolation values
"stroke_width": 1, // change stroke width
"stroke": stroke, // stoke may be true, false or a function that takes and returns a d3 rgb color to style the stroke
"summary": "avg",
"totals_fields": ["min", "max", "avg"], // customize which totals are shown in the legend
"summary_formatter": format_pct,
"hover_formatter": format_pct,
"totals_formatter": format_pct, // customize the formatting of the legend totals
"tick_formatter": format_pct, // and also the y axis ticks
},
{
"alias": "proc mem prod",
Expand Down Expand Up @@ -184,3 +191,6 @@ var scheme = [
function relative_period() { return (typeof period == 'undefined') ? 1 : parseInt(period / 7) + 1; }
function entire_period() { return (typeof period == 'undefined') ? 1 : period; }
function at_least_a_day() { return entire_period() >= 1440 ? entire_period() : 1440; }

function stroke(color) { return color.brighter().brighter() }
function format_pct(n) { return d3.format(",f")(n) + "%" }
58 changes: 42 additions & 16 deletions js/giraffe.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 26 additions & 12 deletions js/src/giraffe.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -172,20 +172,23 @@ createGraph = (anchor, metric) ->
targets: metric.target || metric.targets
summary: metric.summary
summary_formatter: metric.summary_formatter || _formatBase1024KMGTP
totals_formatter: metric.totals_formatter || _formatBase1024KMGTP
totals_fields: metric.totals_fields || ["sum", "min", "max", "avg"]
scheme: metric.scheme || dashboard.scheme || scheme || 'classic9'
annotator_target: metric.annotator?.target || metric.annotator
annotator_description: metric.annotator?.description || 'deployment'
events: metric.events
element: $("#{anchor} .chart")[0]
width: $("#{anchor} .chart").width()
height: metric.height || 300
min: metric.min || 0
min: metric.min || 'auto'
max: metric.max
null_as: if metric.null_as is undefined then null else metric.null_as
renderer: metric.renderer || 'area'
interpolation: metric.interpolation || 'step-before'
unstack: if metric.unstack is undefined then unstackable else metric.unstack
stroke: if metric.stroke is false then false else true
stroke_fn: metric.stroke if typeof metric.stroke is "function"
strokeWidth: metric.stroke_width
dataURL: generateDataURL(metric.target || metric.targets)
onRefresh: (transport) ->
Expand All @@ -198,9 +201,7 @@ createGraph = (anchor, metric) ->
xAxis.render()
yAxis = new Rickshaw.Graph.Axis.Y
graph: graph
# tickFormat: d3.format(".2r") #Rickshaw.Fixtures.Number.formatBase1024KMGTP(y).toFixed(2).replace('.00','')
# tickFormat: (y) -> Rickshaw.Fixtures.Number.formatBase1024KMGTP(d3.format(".2r")(y)) #.toFixed(2).replace('.00','')
tickFormat: (y) -> _formatBase1024KMGTP(y) #.toFixed(2).replace('.00','')
tickFormat: metric.tick_formatter || (y) -> _formatBase1024KMGTP(y)
ticksTreatment: 'glow'
yAxis.render()
# element: $("#{anchor} .y-axis")[0]
Expand Down Expand Up @@ -238,7 +239,6 @@ Rickshaw.Graph.JSONP.Graphite = Rickshaw.Class.create(Rickshaw.Graph.JSONP,
result_data = @preProcess(result_data)
# success is called once to build the initial graph
@success(@parseGraphiteData(result_data, @args.null_as)) if not @graph

series = @parseGraphiteData(result_data, @args.null_as)
annotations = @parseGraphiteData(_.filter(result, (el) =>
el.target == @args.annotator_target.replace(/["']/g, '')), @args.null_as) if @args.annotator_target
Expand All @@ -259,13 +259,19 @@ Rickshaw.Graph.JSONP.Graphite = Rickshaw.Class.create(Rickshaw.Graph.JSONP,
label = $(@legend.lines[i].element).find('span.label').text()
$(@legend.lines[i].element).find('span.totals').remove()
series_data = _.map(@legend.lines[i].series.data, (d) -> d.y)
sum = _formatBase1024KMGTP(_sum(series_data))
max = _formatBase1024KMGTP(_max(series_data))
min = _formatBase1024KMGTP(_min(series_data))
avg = _formatBase1024KMGTP(_avg(series_data))
sum = @args.totals_formatter(_sum(series_data))
max = @args.totals_formatter(_max(series_data))
min = @args.totals_formatter(_min(series_data))
avg = @args.totals_formatter(_avg(series_data))

$(@legend.lines[i].element).append("<span class='totals pull-right'> &Sigma;: #{sum} <i class='icon-caret-down'></i>: #{min} <i class='icon-caret-up'></i>: #{max} <i class='icon-sort'></i>: #{avg}</span>")
totals = "<span class='totals pull-right'>"
totals = totals + " &Sigma;: #{sum}" if "sum" in @args.totals_fields
totals = totals + " <i class='icon-caret-down'></i>: #{min}" if "min" in @args.totals_fields
totals = totals + " <i class='icon-caret-up'></i>: #{max}" if "max" in @args.totals_fields
totals = totals + " <i class='icon-sort'></i>: #{avg}" if "avg" in @args.totals_fields
totals += "</span>"

$(@legend.lines[i].element).append(totals)

preProcess: (result) ->
for item in result
Expand Down Expand Up @@ -293,12 +299,18 @@ Rickshaw.Graph.JSONP.Graphite = Rickshaw.Class.create(Rickshaw.Graph.JSONP,
palette = new Rickshaw.Color.Palette
scheme: @args.scheme
targets = @args.target || @args.targets
stroke_fn = @args.stroke_fn
d = _.map d, (el) ->
if typeof targets in ["string", "function"]
color = palette.color()
else
color = getTargetColor(targets, el.target) || palette.color()
return {"color": color, "name": el.target, "data": rev_xy(el.datapoints)}
return {
color: color
stroke: stroke_fn(d3.rgb(color)) if stroke_fn?
name: el.target
data: rev_xy(el.datapoints)
}
Rickshaw.Series.zeroFill(d)
return d

Expand Down Expand Up @@ -394,7 +406,9 @@ Rickshaw.Graph.Demo = Rickshaw.Class.create(Rickshaw.Graph.JSONP.Graphite,
data: @seriesData[6],
name: 'New York'
}
]
].map((s) =>
s.stroke = @args.stroke_fn(d3.rgb(s.color)) if @args.stroke_fn?
s)

@graph.renderer.unstack = @args.unstack
@graph.render()
Expand Down

0 comments on commit 7b6cc04

Please sign in to comment.