Polymer .9: Convert History

This commit is contained in:
Paulus Schoutsen 2015-05-18 23:49:48 -07:00
parent f517445d36
commit 33122701b9
8 changed files with 530 additions and 389 deletions

View File

@ -11,26 +11,27 @@
"bower_components"
],
"dependencies": {
"webcomponentsjs": "Polymer/webcomponentsjs#~0.7",
"font-roboto": "Polymer/font-roboto#~0.5.6",
"paper-header-panel": "PolymerElements/paper-header-panel#~0.9",
"paper-toolbar": "PolymerElements/paper-toolbar#~0.9",
"paper-menu": "PolymerElements/paper-menu#~0.9",
"iron-input": "PolymerElements/iron-input#~0.9",
"iron-icons": "PolymerElements/iron-icons#~0.9",
"iron-image": "PolymerElements/iron-image#~0.9",
"paper-toast": "PolymerElements/paper-toast#~0.9",
"paper-dialog": "PolymerElements/paper-dialog#~0.9",
"paper-spinner": "PolymerElements/paper-spinner#~0.9",
"paper-button": "PolymerElements/paper-button#~0.9",
"paper-input": "PolymerElements/paper-input#~0.9",
"paper-toggle-button": "PolymerElements/paper-toggle-button#~0.9",
"paper-icon-button": "PolymerElements/paper-icon-button#~0.9",
"paper-item": "PolymerElements/paper-item#~0.9",
"paper-slider": "PolymerElements/paper-slider#~0.9",
"paper-checkbox": "PolymerElements/paper-checkbox#~0.9",
"paper-drawer-panel": "PolymerElements/paper-drawer-panel#~0.9",
"moment": "~2.10.3",
"webcomponentsjs": "Polymer/webcomponentsjs#^0.7",
"font-roboto": "Polymer/font-roboto#^0.5.6",
"paper-header-panel": "PolymerElements/paper-header-panel#^0.9",
"paper-toolbar": "PolymerElements/paper-toolbar#^0.9",
"paper-menu": "PolymerElements/paper-menu#^0.9",
"iron-input": "PolymerElements/iron-input#^0.9",
"iron-icons": "PolymerElements/iron-icons#^0.9",
"iron-image": "PolymerElements/iron-image#^0.9",
"paper-toast": "PolymerElements/paper-toast#^0.9",
"paper-dialog": "PolymerElements/paper-dialog#^0.9",
"paper-spinner": "PolymerElements/paper-spinner#^0.9",
"paper-button": "PolymerElements/paper-button#^0.9",
"paper-input": "PolymerElements/paper-input#^0.9",
"paper-toggle-button": "PolymerElements/paper-toggle-button#^0.9",
"paper-icon-button": "PolymerElements/paper-icon-button#^0.9",
"paper-item": "PolymerElements/paper-item#^0.9",
"paper-slider": "PolymerElements/paper-slider#^0.9",
"paper-checkbox": "PolymerElements/paper-checkbox#^0.9",
"paper-drawer-panel": "PolymerElements/paper-drawer-panel#^0.9",
"google-apis": "GoogleWebComponents/google-apis#0.8-preview",
"moment": "^2.10.3",
"layout": "Polymer/layout"
},
"stillUpgrading": {
@ -44,6 +45,7 @@
"paper-menu-button": "PolymerElements/paper-menu-button#~0.9"
},
"resolutions": {
"polymer": "^0.9.0"
"polymer": "^0.9.0",
"webcomponentsjs": "^0.7.0"
}
}

View File

@ -1,25 +1,27 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-spinner/paper-spinner.html">
<polymer-element name="loading-box" attributes="text">
<dom-module id="loading-box">
<style>
.text {
display: inline-block;
line-height: 28px;
vertical-align: top;
margin-left: 8px;
}
</style>
<template>
<style>
.text {
display: inline-block;
line-height: 28px;
vertical-align: top;
margin-left: 8px;
}
</style>
<div layout='horizontal'>
<paper-spinner active="true"></paper-spinner>
<div class='text'>{{text}}</div>
<div class='text'><content></content></div>
</div>
</template>
</dom-module>
<script>
<script>
(function() {
Polymer({
text: "Loading"
is: 'loading-box',
});
</script>
</polymer-element>
})();
</script>

