mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-26 18:56:39 +00:00
Improve chart rendering
This commit is contained in:
parent
055403f9d3
commit
957b72e806
@ -1,4 +1,4 @@
|
|||||||
import uniq from 'lodash/array/uniq';
|
import range from 'lodash/utility/range';
|
||||||
|
|
||||||
import Polymer from '../polymer';
|
import Polymer from '../polymer';
|
||||||
|
|
||||||
@ -59,12 +59,9 @@ export default new Polymer({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataTable = new window.google.visualization.DataTable();
|
|
||||||
|
|
||||||
dataTable.addColumn({ type: 'datetime', id: 'Time' });
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
legend: { position: 'top' },
|
legend: { position: 'top' },
|
||||||
|
interpolateNulls: true,
|
||||||
titlePosition: 'none',
|
titlePosition: 'none',
|
||||||
vAxes: {
|
vAxes: {
|
||||||
// Adds units to the left hand side of the graph
|
// Adds units to the left hand side of the graph
|
||||||
@ -92,79 +89,55 @@ export default new Polymer({
|
|||||||
options.enableInteractivity = false;
|
options.enableInteractivity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a unique list of times of state changes for all the devices
|
const startTime = new Date(Math.min.apply(
|
||||||
let times = uniq(deviceStates.map(
|
null, deviceStates.map(states => states[0].lastChangedAsDate)));
|
||||||
states => states.map(
|
|
||||||
state => state.lastChangedAsDate)).reduce(
|
|
||||||
(tot, cur) => tot.concat(cur), [])).sort();
|
|
||||||
|
|
||||||
// end time is Math.min(curTime, start time + 1 day)
|
let endTime = new Date(startTime);
|
||||||
let endTime = new Date(times[0]);
|
|
||||||
endTime.setDate(endTime.getDate() + 1);
|
endTime.setDate(endTime.getDate() + 1);
|
||||||
if (endTime > new Date()) {
|
if (endTime > new Date()) {
|
||||||
endTime = new Date();
|
endTime = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
times = times.concat(endTime);
|
const dataTables = deviceStates.map(states => {
|
||||||
|
// Only do interpolation for sensors, makes no sense for ie. thermostat
|
||||||
// This is going to be an array of arrays. Each array contains:
|
const noInterpolation = states[0].domain !== 'sensor';
|
||||||
// [Time, valueSensor1, valueSensor2, etc]
|
|
||||||
|
|
||||||
// Google Graph requires each data series to have an entry for each point.
|
|
||||||
// Since not all sensors have a value for each time, we'll put in the last
|
|
||||||
// known value at that point in time.
|
|
||||||
|
|
||||||
// Because we put in last known value, the 'average' line shown between
|
|
||||||
// times is incorrect. To fix this, we add each time twice and have
|
|
||||||
// transitions shown as a vertical line :-(
|
|
||||||
|
|
||||||
const data = [];
|
|
||||||
times.forEach(time => {
|
|
||||||
data.push([time]);
|
|
||||||
data.push([time]);
|
|
||||||
});
|
|
||||||
|
|
||||||
deviceStates.forEach(states => {
|
|
||||||
let startIndex = 0;
|
|
||||||
let curTime;
|
|
||||||
let curValue;
|
|
||||||
|
|
||||||
const nextState = function nextState() {
|
|
||||||
if (startIndex === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let value;
|
|
||||||
for (let ind = startIndex; ind < states.length; ind++) {
|
|
||||||
value = parseFloat(states[ind].state);
|
|
||||||
if (!isNaN(value) && isFinite(value)) {
|
|
||||||
startIndex = ind + 1;
|
|
||||||
curValue = value;
|
|
||||||
curTime = states[ind].lastChangedAsDate;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startIndex = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
nextState();
|
|
||||||
|
|
||||||
// no usable states found.
|
|
||||||
if (startIndex === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const dataTable = new window.google.visualization.DataTable();
|
||||||
|
dataTable.addColumn({ type: 'datetime', id: 'Time' });
|
||||||
dataTable.addColumn('number', states[states.length - 1].entityDisplay);
|
dataTable.addColumn('number', states[states.length - 1].entityDisplay);
|
||||||
|
const data = [];
|
||||||
|
|
||||||
times.forEach((time, index) => {
|
let prevValue;
|
||||||
data[index * 2].push(curValue);
|
|
||||||
if (curTime === time) {
|
states.forEach(state => {
|
||||||
nextState();
|
const value = parseFloat(state.state);
|
||||||
|
if (!isNaN(value) && isFinite(value)) {
|
||||||
|
if (noInterpolation) {
|
||||||
|
data.push([state.lastChangedAsDate, prevValue]);
|
||||||
|
}
|
||||||
|
data.push([state.lastChangedAsDate, value]);
|
||||||
|
prevValue = value;
|
||||||
}
|
}
|
||||||
data[index * 2 + 1].push(curValue);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
data.push([endTime, prevValue]);
|
||||||
|
|
||||||
|
dataTable.addRows(data);
|
||||||
|
return dataTable;
|
||||||
});
|
});
|
||||||
|
|
||||||
dataTable.addRows(data);
|
|
||||||
this.chartEngine.draw(dataTable, options);
|
let finalDataTable;
|
||||||
|
|
||||||
|
if (dataTables.length === 1) {
|
||||||
|
finalDataTable = dataTables[0];
|
||||||
|
} else {
|
||||||
|
finalDataTable = dataTables.slice(1).reduce(
|
||||||
|
(tot, cur) => window.google.visualization.data.join(
|
||||||
|
tot, cur, 'full', [[0, 0]], range(1, tot.getNumberOfColumns()), [1]),
|
||||||
|
dataTables[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chartEngine.draw(finalDataTable, options);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user