mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 22:57:17 +00:00
refactored line graph code
This commit is contained in:
parent
9499a8297a
commit
b50023ede1
@ -12,13 +12,13 @@
|
|||||||
|
|
||||||
<google-jsapi on-api-load="{{googleApiLoaded}}"></google-jsapi>
|
<google-jsapi on-api-load="{{googleApiLoaded}}"></google-jsapi>
|
||||||
<div id="timeline" style='width: 100%; height: auto;'></div>
|
<div id="timeline" style='width: 100%; height: auto;'></div>
|
||||||
<div id="single_timeline" style='width: 100%; height: auto;'></div>
|
<div id="line_graphs" style='width: 100%; height: auto;'></div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
Polymer({
|
Polymer({
|
||||||
apiLoaded: false,
|
apiLoaded: false,
|
||||||
stateHistory: null,
|
stateHistory: null,
|
||||||
entityIds: [],
|
|
||||||
|
|
||||||
googleApiLoaded: function() {
|
googleApiLoaded: function() {
|
||||||
google.load("visualization", "1", {
|
google.load("visualization", "1", {
|
||||||
@ -39,20 +39,25 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var graphType = '';
|
|
||||||
|
|
||||||
var container = this.$.timeline;
|
var container = this.$.timeline;
|
||||||
|
var chart = new google.visualization.Timeline(container);
|
||||||
|
var dataTable = new google.visualization.DataTable();
|
||||||
|
|
||||||
var chart = null;
|
dataTable.addColumn({ type: 'string', id: 'Entity' });
|
||||||
var dataTable = null;
|
dataTable.addColumn({ type: 'string', id: 'State' });
|
||||||
var addRow = null;
|
dataTable.addColumn({ type: 'date', id: 'Start' });
|
||||||
|
dataTable.addColumn({ type: 'date', id: 'End' });
|
||||||
|
|
||||||
|
var addRow = function(entityDisplay, stateStr, start, end) {
|
||||||
|
dataTable.addRow([entityDisplay, stateStr, start, end]);
|
||||||
|
};
|
||||||
|
|
||||||
if (this.stateHistory.length === 0) {
|
if (this.stateHistory.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// people can pass in history of 1 entityId or a collection.
|
// people can pass in history of 1 entityId or a collection.
|
||||||
var attributes = {};
|
|
||||||
var stateHistory;
|
var stateHistory;
|
||||||
if (_.isArray(this.stateHistory[0])) {
|
if (_.isArray(this.stateHistory[0])) {
|
||||||
stateHistory = this.stateHistory;
|
stateHistory = this.stateHistory;
|
||||||
@ -60,101 +65,25 @@
|
|||||||
stateHistory = [this.stateHistory];
|
stateHistory = [this.stateHistory];
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove any existing chart divs before re-rendering
|
var lineChartDevices = Array();
|
||||||
while (this.$.timeline.firstChild) {
|
var numTimelines = 0;
|
||||||
this.$.timeline.removeChild(this.$.timeline.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
var count = 0;
|
|
||||||
var consecutiveTimelineCount = 0;
|
|
||||||
// stateHistory is a list of lists of sorted state objects
|
// stateHistory is a list of lists of sorted state objects
|
||||||
stateHistory.forEach(function(stateInfo) {
|
stateHistory.forEach(function(stateInfo) {
|
||||||
if(stateInfo.length === 0) return;
|
if(stateInfo.length === 0) return;
|
||||||
|
|
||||||
if(stateHistory.length === 1) {
|
var entityDisplay = stateInfo[0].entityDisplay;
|
||||||
container = this.$.single_timeline;
|
var newLastChanged, prevState = null, prevLastChanged = null;
|
||||||
}
|
|
||||||
else {
|
|
||||||
container = document.createElement("DIV");
|
|
||||||
this.$.timeline.appendChild(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the latest update to get the graph type from the component attributes
|
//get the latest update to get the graph type from the component attributes
|
||||||
attributes = stateInfo[stateInfo.length - 1].attributes;
|
var attributes = stateInfo[stateInfo.length - 1].attributes;
|
||||||
|
|
||||||
graphType = attributes['graph_type'];
|
//if the device has a unit of meaurment it will be added as a line graph further down
|
||||||
|
if(attributes['unit_of_measurement']) {
|
||||||
if(graphType == 'linechart') {
|
if(!lineChartDevices[attributes['unit_of_measurement']]){
|
||||||
|
lineChartDevices[attributes['unit_of_measurement']] = [];
|
||||||
chart = new google.visualization.LineChart(container);
|
|
||||||
|
|
||||||
|
|
||||||
dataTable = new google.visualization.DataTable();
|
|
||||||
dataTable.addColumn({ type: 'datetime', id: 'Time' });
|
|
||||||
dataTable.addColumn({ type: 'number', id: 'Value' });
|
|
||||||
|
|
||||||
addRow = function(entityDisplay, stateStr, start, end) {
|
|
||||||
if(stateStr == 'None') {
|
|
||||||
stateStr = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
lineChartDevices[attributes['unit_of_measurement']].push(stateInfo);
|
||||||
dataTable.addRow([start, parseFloat(stateStr)]);
|
return;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
var entityDisplay = stateInfo[0].entityDisplay;
|
|
||||||
var newLastChanged, prevState = null, prevLastChanged = null;
|
|
||||||
|
|
||||||
stateInfo.forEach(function(state) {
|
|
||||||
newLastChanged = state.lastChangedAsDate;
|
|
||||||
addRow(entityDisplay, state.state, state.lastChangedAsDate, newLastChanged);
|
|
||||||
prevState = state.state;
|
|
||||||
prevLastChanged = newLastChanged;
|
|
||||||
});
|
|
||||||
|
|
||||||
addRow(entityDisplay, prevState, new Date(), new Date());
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
legend: { position: 'none' },
|
|
||||||
vAxes: {
|
|
||||||
// Adds units to the left hand side of the graph
|
|
||||||
0: {title: attributes['unit_of_measurement']}
|
|
||||||
},
|
|
||||||
hAxis: {
|
|
||||||
format: 'H:mm'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//only put in the title when we are rendering multiple graphs
|
|
||||||
if(stateHistory.length === 1) {
|
|
||||||
options['titlePosition'] = 'none';
|
|
||||||
options['height'] = 150;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
options['title'] = attributes['friendly_name'];
|
|
||||||
}
|
|
||||||
chart.draw(dataTable, options);
|
|
||||||
chart = null;
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(chart == null) {
|
|
||||||
chart = new google.visualization.Timeline(container);
|
|
||||||
|
|
||||||
dataTable = new google.visualization.DataTable();
|
|
||||||
|
|
||||||
dataTable.addColumn({ type: 'string', id: 'Entity' });
|
|
||||||
dataTable.addColumn({ type: 'string', id: 'State' });
|
|
||||||
dataTable.addColumn({ type: 'date', id: 'Start' });
|
|
||||||
dataTable.addColumn({ type: 'date', id: 'End' });
|
|
||||||
|
|
||||||
addRow = function(entityDisplay, stateStr, start, end) {
|
|
||||||
dataTable.addRow([entityDisplay, stateStr, start, end]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var entityDisplay = stateInfo[0].entityDisplay;
|
|
||||||
var newLastChanged, prevState = null, prevLastChanged = null;
|
|
||||||
|
|
||||||
stateInfo.forEach(function(state) {
|
stateInfo.forEach(function(state) {
|
||||||
if (prevState !== null && state.state !== prevState) {
|
if (prevState !== null && state.state !== prevState) {
|
||||||
@ -171,18 +100,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
addRow(entityDisplay, prevState, prevLastChanged, new Date());
|
addRow(entityDisplay, prevState, prevLastChanged, new Date());
|
||||||
|
numTimelines++;
|
||||||
var nextHist = (count + 1 < stateHistory.length) ? stateHistory[count + 1] : null;
|
}.bind(this));
|
||||||
|
|
||||||
var nextGraphType = (nextHist === null) ? '' : nextHist[nextHist.length - 1].attributes['graph_type'];
|
|
||||||
|
|
||||||
consecutiveTimelineCount++
|
|
||||||
|
|
||||||
//this is so that timelines get grouped together into a single chart
|
|
||||||
if(nextHist == null || (nextGraphType && nextGraphType != 'timeline')) {
|
|
||||||
|
|
||||||
chart.draw(dataTable, {
|
chart.draw(dataTable, {
|
||||||
height: 55 + consecutiveTimelineCount * 42,
|
height: 55 + numTimelines * 42,
|
||||||
|
|
||||||
// interactive properties require CSS, the JS api puts it on the document
|
// interactive properties require CSS, the JS api puts it on the document
|
||||||
// instead of inside our Shadow DOM.
|
// instead of inside our Shadow DOM.
|
||||||
@ -196,16 +118,119 @@
|
|||||||
format: 'H:mm'
|
format: 'H:mm'
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
chart = null;
|
|
||||||
consecutiveTimelineCount = 0;
|
var isSingleDevice = false;
|
||||||
|
if(stateHistory.length === 1) {
|
||||||
|
isSingleDevice = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var key in lineChartDevices) {
|
||||||
|
var deviceStates = lineChartDevices[key];
|
||||||
|
|
||||||
|
if(isSingleDevice) {
|
||||||
|
container = this.$.timeline
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
container = this.$.single_timeline;
|
||||||
|
container = document.createElement("DIV");
|
||||||
|
this.$.line_graphs.appendChild(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var chart = new google.visualization.LineChart(container);
|
||||||
|
|
||||||
|
|
||||||
|
var dataTable = new google.visualization.DataTable();
|
||||||
|
dataTable.addColumn({ type: 'datetime', id: 'Time' });
|
||||||
|
//dataTable.addColumn({ type: 'number', id: 'Value' });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
legend: { position: 'top' },
|
||||||
|
vAxes: {
|
||||||
|
// Adds units to the left hand side of the graph
|
||||||
|
0: {title: key}
|
||||||
|
},
|
||||||
|
hAxis: {
|
||||||
|
format: 'H:mm'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(isSingleDevice) {
|
||||||
|
options.legend.position = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var times = _(deviceStates).chain().flatten().pluck('lastChangedAsDate').unique().value();
|
||||||
|
|
||||||
|
times = _.sortBy(times, function(o) { return o; })
|
||||||
|
//console.log(times);
|
||||||
|
var data = [];
|
||||||
|
var empty = new Array(deviceStates.length);
|
||||||
|
for(var i = 0; i < empty.length; i++) {
|
||||||
|
empty[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeIndex = 1;
|
||||||
|
var endDate = new Date();
|
||||||
|
var prevDate = times[0];
|
||||||
|
data.push([times[0]].concat(empty));
|
||||||
|
while(prevDate < endDate) {
|
||||||
|
var currentDate = new Date(prevDate);
|
||||||
|
currentDate.setMinutes(prevDate.getMinutes() + 1);
|
||||||
|
if(currentDate >= times[timeIndex] && timeIndex < times.length) {
|
||||||
|
data.push([times[timeIndex]].concat(empty));
|
||||||
|
timeIndex++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.push([currentDate].concat(empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
prevDate = currentDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
var deviceCount = 0;
|
||||||
|
deviceStates.forEach(function(device) {
|
||||||
|
var attributes = device[device.length - 1].attributes;
|
||||||
|
dataTable.addColumn('number', attributes['friendly_name']);
|
||||||
|
|
||||||
|
var currentState = 0;
|
||||||
|
var previousState = 0;
|
||||||
|
var lastIndex = 0;
|
||||||
|
var count = 0;
|
||||||
|
device.forEach(function(state) {
|
||||||
|
|
||||||
|
currentState = state.state;
|
||||||
|
var start = state.lastChangedAsDate;
|
||||||
|
//console.log(start);
|
||||||
|
if(state.state == 'None') {
|
||||||
|
currentState = previousState;
|
||||||
|
}
|
||||||
|
for(var i = lastIndex; i < data.length; i++) {
|
||||||
|
data[i][1 + deviceCount] = parseFloat(previousState);
|
||||||
|
if(data[i][0] == start) {
|
||||||
|
data[i][1 + deviceCount] = parseFloat(currentState);
|
||||||
|
lastIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previousState = currentState;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
chart == null;
|
//fill in the rest of the Array
|
||||||
|
for(var i = lastIndex; i < data.length; i++) {
|
||||||
|
data[i][1 + deviceCount] = parseFloat(previousState);
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceCount++;
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
dataTable.addRows(data);
|
||||||
|
chart.draw(dataTable, options);
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user