Create a dashboard based on a collection
Introduction
Dashboards let you get a high level summary information about data. This tutorial will show how to create pie and column charts based on data stored within a RunMyProcess collection.
Practice
To configure a RunMyProcess dashboard with pie and column charts, we will use Google Visualisation for chart rendering, and a collection as source of data.
We will need this two predefined Javascript functions :
The drawPieChart function allows to draw a pie chart:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //Display a PieChart function drawPieChart(html_id, array_data, array_column, chart_title, chart_width, chart_height) { // Create our data table. var data = new google.visualization.DataTable(); for (i = 0; i < array_column.length; i++) { data.addColumn(array_column[i].type, array_column[i].title); } var array_array_data = new Array(); for (i = 0; i < array_data.length; i++) { array_array_data.push([array_data[i].label, array_data[i].value]); } data.addRows(array_array_data); // Instantiate and draw our chart, passing in some options. var chart = new google.visualization.PieChart(document.getElementById(html_id)); chart.draw(data, { width : chart_width, height : chart_height, is3D : true, title : chart_title, isStack : true }); } |
The drawColumnChart function allows to draw a column chart:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | //Display a ColumnChart function drawColumnChart(html_id, array_data, array_column, chart_title, chart_width, chart_height, isMultiChart) { /*If The column chart is not multi columns*/ if (!isMultiChart) { var data = new google.visualization.DataTable(); for (i = 0; i < array_column.length; i++) { data.addColumn(array_column[i].type, array_column[i].title); } var array_array_data = new Array(); for (i = 0; i < array_data.length; i++) { array_array_data.push([array_data[i].label, array_data[i].value]); } data.addRows(array_array_data); } else { var array_column_title = new Array(); for (i = 0; i < array_column.length; i++) { array_column_title[i] = array_column[i].title; } var lastResultArray = new Array(); lastResultArray.push(array_column_title); for (i = 0; i < array_data.length; i++) { var array_data_value = new Array(); array_data_value.push(array_data[i].label); for (key in array_data[i].value) { array_data_value.push(array_data[i].value[key]); } lastResultArray.push(array_data_value); } var data = google.visualization.arrayToDataTable(lastResultArray); } var chart = new google.visualization.ColumnChart(document.getElementById(html_id)); chart.draw(data, { width : chart_width, height : chart_height, is3D : true, title : chart_title, isStack : true }); } |
Getting Started
This represents the content of my collection:
Let's assume that we want to display the number of cars per state. Therefore, we will use the aggregate function as follow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function load_get_stats() { var pipelines = [{ "$group" : { "_id" : { "State" : "$state" }, "Total" : { "$sum" : "$nb_of_cars" } } }, { "$project" : { "STATE" : "$_id.State", "TOTAL" : "$Total" } } ]; col_my_collection.aggregateCallback(pipelines, {}, load_stats_ok, load_stats_ko); } |
The load_stats_ok function will pass aggregation result to both drawPieChart and drawColumnChart functions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | function load_stats_ok(result) { var array_data = new Array(); for (var i = 0; i < result.length; i++) { array_data.push({ "label" : result[i].STATE, "value" : parseInt(result[i].TOTAL) }); } var array_column = [{ "type" : "string", "title" : "State" }, { "type" : "number", "title" : "Total Nb Of Cars" } ]; var html_id_pie_chart = "chart_div2"; var html_id_column_chart = "chart_div1"; var chart_title = "Total Nb Of Cars"; var chart_width = 0; var chart_height = 240; drawPieChart(html_id_pie_chart, array_data, array_column, chart_title, chart_width, chart_height); drawColumnChart(html_id_column_chart, array_data, array_column, chart_title, chart_width, chart_height, false); } |
The load_stats_ko function will pop up a message in case of error while loading data from the collection:
1 | function load_stats_ko(result) {alert("ko "+JSON.stringify(result));} |
Let's assume that we want to display the number of cars and the numbers of motors per state. Therefore, we will use the aggregate function as follow:
The load_stats_multi_chart function will retrieve data to be shown in the charts from the collection:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | function load_stats_multi_chart() { var my_pipelines = [{ "$group" : { "_id" : { "State" : "$state" }, "Total_Cars" : { "$sum" : "$nb_of_cars" }, "Total_Motors" : { "$sum" : "$nb_of_motors" } } }, { "$project" : { "state" : "$_id.State", "TOTAL_CARS" : "$Total_Cars", "TOTAL_MOTORS" : "$Total_Motors" } } ]; col_my_collection.aggregateCallback(my_pipelines, {}, load_stats_multi_ok, load_stats_multi_ko); } |
The load_stats_multi_ok function will pass aggregation result to drawColumnChart function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | function load_stats_multi_ok(result) { var array_data_multi = new Array(); var my_value = {}; var value_array = new Array(); for (var i = 0; i < result.length; i++) { my_value = {}; my_value.TOTAL_CARS = parseInt(result[i].TOTAL_CARS); my_value.TOTAL_MOTORS = parseInt(result[i].TOTAL_MOTORS); value_array[i] = my_value; } for (var i = 0; i < result.length; i++) { array_data_multi.push({ "label" : result[i].state, "value" : value_array[i] }); } var array_column_multi = [{ "type" : "string", "title" : "State" }, { "type" : "number", "title" : "Total Nb Of Cars" }, { "type" : "number", "title" : "Total Nb Of Motors" } ]; var html_id = "chart_div3"; var chart_title = "Total Nb Of Cars And Motors"; var chart_width = 0; var chart_height = 240; drawColumnChart(html_id, array_data_multi, array_column_multi, chart_title, chart_width, chart_height, true); } |
The load_stats_multi_ko function will pop up a message in case of error while loading data from the collection:
1 | function load_stats_multi_ko(result) {alert("ko "+JSON.stringify(result));} |
Data Structure
The drawColumnChart function will take as input parameter an array with format as below:
- In case it's a Multi-Chart:
array_data structure will look like:
1 2 3 | [{"label":"Arizona","value":{"TOTAL_CARS":4,"TOTAL_MOTORS":5}}, {"label":"Florida","value":{"TOTAL_CARS":2,"TOTAL_MOTORS":3}}, {"label":"Alaska","value":{"TOTAL_CARS":5,"TOTAL_MOTORS":3}}] |
array_column structure will look like:
1 2 3 | [{ "type" : "string", "title" : "State" }, { "type" : "number", "title" : "Total Nb Of Cars" }, { "type" : "number", "title" : "Total Nb Of Motors" }] |
- In case it is not a Multi-Chart:
array_data structure will look like:
1 2 3 | [{"label":"Arizona","value":4}, {"label":"Florida","value":2}, {"label":"Alaska","value":5}] |
array_column structure will look like:
1 2 | [{ "type" : "string", "title" : "State"}, { "type" : "number", "title" : "Total Nb Of Cars"}] |
The drawPieChart function will take the same format of input parameter as for drawColumnChart / non-Multi-Chart.
Important : The first column of column_array should have string as type. All other columns must have number as type.
Web Interface
Since we have the definitions of the functions, let's create our Web Interface. - Create a new Web Interface, title 'Dashboard'. - Go to JavaScript tab - Insert as HEADER the Google visualization library:
1 | https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22corechart%22%5D%7D%5D%7D |
1 | - Go to the Design tab: |
(1) Create a HTML widget with following code:
1 | <div id="chart_div1"><div> |
(2) Create a HTML widget with following code:
1 | <div id="chart_div2"><div> |
(3) Create a HTML widget with following code:
1 | <div id="chart_div3"><div> |
(4) Create a hidden split widget
(5) Create a Javascript widget containing all of the functions described above.
This is the Javascript code to be used:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | //Display a PieChart function drawPieChart(html_id, array_data, array_column, chart_title, chart_width, chart_height) { // Create our data table. var data = new google.visualization.DataTable(); for (i = 0; i < array_column.length; i++) { data.addColumn(array_column[i].type, array_column[i].title); } var array_array_data = new Array(); for (i = 0; i < array_data.length; i++) { array_array_data.push([array_data[i].label, array_data[i].value]); } data.addRows(array_array_data); // Instantiate and draw our chart, passing in some options. var chart = new google.visualization.PieChart(document.getElementById(html_id)); chart.draw(data, { width : chart_width, height : chart_height, is3D : true, title : chart_title, isStack : true }); } //Display a ColumnChart function drawColumnChart(html_id, array_data, array_column, chart_title, chart_width, chart_height, isMultiChart) { /*If The column chart is not multi columns*/ if (!isMultiChart) { var data = new google.visualization.DataTable(); for (i = 0; i < array_column.length; i++) { data.addColumn(array_column[i].type, array_column[i].title); } var array_array_data = new Array(); for (i = 0; i < array_data.length; i++) { array_array_data.push([array_data[i].label, array_data[i].value]); } data.addRows(array_array_data); } else { var array_column_title = new Array(); for (i = 0; i < array_column.length; i++) { array_column_title[i] = array_column[i].title; } var lastResultArray = new Array(); lastResultArray.push(array_column_title); for (i = 0; i < array_data.length; i++) { var array_data_value = new Array(); array_data_value.push(array_data[i].label); for (key in array_data[i].value) { array_data_value.push(array_data[i].value[key]); } lastResultArray.push(array_data_value); } var data = google.visualization.arrayToDataTable(lastResultArray); } var chart = new google.visualization.ColumnChart(document.getElementById(html_id)); chart.draw(data, { width : chart_width, height : chart_height, is3D : true, title : chart_title, isStack : true }); } function load_get_stats() { var pipelines = [{"$group":{"_id":{"State":"$state"},"Total":{"$sum":"$nb_of_cars"}}},{"$project":{"STATE":"$_id.State","TOTAL":"$Total"}}]; col_my_collection.aggregateCallback(pipelines ,{},load_stats_ok,load_stats_ko); } function load_stats_ok(result){ var array_data = new Array(); for (var i = 0; i < result.length; i++) { array_data.push({"label":result[i].STATE,"value":parseInt(result[i].TOTAL)}); } var array_column = [{ "type" : "string", "title" : "State" }, { "type" : "number", "title" : "Total Nb Of Cars" } ]; var html_id_pie_chart = "chart_div2"; var html_id_column_chart = "chart_div1"; var chart_title = "Total Nb Of Cars"; var chart_width = 0; var chart_height = 240; drawPieChart(html_id_pie_chart, array_data, array_column, chart_title, chart_width, chart_height); drawColumnChart(html_id_column_chart, array_data, array_column, chart_title, chart_width, chart_height,false); } function load_stats_ko(result) {alert("ko"+JSON.stringify(result));} function load_stats_multi_chart() { var my_pipelines = [{"$group":{"_id":{"State":"$state"},"Total_Cars":{"$sum":"$nb_of_cars"},"Total_Motors":{"$sum":"$nb_of_motors"}}},{"$project":{"state":"$_id.State","TOTAL_CARS":"$Total_Cars","TOTAL_MOTORS":"$Total_Motors"}}]; col_my_collection.aggregateCallback(my_pipelines, {}, load_stats_multi_ok, load_stats_multi_ko); } function load_stats_multi_ok(result){ var array_data_multi = new Array(); var my_value = {}; var value_array = new Array(); for (var i = 0; i < result.length; i++) { my_value = {}; my_value.TOTAL_CARS = parseInt(result[i].TOTAL_CARS); my_value.TOTAL_MOTORS = parseInt(result[i].TOTAL_MOTORS); value_array[i] = my_value; } for (var i = 0; i < result.length; i++) { array_data_multi.push({"label":result[i].state,"value":value_array[i]}); } var array_column_multi = [{ "type" : "string", "title" : "State" }, { "type" : "number", "title" : "Total Nb Of Cars" },{ "type" : "number", "title" : "Total Nb Of Motors" } ]; var html_id = "chart_div3"; var chart_title = "Total Nb Of Cars And Motors"; var chart_width = 0; var chart_height = 240; drawColumnChart(html_id, array_data_multi, array_column_multi, chart_title, chart_width, chart_height, true); } function load_stats_multi_ko(result) {alert("ko"+JSON.stringify(result));} load_get_stats(); load_stats_multi_chart(); |
Do note, you will have to replace the following parameters with your own values: - Charts labels/title - The value true/false in the drawColumnChart function will indicate if the data structure sent to the function represents a single column or an array of columns.
Save your Web Interface and preview it.
Note: Every chart will need its associated chart_divXX HTML div id to be displayed.
Please give details of the problem