View File

@ -0,0 +1,196 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<script>
(function() {
Polymer({
is: 'state-history-chart-line',
properties: {
data: {
type: Object,
observer: 'dataChanged',
},
unit: {
type: String,
},
isSingleDevice: {
type: Boolean,
value: false,
},
isAttached: {
type: Boolean,
value: false,
observer: 'dataChanged',
},
},
created: function() {
this.style.display = 'block';
},
attached: function() {
this.isAttached = true;
},
dataChanged: function() {
this.drawChart();
},
/**************************************************
The following code gererates line line graphs for devices with continuous
values(which are devices that have a unit_of_measurement values defined).
On each graph the devices are grouped by their unit of measurement, eg. all
sensors measuring MB will be a separate line on single graph. The google
chart API takes data as a 2 dimensional array in the format:
DateTime, device1, device2, device3
2015-04-01, 1, 2, 0
2015-04-01, 0, 1, 0
2015-04-01, 2, 1, 1
NOTE: the first column is a javascript date objects.
The first thing we do is build up the data with rows for each time of a state
change and initialise the values to 0. THen we loop through each device and
fill in its data.
**************************************************/
drawChart: function() {
if (!this.isAttached) {
return;
}
var root = Polymer.dom(this);
var unit = this.unit;
var deviceStates = this.data;
while (root.lastChild) {
root.removeChild(root.lastChild);
}
if (deviceStates.length === 0) {
return;
}
var chart = new google.visualization.LineChart(this);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'datetime', id: 'Time' });
var options = {
legend: { position: 'top' },
titlePosition: 'none',
vAxes: {
// Adds units to the left hand side of the graph
0: {title: unit}
},
hAxis: {
format: 'H:mm'
},
lineWidth: 1,
chartArea:{left:'60',width:"95%"},
explorer: {
actions: ['dragToZoom', 'rightClickToReset', 'dragToPan'],
keepInBounds: true,
axis: 'horizontal',
maxZoomIn: 0.1
}
};
if(this.isSingleDevice) {
options.legend.position = 'none';
options.vAxes[0].title = null;
options.chartArea.left = 40;
options.chartArea.height = '80%';
options.chartArea.top = 5;
options.enableInteractivity = false;
}
// Get a unique list of times of state changes for all the device
// for a particular unit of measureent.
var times = _.pluck(_.flatten(deviceStates), "lastChangedAsDate");
times = _.uniq(times, function(e) {
return e.getTime();
});
times = _.sortBy(times, function(o) { return o; });
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];
for(i = 0; i < times.length; i++) {
var currentDate = new Date(prevDate);
// because we only have state changes we add an extra point at the same time
// that holds the previous state which makes the line display correctly
var beforePoint = new Date(times[i]);
data.push([beforePoint].concat(empty));
data.push([times[i]].concat(empty));
prevDate = times[i];
timeIndex++;
}
data.push([endDate].concat(empty));
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;
var prevTime = data[0][0];
device.forEach(function(state) {
currentState = state.state;
var start = state.lastChangedAsDate;
if(state.state == 'None') {
currentState = previousState;
}
for(var i = lastIndex; i < data.length; i++) {
data[i][1 + deviceCount] = parseFloat(previousState);
// this is where data gets filled in for each time for the particular device
// because for each time two entries were create we fill the first one with the
// previous value and the second one with the new value
if(prevTime.getTime() == data[i][0].getTime() && data[i][0].getTime() == start.getTime()) {
data[i][1 + deviceCount] = parseFloat(currentState);
lastIndex = i;
prevTime = data[i][0];
break;
}
prevTime = data[i][0];
}
previousState = currentState;
count++;
}.bind(this));
//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);
},
});
})();
</script>

View File

@ -0,0 +1,115 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<script>
(function() {
Polymer({
is: 'state-history-chart-timeline',
properties: {
data: {
type: Object,
observer: 'dataChanged',
},
isAttached: {
type: Boolean,
value: false,
observer: 'dataChanged',
},
},
created: function() {
this.style.display = 'block';
},
attached: function() {
this.isAttached = true;
},
dataChanged: function() {
this.drawChart();
},
drawChart: function() {
if (!this.isAttached) {
return;
}
var root = Polymer.dom(this);
var data = this.data;
while (root.lastChild) {
root.removeChild(root.lastChild);
}
if (data.length === 0) {
return;
}
var chart = new google.visualization.Timeline(this);
var 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' });
var addRow = function(entityDisplay, stateStr, start, end) {
stateStr = stateStr.replace(/_/g, ' ');
dataTable.addRow([entityDisplay, stateStr, start, end]);
};
// people can pass in history of 1 entityId or a collection.
var stateHistory;
if (_.isArray(data[0])) {
stateHistory = data;
} else {
stateHistory = [data];
isSingleDevice = true;
}
var numTimelines = 0;
// stateHistory is a list of lists of sorted state objects
stateHistory.forEach(function(stateInfo) {
if(stateInfo.length === 0) return;
var entityDisplay = stateInfo[0].entityDisplay;
var newLastChanged, prevState = null, prevLastChanged = null;
stateInfo.forEach(function(state) {
if (prevState !== null && state.state !== prevState) {
newLastChanged = state.lastChangedAsDate;
addRow(entityDisplay, prevState, prevLastChanged, newLastChanged);
prevState = state.state;
prevLastChanged = newLastChanged;
} else if (prevState === null) {
prevState = state.state;
prevLastChanged = state.lastChangedAsDate;
}
});
addRow(entityDisplay, prevState, prevLastChanged, new Date());
numTimelines++;
}.bind(this));
chart.draw(dataTable, {
height: 55 + numTimelines * 42,
// interactive properties require CSS, the JS api puts it on the document
// instead of inside our Shadow DOM.
enableInteractivity: false,
timeline: {
showRowLabels: stateHistory.length > 1
},
hAxis: {
format: 'H:mm'
},
});
},
});
})();
</script>

View File

@ -0,0 +1,140 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/google-apis/google-legacy-loader.html">
<link rel="import" href="./loading-box.html">
<link rel="import" href="./state-history-chart-timeline.html">
<link rel="import" href="./state-history-chart-line.html">
<dom-module id="state-history-charts">
<style>
:host {
display: block;
}
</style>
<template>
<google-legacy-loader on-api-load="googleApiLoaded"></google-legacy-loader>
<div hidden$="{{!isLoading}}" >
<div class='layout horizontal center'>
<div class='layout vertical center'>
<loading-box>Loading history data</loading-box>
</div>
</div>
</div>
<template is='dom-if' if='[[!isLoading]]'>
<template is='dom-if' if='[[groupedStateHistory.timeline]]'>
<state-history-chart-timeline data='[[groupedStateHistory.timeline]]'
is-single-device='[[isSingleDevice]]'>
</state-history-chart-timeline>
</template>
<template is='dom-if' if='[[groupedStateHistory.line]]'>
<template is='dom-repeat' items='[[groupedStateHistory.line]]'>
<state-history-chart-line unit='[[extractUnit(item)]]'
data='[[extractData(item)]]' is-single-device='[[isSingleDevice]]'>
</state-history-chart-line>
</template>
</template>
</template>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'state-history-charts',
properties: {
stateHistory: {
type: Object,
},
isLoadingData: {
type: Boolean,
value: false,
},
apiLoaded: {
type: Boolean,
value: false,
},
isLoading: {
type: Boolean,
computed: 'computeIsLoading(isLoadingData, apiLoaded)',
},
groupedStateHistory: {
type: Object,
computed: 'computeGroupedStateHistory(stateHistory)',
},
isSingleDevice: {
type: Boolean,
computed: 'computeIsSingleDevice(stateHistory)',
},
},
computeIsSingleDevice: function(stateHistory) {
return stateHistory.length == 1;
},
computeGroupedStateHistory: function(stateHistory) {
var lineChartDevices = {};
var timelineDevices = [];
stateHistory.forEach(function(stateInfo) {
if (!stateInfo || stateInfo.length === 0) {
return;
}
var unit;
for (var i = 0; i < stateInfo.length && !unit; i++) {
unit = stateInfo[i].attributes.unit_of_measurement;
}
if (unit) {
if (!(unit in lineChartDevices)) {
lineChartDevices[unit] = [stateInfo];
} else {
lineChartDevices[unit].push(stateInfo);
}
} else {
timelineDevices.push(stateInfo);
}
});
timelineDevices = timelineDevices.length > 0 && timelineDevices;
var unitStates = Object.keys(lineChartDevices).map(function(unit) {
return [unit, lineChartDevices[unit]]; });
return {line: unitStates, timeline: timelineDevices};
},
googleApiLoaded: function() {
google.load("visualization", "1", {
packages: ["timeline", "corechart"],
callback: function() {
this.apiLoaded = true;
}.bind(this)
});
},
computeIsLoading: function(isLoadingData, apiLoaded) {
return isLoadingData || !apiLoaded;
},
extractUnit: function(arr) {
return arr[0];
},
extractData: function(arr) {
return arr[1];
},
});
})();
</script>

