+ var options = {
+\r width: 600,\r
+ height: 400,\r
+ showRowNumber: false,\r
+ pages: true,\r
+ numRows: 9,\r
+ backgroundColor: "black"\r
+ };\r
+\r
+ // ask django for a data source URL to use for the graphs\r
+\r
+ function updateDataSourceUrl() {\r
+ var sliceName = $("#historical_slicename :selected").text();\r
+ var queryString = "/analytics/bigquery/?sum=@bytes_sent&avg=@cpu&groupBy=Time,city,@hostname,@site&slice=" + sliceName;\r
+\r
+ $.ajax({\r
+ url: queryString,\r
+ dataType: 'json',\r
+ type: 'GET',\r
+ success: function (newData) {\r
+ sendAndDraw(newData["dataSourceUrl"])\r
+ }\r
+ });\r
+ }\r
+\r
+ TIME_COL = 0;\r
+ BANDWIDTH_COL = 2;\r
+ CPU_COL = 1;\r
+ CITY_COL = 3;\r
+ NODE_COL = 4;\r
+ SITE_COL = 5;\r
+\r
+ google.setOnLoadCallback(function () {\r
+ $('#historical_slicename').change(function()\r
+ {\r
+ updateDataSourceUrl();\r
+ });\r
+\r
+ updateDataSourceUrl();\r
+ });\r
+\r
+ function showSiteTimeAgg(dt) {\r
+ var lineChart = new google.visualization.ChartWrapper({\r
+ 'chartType': 'LineChart',\r
+ 'containerId': 'chart-site-time',\r
+ 'options': {\r
+ 'width': 320,\r
+ 'height': 300,\r
+ 'title': 'Network-wide usage',\r
+ 'pages': true,\r
+ 'numRows': 9\r
+ },\r
+ 'view': {\r
+ 'columns': [0, 1, 2]\r
+ }\r
+ });\r
+ lineChart.setDataTable(dt);\r
+ lineChart.draw();\r
+ }\r
+\r
+ function showSiteAgg(dt) {\r
+ var barChart = new google.visualization.ChartWrapper({\r
+ 'chartType': 'ColumnChart',\r
+ 'containerId': 'chart-site-agg',\r
+ 'options': {\r
+ 'width': 670,\r
+ 'height': 300,\r
+ 'title': 'Site-wise usage',\r
+ 'pages': true,\r
+ 'numRows': 9\r
+ },\r
+ 'view': {\r
+ 'columns': [1, 2, 3]\r
+ }\r
+ });\r
+ barChart.setDataTable(dt);\r
+ barChart.draw();\r
+ var geoChart = new google.visualization.ChartWrapper({\r
+ 'chartType': 'GeoChart',\r
+ 'containerId': 'chart-geo',\r
+ 'options': {\r
+ 'width': 320,\r
+ 'height': 300,\r
+ 'displayMode': 'markers',\r
+ 'region': '021',\r
+ 'title': 'Usage map',\r
+ colorAxis: {\r
+ colors: ['green', 'purple', 'red']\r
+ }\r
+ },\r
+ 'view': {\r
+ 'columns': [0, 2, 3]\r
+ }\r
+ });\r
+ geoChart.setDataTable(dt);\r
+ geoChart.draw();\r
+\r
+/* var histogram = new google.visualization.ChartWrapper({\r
+ 'chartType': 'Histogram',\r
+ 'containerId': 'chart-histo',\r
+ 'options': {\r
+ 'width': 300,\r
+ 'height': 300,\r
+ },\r
+ 'title': 'Sites by load',\r
+ 'view': {\r
+ 'columns': [1, 2]\r
+ }\r
+ });\r
+ histogram.setDataTable(dt);\r
+ histogram.draw(); */\r
+\r
+ }\r
+\r
+ function handleResponse(response) {\r
+ var timeSlider = new google.visualization.ControlWrapper({\r
+ 'controlType': 'DateRangeFilter',\r
+ 'containerId': 'control1',\r
+ 'options': {\r
+ 'filterColumnLabel': 'Time',\r
+ ui: {\r
+ ticks: 10,\r
+ step: "minute"\r
+ }\r
+ }\r
+ });\r
+\r
+ var categoryPicker = new google.visualization.ControlWrapper({\r
+ 'controlType': 'CategoryFilter',\r
+ 'allowMultiple': true,\r
+ 'containerId': 'control2',\r
+ 'options': {\r
+ 'filterColumnLabel': 'site',\r
+ 'ui': {\r
+ 'labelStacking': 'vertical',\r
+ 'allowTyping': false\r
+ }\r
+ }\r
+ });\r
+\r
+ var proxy = new google.visualization.ChartWrapper({\r
+ 'chartType': 'Table',\r
+ 'containerId': 'chart7',\r
+ 'options': {\r
+ 'width': 800,\r
+ 'height': 300,\r
+ pageSize: 5,\r
+ page: 'enable',\r
+ 'legend': 'none',\r
+ 'title': 'Nodes'\r
+ },\r
+ 'view': {\r
+ 'columns': [0, 1, 2, 3, 4, 5]\r
+ }\r
+ });\r
+\r
+ function avg_bandwidth(arr) {\r
+ var ret = 0;
+ for (var i = 0; i < arr.length; i++) {
+ ret+=arr[i]*8.0/1024.0/1024.0/1024.0;
+ }
+ if (arr.length==0) {
+ return 0;
+ }
+ return ret/arr.length;
+ }\r
+\r
+ function sum_bytes_sent_as_bw(arr) {\r
+ var ret = 0;
+ for (var i = 0; i < arr.length; i++) {
+ ret+=arr[i]*8.0/1024.0/1024.0/1024.0;
+ }
+ return ret/60.0;
+ }\r
+\r
+ function sum_bytes_sent_as_GB(arr) {\r
+ var ret = 0;
+ for (var i = 0; i < arr.length; i++) {
+ ret+=arr[i]/1024.0/1024.0/1024.0;
+ }
+ return ret;
+ }\r
+\r
+ function fixDate2(unixDate) {\r
+ // not completely sure why we have to do this, as the data was in\r
+ // javascript Date() objects to start with. If we don't do it,\r
+ // then the horizontal axis will be blank.\r
+ return new Date(unixDate);
+ }\r
+\r
+ var format0dp = new google.visualization.NumberFormat({fractionDigits:0});\r
+ var format2dp = new google.visualization.NumberFormat({fractionDigits:2});\r
+\r
+ // Create a group for charts that will have a horizontal axis that is\r
+ // time.\r
+\r
+ google.visualization.events.addListener(proxy, 'ready', function () {\r
+ var dt = proxy.getDataTable();\r
+ var groupedData1 = google.visualization.data.group(dt, [{\r
+ column: TIME_COL,
+ type: 'datetime',
+ modifier: fixDate2,
+ }], [{\r
+ column: CPU_COL,\r
+ type: 'number',\r
+ label: "avg cpu",\r
+ aggregation: google.visualization.data.avg\r
+ }, {\r
+ column: BANDWIDTH_COL,\r
+ type: 'number',\r
+ label: "Gbps",\r
+ aggregation: sum_bytes_sent_as_bw\r
+ }]);\r
+\r
+ format0dp.format(groupedData1,1);\r
+ format2dp.format(groupedData1,2);\r
+\r
+ showSiteTimeAgg(groupedData1);\r
+ });\r
+\r
+ // Create a group for charts that will have a horizontal axis that is\r
+ // city or site.\r
+\r
+ google.visualization.events.addListener(proxy, 'ready', function () {\r
+ var dt = proxy.getDataTable();\r
+ var groupedData0 = google.visualization.data.group(dt, [CITY_COL, SITE_COL], [{\r
+ column: CPU_COL,\r
+ type: 'number',\r
+ label: 'avg cpu',\r
+ aggregation: google.visualization.data.avg\r
+ }, {\r
+ column: BANDWIDTH_COL,\r
+ type: 'number',\r
+ label: "GB sent",\r
+ aggregation: sum_bytes_sent_as_GB\r
+ }]);\r
+\r
+ format0dp.format(groupedData0,2);\r
+ format2dp.format(groupedData0,3);\r
+\r
+ showSiteAgg(groupedData0);\r
+ });\r
+\r
+ data = response.getDataTable();\r
+ new google.visualization.Dashboard(document.getElementById('dashboard')).\r
+ // Establish bindings, declaring the both the slider and the category\r
+ // picker will drive both charts.\r
+ bind([categoryPicker, timeSlider], [proxy]).\r
+ // Draw the entire dashboard.\r
+ draw(data);\r
+\r
+ }\r
+\r
+ function sendAndDraw(queryString) {\r
+ query = new google.visualization.Query(queryString)\r
+ query && query.abort();\r
+ query.send(function (response) {\r
+ handleResponse(response);\r
+ });\r
+ }