mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-16 13:56:35 +00:00
Support multi-day history charts (#207)
* Support multi-day history charts * Fix lint * Reduce the periods to 1/3/7 days. * Switch to end_time param instead of days * Move async waiting from history-data to panel-history
This commit is contained in:
parent
5207629e87
commit
f396c9acde
@ -1,7 +1,9 @@
|
|||||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||||
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
|
||||||
|
<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||||
|
<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
|
||||||
|
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||||
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
|
||||||
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
|
||||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||||
@ -21,17 +23,20 @@
|
|||||||
|
|
||||||
paper-input {
|
paper-input {
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
paper-dropdown-menu {
|
||||||
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<ha-state-history-data
|
<ha-state-history-data
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
filter-type='[[_filterType]]'
|
filter-type='[[_filterType]]'
|
||||||
filter-value='[[_computeFilterDate(_selectedDate)]]'
|
filter-value='[[_computeFilterDate(_selectedDate, _periodIndex)]]'
|
||||||
data='{{stateHistory}}'
|
data='{{stateHistoryInput}}'
|
||||||
isLoading='{{isLoadingData}}'
|
is-loading='{{isLoadingData}}'
|
||||||
></ha-state-history-data>
|
></ha-state-history-data>
|
||||||
|
|
||||||
<app-header-layout has-scrolling-region>
|
<app-header-layout has-scrolling-region>
|
||||||
<app-header fixed>
|
<app-header fixed>
|
||||||
<app-toolbar>
|
<app-toolbar>
|
||||||
@ -41,14 +46,22 @@
|
|||||||
</app-header>
|
</app-header>
|
||||||
|
|
||||||
<div class="flex content">
|
<div class="flex content">
|
||||||
<paper-input
|
<div class="flex layout horizontal wrap">
|
||||||
label='Showing entries for'
|
<paper-input
|
||||||
id='datePicker'
|
label='Start date'
|
||||||
value='[[_computeDateDisplay(_selectedDate)]]'
|
id='datePicker'
|
||||||
on-focus='datepickerFocus'
|
value='[[_computeDateDisplay(_selectedDate)]]'
|
||||||
></paper-input>
|
on-focus='datepickerFocus'
|
||||||
|
></paper-input>
|
||||||
<state-history-charts history-data="[[stateHistory]]"
|
<paper-dropdown-menu label-float label='Period'>
|
||||||
|
<paper-menu class="dropdown-content" selected="{{_periodIndex}}">
|
||||||
|
<paper-item>1 day</paper-item>
|
||||||
|
<paper-item>3 days</paper-item>
|
||||||
|
<paper-item>1 week</paper-item>
|
||||||
|
</paper-menu>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
</div>
|
||||||
|
<state-history-charts history-data="[[stateHistoryOutput]]"
|
||||||
is-loading-data="[[isLoadingData]]"></state-history-charts>
|
is-loading-data="[[isLoadingData]]"></state-history-charts>
|
||||||
</div>
|
</div>
|
||||||
</app-header-layout>
|
</app-header-layout>
|
||||||
@ -73,9 +86,20 @@ Polymer({
|
|||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
stateHistory: {
|
stateHistoryInput: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: null,
|
value: null,
|
||||||
|
observer: 'stateHistoryObserver'
|
||||||
|
},
|
||||||
|
|
||||||
|
stateHistoryOutput: {
|
||||||
|
type: Object,
|
||||||
|
value: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
_periodIndex: {
|
||||||
|
type: Number,
|
||||||
|
value: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
isLoadingData: {
|
isLoadingData: {
|
||||||
@ -124,8 +148,30 @@ Polymer({
|
|||||||
return window.hassUtil.formatDate(new Date(date));
|
return window.hassUtil.formatDate(new Date(date));
|
||||||
},
|
},
|
||||||
|
|
||||||
_computeFilterDate: function (_selectedDate) {
|
_computeFilterDate: function (selectedDate, periodIndex) {
|
||||||
return _selectedDate.toISOString();
|
var endTime = new Date(selectedDate);
|
||||||
|
endTime.setDate(
|
||||||
|
selectedDate.getDate() + this._computeFilterDays(periodIndex));
|
||||||
|
return selectedDate.toISOString() + '?end_time=' + endTime.toISOString();
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeFilterDays: function (periodIndex) {
|
||||||
|
switch (periodIndex) {
|
||||||
|
case 1:
|
||||||
|
return 3;
|
||||||
|
case 2:
|
||||||
|
return 7;
|
||||||
|
default: return 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
stateHistoryObserver: function (newVal) {
|
||||||
|
this.async(function () {
|
||||||
|
if (newVal === this.stateHistoryInput) {
|
||||||
|
// Input didn't change
|
||||||
|
this.stateHistoryOutput = newVal;
|
||||||
|
}
|
||||||
|
}.bind(this), 1);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
var endTime;
|
var endTime;
|
||||||
var dataTables;
|
var dataTables;
|
||||||
var finalDataTable;
|
var finalDataTable;
|
||||||
|
var daysDelta;
|
||||||
|
|
||||||
if (!this.isAttached) {
|
if (!this.isAttached) {
|
||||||
return;
|
return;
|
||||||
@ -115,12 +116,22 @@
|
|||||||
return new Date(states[0].last_changed);
|
return new Date(states[0].last_changed);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
endTime = new Date(startTime);
|
endTime = new Date(Math.max.apply(null, deviceStates.map(function (states) {
|
||||||
endTime.setDate(endTime.getDate() + 1);
|
return new Date(states[states.length - 1].last_changed);
|
||||||
|
})));
|
||||||
if (endTime > new Date()) {
|
if (endTime > new Date()) {
|
||||||
endTime = new Date();
|
endTime = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
daysDelta = (endTime - startTime) / (24 * 3600 * 1000);
|
||||||
|
if (daysDelta > 30) {
|
||||||
|
options.hAxis.format = 'MMM d';
|
||||||
|
} else if (daysDelta > 3) {
|
||||||
|
options.hAxis.format = 'EEE, MMM d';
|
||||||
|
} else if (daysDelta > 1) {
|
||||||
|
options.hAxis.format = 'EEE, MMM d, H:mm';
|
||||||
|
}
|
||||||
|
|
||||||
dataTables = deviceStates.map(function (states) {
|
dataTables = deviceStates.map(function (states) {
|
||||||
var last = states[states.length - 1];
|
var last = states[states.length - 1];
|
||||||
var domain = window.hassUtil.computeDomain(last);
|
var domain = window.hassUtil.computeDomain(last);
|
||||||
|
@ -44,6 +44,8 @@ Polymer({
|
|||||||
var startTime;
|
var startTime;
|
||||||
var endTime;
|
var endTime;
|
||||||
var numTimelines;
|
var numTimelines;
|
||||||
|
var format;
|
||||||
|
var daysDelta;
|
||||||
|
|
||||||
if (!this.isAttached) {
|
if (!this.isAttached) {
|
||||||
return;
|
return;
|
||||||
@ -76,12 +78,25 @@ Polymer({
|
|||||||
return Math.min(minTime, new Date(stateInfo[0].last_changed));
|
return Math.min(minTime, new Date(stateInfo[0].last_changed));
|
||||||
}, new Date()));
|
}, new Date()));
|
||||||
|
|
||||||
// end time is Math.min(curTime, start time + 1 day)
|
// end time is Math.max(startTime, last_event)
|
||||||
endTime = new Date(startTime);
|
endTime = new Date(
|
||||||
endTime.setDate(endTime.getDate() + 1);
|
stateHistory.reduce(
|
||||||
|
function (maxTime, stateInfo) {
|
||||||
|
return Math.max(maxTime, new Date(stateInfo[stateInfo.length - 1].last_changed));
|
||||||
|
}, startTime));
|
||||||
|
|
||||||
if (endTime > new Date()) {
|
if (endTime > new Date()) {
|
||||||
endTime = new Date();
|
endTime = new Date();
|
||||||
}
|
}
|
||||||
|
format = 'H:mm';
|
||||||
|
daysDelta = (endTime - startTime) / (24 * 3600 * 1000);
|
||||||
|
if (daysDelta > 30) {
|
||||||
|
format = 'MMM d';
|
||||||
|
} else if (daysDelta > 3) {
|
||||||
|
format = 'EEE, MMM d';
|
||||||
|
} else if (daysDelta > 1) {
|
||||||
|
format = 'EEE, MMM d, H:mm';
|
||||||
|
}
|
||||||
|
|
||||||
numTimelines = 0;
|
numTimelines = 0;
|
||||||
// stateHistory is a list of lists of sorted state objects
|
// stateHistory is a list of lists of sorted state objects
|
||||||
@ -121,7 +136,7 @@ Polymer({
|
|||||||
},
|
},
|
||||||
|
|
||||||
hAxis: {
|
hAxis: {
|
||||||
format: 'H:mm',
|
format: format
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user