View File

@ -1,321 +0,0 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/google-apis/google-jsapi.html">
<polymer-element name="state-timeline" attributes="stateHistory isLoadingData">
<template>
<style>
:host {
display: block;
}
#loadingbox {
text-align: center;
}
.loadingmessage {
margin-top: 10px;
}
.singlelinechart {
min-height:140px;
}
</style>
<div style='width: 100%; height: auto;' hidden?="{{!isLoading}}" >
<div layout horizontal center id="splash">
<div layout vertical center flex>
<div id="loadingbox">
<paper-spinner active="true"></paper-spinner><br />
<div class="loadingmessage">{{spinnerMessage}}</div>
</div>
</div>
</div>
</div>
<google-jsapi on-api-load="{{googleApiLoaded}}"></google-jsapi>
<div id="timeline" style='width: 100%; height: auto;' class="{{ {singlelinechart: isSingleDevice && hasLineChart } | tokenList}}" hidden?="{{isLoadingData}}"></div>
<div id="line_graphs" style='width: 100%; height: auto;' hidden?="{{isLoadingData}}"></div>
</template>
<script>
Polymer({
apiLoaded: false,
stateHistory: null,
isLoading: true,
isLoadingData: false,
spinnerMessage: "Loading history data...",
isSingleDevice: false,
hasLineChart: false,
googleApiLoaded: function() {
google.load("visualization", "1", {
packages: ["timeline", "corechart"],
callback: function() {
this.apiLoaded = true;
this.drawChart();
}.bind(this)
});
},
stateHistoryChanged: function() {
this.drawChart();
},
isLoadingDataChanged: function() {
if(this.isLoadingData) {
isLoading = true;
}
},
drawChart: function() {
if (!this.apiLoaded || !this.stateHistory) {
return;
}
this.isLoading = true;
var container = this.$.timeline;
var chart = new google.visualization.Timeline(container);
var 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' });
var addRow = function(entityDisplay, stateStr, start, end) {
stateStr = stateStr.replace(/_/g, ' ');
dataTable.addRow([entityDisplay, stateStr, start, end]);
};
if (this.stateHistory.length === 0) {
return;
}
this.hasLineChart = false;
this.isSingleDevice = false;
// people can pass in history of 1 entityId or a collection.
var stateHistory;
if (_.isArray(this.stateHistory[0])) {
stateHistory = this.stateHistory;
} else {
stateHistory = [this.stateHistory];
this.isSingleDevice = true;
}
var lineChartDevices = {};
var numTimelines = 0;
// stateHistory is a list of lists of sorted state objects
stateHistory.forEach(function(stateInfo) {
if(stateInfo.length === 0) return;
var entityDisplay = stateInfo[0].entityDisplay;
var newLastChanged, prevState = null, prevLastChanged = null;
//get the latest update to get the graph type from the component attributes
var attributes = stateInfo[stateInfo.length - 1].attributes;
//if the device has a unit of meaurment it will be added as a line graph further down
if(attributes.unit_of_measurement) {
if(!lineChartDevices[attributes.unit_of_measurement]){
lineChartDevices[attributes.unit_of_measurement] = [];
}
lineChartDevices[attributes.unit_of_measurement].push(stateInfo);
this.hasLineChart = true;
return;
}
stateInfo.forEach(function(state) {
if (prevState !== null && state.state !== prevState) {
newLastChanged = state.lastChangedAsDate;
addRow(entityDisplay, prevState, prevLastChanged, newLastChanged);
prevState = state.state;
prevLastChanged = newLastChanged;
} else if (prevState === null) {
prevState = state.state;
prevLastChanged = state.lastChangedAsDate;
}
});
addRow(entityDisplay, prevState, prevLastChanged, new Date());
numTimelines++;
}.bind(this));
chart.draw(dataTable, {
height: 55 + numTimelines * 42,
// interactive properties require CSS, the JS api puts it on the document
// instead of inside our Shadow DOM.
enableInteractivity: false,
timeline: {
showRowLabels: stateHistory.length > 1
},
hAxis: {
format: 'H:mm'
},
});
/**************************************************
The following code gererates line line graphs for devices with continuous
values(which are devices that have a unit_of_measurment values defined).
On each graph the devices are grouped by their unit of measurement, eg. all
sensors measuring MB will be a separate line on single graph. The google
chart API takes data as a 2 dimensional array in the format:
DateTime, device1, device2, device3
2015-04-01, 1, 2, 0
2015-04-01, 0, 1, 0
2015-04-01, 2, 1, 1
NOTE: the first column is a javascript date objects.
The first thing we do is build up the data with rows for each time of a state
change and initialise the values to 0. THen we loop through each device and
fill in its data.
**************************************************/
while (this.$.line_graphs.firstChild) {
this.$.line_graphs.removeChild(this.$.line_graphs.firstChild);
}
for (var key in lineChartDevices) {
var deviceStates = lineChartDevices[key];
if(this.isSingleDevice) {
container = this.$.timeline;
}
else {
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' });
var options = {
legend: { position: 'top' },
titlePosition: 'none',
vAxes: {
// Adds units to the left hand side of the graph
0: {title: key}
},
hAxis: {
format: 'H:mm'
},
lineWidth: 1,
chartArea:{left:'60',width:"95%"},
explorer: {
actions: ['dragToZoom', 'rightClickToReset', 'dragToPan'],
keepInBounds: true,
axis: 'horizontal',
maxZoomIn: 0.1
}
};
if(this.isSingleDevice) {
options.legend.position = 'none';
options.vAxes[0].title = null;
options.chartArea.left = 40;
options.chartArea.height = '80%';
options.chartArea.top = 5;
options.enableInteractivity = false;
}
// Get a unique list of times of state changes for all the device
// for a particular unit of measureent.
var times = _.pluck(_.flatten(deviceStates), "lastChangedAsDate");
times = _.uniq(times, function(e) {
return e.getTime();
});
times = _.sortBy(times, function(o) { return o; });
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];
for(var i = 0; i < times.length; i++) {
var currentDate = new Date(prevDate);
// because we only have state changes we add an extra point at the same time
// that holds the previous state which makes the line display correctly
var beforePoint = new Date(times[i]);
data.push([beforePoint].concat(empty));
data.push([times[i]].concat(empty));
prevDate = times[i];
timeIndex++;
}
data.push([endDate].concat(empty));
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;
var prevTime = data[0][0];
device.forEach(function(state) {
currentState = state.state;
var start = state.lastChangedAsDate;
if(state.state == 'None') {
currentState = previousState;
}
for(var i = lastIndex; i < data.length; i++) {
data[i][1 + deviceCount] = parseFloat(previousState);
// this is where data gets filled in for each time for the particular device
// because for each time two entires were create we fill the first one with the
// previous value and the second one with the new value
if(prevTime.getTime() == data[i][0].getTime() && data[i][0].getTime() == start.getTime()) {
data[i][1 + deviceCount] = parseFloat(currentState);
lastIndex = i;
prevTime = data[i][0];
break;
}
prevTime = data[i][0];
}
previousState = currentState;
count++;
}.bind(this));
//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);
}
this.isLoading = (!this.isLoadingData) ? false : true;
},
});
</script>
</polymer-element>

