jquery flot
TRANSCRIPT
JQuery Flotby Arshavski Alexander
Charting libraries
A lot of choices - http://my.opera.com/tagawa/blog/list-of-javascript-charting-libraries
Good list of features
http://socialcompare.com/en/comparison/javascript-graphs-and-charts-libraries
Should work offline
Date-time axis
...
Flot works on:
Firefox 2.x+
Safari 3.0+
Opera 9.5+
Konqueror 4.x+
Internet Explorer 6+ (the excanvas Javascript emulation helper is used for IE < 9)
A lot of plugins and examples
Plugins - http://code.google.com/p/flot/wiki/Plugins
Bubble charts - https://github.com/ubermajestix/flot-plugins
Usage examples: http://code.google.com/p/flot/wiki/FlotUsage
It’s not all pink and rosy
Documentation sucks!
That’s why I’m here
What I want to do?
What I want to do?
What I want to do?
Imports
<link type="text/css" href="...jquery-ui.css"><link type="text/css" href="...jquery-ui.css"> <link type="text/css" href="...flot_layout.css" > <link type="text/css" href="...flot_layout.css" > <link type="text/css" href="...jquery-ui-1.8.16.custom.css"><link type="text/css" href="...jquery-ui-1.8.16.custom.css">
<script type="text/javascript" src="...jquery-1.5.1.min.js"></script> <script type="text/javascript" src="...jquery-1.5.1.min.js"></script> <script type="text/javascript" src="...jquery-ui-1.8.10.custom.min.js"></script><script type="text/javascript" src="...jquery-ui-1.8.10.custom.min.js"></script> <script type="text/javascript" src="...jquery.flot.min.js"></script> <script type="text/javascript" src="...jquery.flot.min.js"></script> <script type="text/javascript" src="...jquery.flot.pie.min.js"></script> <script type="text/javascript" src="...jquery.flot.pie.min.js"></script> <script type="text/javascript" src="...jquery.blockUI.js"></script><script type="text/javascript" src="...jquery.blockUI.js"></script>
Radio buttons
<div id="radio"> <div id="radio"> <input type="radio" id="connections_radio" name="radio" <input type="radio" id="connections_radio" name="radio" checked="checked" /><label for="connections_radio">Connections</label>checked="checked" /><label for="connections_radio">Connections</label> <input type="radio" id="usage_radio" name="radio" /><label <input type="radio" id="usage_radio" name="radio" /><label for="usage_radio">Usage</label> for="usage_radio">Usage</label> <input type="radio" id="export_radio" name="radio" /><label <input type="radio" id="export_radio" name="radio" /><label for="export_radio">Export</label>for="export_radio">Export</label> </div></div>
Tabs <div id="usage" style="display: none"> <div id="usage" style="display: none"> <div id="usage_tabs"> <div id="usage_tabs"> <ul> <ul>
<li><a href="#day_statistics">Day</a></li> <li><a href="#day_statistics">Day</a></li> <li><a href="#week_statistics">Week</a></li> <li><a href="#week_statistics">Week</a></li> <li><a href="#month_statistics">Month</a></li> <li><a href="#month_statistics">Month</a></li> <li><a href="#year_statistics">Year</a></li> <li><a href="#year_statistics">Year</a></li> </ul> </ul> <div id="day_statistics"> <div id="day_statistics"> <div id="graphs_container1" class="graph_container”><div id="graphs_container1" class="graph_container”> <div id="graph1"></div> <div id="graph1"></div> <div id="graph1_legend" class="graph_legend"></div> <div id="graph1_legend" class="graph_legend"></div> </div> </div> </div> </div> ......
</div></div> ...... </div></div>
Radio buttons $(function () { $(function () { $("#connections_radio").click(function(event) { $("#connections_radio").click(function(event) { $("#connections").show(); $("#connections").show(); $("#usage").hide(); $("#usage").hide();
$("#export").hide(); $("#export").hide(); }); }); $("#usage_radio").click(function(event) { $("#usage_radio").click(function(event) { $("#connections").hide(); $("#connections").hide();
$("#usage").show(); $("#usage").show(); $("#export").hide(); $("#export").hide();
}); }); $("#export_radio").click(function(event) { $("#export_radio").click(function(event) {
$("#connections").hide(); $("#connections").hide(); $("#usage").hide(); $("#usage").hide(); $("#export").show(); $("#export").show();
});}); });});
Tabs
$(function () { $(function () { ...... $("#connections_tabs").tabs(); $("#connections_tabs").tabs(); $("#usage_tabs").tabs(); $("#usage_tabs").tabs(); $("#usage_distribution_tabs").tabs();$("#usage_distribution_tabs").tabs(); });});
Till now...
As a python
guy it’s a lot of
code for me
already, so it’s
gonna be a mess
Refactoring <script type="text/javascript" src="...statistics.js"></script><script type="text/javascript" src="...statistics.js"></script>
$(function () { $(function () { ...... get_connections_statistics(); get_connections_statistics(); get_usage_statistics(); get_usage_statistics(); get_api_distribution_statistics(); get_api_distribution_statistics(); get_distribution_statistics();get_distribution_statistics(); ...... });});
{% include "statistics/connections.html" %} {% include "statistics/connections.html" %} {% include "statistics/usage.html" %} {% include "statistics/usage.html" %} {% include "statistics/export.html" %}{% include "statistics/export.html" %}
And now to the main part...
var weekdayNames = "Sunday Monday Tuesday Wednesday Thursday Friday var weekdayNames = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "); Saturday".split(" "); var shortMonthNames = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov var shortMonthNames = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" ");Dec".split(" ");
$.get('/manage/get_statistics_usage_data', {}, function(data){ $.get('/manage/get_statistics_usage_data', {}, function(data){ var stat_data = jQuery.parseJSON(data); var stat_data = jQuery.parseJSON(data); //variables init //variables init var now = new Date().getTime() + stat_data.time_offset; var now = new Date().getTime() + stat_data.time_offset; var weekday = new Date(now).getDay(); var weekday = new Date(now).getDay(); var month = new Date(now).getMonth(); var month = new Date(now).getMonth(); ... ...
And now to the main part...
//building weekly data //building weekly data var api_calls_points = stat_data.api_calls_weekly; var api_calls_points = stat_data.api_calls_weekly; var bandwidth_points = stat_data.bandwidth_weekly; var bandwidth_points = stat_data.bandwidth_weekly; for(var i=0; i<api_calls_points.length; i++) { for(var i=0; i<api_calls_points.length; i++) { graph2_ticks.push([7-i, weekdayNames[(weekday+7-i)%7]]);graph2_ticks.push([7-i, weekdayNames[(weekday+7-i)%7]]); api_calls_weekly.push([i, api_calls_points[i]]); api_calls_weekly.push([i, api_calls_points[i]]); bandwidth_weekly.push([i, bandwidth_points[i]]); bandwidth_weekly.push([i, bandwidth_points[i]]); }} ... ... //building yearly data //building yearly data var api_calls_points = stat_data.api_calls_yearly; var api_calls_points = stat_data.api_calls_yearly; var bandwidth_points = stat_data.bandwidth_yearly; var bandwidth_points = stat_data.bandwidth_yearly; for(var i=0; i<api_calls_points.length; i++) { for(var i=0; i<api_calls_points.length; i++) { graph4_ticks.push([12-i, shortMonthNames[(month+12-i)%12]]);graph4_ticks.push([12-i, shortMonthNames[(month+12-i)%12]]); api_calls_yearly.push([i, api_calls_points[i]]); api_calls_yearly.push([i, api_calls_points[i]]); bandwidth_yearly.push([i, bandwidth_points[i]]); bandwidth_yearly.push([i, bandwidth_points[i]]); }}
And now to the main part...
var options2 = { var options2 = { legend: { legend: {
position: "ne", position: "ne", container: $("#graph2_legend") container: $("#graph2_legend")
}, xaxis: { }, xaxis: { ticks: graph2_ticks ticks: graph2_ticks
}, yaxis: { }, yaxis: { min: 0, min: 0, tickDecimals: 0 //only whole numbers tickDecimals: 0 //only whole numbers
}, grid: { hoverable: true } }, grid: { hoverable: true } };};
xaxis: { //in case of time axis xaxis: { //in case of time axis mode: "time", mode: "time", timeformat: "%H:%M" timeformat: "%H:%M" },},
And now to the main part...
var var usage_plot2 = usage_plot2 = $.plot($("#graph2"), [ $.plot($("#graph2"), [ { { data: api_calls_weekly, data: api_calls_weekly,
label: "API calls", label: "API calls", lines: { show: true } lines: { show: true }
}, }, { {
label: "Bandwidth (KB)", label: "Bandwidth (KB)", data: bandwidth_weekly, data: bandwidth_weekly, lines: { show: true } lines: { show: true }
}, }, ], options2);], options2);
Till now...
What if I want to select a graph?
Graph Select $('.legendColorBox').parent().click(function() { $('.legendColorBox').parent().click(function() { var plot = usage_plot1; var plot = usage_plot1; var data = [api_calls_daily, bandwidth_daily]; var data = [api_calls_daily, bandwidth_daily]; var graph = $(this).parent().parent().parent().attr("id").split("_")[0]; var graph = $(this).parent().parent().parent().attr("id").split("_")[0]; if (graph == "graph2") { if (graph == "graph2") { plot = usage_plot2; plot = usage_plot2; data = [api_calls_weekly, bandwidth_weekly]; data = [api_calls_weekly, bandwidth_weekly]; } } ... ... if ($(this).children().text() == "API calls”) { if ($(this).children().text() == "API calls”) { plot.setData(get_plot_data([data[0], null, "lines", [], null, "lines"])); plot.setData(get_plot_data([data[0], null, "lines", [], null, "lines"])); } } if ($(this).children().text() == "Bandwidth (KB)") { if ($(this).children().text() == "Bandwidth (KB)") { plot.setData(get_plot_data([[], null, "lines", data[1], null, "lines"])); plot.setData(get_plot_data([[], null, "lines", data[1], null, "lines"])); } } plot.draw(); plot.draw(); ......
Graph Select var ticks = [graph2_ticks, graph3_ticks, graph4_ticks]; var ticks = [graph2_ticks, graph3_ticks, graph4_ticks]; if ($(this).siblings().text().search("Show all") == -1) { if ($(this).siblings().text().search("Show all") == -1) { $('<tr/>', { $('<tr/>', {
style: 'cursor: auto;' style: 'cursor: auto;' }).bind('click', {plot: plot, data: data, ticks: ticks, now: now},}).bind('click', {plot: plot, data: data, ticks: ticks, now: now}, show_all_usage_graphs) show_all_usage_graphs) .append("<td class='legendColorBox'></td><td>Show all</td>").appendTo($.append("<td class='legendColorBox'></td><td>Show all</td>").appendTo($(this).parent()); (this).parent()); } } });});
function show_all_usage_graphs(e) { function show_all_usage_graphs(e) { e.data.plot.setData(get_plot_data([e.data.data[0], null, "lines", e.data.plot.setData(get_plot_data([e.data.data[0], null, "lines", e.data.data[1], null, "lines"])); e.data.data[1], null, "lines"])); e.data.plot.draw(); e.data.plot.draw(); $(this).remove();$(this).remove(); }}
Till now...
What about tooltips?
I could take them from a lot of places. For example: http://jquerytools.org/
I decided to do it myself
Tooltips function add_usage_tooltips(now, ticks) { function add_usage_tooltips(now, ticks) { for (var i=1; i<=4; i++) { for (var i=1; i<=4; i++) { ... ... $("#graph" + i).bind("plothover", function (event, pos, item) { $("#graph" + i).bind("plothover", function (event, pos, item) { draw_tooltip(item, tick, now); draw_tooltip(item, tick, now); }); }); } } }}
function draw_tooltip(item, ticks, now) {function draw_tooltip(item, ticks, now) { ... ... var tooltip = get_tooltip_message(item, ticks, now); var tooltip = get_tooltip_message(item, ticks, now); showChartTooltip(tooltip, item); showChartTooltip(tooltip, item); ...... }}
Tooltips function showChartTooltip(contents, item) { function showChartTooltip(contents, item) { ... ... $("<div id='charttooltip'>" + contents + "</div>").css( $("<div id='charttooltip'>" + contents + "</div>").css( { {
position: 'absolute', position: 'absolute', display: 'none', display: 'none', top: item.pageY + 5, top: item.pageY + 5, left: item.pageX + 5, left: item.pageX + 5, border: '1px solid #bfbfbf', border: '1px solid #bfbfbf',
padding: '2px',padding: '2px', 'background-color': item.series.color, 'background-color': item.series.color,
opacity: 1 opacity: 1 }).appendTo("body").fadeIn(200); }).appendTo("body").fadeIn(200); ... ... }}
Till now...
How can I make bars?
$.plot($("#graph2"), [ $.plot($("#graph2"), [ { { data: api_calls_weekly, data: api_calls_weekly, label: "Clients API hourly", label: "Clients API hourly", bars: { show: true } //instead of: lines: { show: true } bars: { show: true } //instead of: lines: { show: true } }, }, ... ... ], options2);], options2);
By the way tooltips on bars looks
good...
For charts you should add:
<script type="text/javascript" src="...jquery.flot.pie.min.js"></script><script type="text/javascript" src="...jquery.flot.pie.min.js"></script>
Charts var options = { var options = { series: { series: { pie: { pie: {
show: true, show: true, radius: 1, radius: 1,
label: { label: { show: true, show: true, radius: 3/4, radius: 3/4, formatter: function(label, series){ formatter: function(label, series){
return '<div style="font-size:12pt;text-return '<div style="font-size:12pt;text-align:center;padding:2px;color:black;">'+label+'<br/>'+Math.round(series.percent)+'%</align:center;padding:2px;color:black;">'+label+'<br/>'+Math.round(series.percent)+'%</div>'; }, div>'; }, background: { opacity: 0.5 } background: { opacity: 0.5 } } }
} } } } }; }; $.plot($("#countries_piechart"), data, options);$.plot($("#countries_piechart"), data, options);
One last thing...
JQuery BlockUI Plugin: http://jquery.malsup.com/block/
BlockUI $(function () {$(function () { ... ... var message = '<img src=".../loader.gif" /> Please wait...'; var message = '<img src=".../loader.gif" /> Please wait...'; $("#usage_tabs").block({ message: message });$("#usage_tabs").block({ message: message }); ......
get_usage_statistics();get_usage_statistics();......
}}
function get_usage_statistics() {function get_usage_statistics() {$.get('.../get_statistics_usage_data', {}, function(data){$.get('.../get_statistics_usage_data', {}, function(data){ ...... $("#usage_tabs").unblock();$("#usage_tabs").unblock();});});
}}
<script type="text/javascript" src="...jquery.blockUI.js"></script><script type="text/javascript" src="...jquery.blockUI.js"></script>
BlockUI
Questions?
http://twitter.com/alexarsh
http://www.linkedin.com/pub/alexander-arshavski/a/833/26a