Skip to content

Instantly share code, notes, and snippets.

@jplitza
Created February 22, 2014 22:14
Show Gist options
  • Save jplitza/9163245 to your computer and use it in GitHub Desktop.
Save jplitza/9163245 to your computer and use it in GitHub Desktop.
Graphing RRDs with javascriptrrd+flot
<!DOCTYPE html>
<html>
<head>
<title>Graph-Test</title>
<script src="//code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="lib/flot/jquery.flot.js"></script>
<script type="text/javascript" src="lib/flot/jquery.flot.time.js"></script>
<script type="text/javascript" src="lib/flot/jquery.flot.selection.js"></script>
<script type="text/javascript" src="lib/flot/jquery.flot.tooltip.js"></script>
<script type="text/javascript" src="lib/javascriptrrd/binaryXHR.js"></script>
<script type="text/javascript" src="lib/javascriptrrd/rrdFlotSupport.js"></script>
<script type="text/javascript" src="lib/javascriptrrd/rrdFlot.js"></script>
<script type="text/javascript" src="lib/javascriptrrd/rrdFile.js"></script>
<script type="text/javascript" src="lib/javascriptrrd/rrdFilter.js"></script>
<script type="text/javascript" src="lib/javascriptrrd/rrdFlotAsync.js"></script>
<style type="text/css">
.graph {
display: inline-block;
}
.axisLabel {
position: absolute;
text-align: center;
font-size: 12px;
}
.yaxisLabel {
top: 50%;
left: 2px;
transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
transform-origin: 0 0;
-o-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
}
button.reset {
top: 7px;
right: 7px;
position: absolute;
background: transparent;
border: 0;
color: blue;
cursor: pointer;
padding: 0;
}
#flotTip h4 {
margin: 0;
}
</style>
</head>
<body>
<script type="text/javascript">
function bindLegendClick(plot) {
$('.legendColorBox', plot.getPlaceholder()).click(function(e) {
var ds = this.nextSibling.textContent;
var rrd = plot.getPlaceholder().parent().closest('div').get(0).rrd;
var data = rrd.rrd_flot_obj.graph.getData();
for(var i = 0; i < data.length; i++) {
if(data[i].label == ds) {
if(data[i].data_bak) {
data[i].data = data[i].data_bak;
data[i].data_bak = null;
data[i].color = data[i].color_bak;
} else {
data[i].data_bak = data[i].data;
data[i].data = [];
data[i].color_bak = data[i].color;
data[i].color = "#fff";
}
}
}
rrd.rrd_flot_obj.graph.setData(data);
rrd.rrd_flot_obj.graph.setupGrid();
rrd.rrd_flot_obj.graph.draw();
});
}
function addAxisLabel(plot) {
var rrd = plot.getPlaceholder().parent().closest('div').get(0).rrd;
var yaxisLabel = $('<div class="axisLabel yaxisLabel">')
.text(rrd.unit)
.appendTo(plot.getPlaceholder());
yaxisLabel.css("margin-top", yaxisLabel.width() / 2 - 20)
}
function addResetButton(plot) {
var rrd = plot.getPlaceholder().parent().closest('div').get(0).rrd;
var button = $('<button>')
.addClass('reset')
.text('Reset')
.on('click', function() {rrd.rrd_flot_obj.callback_scale_reset();})
.appendTo(plot.getPlaceholder());
}
function suffixFormatter(val, axis) {
if (val > 1000000)
return (val / 1000000).toFixed(axis.tickDecimals) + " M";
else if (val > 1000)
return (val / 1000).toFixed(axis.tickDecimals) + " k";
else
return val.toFixed(axis.tickDecimals);
}
function timeFormatter(val, axis) {
var ret = "";
if(val > 60*60) {
ret += (val / (60*60)).toFixed(0) + "h";
val %= 60*60;
}
if(val != 0) {
ret += ((val % (60*60)) / 60).toFixed(0) + "m";
val %= 60;
}
if(val > 0)
ret += (val % 60).toFixed(0) + "s";
return ret;
}
function timeTickGenerator(axis) {
if(axis.delta > 60*60)
axis.tickSize = Math.round(axis.tickSize / (60*60))*(60*60);
if(axis.delta > 60)
axis.tickSize = Math.round(axis.tickSize / 60)*60;
return axis.tickGenerator(axis);
}
var graphs = [
{name: "clients", unit: "# of clients", DS: ['clients']},
{name: "neighbors", unit: "# of neighbors", DS: ['neighbors', 'vpn_neighbors']},
{name: "traffic_bytes", unit: "Bytes/s", formatter: suffixFormatter, DS: ['rx_bytes', 'tx_bytes', 'mgmt_rx_bytes', 'mgmt_tx_bytes', 'forward_bytes']},
{name: "traffic_packets", unit: "Packets/s", formatter: suffixFormatter, DS: ['rx_packets', 'tx_packets', 'mgmt_rx_packets', 'mgmt_tx_packets', 'forward_packets']},
{name: "loadavg", unit: "processes waiting for execution", DS: ['loadavg']},
];
for(var i = 0; i < graphs.length; i++) {
document.write('<div class="graph" id="' + graphs[i].name + '"></div>');
var rrd = new rrdFlotAsync(
graphs[i].name,
"data/" + document.location.search.substring(1) + ".rrd",
null,
{
grid: {
margin: {left: graphs[i].unit?22:0},
borderWidth: 1,
},
yaxis: {
min: 0,
tickDecimals: graphs[i].unit.substring(0,1) == '#'? 0 : null,
tickFormatter: graphs[i].formatter,
ticks: graphs[i].name == "uptime"? timeTickGenerator : null,
autoscaleMargin: 0.01,
},
hooks: {
draw: [bindLegendClick],
bindEvents: [graphs[i].unit?addAxisLabel:function(){}, addResetButton]
},
selection: {
minWidth: 5
},
tooltip: true,
tooltipOpts: { content: "<h4>%s</h4> Value: %y" },
},
null,
{graph_only: true, use_checked_DSs: true, checked_DSs: graphs[i].DS}
);
rrd.unit = graphs[i].unit;
document.getElementById(graphs[i].name).rrd = rrd;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment