Newer
Older
Authors: Tristan Wright, July 2012, Lillian Gray 2017-2020
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
//chart data source is global so we don't have to reload every time.
var lineChartData
var dashboard
var controlWrapper
var chartWrapper
const buildingNum = 8
var whichBuildings = new Array()
var buildingColors = new Array( '#9c1c34', '#0A22af', '#ff381a','#00ff00', '#009944','#50D8F1','#e9af32', '#E07628')
//variables for range of control under chart
var endDate
var startDate
//split url on '?' for permalink creation and parsing
var URLComponents = document.URL.split('?')
/*called when GoogleAPI finishes loading in index.html
calls getData and then passes the data into initializeLineChart when finished*/
function onAPILoad(){
getData().done(initializeLineChart)
}
//fetches data for chart from text file generated by data_gen.py
url: "raw_line_chart.txt", //location of data file
dataType: "json",
})
}
/*creates chart with initial options
options that change such as visible columns are declared in drawLineChart*/
function initializeLineChart(data){
lineChartData = new google.visualization.DataView(new google.visualization.DataTable(data))
dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'))
var latestEntryDate = new Date(lineChartData.getValue(lineChartData.getNumberOfRows()-1, 0))
endDate = new Date(latestEntryDate)
startDate = new Date(latestEntryDate.setMonth(latestEntryDate.getMonth() - 1))
parsePermalink()
//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%'},
colors: buildingColors.slice(1),
hAxis: {baselineColor: 'none'}
},
}//close ui
},//close options
//chart settings
chartWrapper = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'lineChart',
options: {
fontName: 'Georgia',
vAxis: {title: 'Individual Building Usage in Kilowatts'},
hAxis: {
textStyle: {fontSize: 14},
gridlines: {
count: -1,
color: '#fff',
units: {
years: {format: ['yyyy', "''yy"]},
months: {format: ['MMM yyyy', "MMM ''yy",'MMM']},
days: {format: ['EEE MMM d, yyyy', "MMM d, ''yy", 'MMM d']},
hours: {format: ['']}
minorGridlines: {
units: {
months: {format: ['MMM']},
days: {format: ['d']},
hours: {format: ['']}
//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
handleTotalOptions(whichBuildings[0])
google.visualization.events.addOneTimeListener(dashboard, 'ready', disableLoadingScreen);
//hides loading icon, called once chart is ready
function disableLoadingScreen() {
document.getElementById("spinner").classList.add('displayNone')
}
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
//toggles if a building is shown in the chart and calls the chart to be redrawn
function flipAndRedraw(which){
whichBuildings[which] = !whichBuildings[which]
if(which===0){
//Adds or removes total options for chart
handleTotalOptions(whichBuildings[0])
}
drawLineChart()
}
//adds or removes options needed for Total which involves a second y-axis
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',{})
}
}
//sets options for columns and colors in the chart and control bar and then draws the chart
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)
}
//changes view within dashboard div between chart, how to use page, and about page
function changeDashboard(button) {
if(button=="close"){
document.getElementById("lineChart").classList.remove('displayNone')
document.getElementById("control").classList.remove('displayNone')
document.getElementById("howToUse").classList.add('displayNone')
document.getElementById("aboutText").classList.add('displayNone')
document.getElementById("closeButton").classList.add('displayNone')
}
else{
document.getElementById("lineChart").classList.add('displayNone')
document.getElementById("control").classList.add('displayNone')
document.getElementById("closeButton").classList.remove('displayNone')
if(button=="about"){
document.getElementById("howToUse").classList.add('displayNone')
document.getElementById("aboutText").classList.remove('displayNone')
}
if(button=="howToUse"){
document.getElementById("aboutText").classList.add('displayNone')
document.getElementById("howToUse").classList.remove('displayNone')
}
}
}
//if user changes the window size the chart is redrawn to be the right size
$(window).resize(function() {
dashboard.draw(lineChartData)
})
//called if series menu is clicked, toggles menu being shown
function showSeriesOptions(el) {
el.nextElementSibling.classList.toggle('displayNone')
}
//if site was loaded using a permalink, modifies startDate, endDate, and whichBuildings
function parsePermalink(){
permalinked = URLComponents.length==2
if(permalinked){
var args = URLComponents[1]
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){
startDate = startTemp
endDate = endTemp
//takes the date string from a permalink and returns them as a date object
var dateArr = urlArg.split("-")
return new Date(parseInt(dateArr[0]), parseInt(dateArr[1]) - 1, parseInt(dateArr[2]))
//takes the string of integers from a permalink and returns them as an array of integers
a.push(parseInt(strArray[i]))
return a
//generates a permalink and copies it, called in index.html when the Get Permalink button is clicked
var startStr = startDate.getFullYear()+"-"+(startDate.getMonth() + 1)+"-"+startDate.getDate()
var endStr = endDate.getFullYear()+"-"+(endDate.getMonth() + 1)+"-"+endDate.getDate()
var disabledBuildings = ""
var permalink = URLComponents[0]+"?"+startStr+"+"+endStr+"+"+disabledBuildings
//Copies permalink and puts permalink in text box next to the button
var permalinkTextField = document.getElementById('permalink')
permalinkTextField.value = permalink
permalinkTextField.select()
document.execCommand('copy')
var tooltip = document.querySelector('.tooltip')
tooltip.classList.add('active')
tooltip.classList.remove('inactive')
tooltip.classList.remove('active')
tooltip.classList.add('inactive')
//prepares and then downloads a csv file based on what is currently shown in the chart
function downloadCSV(el) {
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)
csvHeader += lineChartData.getColumnLabel(i)
csvHeader += ","
csvString = csvHeader + "\n" + csvString
var encodedUri = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csvString)
el.href = encodedUri
el.download = 'energy-monitoring-data.csv'
el.target = '_blank'