Newer
Older
Authors: Tristan Wright, July 2012, Lillian Gray 2017-2020
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
This reads the json formatted data generated by data_gen.py
the data is piped into the Google Charts API and a graph with controls are made
If more buildings are added increment buildingNum and add
a new color to buildingColors
Benchmark functions or sections by wrapping them in:
console.log(var a = new Date()-0);
console.log(var b = new Date()-0 - a);
*/
//init globals
//adaptive screen height.
var graphHeight = Math.floor($(document).height() * .6);
$("#dashboard").css("height", graphHeight+70);
//chart data source is global so we don't have to reload every time.
var lineChartJSONData = jQuery.ajax({
url: "raw_line_chart.txt", //location of data file
dataType: "json",
async: false
}).responseText;
var lineChartData;
var dashboard;
var controlWrapper;
var chartWrapper;
const buildingNum = 8;
var whichBuildings = new Array();
for(i=0; i < buildingNum; i++){
whichBuildings[i] = true;
}
//change colors here
var buildingColors = new Array( '#9c1c34', '#0A22af', '#ff381a','#00ff00', '#009944','#50D8F1','#e9af32', '#E07628');
//Sets initial range of site to the last month
var today = new Date((new Date).toDateString());
var endDate = new Date(today);
var startDate = new Date(today.setMonth(today.getMonth() - 1));
//for permalink parsing
var URLComponents = document.URL.split('?');
if(URLComponents.length==2){
var args = URLComponents[1];
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
130
131
132
var argsArray = args.split("+");
var startTemp = parseDate(argsArray[0]);
var endTemp = parseDate(argsArray[1]);
var whichArgs = parseInts(argsArray[2].split(""));
for(i=0; i<whichArgs.length; i++)
whichBuildings[whichArgs[i]] = !whichBuildings[whichArgs[i]];
if(startTemp < endTemp){
var startDate = startTemp;
var endDate = endTemp;
}
}
function flipAndRedraw(which){
whichBuildings[which] = !whichBuildings[which];
if(which===0)
//Adds or removes total options for chart
handleTotalOptions(whichBuildings[0]);
drawLineChart();
}
function handleTotalOptions(totalVisible){
if(totalVisible===true){
//adds options for separate series for total data
chartWrapper.setOption('series',{0:{'targetAxisIndex': 1}});
chartWrapper.setOption('vAxes', {1:{
'title':'Total Campus Usage in Kilowatts',
'titleColor':buildingColors[0],
'textColor':buildingColors[0],
'gridlines':{'color':'transparent'},
'baselineColor':'transparent'
}});
}
else{
//removes options for total data
chartWrapper.setOption('series',{});
}
}
function drawLineChart(){
// column 0 is date and should always be included
var visibleColumns = [0];
var visibleColors = [];
for(i=0;i<whichBuildings.length;i++){
if(whichBuildings[i]){
//since column 0 is date, column index is one greater for API
visibleColumns.push(i+1);
visibleColors.push(buildingColors[i]);
}
}
lineChartData.setColumns(visibleColumns);
chartWrapper.setOption('colors', visibleColors)
// Total is not displayed in controlWrapper if it is enabled
if(whichBuildings[0]===true){
controlWrapper.setOption('ui.chartOptions.colors', visibleColors.slice(1));
//Control wrapper columns are based on indexes of chart columns, include every index but 1 for Total
var controlWrapperColumns = [0];
for(i=2; i<visibleColumns.length;i++){
controlWrapperColumns.push(i);
}
controlWrapper.setOption('ui.chartView.columns', controlWrapperColumns);
}
else{
controlWrapper.setOption('ui.chartOptions.colors', visibleColors);
controlWrapper.setOption('ui.chartView.columns', null);
}
dashboard.draw(lineChartData);
}
function initializeLineChart(){
lineChartData = new google.visualization.DataView(new google.visualization.DataTable(lineChartJSONData));
dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
//changes time range if most current data isn't available
var latestEntryDate = new Date(lineChartData.getValue(lineChartData.getNumberOfRows()-1, 0))
if(!permalinked && latestEntryDate!=endDate){
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
endDate = new Date(latestEntryDate)
startDate = new Date(latestEntryDate.setMonth(latestEntryDate.getMonth() - 1));
}
//settings for control bar below chart
controlWrapper = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control',
'options': {
// Filter by the date axis.
'filterColumnIndex': 0,
'ui': {
'chartType': 'LineChart',
'chartOptions': {
'chartArea': {'width': '100%', 'height': 75},
'colors': buildingColors.slice(1),
'hAxis': {'baselineColor': 'none'}},
//1 day in milliseconds = 24 * 60 * 60 * 1000 = 86,400,000
'minRangeSize': 86400000
} //close ui
}, // Initial range: (yyyy-mm-dd)
'state': {'range': {'start': startDate, 'end': endDate}}
});
//chart settings
chartWrapper = new google.visualization.ChartWrapper({
'chartType': 'LineChart',
'containerId': 'lineChart',
'options':{
// Use the same chart area width as the control for axis alignment.
'width': '100%','height': graphHeight,
'fontName': 'Georgia',
'vAxis': {'title': 'Individual Building Usage in Kilowatts'},
'hAxis': {
'slantedText': true,
'format': 'EEE MMM d, yyyy', //ICU Simple Date Format
'textStyle': {'fontSize':14},
'gridlines': {'count':0, 'color': '#fff'}},
'colors': buildingColors,
'legend': 'none'
},//close options
}); //close chart_wrapper
//event handler saves date
google.visualization.events.addListener(controlWrapper, 'statechange',
function(){
startDate = controlWrapper.getState().range.start;
endDate = controlWrapper.getState().range.end;
}
);
dashboard.bind(controlWrapper, chartWrapper); //bind control to chart
if(whichBuildings[0]===true){
handleTotalOptions(whichBuildings[0]);
}
drawLineChart();
}
function parseDate(urlArg){
var dateArr = urlArg.split("-");
//month is zero-indexed
return new Date(parseInt(dateArr[0]), parseInt(dateArr[1]) - 1, parseInt(dateArr[2]));
}
function parseInts(strArray){
var a = new Array();
for(i=0; i < strArray.length; i++)
a.push(parseInt(strArray[i]));
return a;
}
// Generating a permalink
function genPermalink(){
//month is zero-indexed
var startStr = startDate.getFullYear()+"-"+(startDate.getMonth() + 1)+"-"+startDate.getDate();
var endStr = endDate.getFullYear()+"-"+(endDate.getMonth() + 1)+"-"+endDate.getDate();
var disabledBuildings = "";
for(i=0; i < buildingNum; i++){
if(!whichBuildings[i])
disabledBuildings += i;
}
var permalink = URLComponents[0]+"?"+startStr+"+"+endStr+"+"+disabledBuildings;
//Copies permalink and puts permalink in text box next to the button
var plinkTextField = document.getElementById('plink');
plinkTextField.value = permalink;
plinkTextField.select();
document.execCommand('copy');
//Fades tooltip in and out
var plinkButton = document.querySelector('.getPlink')
plinkButton.classList.add('active')
plinkButton.classList.remove('inactive')
setTimeout(function(){
plinkButton.classList.remove('active')
setTimeout(function(){
plinkButton.classList.add('inactive')
}, 1000);
}, 1000);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
$('#csvDownload').click(function () {
//prepares and then downloads a csv file based on what is currently shown in the chart
//creates csvString using same visible data as chart
var dataView = new google.visualization.DataView(lineChartData);
var filteredRows = dataView.getFilteredRows([{column: 0, minValue: startDate, maxValue: endDate}]);
dataView.setRows(filteredRows);
var csvString = google.visualization.dataTableToCsv(dataView);
//generates header to append to beginning of csvString
var csvHeader = "";
for(i=0; i < lineChartData.getNumberOfColumns(); i++){
csvHeader += lineChartData.getColumnLabel(i);
csvHeader += ",";
}
csvString = csvHeader + "\n" + csvString;
//downloads csv
var encodedUri = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csvString);
this.href = encodedUri;
this.download = 'energy-monitoring-data.csv';
this.target = '_blank';
});
function changeDashboard(button) {
if(button=="about") {
if(document.getElementById("aboutText").classList.toggle('displayNone')){
document.getElementById("lineChart").classList.remove('displayNone');
document.getElementById("control").classList.remove('displayNone');
document.getElementById("aboutButton").innerHTML = "About";
}
else {
document.getElementById("lineChart").classList.add('displayNone');
document.getElementById("control").classList.add('displayNone');
document.getElementById("howToUse").classList.add('displayNone');
document.getElementById("aboutButton").innerHTML = "Back";
document.getElementById("howToButton").innerHTML = "How To Use";
}
}
else if(button=="howToUse") {
if(document.getElementById("howToUse").classList.toggle('displayNone')){
document.getElementById("lineChart").classList.remove('displayNone');
document.getElementById("control").classList.remove('displayNone');
document.getElementById("howToButton").innerHTML = "How To Use";
}
else {
document.getElementById("lineChart").classList.add('displayNone');
document.getElementById("control").classList.add('displayNone');
document.getElementById("aboutText").classList.add('displayNone');
document.getElementById("aboutButton").innerHTML = "About";
document.getElementById("howToButton").innerHTML = "Back";
}
}
}