lib/visage-app/public/javascripts/graph.js in visage-app-0.3.3 vs lib/visage-app/public/javascripts/graph.js in visage-app-0.9.0.pre1
- old
+ new
@@ -1,45 +1,156 @@
+function formatSeriesLabel(labels) {
+ var host = labels[0],
+ plugin = labels[1],
+ instance = labels[2],
+ metric = labels[3],
+ name;
+
+ // Generic label building
+ name = instance
+ name = name.replace(plugin, '')
+ name = name.replace(plugin.split('-')[0], '')
+ name = name.replace('tcp_connections', '')
+ name = name.replace('ps_state', '')
+ name += metric == "value" ? "" : " (" + metric + ")"
+ name = name.replace(/^[-|_]*/, '')
+ name = name.trim().replace(/^\((.*)\)$/, '$1')
+ name = plugin == "irq" ? name.replace(/^/, 'irq ') : ''
+
+ // Plugin specific labeling
+ if (plugin == "interface") {
+ name += instance.replace(/^if_(.*)-(.*)/, '$2 $1') + ' (' + metric + ')'
+ }
+ if (["processes", "memory"].contains(plugin) || plugin.test(/^cpu-\d+/) ) {
+ name += instance.split('-')[1]
+ }
+ if (plugin == "swap") {
+ if (instance.test(/^swap_io/)) {
+ name += instance.replace(/^swap_(\w*)-(.*)$/, '$1 $2')
+ }
+ if (instance.test(/^swap-/)) {
+ name += instance.split('-')[1]
+ }
+ }
+ if (plugin == "load") {
+ name += metric.replace(/^\((.*)\)$/, '$1')
+ }
+ if (plugin.test(/^disk/)) {
+ name += instance.replace(/^disk_/, '') + ' (' + metric + ')'
+ }
+ if (["entropy","users"].contains(plugin)) {
+ name += metric
+ }
+ if (plugin == "uptime") {
+ name += instance
+ }
+ if (plugin == "ping") {
+ if (instance.test(/^ping_/)) {
+ name += instance.replace(/^ping_(.*)-(.*)$/, '$1 $2')
+ } else {
+ name += metric + ' ' + instance.split('-')[1]
+ }
+ }
+ if (plugin == "vmem") {
+ if (instance.test(/^vmpage_number-/)) {
+ name += instance.replace(/^vmpage_number-(.*)$/, '$1').replace('_', ' ')
+ }
+ if (instance.test(/^vmpage_io/)) {
+ name += instance.replace(/^vmpage_io-(.*)$/, '$1 ') + metric
+ }
+ if (instance.test(/^vmpage_faults/)) {
+ name += metric.trim() == "minflt" ? 'minor' : 'major'
+ name += ' faults'
+ }
+ }
+ if (plugin.test(/^tcpconns/)) {
+ name += instance.split('-')[1].replace('_', ' ')
+ }
+ if (plugin.test(/^tail/)) {
+ name += plugin.split('-').slice(1).join('-') + ' '
+ name += instance.split('-').slice(1).join('-')
+ }
+ if (plugin == "apache") {
+ var stash = instance.split('_')[1]
+ if (stash.test(/^scoreboard/)) {
+ name += 'connections: ' + stash.split('-')[1]
+ } else {
+ name += stash
+ }
+
+ }
+ return name.trim()
+}
+
+function formatValue(value, places) {
+ var places = places ? places : 0
+ switch(true) {
+ case (Math.abs(value) > 1125899906842624):
+ var label = value / 1125899906842624,
+ unit = 'P';
+ break
+ case (Math.abs(value) > 1099511627776):
+ var label = value / 1099511627776,
+ unit = 'T';
+ break
+ case (Math.abs(value) > 1073741824):
+ var label = value / 1073741824,
+ unit = 'G';
+ break
+ case (Math.abs(value) > 1048576):
+ var label = value / 1048576,
+ unit = 'M';
+ break
+ case (Math.abs(value) > 1024):
+ var label = value / 1024,
+ unit = 'K';
+ break
+ default:
+ var label = value,
+ unit = '';
+ break
+ }
+
+ var rounded = label.round(places)
+
+ return rounded + unit
+}
+
+function formatDate(d) {
+ var datetime = new Date(d * 1000)
+ return datetime.format("%Y-%m-%d %H:%M:%S UTC%T")
+}
+
+
+
/*
* visageBase()
*
* Base class for fetching data and setting graph options.
* Should be used by other classes to build specialised graphing behaviour.
*
*/
var visageBase = new Class({
Implements: [Options, Events],
options: {
- width: 900,
- height: 220,
- leftEdge: 100,
- topEdge: 10,
- gridWidth: 670,
- gridHeight: 200,
- columns: 60,
- rows: 8,
- gridBorderColour: '#ccc',
- shade: false,
secureJSON: false,
httpMethod: 'get',
- axis: "0 0 1 1"
+ live: false
},
initialize: function(element, host, plugin, options) {
- this.parentElement = element;
- this.setOptions(options);
- this.options.host = host;
- this.options.plugin = plugin;
- this.buildGraphHeader();
- this.buildGraphContainer();
- this.canvas = Raphael(this.graphContainer, this.options.width, this.options.height);
+ this.parentElement = element
+ this.setOptions(options)
+ this.options.host = host
+ this.options.plugin = plugin
data = new Hash()
if($chk(this.options.start)) {
data.set('start', this.options.start)
}
if($chk(this.options.finish)) {
data.set('finish', this.options.finish)
}
- this.requestData = data
+ this.requestData = data;
this.getData(); // calls graphData
},
dataURL: function() {
var url = ['data', this.options.host, this.options.plugin]
// if the data exists on another host (useful for embedding)
@@ -70,32 +181,14 @@
}.bind(this)
});
this.request.send();
},
- buildGraphHeader: function() {
- header = $chk(this.options.name) ? this.options.name : this.options.plugin
- this.graphHeader = new Element('h3', {
- 'class': 'graph-title',
- 'html': header,
- 'styles': {
- 'color': "#121212"
- }
- });
- $(this.parentElement).grab(this.graphHeader);
+ graphName: function() {
+ name = $chk(this.options.name) ? this.options.name : this.options.plugin
+ return name
},
- buildGraphContainer: function() {
- $(this.parentElement).set('style', 'padding-top: 1em');
-
- this.graphContainer = new Element('div', {
- 'class': 'graph container',
- 'styles': {
- 'margin-bottom': '24px'
- }
- });
- $(this.parentElement).grab(this.graphContainer)
- }
});
/*
* visageGraph()
@@ -109,455 +202,321 @@
var visageGraph = new Class({
Extends: visageBase,
Implements: Chain,
// assemble data to graph, then draw it
graphData: function(data) {
+ this.response = data
+ this.buildDataStructures()
- this.ys = []
- this.colors = []
- this.instances = []
- this.metrics = []
+ if ( $defined(this.chart) ) {
+ this.series.each(function(series, index) {
+ this.chart.series[index].setData(series.data)
+ }, this);
+ } else {
+ this.drawChart()
+ }
+ },
+ buildDataStructures: function (data) {
+ var series = this.series = []
+ var host = this.options.host
+ var plugin = this.options.plugin
+ var data = data ? data : this.response
- var host = this.options.host
- var plugin = this.options.plugin
-
$each(data[host][plugin], function(instance, iname) {
$each(instance, function(metric, mname) {
- this.colors.push(metric.color)
- if ( !$defined(this.x) ) {
- this.x = this.buildXAxis(metric)
- }
- this.ys.push(metric.data)
- this.instances.push(iname) // labels
- this.metrics.push(mname) // labels
+ var set = {
+ name: [ host, plugin, iname, mname ],
+ data: metric.data,
+ pointStart: metric.start,
+ pointInterval: (metric.finish - metric.start) / metric.data.length
+ };
+
+ series.push(set)
}, this);
}, this);
- this.buildContainers();
- this.drawGraph();
-
- this.buildLabels();
- this.addSelectionInterface();
- this.addDebugInterface();
- this.buildDateSelector();
-
- /* disabling this for now for dramatic effect
- this.buildEmbedder();
- */
+ return series
},
- buildXAxis: function(metric) {
- var start = metric.start.toInt(),
- finish = metric.finish.toInt(),
- length = metric.data.length,
- interval = (finish - start) / length,
- counter = start,
- x = []
+ drawChart: function() {
+ var series = this.series,
+ title = this.graphName(),
+ element = this.parentElement,
+ ytitle = this.options.plugin
+ max = 0
- while (counter < finish) {
- x.push(counter)
- counter += interval
- }
- return x
- },
- drawGraph: function() {
-
- var colors = this.colors;
- var left = this.options.leftEdge
- var top = this.options.topEdge
- var width = this.options.gridWidth
- var height = this.options.gridHeight
- var x = this.x // x axis
- var ys = this.ys // y axes
- var xstep = x.length / 20
- var shade = this.options.shade
- var axis = this.options.axis
-
- this.canvas.g.txtattr.font = "11px 'sans-serif'";
- this.graph = this.canvas.g.linechart(left, top, width, height, x, ys, {
- nostroke: false,
- width: 1.5,
- axis: axis,
- colors: colors,
- axisxstep: xstep,
- shade: shade
- });
-
- this.formatAxes();
- },
- formatAxes: function() {
-
- /* clean up graph labels */
- this.graph.axis[0].text.items.getLast().hide()
- $each(this.graph.axis[0].text.items, function (time) {
-
- var unixTime = time.attr('text')
- var d = new Date(time.attr('text') * 1000);
- time.attr({'text': d.strftime("%H:%M")});
-
- time.mouseover(function () {
- this.attr({'text': d.strftime("%H:%M")});
- });
-
- /*
- time.mouseout(function () {
- this.attr({'text': d.strftime("%H:%M")});
- });
- */
- });
-
- $each(this.graph.axis[1].text.items, function (value) {
- // FIXME: no JS reference on train means awful rounding hacks!
- // if you are reading this, it's a bug!
- if (value.attr('text') > 1073741824) {
- var label = value.attr('text') / 1073741824;
- var unit = 'g'
- } else if (value.attr('text') > 1048576) {
- // and again :-(
- var label = value.attr('text') / 1048576;
- var unit = 'm'
- } else if (value.attr('text') > 1024) {
- var label = value.attr('text') / 1024;
- var unit = 'k';
- } else {
- var label = value.attr('text');
- var unit = ''
+ /* Get the maximum value across all sets.
+ * Used later on to determine the decimal place in the label. */
+ series.each(function(set) {
+ var setMax = set.data.max()
+ if ( setMax > max ) {
+ max = setMax
}
-
- var decimal = label.toString().split('.')
- if ($chk(this.previous) && this.previous.toString()[0] == label.toString()[0] && decimal.length > 1) {
- var round = '.' + decimal[1][0]
- } else {
- var round = ''
- }
-
- value.attr({'text': Math.floor(label) + round + unit})
- this.previous = value.attr('text')
});
- },
- buildEmbedder: function() {
- var pre = new Element('textarea', {
- 'id': 'embedder',
- 'class': 'embedder',
- 'html': this.embedCode(),
- 'styles': {
- 'width': '500px',
- 'padding': '3px'
+ this.chart = new Highcharts.Chart({
+ chart: {
+ renderTo: element,
+ defaultSeriesType: 'line',
+ marginRight: 200,
+ marginBottom: 25,
+ zoomType: 'xy',
+ height: 300,
+ events: {
+ load: function(e) {
+ setInterval(function() {
+ if (this.options.live) {
+ this.getData()
+ }
+ }.bind(this), 10000);
+ }.bind(this)
}
- });
- this.embedderContainer.grab(pre);
+ },
+ title: {
+ text: title,
+ style: {
+ fontSize: '20px',
+ fontWeight: 'bold',
+ color: "#333333"
+ }
+ },
+ xAxis: {
+ type: 'datetime',
+ labels: {
+ y: 20,
+ formatter: function() {
+ var d = new Date(this.value * 1000)
+ return d.format("%H:%M")
+ }
+ },
+ title: {
+ text: null
+ }
+ },
+ yAxis: {
+ title: {
+ text: ytitle
+ },
+ maxPadding: 0,
+ plotLines: [{
+ width: 0.5,
+ }],
+ labels: {
+ formatter: function() {
+ var places = max < 10 ? 2 : 0
+ return formatValue(this.value, places)
+ }
+ }
+ },
+ plotOptions: {
+ series: {
+ stacking: 'normal',
+ marker: {
+ enabled: false
+ },
+ states: {
+ hover: {
+ enabled: true,
+ marker: {
+ symbol: 'triangle'
+ }
+ }
+ }
+ }
+ },
+ tooltip: {
+ formatter: function() {
+ var tip;
+ tip = '<b>' + formatSeriesLabel(this.series.name).trim() + '</b>-> '
+ tip += formatValue(this.y, 2) + ' <br/>'
+ tip += formatDate(this.x)
- var slider = new Fx.Slide(pre, {
- duration: 200
- });
+ return tip
+ }
+ },
+ legend: {
+ layout: 'vertical',
+ align: 'right',
+ verticalAlign: 'top',
+ x: -10,
+ y: 60,
+ borderWidth: 0,
+ itemWidth: 186,
+ labelFormatter: function() {
+ return formatSeriesLabel(this.name)
+ },
+ itemStyle: {
+ cursor: 'pointer',
+ color: '#333333'
+ },
+ itemHoverStyle: {
+ color: '#777777'
+ }
- slider.hide();
+ },
+ series: series,
+ credits: {
+ enabled: false
+ }
+ });
- var toggler = new Element('a', {
- 'id': 'toggler',
- 'class': 'toggler',
- 'html': '(embed)',
- 'href': '#',
- 'styles': {
- 'font-size': '0.7em',
- }
- });
- toggler.addEvent('click', function(e) {
- e.stop();
- slider.toggle();
- });
- this.embedderTogglerContainer.grab(toggler);
+ this.buildDateSelector();
},
- embedCode: function() {
- baseurl = "{protocol}//{host}".substitute({'host': window.location.host, 'protocol': window.location.protocol});
- code = "<script src='{baseurl}/javascripts/visage.js' type='text/javascript'></script>".substitute({'baseurl': baseurl});
- code += "<div id='graph'></div>"
- code += "<script type='text/javascript'>window.addEvent('domready', function() { var graph = new visageGraph('graph', '{host}', '{plugin}', ".substitute({'host': this.options.host, 'plugin': this.options.plugin});
- code += "{"
- code += "width: 900, height: 220, gridWidth: 800, gridHeight: 200, baseurl: '{baseurl}'".substitute({'baseurl': baseurl});
- code += "}); });</script>"
- return code.replace('<', '<').replace('>', '>')
- },
- addDebugInterface: function() {
- var graph = this.graph;
+ buildDateSelector: function() {
/*
- graph.hoverColumn(function () {
- });
- */
- },
- addSelectionInterface: function() {
- var graph = this.graph;
- var parentElement = this.parentElement
- var gridHeight = this.options.gridHeight
- graph.selectionMade = true
- this.graph.clickColumn(function () {
- if ($chk(graph.selectionMade) && graph.selectionMade) {
- if ($defined(graph.selection)) {
- graph.selection.remove();
- }
- graph.selectionMade = false
- graph.selection = this.paper.rect(this.x, 0, 1, gridHeight);
- graph.selection.toBack();
- graph.selection.attr({fill: '#555', stroke: '#555', opacity: 0.4});
- graph.selectionStart = this.axis.toInt()
- } else {
- graph.selectionMade = true
- graph.selectionFinish = this.axis.toInt()
- var select = $(parentElement).getElement('div.timescale.container select')
- var hasSelected = select.getChildren('option').some(function(option) {
- return option.get('html') == 'selected'
- });
- if (!hasSelected) {
- var option = new Element('option', {
- html: 'selected',
- value: '',
- selected: true
+ * container
+ * \
+ * - form
+ * \
+ * - select
+ * | \
+ * | - option
+ * | |
+ * | - option
+ * |
+ * - submit
+ */
+ var currentDate = new Date;
+ var currentUnixTime = parseInt(currentDate.getTime() / 1000);
+
+ var container = $(this.parentElement);
+ var form = new Element('form', {
+ 'method': 'get',
+ 'events': {
+ 'submit': function(e, foo) {
+ e.stop();
+ e.target.getElement('select').getSelected().each(function(option) {
+ data = new Hash()
+ split = option.value.split('=')
+ data.set(split[0], split[1])
});
- select.grab(option)
- }
+ this.requestData = data
+
+ /* Draw everything again. */
+ this.getData();
+ }.bind(this)
}
});
- this.graph.hoverColumn(function () {
- if ($chk(graph.selection) && !graph.selectionMade) {
- var width = this.x - graph.selection.attr('x');
- graph.selection.attr({'width': width});
- }
- });
- },
- buildContainers: function() {
- this.embedderTogglerContainer = new Element('div', {
- 'class': 'embedder-toggler container',
- 'styles': {
- 'float': 'right',
- 'width': '20%',
- 'text-align': 'right',
- 'margin-right': '12px',
- 'padding-top': '4px'
- }
+ var select = new Element('select', { 'class': 'date timescale' });
+ var timescales = new Hash({ 'hour': 1, '2 hours': 2, '6 hours': 6, '12 hours': 12,
+ 'day': 24, '2 days': 48, '3 days': 72,
+ 'week': 168, '2 weeks': 336, 'month': 672 });
+ timescales.each(function(hour, label) {
+ var current = this.currentTimePeriod == 'last {label}'.substitute({'label': label });
+ var value = "start={start}".substitute({'start': currentUnixTime - (hour * 3600)});
+ var html = 'last {label}'.substitute({'label': label });
+
+ var option = new Element('option', {
+ html: html,
+ value: value,
+ selected: (current ? 'selected' : '')
+
+ });
+ select.grab(option)
});
- $(this.parentElement).grab(this.embedderTogglerContainer, 'top')
- this.timescaleContainer = new Element('div', {
- 'class': 'timescale container',
+ var submit = new Element('input', { 'type': 'submit', 'value': 'show' });
+
+ var liveToggler = new Element('input', {
+ 'type': 'checkbox',
+ 'id': this.parentElement + '-live',
+ 'name': 'live',
+ 'events': {
+ 'click': function() {
+ this.options.live = !this.options.live
+ }.bind(this)
+ },
'styles': {
- 'float': 'right',
- 'width': '20%'
+ 'margin-left': '4px',
+ 'cursor': 'pointer'
}
});
- $(this.parentElement).grab(this.timescaleContainer, 'top')
- this.labelsContainer = new Element('div', {
- 'class': 'labels container',
- 'title': 'click to hide',
+ var liveLabel = new Element('label', {
+ 'for': this.parentElement + '-live',
+ 'html': 'Live',
'styles': {
- 'float': 'left',
- 'margin-left': '80px',
- 'padding-bottom': '1em'
+ 'font-family': 'sans-serif',
+ 'font-size': '11px',
+ 'margin-left': '8px',
+ 'cursor': 'pointer'
}
});
- $(this.parentElement).grab(this.labelsContainer)
- this.embedderContainer = new Element('div', {
- 'class': 'embedder container',
+ var exportLink = new Element('a', {
+ 'href': this.dataURL(),
+ 'html': 'Export data',
'styles': {
- 'font-style': 'monospace',
- 'margin-left': '80px',
- 'font-size': '0.8em',
- 'clear': 'both'
- }
- });
- $(this.parentElement).grab(this.embedderContainer)
- },
- buildDateSelector: function() {
- /*
- * container
- * \
- * - form
- * \
- * - select
- * | \
- * | - option
- * | |
- * | - option
- * |
- * - submit
- */
- var currentDate = new Date;
- var currentUnixTime = parseInt(currentDate.getTime() / 1000);
+ 'font-family': 'sans-serif',
+ 'font-size': '11px',
+ 'margin-left': '8px',
+ },
+ 'events': {
+ 'mouseover': function(e) {
+ var url = e.target.get('href')
+ var options = this.requestData.toQueryString()
- var container = $(this.timescaleContainer);
- var form = new Element('form', {
- 'method': 'get',
- 'events': {
- 'submit': function(e, foo) {
- e.stop();
-
- /*
- * Get the selected option, turn it into a hash for
- * getData() to use.
- */
- data = new Hash()
- if (e.target.getElement('select').getSelected().get('html') == 'selected') {
- data.set('start', this.graph.selectionStart);
- data.set('finish', this.graph.selectionFinish);
- } else {
- e.target.getElement('select').getSelected().each(function(option) {
- split = option.value.split('=')
- data.set(split[0], split[1])
- currentTimePeriod = option.get('html') // is this setting a global?
- }, this);
- }
- this.requestData = data
-
- /* Nuke graph + labels. */
- this.graph.remove();
- delete this.x;
- $(this.labelsContainer).empty();
- $(this.timescaleContainer).empty();
- $(this.embedderContainer).empty();
- $(this.embedderTogglerContainer).empty();
- if ($defined(this.graph.selection)) {
- this.graph.selection.remove();
- }
- /* Draw everything again. */
- this.getData();
- }.bind(this)
+ if ( options != '' && ! url.contains('?') ) {
+ url += '?' + options
}
- });
- var select = new Element('select', { 'class': 'date timescale' });
- var timescales = new Hash({ 'hour': 1, '2 hours': 2, '6 hours': 6, '12 hours': 12,
- 'day': 24, '2 days': 48, '3 days': 72,
- 'week': 168, '2 weeks': 336, 'month': 672 });
- timescales.each(function(hour, label) {
- var current = this.currentTimePeriod == 'last {label}'.substitute({'label': label });
- var value = "start={start}".substitute({'start': currentUnixTime - (hour * 3600)});
- var html = 'last {label}'.substitute({'label': label });
+ e.target.set('href', url)
+ }.bind(this)
+ }
+ });
- var option = new Element('option', {
- html: html,
- value: value,
- selected: (current ? 'selected' : '')
-
- });
- select.grab(option)
- });
-
- var submit = new Element('input', { 'type': 'submit', 'value': 'show' });
-
- form.grab(select);
- form.grab(submit);
- container.grab(form);
+ form.grab(select)
+ form.grab(submit)
+ form.grab(liveToggler)
+ form.grab(liveLabel)
+ form.grab(exportLink)
+ container.grab(form, 'top')
},
- buildLabels: function() {
- //buildLabels: function(graphLines, instanceNames, dataSources, colors) {
- this.ys.each(function(set, index) {
- var path = this.graph.lines[index],
- color = this.colors[index]
- plugin = this.options.plugin
- instance = this.instances[index]
- metric = this.metrics[index]
- var container = new Element('div', {
- 'class': 'label plugin',
- 'styles': {
- 'padding': '0.2em 0.5em 0',
- 'float': 'left',
- 'width': '180px',
- 'font-size': '0.8em'
- },
- 'events': {
- 'mouseover': function(e) {
- e.stop();
- path.animate({'stroke-width': 3}, 300);
- //path.toFront();
- },
- 'mouseout': function(e) {
- e.stop();
- path.animate({'stroke-width': 1.5}, 300);
- //path.toBack();
- },
- 'click': function(e) {
- e.stop();
- path.attr('opacity') == 0 ? path.animate({'opacity': 1}, 350) : path.animate({'opacity': 0}, 350);
- }
- }
- });
- var box = new Element('div', {
- 'class': 'label plugin box ' + metric,
- 'html': ' ',
- 'styles': {
- 'background-color': color,
- 'width': '48px',
- 'height': '18px',
- 'float': 'left',
- 'margin-right': '0.5em'
- }
- });
+});
- // plugin/instance/metrics names can be unmeaningful. make them pretty
- var name;
- name = instance.replace(plugin, '');
- name = name.replace('tcp_connections', '')
- name = name.replace('ps_state', '')
- name = name.replace(plugin.split('-')[0], '')
- name += metric == "value" ? "" : " (" + metric + ")"
- name = name.replace(/^[-|_]*/, '')
+// buildEmbedder: function() {
+// var pre = new Element('textarea', {
+// 'id': 'embedder',
+// 'class': 'embedder',
+// 'html': this.embedCode(),
+// 'styles': {
+// 'width': '500px',
+// 'padding': '3px'
+// }
+// });
+// this.embedderContainer.grab(pre);
+//
+// var slider = new Fx.Slide(pre, {
+// duration: 200
+// });
+//
+// slider.hide();
+//
+// var toggler = new Element('a', {
+// 'id': 'toggler',
+// 'class': 'toggler',
+// 'html': '(embed)',
+// 'href': '#',
+// 'styles': {
+// 'font-size': '0.7em',
+// }
+// });
+// toggler.addEvent('click', function(e) {
+// e.stop();
+// slider.toggle();
+// });
+// this.embedderTogglerContainer.grab(toggler);
+// },
+// embedCode: function() {
+// baseurl = "{protocol}//{host}".substitute({'host': window.location.host, 'protocol': window.location.protocol});
+// code = "<script src='{baseurl}/javascripts/visage.js' type='text/javascript'></script>".substitute({'baseurl': baseurl});
+// code += "<div id='graph'></div>"
+// code += "<script type='text/javascript'>window.addEvent('domready', function() { var graph = new visageGraph('graph', '{host}', '{plugin}', ".substitute({'host': this.options.host, 'plugin': this.options.plugin});
+// code += "{"
+// code += "width: 900, height: 220, gridWidth: 800, gridHeight: 200, baseurl: '{baseurl}'".substitute({'baseurl': baseurl});
+// code += "}); });</script>"
+// return code.replace('<', '<').replace('>', '>')
+// },
- var desc = new Element('span', {
- 'class': 'label plugin description ' + metric,
- 'html': name
- });
-
- container.grab(box);
- container.grab(desc);
- $(this.labelsContainer).grab(container);
-
- }, this);
- }
-})
-
-var visageSparkline = new Class({
- Extends: visageGraph,
- options: {
- width: 450,
- height: 80,
- leftEdge: 1,
- topEdge: 1,
- gridWidth: 449,
- gridHeight: 79,
- columns: 60,
- rows: 8,
- gridBorderColour: '#ccc',
- shade: false,
- secureJSON: false,
- httpMethod: 'get',
- axis: "0 0 0 0"
- },
- graphData: function(data) {
-
- this.ys = []
- this.colors = []
- this.instances = []
- this.metrics = []
-
- var host = this.options.host
- var plugin = this.options.plugin
-
- $each(data[host][plugin], function(instance, iname) {
- $each(instance, function(metric, mname) {
- this.colors.push(metric.color)
- if ( !$defined(this.x) ) {
- this.x = this.buildXAxis(metric)
- }
- this.ys.push(metric.data)
- this.instances.push(iname) // labels
- this.metrics.push(mname) // labels
- }, this);
- }, this);
-
- this.drawGraph();
- }
-});