summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Wall <richard@largo>2011-01-09 15:36:01 +0000
committerRichard Wall <richard@largo>2011-01-09 15:36:01 +0000
commit2447194a8f52ba7577ef2a0e0929d433dfa292aa (patch)
treedb3d469c46249b35e7291ce1100e071d2bc5a6f4
parent7e7a9e36693919bd79a11be271a379303f581c54 (diff)
Simplify the example application - move most code to jarmon.js
-rw-r--r--docs/examples/index.html152
-rw-r--r--docs/examples/jarmon_example_recipes.js8
-rw-r--r--jarmon/jarmon.js158
3 files changed, 170 insertions, 148 deletions
diff --git a/docs/examples/index.html b/docs/examples/index.html
index ec5143d..e561b9e 100644
--- a/docs/examples/index.html
+++ b/docs/examples/index.html
@@ -16,154 +16,15 @@
<script type="text/javascript" src="../../jarmon/jarmon.js"></script>
<script type="text/javascript" src="jarmon_example_recipes.js"></script>
<script type="text/javascript">
- // Recipes for the charts on this page
-
- var application_recipe = {
- title: 'Jarmon Webserver TCP Stats',
- data: [
- ['data/tcpconns-8080-local/tcp_connections-CLOSE_WAIT.rrd', 0, 'CLOSE_WAIT', ''],
- ['data/tcpconns-8080-local/tcp_connections-SYN_RECV.rrd', 0, 'SYN_RECV', ''],
- ['data/tcpconns-8080-local/tcp_connections-TIME_WAIT.rrd', 0, 'TIME_WAIT', ''],
- ['data/tcpconns-8080-local/tcp_connections-CLOSED.rrd', 0, 'CLOSED', ''],
- ['data/tcpconns-8080-local/tcp_connections-FIN_WAIT2.rrd', 0, 'FIN_WAIT2', ''],
- ['data/tcpconns-8080-local/tcp_connections-FIN_WAIT1.rrd', 0, 'FIN_WAIT1', ''],
- ['data/tcpconns-8080-local/tcp_connections-ESTABLISHED.rrd', 0, 'ESTABLISHED', ''],
- ['data/tcpconns-8080-local/tcp_connections-LAST_ACK.rrd', 0, 'LAST_ACK', ''],
- ['data/tcpconns-8080-local/tcp_connections-LISTEN.rrd', 0, 'LISTEN', ''],
- ['data/tcpconns-8080-local/tcp_connections-SYN_SENT.rrd', 0, 'SYN_SENT', ''],
- ['data/tcpconns-8080-local/tcp_connections-CLOSING.rrd', 0, 'CLOSING', '']
- ],
- options: jQuery.extend(true, {yaxis: {tickDecimals: 0}}, jarmon.Chart.BASE_OPTIONS, jarmon.Chart.STACKED_OPTIONS)
- };
-
-
- function initialiseCharts() {
- /**
- * Setup chart date range controls and all charts
- **/
- var cc = new jarmon.ChartCoordinator($('.chartRangeControl'));
-
- var TABS = [
- ['System', ['cpu', 'memory','load']],
- ['Network', ['interface']],
- ['DNS', ['dns_query_types', 'dns_return_codes']]
- ];
-
- var p = new jarmon.Parallimiter(1);
- function serialDownloader(url) {
- return p.addCallable(jarmon.downloadBinary, [url]);
- }
-
- // Extract the chart template from the page
- var $chartTemplate = $('.chart-container').remove();
-
- var $tabs = $('<ul/>', {'class': 'css-tabs'}).appendTo('.tabbed-chart-interface');
- var $tabPanels = $('<div/>', {'class': 'css-panes charts'}).appendTo('.tabbed-chart-interface');
- var tabName, $tabPanel, chartNames;
- for(var i=0; i<TABS.length; i++) {
- tabName = TABS[i][0];
- chartNames = TABS[i][1];
- // Add a tab
- $('<li/>').append(
- $('<a/>', {href: ['#', tabName].join('')}).text(tabName)
- ).appendTo($tabs);
-
- // Add tab panel
- $tabPanel = $('<div/>').appendTo($tabPanels);
-
- for(var j=0; j<chartNames.length; j++) {
- cc.charts.push(
- new jarmon.Chart(
- $chartTemplate.clone().appendTo($tabPanel),
- jarmon.COLLECTD_RECIPES[chartNames[j]],
- serialDownloader
- )
- );
- }
- }
-
- // Setup dhtml tabs
- $(".css-tabs").tabs(".css-panes > div", {history: true});
-
- var t;
- // Initialise tabs and update charts when tab is clicked
- $(".css-tabs:first").bind('click', function(i) {
- // XXX: Hack to give the tab just enough time to become visible
- // so that flot can calculate chart dimensions.
- window.clearTimeout(t);
- t = window.setTimeout(function() { cc.update(); }, 100);
- });
-
- // Initialise all the charts
- cc.init();
- }
$(function() {
- // Add dhtml calendars to the date input fields
- $(".timerange_control img")
- .dateinput({
- 'format': 'dd mmm yyyy 00:00:00',
- 'max': +1,
- 'css': {'input': 'jquerytools_date'}})
- .bind('onBeforeShow', function(e) {
- var classes = $(this).attr('class').split(' ');
- var currentDate, input_selector;
- for(var i=0; i<=classes.length; i++) {
- input_selector = '[name="' + classes[i] + '"]';
- // Look for a neighboring input element whose name matches the
- // class name of this calendar
- // Parse the value as a date if the returned date.getTime
- // returns NaN we know it's an invalid date
- // XXX: is there a better way to check for valid date?
- currentDate = new Date($(this).siblings(input_selector).val());
- if(currentDate.getTime() != NaN) {
- $(this).data('dateinput')._input_selector = input_selector;
- $(this).data('dateinput')._initial_val = currentDate.getTime();
- $(this).data('dateinput').setValue(currentDate);
- break;
- }
- }
- })
- .bind('onHide', function(e) {
- // Called after a calendar date has been chosen by the user.
-
- // Use the sibling selector that we generated above before opening
- // the calendar
- var input_selector = $(this).data('dateinput')._input_selector;
- var oldStamp = $(this).data('dateinput')._initial_val;
- var newDate = $(this).data('dateinput').getValue();
- // Only update the form field if the date has changed.
- if(oldStamp != newDate.getTime()) {
- $(this).siblings(input_selector).val(
- newDate.toString().split(' ').slice(1,5).join(' '));
- // Trigger a change event which should automatically update the
- // graphs and change the timerange drop down selector to
- // "custom"
- $(this).siblings(input_selector).trigger('change');
- }
- });
-
- // Avoid overlaps between the calendars
- // XXX: This is a bit of hack, what if there's more than one set of calendar
- // controls on a page?
- $(".timerange_control img.from_custom").bind('onBeforeShow',
- function() {
- var otherVal = new Date(
- $('.timerange_control [name="to_custom"]').val());
-
- $(this).data('dateinput').setMax(otherVal);
- }
+ jarmon.buildTabbedChartUi(
+ $('.chart-container').remove(),
+ jarmon.CHART_RECIPES_COLLECTD,
+ $('.tabbed-chart-interface'),
+ jarmon.TAB_RECIPES_STANDARD,
+ $('.chartRangeControl')
);
- $(".timerange_control img.to_custom").bind('onBeforeShow',
- function() {
- var otherVal = new Date(
- $('.timerange_control [name="from_custom"]').val());
-
- $(this).data('dateinput').setMin(otherVal);
- }
- );
-
- initialiseCharts();
});
</script>
</head>
@@ -205,5 +66,6 @@
<div class="graph-legend"></div>
</div>
</div>
+
</body>
</html>
diff --git a/docs/examples/jarmon_example_recipes.js b/docs/examples/jarmon_example_recipes.js
index e2e42b9..610ecb2 100644
--- a/docs/examples/jarmon_example_recipes.js
+++ b/docs/examples/jarmon_example_recipes.js
@@ -9,7 +9,13 @@ if(typeof jarmon == 'undefined') {
var jarmon = {};
}
-jarmon.COLLECTD_RECIPES = {
+jarmon.TAB_RECIPES_STANDARD = [
+ ['System', ['cpu', 'memory','load']],
+ ['Network', ['interface']],
+ ['DNS', ['dns_query_types', 'dns_return_codes']]
+];
+
+jarmon.CHART_RECIPES_COLLECTD = {
'cpu': {
title: 'CPU Usage',
data: [
diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js
index 0919915..a2c862d 100644
--- a/jarmon/jarmon.js
+++ b/jarmon/jarmon.js
@@ -972,6 +972,89 @@ jarmon.ChartEditor.prototype._addDatasourceRow = function(record) {
};
+jarmon.TabbedInterface = function($tpl, recipe) {
+ this.$tpl = $tpl;
+ this.recipe = recipe;
+ this.placeholders = [];
+
+ var $tabBar = $('<ul/>', {'class': 'css-tabs'}).appendTo($tpl);
+ var $tabPanels = $('<div/>', {'class': 'css-panes charts'}).appendTo($tpl);
+ var tabName, $tabPanel, placeNames;
+ for(var i=0; i<recipe.length; i++) {
+ tabName = recipe[i][0];
+ placeNames = recipe[i][1];
+ // Add a tab
+ $('<li/>').append(
+ $('<a/>', {href: ['#', tabName].join('')}).text(tabName)
+ ).appendTo($tabBar);
+
+ // Add tab panel
+ $tabPanel = $('<div/>').appendTo($tabPanels);
+
+ for(var j=0; j<placeNames.length; j++) {
+ this.placeholders.push([
+ placeNames[j], $('<div/>').appendTo($tabPanel)]);
+ }
+ }
+
+ // Setup dhtml tabs
+ $tabBar.tabs($tabPanels.children('div'), {history: true});
+
+};
+
+jarmon.TabbedInterface.prototype.draw = function() {
+
+};
+
+
+jarmon.buildTabbedChartUi = function ($chartTemplate, chartRecipes,
+ $tabTemplate, tabRecipes,
+ $controlPanelTemplate) {
+ /**
+ * Setup chart date range controls and all charts
+ **/
+ var p = new jarmon.Parallimiter(1);
+ function serialDownloader(url) {
+ return p.addCallable(jarmon.downloadBinary, [url]);
+ }
+
+ var ti = new jarmon.TabbedInterface($tabTemplate, tabRecipes);
+
+ var charts = jQuery.map(
+ ti.placeholders,
+ function(el, i) {
+ return new jarmon.Chart(
+ $chartTemplate.clone().replaceAll(el[1]),
+ chartRecipes[el[0]],
+ serialDownloader
+ )
+ }
+ );
+
+ var cc = new jarmon.ChartCoordinator($controlPanelTemplate, charts);
+ // Update charts when tab is clicked
+ ti.$tpl.find(".css-tabs:first").bind(
+ 'click',
+ {'cc': cc},
+ function(e) {
+ var cc = e.data.cc;
+ // XXX: Hack to give the tab just enough time to become visible
+ // so that flot can calculate chart dimensions.
+ window.clearTimeout(cc.t);
+ cc.t = window.setTimeout(
+ function() {
+ cc.update();
+ }, 100);
+ }
+ );
+
+ // Initialise all the charts
+ cc.init();
+
+ return [charts, ti, cc];
+};
+
+
// Options common to all the chart on this page
jarmon.Chart.BASE_OPTIONS = {
grid: {
@@ -1038,10 +1121,10 @@ jarmon.timeRangeShortcuts = [
* @param ui {Object} A one element jQuery containing an input form and
* placeholders for the timeline and for the series of charts.
**/
-jarmon.ChartCoordinator = function(ui) {
+jarmon.ChartCoordinator = function(ui, charts) {
var self = this;
this.ui = ui;
- this.charts = [];
+ this.charts = charts;
// Style and configuration of the range timeline
this.rangePreviewOptions = {
@@ -1140,6 +1223,77 @@ jarmon.ChartCoordinator = function(ui) {
self.setTimeRange(ranges.xaxis.from, ranges.xaxis.to);
self.update();
});
+
+ // Add dhtml calendars to the date input fields
+ this.ui.find(".timerange_control img")
+ .dateinput({
+ 'format': 'dd mmm yyyy 00:00:00',
+ 'max': +1,
+ 'css': {'input': 'jquerytools_date'}})
+ .bind('onBeforeShow', function(e) {
+ var classes = $(this).attr('class').split(' ');
+ var currentDate, input_selector;
+ for(var i=0; i<=classes.length; i++) {
+ input_selector = '[name="' + classes[i] + '"]';
+ // Look for a neighboring input element whose name matches the
+ // class name of this calendar
+ // Parse the value as a date if the returned date.getTime
+ // returns NaN we know it's an invalid date
+ // XXX: is there a better way to check for valid date?
+ currentDate = new Date($(this).siblings(input_selector).val());
+ if(currentDate.getTime() != NaN) {
+ $(this).data('dateinput')._input_selector = input_selector;
+ $(this).data('dateinput')._initial_val = currentDate.getTime();
+ $(this).data('dateinput').setValue(currentDate);
+ break;
+ }
+ }
+ })
+ .bind('onHide', function(e) {
+ // Called after a calendar date has been chosen by the user.
+
+ // Use the sibling selector that we generated above before opening
+ // the calendar
+ var input_selector = $(this).data('dateinput')._input_selector;
+ var oldStamp = $(this).data('dateinput')._initial_val;
+ var newDate = $(this).data('dateinput').getValue();
+ // Only update the form field if the date has changed.
+ if(oldStamp != newDate.getTime()) {
+ $(this).siblings(input_selector).val(
+ newDate.toString().split(' ').slice(1,5).join(' '));
+ // Trigger a change event which should automatically update the
+ // graphs and change the timerange drop down selector to
+ // "custom"
+ $(this).siblings(input_selector).trigger('change');
+ }
+ });
+
+ // Avoid overlaps between the calendars
+ // XXX: This is a bit of hack, what if there's more than one set of calendar
+ // controls on a page?
+ this.ui.find(".timerange_control img.from_custom").bind(
+ 'onBeforeShow',
+ {self: this},
+ function(e) {
+ var self = e.data.self;
+ var otherVal = new Date(
+ self.ui.find('.timerange_control [name="to_custom"]').val());
+
+ $(this).data('dateinput').setMax(otherVal);
+ }
+ );
+ this.ui.find(".timerange_control img.to_custom").bind(
+ 'onBeforeShow',
+ {self: this},
+ function(e) {
+ var self = e.data.self;
+ var otherVal = new Date(
+ self.ui.find('.timerange_control [name="from_custom"]').val());
+
+ $(this).data('dateinput').setMin(otherVal);
+ }
+ );
+
};