View File

@ -11,12 +11,12 @@
<link rel="import" href="../layouts/partial-states.html">
<link rel="import" href="../layouts/partial-logbook.html">
<!-- <link rel="import" href="../layouts/partial-history.html">
<link rel="import" href="../layouts/partial-dev-fire-event.html">
<link rel="import" href="../layouts/partial-history.html">
<!-- <link rel="import" href="../layouts/partial-dev-fire-event.html">
<link rel="import" href="../layouts/partial-dev-call-service.html">
<link rel="import" href="../layouts/partial-dev-set-state.html"> -->
<link rel="import" href="../layouts/partial-dev-set-state.html">
<!-- <link rel="import" href="../components/ha-notifications.html">
<link rel="import" href="../components/ha-notifications.html">
<link rel="import" href="../components/ha-modals.html"> -->
<link rel="import" href="../components/stream-status.html">
@ -132,10 +132,10 @@
<template is='dom-if' if="{{isSelectedLogbook}}">
<partial-logbook main narrow="{{narrow}}"></partial-logbook>
</template>
<!--
<template is='dom-if' if="{{selected == 'history'}}">
<template is='dom-if' if="{{isSelectedHistory}}">
<partial-history main narrow="{{narrow}}"></partial-history>
</template>
<!--
<template is='dom-if' if="{{selected == 'fire-event'}}">
<partial-dev-fire-event main narrow="{{narrow}}"></partial-dev-fire-event>
</template>

View File

@ -1,13 +1,11 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/state-timeline.html">
<link rel="import" href="../components/state-history-charts.html">
<polymer-element name="partial-history" attributes="narrow togglePanel">
<template>
<dom-module id="partial-history">
<style>
.content {
background-color: white;
@ -17,33 +15,38 @@
padding: 8px;
}
</style>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>History</span>
<template>
<partial-base narrow="[[narrow]]">
<span header-title>History</span>
<span header-buttons>
<paper-icon-button icon="refresh"
on-click="{{handleRefreshClick}}"></paper-icon-button>
</span>
<paper-icon-button icon="refresh" header-buttons
on-click="handleRefreshClick"></paper-icon-button>
<div flex class="{{ {content: true, narrow: narrow, wide: !narrow} | tokenList }}">
<state-timeline stateHistory="{{stateHistory}}" isLoadingData="{{isLoadingData}}"></state-timeline>
</div>
</partial-base>
</template>
<div flex class="[[computeContentClasses(narrow)]]">
<state-history-charts state-history="[[stateHistory]]"
is-loading-data="[[isLoadingData]]"></state-history-charts>
</div>
</partial-base>
</template>
</dom-module>
<script>
var storeListenerMixIn = window.hass.storeListenerMixIn;
(function() {
var stateHistoryActions = window.hass.stateHistoryActions;
Polymer(Polymer.mixin({
stateHistory: null,
isLoadingData: false,
Polymer({
is: 'partial-history',
attached: function() {
this.listenToStores(true);
},
behaviors: [StoreListenerBehavior],
detached: function() {
this.stopListeningToStores();
properties: {
stateHistory: {
type: Object,
},
isLoadingData: {
type: Boolean,
value: false,
},
},
stateHistoryStoreChanged: function(stateHistoryStore) {
@ -62,6 +65,10 @@
this.isLoadingData = true;
stateHistoryActions.fetchAll();
},
}, storeListenerMixIn));
</script>
</polymer>
computeContentClasses: function(narrow) {
return 'content ' + (this.narrow ? 'narrow' : 'wide');
},
});
})();
</script>