(function($, block) { // a simple rolling chart with memory block.fn.rolling_chart = function(config) { // combine default configuration with user configuration var options = $.extend({ memory: 100, // required!! series: { 'default': {data: []} }, // flot initialization options options: { xaxis: { show: false } } }, config); // maintain state for this block var data = {}; for(var k in options.series) { data[k] = (options.series[k].data || []).slice(); } // function to project our state to something the library understands var prepare_data = function() { var result = []; // process each series for(var k in data) { var series = data[k]; var points = []; // create point pairs and gap values for(var i in series) { if(series[i] == null) { points.push(null); } else { points.push([i, series[i]]); } } // combine state data with series configuration by user result.push($.extend(options.series[k], {data: points})); } return result; }; // initial setup of library state (also builds necessary HTML) var plot = $.plot(this.$element, prepare_data(), options.options); // register actions for this block this.actions({ 'add': function(e, message) { // if the 'value' field is used, update all series (useful with a single series) if(typeof message.values == 'undefined' && typeof message.value != 'undefined') { message.values = {} for(var k in options.series) { message.values[k] = message.value; } } // update all series for(var k in options.series) { // roll memory if(data[k].length > options.memory) { data[k] = data[k].slice(1); } // insert value or gap (in case of null) data[k].push(message.values[k]); } // update HTML plot.setData(prepare_data()); plot.setupGrid(); plot.draw(); } }); // return element to allow further work return this.$element; } // // // // a simple linechart example block.fn.linechart = function(config) { var options = $.extend({ // required series : {default:{}}, // flot initialization options options : {} }, config); // create empty linechart with parameter options var plot = $.plot(this.$element, [],options.options); // dict containing the labels and values var linedata_series = {}; var linedata_first; var initline = function(series) { linedata_first = undefined; for(var k in series) { var si = series[k]; si.data = []; linedata_series[k] = si; if ( linedata_first == undefined ) linedata_first = si; } } initline(options.series); var addline = function(label, values) { var data; if (linedata_series.hasOwnProperty(label)) data = linedata_series[label].data; else data = linedata_first.data; for(var v in values) { data.push(values[v]); } redraw(); } var setline = function(label, values) { if (linedata_series.hasOwnProperty(label)) linedata_series[label].data = values; else linedata_first.data = values; redraw(); } var redraw = function() { var result = []; for(var k in linedata_series) { if (linedata_series.hasOwnProperty(k)) { var line_serie = linedata_series[k]; result.push({label:k,data:line_serie.data}); } } plot.setData(result); plot.setupGrid(); plot.draw(); } var reset = function() { initline(options.series); } this.actions({ 'set': function(e, message) { setline(message.series, message.value); }, 'add': function(e, message) { addline(message.series, message.value); }, 'reset': function(e, message) { reset(); } }); // return element to allow further work return this.$element; } // // // // a simple barchart example block.fn.barchart = function(config) { var options = $.extend({ filter_function : function(category,val,max) { return true; }, // required series : { "default":{ data: {}, label: "default", bars: { show: true, barWidth: 0.2, align: "left" } } }, // flot initialization options options: { xaxis: { mode: "categories", tickLength: 0 }} }, config); var bardata_series = options.series; var bardata_first; for (bardata_first in bardata_series) break; var translate_bar = function() { var result = []; for(var k in bardata_series) { if (bardata_series.hasOwnProperty(k)) { var newserie = jQuery.extend({}, bardata_series[k]); var newdata = []; var data = newserie.data; var max = 0; for(var l in data) { if (data.hasOwnProperty(l)) { max = Math.max(max, data[l]); } } for(var l in data) { if (data.hasOwnProperty(l)) { if ( options.filter_function(l,data[l],max) ) newdata.push([l,data[l]]); } } newserie.data = newdata; result.push(newserie); } } return result; } var plot = $.plot(this.$element, translate_bar(), options.options); var addbar = function(serie_label, category, value) { var data; if ( serie_label == undefined ) data = bardata_series[bardata_first].data; else data = bardata_series[serie_label].data; if (data.hasOwnProperty(category)) data[category] = (data[category] + value); else data[category] = value; redraw(); } var setbar = function(serie_label, category, value) { var data; if ( serie_label == undefined ) data = bardata_series[bardata_first].data; else data = bardata_series[serie_label].data; data[category] = value; redraw(); } var redraw = function() { plot.setData(translate_bar()); plot.setupGrid(); plot.draw(); } var reset = function() { for(var k in bardata_series) { if (bardata_series.hasOwnProperty(k)) { bardata_series[k].data = {}; } } } this.actions({ 'set': function(e, message) { setbar(message.series,message.value[0],message.value[1]); }, 'add': function(e, message) { addbar(message.series,message.value[0],message.value[1]); }, 'reset': function(e, message) { reset(); } }); // return element to allow further work return this.$element; } // // // // a simple piechart example block.fn.piechart = function(config) { var options = $.extend({ // see: http://www.flotcharts.org/flot/examples/series-pie/ filter_function : function(category,val,max) { return true; }, options : { series: { pie: { show: true } }, // demo crashes with this option // legend: { show: false } }}, config); // create empty piechart with parameter options var plot = $.plot(this.$element, [],options.options); // dict containing the labels and values var piedata_dict = {}; var addpie = function(label, value) { if (piedata_dict.hasOwnProperty(label)) piedata_dict[label] = (piedata_dict[label] + value); else piedata_dict[label] = value; redraw(); } var setpie = function(label, value) { piedata_dict[label] = value; redraw(); } var redraw = function() { var result = []; var max = 0; for(var k in piedata_dict) { if (piedata_dict.hasOwnProperty(k)) { max = Math.max(max, piedata_dict[k]); } } for(var k in piedata_dict) { if (piedata_dict.hasOwnProperty(k)) { if ( options.filter_function(k,piedata_dict[k],max) ) result.push({label:k,data:piedata_dict[k]}); } } plot.setData(result); plot.setupGrid(); plot.draw(); } var reset = function() { piedata_dict = {}; } this.actions({ 'set': function(e, message) { setpie(message.value[0],message.value[1]); }, 'add': function(e, message) { addpie(message.value[0],message.value[1]); }, 'reset': function(e, message) { reset(); } }); // return element to allow further work return this.$element; } })(jQuery, block);