Created
April 23, 2013 18:29
-
-
Save stuart-warren/5446117 to your computer and use it in GitHub Desktop.
Loads up data from local KairosDB instance and creates NVD3.js graphs.
Updates every 30 seconds, best used with start_relative times.
See https://github.com/stuart-warren/django-opentsdb and https://github.com/proofpoint/kairosdb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <link href="static/novus-nvd3-f74b4de/src/nv.d3.css" rel="stylesheet" type="text/css"> | |
| <style> | |
| body { | |
| overflow-y:scroll; | |
| } | |
| text { | |
| font: 12px sans-serif; | |
| } | |
| svg { | |
| display: block; | |
| } | |
| #chart1 svg { | |
| height: 500px; | |
| min-width: 100px; | |
| min-height: 100px; | |
| padding: 50px; | |
| /* | |
| margin: 50px; | |
| Minimum height and width is a good idea to prevent negative SVG dimensions... | |
| For example width should be =< margin.left + margin.right + 1, | |
| of course 1 pixel for the entire chart would not be very useful, BUT should not have errors | |
| */ | |
| } | |
| </style> | |
| <body> | |
| <h3>Be patient =]</h3> | |
| <div id="loading"> | |
| <div style="position: fixed; top: 40%; width: 100%; | |
| font-size: 600%; text-align: center; z-index: 11;">loading...</div> | |
| <div style="position: fixed; height: 100%; width: 100%; | |
| z-index: 10; background-color: #c8ebf0; opacity: 0.3;"></div> | |
| </div> | |
| <div id="chart"> | |
| <svg style="height: 500px;"></svg> | |
| </div> | |
| <textarea id="jsonreq" cols="40" rows="20" onblur="updateReq();" > | |
| </textarea> | |
| <button type="button" onclick="updateGraph();">Update graph</button> | |
| <script src="static/novus-nvd3-f74b4de/lib/d3.v3.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/nv.d3.min.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/src/tooltip.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/src/utils.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/src/models/legend.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/src/models/axis.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/src/models/scatter.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/src/models/line.js"></script> | |
| <script src="static/novus-nvd3-f74b4de/src/models/lineWithFocusChart.js"></script> | |
| <script> | |
| var data; | |
| var chart = nv.models.lineWithFocusChart() | |
| .margin({top: 30, right: 30, bottom: 50, left: 120}) | |
| .margin2({top: 0, right: 30, bottom: 40, left: 120}); | |
| var reqdata = '\ | |
| {\n\ | |
| "metrics": [\n\ | |
| {\n\ | |
| "tags": {\n\ | |
| "host": "dc1-1"\n\ | |
| },\n\ | |
| "name": "proc.loadavg.1min"\n\ | |
| },\n\ | |
| {\n\ | |
| "tags": {\n\ | |
| "host": "dc1-2"\n\ | |
| },\n\ | |
| "name": "proc.loadavg.1min"\n\ | |
| },\n\ | |
| {\n\ | |
| "tags": {\n\ | |
| "host": "dc1-3"\n\ | |
| },\n\ | |
| "name": "proc.loadavg.1min"\n\ | |
| }\n\ | |
| ],\n\ | |
| "cache_time": 0,\n\ | |
| "start_relative": {\n\ | |
| "value": "6",\n\ | |
| "unit": "hours"\n\ | |
| }\n\ | |
| }\n\ | |
| '; | |
| // update variable onBlur of texarea | |
| function updateReq() { | |
| reqdata = document.getElementById("jsonreq").value; | |
| } | |
| function updateGraph() { | |
| document.getElementById("loading").style.display = 'block'; | |
| redraw(); | |
| } | |
| // set initial contents of textarea | |
| document.getElementById("jsonreq").value = reqdata; | |
| // translate json from kairosdb to something that works with NVD3 | |
| function translate(json) { | |
| // ARGHH so ugly!!! But mostly works.... | |
| data = []; | |
| for(var m = 0, s = json['queries'].length; m < s; m++) { | |
| var q = json.queries[m]; | |
| var k = []; | |
| var tags = []; | |
| for (var key in q.results[0].tags) { | |
| if(q.results[0].tags.hasOwnProperty(key)) { | |
| tags.push(key + '=' + q.results[0].tags[key][0]); | |
| } | |
| } | |
| for (n = 0, t = q.results[0].values.length; n < t; n++) { | |
| k.push({'x': q.results[0].values[n][0], 'y': q.results[0].values[n][1]}); | |
| } | |
| data.push({'key': q.results[0].name + '{' + tags.join() + '}', 'values': k}); | |
| } | |
| return data; | |
| } | |
| // Create initial graph | |
| nv.addGraph(function() { | |
| document.getElementById("loading").style.display = 'block'; | |
| // TODO: Use dynamic date formats depending on range of data? | |
| var dateFormat = '%a %d %b %Y %H:%M:%S'; | |
| // Enable for log scale | |
| var logyAxis = false | |
| chart.xAxis | |
| .rotateLabels(-8) | |
| .showMaxMin(false) | |
| .tickFormat(function(d) { return d3.time.format(dateFormat)(new Date(d)); }) | |
| chart.x2Axis | |
| .rotateLabels(-8) | |
| .showMaxMin(false) | |
| .tickFormat(function(d) { return d3.time.format(dateFormat)(new Date(d)); }) | |
| if (logyAxis) { | |
| chart.lines.yScale(d3.scale.log()); | |
| chart.yAxis.tickValues([0.01,0.1,1,10,100,1000,10000,100000,1000000]); | |
| chart.forceY([1,1000000]); | |
| } | |
| chart.yAxis | |
| .tickFormat(d3.format(',.2f')); | |
| chart.y2Axis | |
| .tickFormat(d3.format(',.2f')); | |
| // draw actual graph | |
| redraw(); | |
| nv.utils.windowResize(chart.update); | |
| return chart; | |
| }); | |
| function redraw() { | |
| d3.json("/api/v1/datapoints/query").post(reqdata, function(error, json) { | |
| if (error) return console.warn(error); | |
| data = translate(json); | |
| d3.select('#chart svg') | |
| .datum(data) | |
| .transition().duration(2000) | |
| .call(chart); | |
| document.getElementById("loading").style.display = 'none'; | |
| }); | |
| } | |
| setInterval(function () { | |
| redraw(); | |
| }, 30000); | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment