mirror of
https://github.com/home-assistant/frontend.git
synced 2025-06-24 11:06:35 +00:00
Charts improvements (#992)
* Charts improvements * Improve last-odd legend item. * Revert dblclick * Lint
This commit is contained in:
parent
9dc809cdb9
commit
05da295f27
@ -84,7 +84,8 @@
|
||||
history-data="[[stateHistory]]"
|
||||
is-loading-data="[[isLoadingData]]"
|
||||
end-time="[[endTime]]"
|
||||
no-single>
|
||||
no-single
|
||||
is-zoomable>
|
||||
</state-history-charts>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
|
@ -42,7 +42,8 @@
|
||||
history-data="[[stateHistory]]"
|
||||
is-loading-data="[[stateHistoryLoading]]"
|
||||
up-to-now
|
||||
no-single>
|
||||
no-single
|
||||
is-zoomable="[[inDialog]]">
|
||||
</state-history-charts>
|
||||
</div>
|
||||
</paper-card>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<link rel='import' href='../../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel="import" href="../../../bower_components/iron-resizable-behavior/iron-resizable-behavior.html">
|
||||
<link rel='import' href='../../../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||
|
||||
<dom-module id="ha-chart-base">
|
||||
@ -59,6 +60,10 @@
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.chartLegend li:nth-child(odd):last-of-type {
|
||||
/* Make last item take full width if it is add-numbered. */
|
||||
max-width: 100%;
|
||||
}
|
||||
.chartLegend li.hidden {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
@ -119,20 +124,25 @@
|
||||
{
|
||||
let SCRIPT_LOADED = false;
|
||||
|
||||
class HaChartBase extends Polymer.Element {
|
||||
class HaChartBase extends Polymer.mixinBehaviors([
|
||||
Polymer.IronResizableBehavior
|
||||
], Polymer.Element) {
|
||||
get chart() {
|
||||
return this._chart;
|
||||
}
|
||||
static get is() { return 'ha-chart-base'; }
|
||||
static get properties() {
|
||||
return {
|
||||
data: {
|
||||
type: Object,
|
||||
observer: 'onPropsChange'
|
||||
},
|
||||
data: Object,
|
||||
identifier: String,
|
||||
isZoomable: Boolean,
|
||||
};
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return ['onPropsChange(data, isZoomable)'];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._isAttached = true;
|
||||
@ -157,7 +167,17 @@
|
||||
}
|
||||
);
|
||||
};
|
||||
window.addEventListener('resize', this._resizeListener);
|
||||
|
||||
if (typeof ResizeObserver === 'function') {
|
||||
this.resizeObserver = new ResizeObserver((entries) => {
|
||||
entries.forEach(() => {
|
||||
this._resizeListener();
|
||||
});
|
||||
});
|
||||
this.resizeObserver.observe(this.$.chartTarget);
|
||||
} else {
|
||||
this.addEventListener('iron-resize', this._resizeListener);
|
||||
}
|
||||
|
||||
if (!SCRIPT_LOADED) {
|
||||
Polymer.importHref(
|
||||
@ -169,10 +189,15 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._isAttached = false;
|
||||
window.removeEventListener('resize', this._resizeListener);
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.unobserve(this.$.chartTarget);
|
||||
}
|
||||
|
||||
this.removeEventListener('iron-resize', this._resizeListener);
|
||||
|
||||
if (this._resizeTimer !== undefined) {
|
||||
clearInterval(this._resizeTimer);
|
||||
@ -351,14 +376,12 @@
|
||||
options.scales.xAxes[0].ticks.callback = this._formatTickValue;
|
||||
if (this.data.type === 'timeline') {
|
||||
// timeline is not zoomable, so dont capture mouse
|
||||
this.set('isZoomable', false);
|
||||
options = Chart.helpers.merge(options, {
|
||||
pan: { enabled: false },
|
||||
zoom: { enabled: false },
|
||||
});
|
||||
} else {
|
||||
// allow free zooming&moving around
|
||||
this.set('isZoomable', true);
|
||||
options = Chart.helpers.merge(options, {
|
||||
pan: {
|
||||
enabled: true,
|
||||
@ -407,6 +430,7 @@
|
||||
this.updateZoomlimits();
|
||||
}
|
||||
}
|
||||
|
||||
updateZoomlimits() {
|
||||
if (!this._chart) return;
|
||||
if (this.isTimeline) return;
|
||||
@ -432,10 +456,12 @@
|
||||
|
||||
this._chart.options = Chart.helpers.merge(this._chart.options, {
|
||||
pan: {
|
||||
enabled: !!this.isZoomable,
|
||||
rangeMin: { x: buffer.x.min, y: buffer.y.min },
|
||||
rangeMax: { x: buffer.x.max, y: buffer.y.max }
|
||||
},
|
||||
zoom: {
|
||||
enabled: !!this.isZoomable,
|
||||
// x is nulled so users are able to "zoom in on time"
|
||||
rangeMin: { x: null /* buffer.x.min */, y: buffer.y.min },
|
||||
rangeMax: { x: null /* buffer.x.max */, y: buffer.y.max }
|
||||
|
@ -4,7 +4,11 @@
|
||||
|
||||
<dom-module id='state-history-chart-line'>
|
||||
<template>
|
||||
<ha-chart-base data="[[chartData]]" identifier="[[identifier]]"></ha-chart-base>
|
||||
<ha-chart-base
|
||||
data="[[chartData]]"
|
||||
is-zoomable="[[isZoomable]]"
|
||||
identifier="[[identifier]]">
|
||||
</ha-chart-base>
|
||||
</template>
|
||||
</dom-module>
|
||||
<script>
|
||||
@ -15,6 +19,7 @@ class StateHistoryChartLine extends Polymer.Element {
|
||||
data: Object,
|
||||
unit: String,
|
||||
identifier: String,
|
||||
isZoomable: Boolean,
|
||||
|
||||
isSingleDevice: {
|
||||
type: Boolean,
|
||||
@ -25,7 +30,7 @@ class StateHistoryChartLine extends Polymer.Element {
|
||||
};
|
||||
}
|
||||
static get observers() {
|
||||
return ['dataChanged(data, endTime)'];
|
||||
return ['dataChanged(data, endTime, isSingleDevice)'];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
|
@ -30,6 +30,7 @@
|
||||
data='[[item.data]]'
|
||||
identifier='[[item.identifier]]'
|
||||
is-single-device='[[_computeIsSingleLineChart(item.data, noSingle)]]'
|
||||
is-zoomable='[[isZoomable]]'
|
||||
end-time='[[_computeEndTime(endTime, upToNow, historyData)]]'>
|
||||
</state-history-chart-line>
|
||||
</template>
|
||||
@ -41,9 +42,7 @@ class StateHistoryCharts extends Polymer.Element {
|
||||
static get is() { return 'state-history-charts'; }
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object
|
||||
},
|
||||
hass: Object,
|
||||
historyData: {
|
||||
type: Object,
|
||||
value: null,
|
||||
@ -60,6 +59,7 @@ class StateHistoryCharts extends Polymer.Element {
|
||||
|
||||
upToNow: Boolean,
|
||||
noSingle: Boolean,
|
||||
isZoomable: Boolean,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
<link rel="import" href="../../bower_components/paper-dialog-behavior/paper-dialog-shared-styles.html">
|
||||
<link rel="import" href="../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
|
||||
<link rel="import" href="../components/state-history-charts.html">
|
||||
<link rel="import" href="../data/ha-state-history-data.html">
|
||||
<link rel='import' href='../util/hass-mixins.html'>
|
||||
<link rel='import' href='../resources/ha-style.html'>
|
||||
|
||||
@ -39,7 +37,7 @@
|
||||
width: auto;
|
||||
}
|
||||
|
||||
:host([data-domain=history_graph]) {
|
||||
:host([data-domain=history_graph]), :host([large]) {
|
||||
width: 90%;
|
||||
}
|
||||
</style>
|
||||
@ -51,6 +49,7 @@
|
||||
state-obj='[[stateObj]]'
|
||||
dialog-element='[[_dialogElement]]'
|
||||
can-configure='[[_registryInfo]]'
|
||||
large='{{large}}'
|
||||
></more-info-controls>
|
||||
</template>
|
||||
<template is='dom-if' if='[[_equals(_page, "settings")]]'>
|
||||
@ -76,6 +75,12 @@ class HaMoreInfoDialog extends window.hassMixins.DialogMixin(Polymer.Element) {
|
||||
observer: '_stateObjChanged',
|
||||
},
|
||||
|
||||
large: {
|
||||
type: Boolean,
|
||||
reflectToAttribute: true,
|
||||
observer: 'notifyResize',
|
||||
},
|
||||
|
||||
_dialogElement: Object,
|
||||
_registryInfo: Object,
|
||||
|
||||
@ -113,6 +118,7 @@ class HaMoreInfoDialog extends window.hassMixins.DialogMixin(Polymer.Element) {
|
||||
opened: false,
|
||||
_page: null,
|
||||
_registryInfo: null,
|
||||
large: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../components/state-history-charts.html">
|
||||
<link rel="import" href="../../data/ha-state-history-data.html">
|
||||
<link rel="import" href="../../state-summary/state-card-content.html">
|
||||
<link rel='import' href='../../util/hass-mixins.html'>
|
||||
<link rel='import' href='../../resources/ha-style.html'>
|
||||
@ -28,10 +30,18 @@
|
||||
state-history-charts {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
max-width: 365px;
|
||||
max-width: 100%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
@media all and (min-width: 451px) and (min-height: 501px) {
|
||||
.main-title {
|
||||
pointer-events: auto;
|
||||
cursor: default;
|
||||
line-height: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
:host([domain=camera]) paper-dialog-scrollable {
|
||||
margin: 0 -24px -5px;
|
||||
}
|
||||
@ -42,7 +52,7 @@
|
||||
icon='mdi:close'
|
||||
dialog-dismiss
|
||||
></paper-icon-button>
|
||||
<div main-title>[[_computeStateName(stateObj)]]</div>
|
||||
<div class="main-title" main-title on-click="enlarge">[[_computeStateName(stateObj)]]</div>
|
||||
<template is='dom-if' if='[[canConfigure]]'>
|
||||
<paper-icon-button
|
||||
icon='mdi:settings'
|
||||
@ -58,21 +68,21 @@
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if="[[_computeShowHistoryComponent(hass, stateObj)]]" restamp>
|
||||
<div>
|
||||
<ha-state-history-data
|
||||
hass='[[hass]]'
|
||||
filter-type='recent-entity'
|
||||
entity-id='[[stateObj.entity_id]]'
|
||||
data='{{_stateHistory}}'
|
||||
is-loading='{{_stateHistoryLoading}}'
|
||||
cache-config='[[_cacheConfig]]'
|
||||
></ha-state-history-data>
|
||||
<state-history-charts
|
||||
history-data="[[_stateHistory]]"
|
||||
is-loading-data="[[_stateHistoryLoading]]"
|
||||
up-to-now
|
||||
></state-history-charts>
|
||||
</div>
|
||||
<ha-state-history-data
|
||||
hass='[[hass]]'
|
||||
filter-type='recent-entity'
|
||||
entity-id='[[stateObj.entity_id]]'
|
||||
data='{{_stateHistory}}'
|
||||
is-loading='{{_stateHistoryLoading}}'
|
||||
cache-config='[[_cacheConfig]]'
|
||||
></ha-state-history-data>
|
||||
<state-history-charts
|
||||
history-data="[[_stateHistory]]"
|
||||
is-loading-data="[[_stateHistoryLoading]]"
|
||||
up-to-now
|
||||
no-single=[[large]]
|
||||
is-zoomable=[[large]]
|
||||
></state-history-charts>
|
||||
</template>
|
||||
<paper-dialog-scrollable dialog-element='[[dialogElement]]'>
|
||||
<more-info-content
|
||||
@ -110,6 +120,13 @@
|
||||
|
||||
_stateHistory: Object,
|
||||
_stateHistoryLoading: Boolean,
|
||||
|
||||
large: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
notify: true,
|
||||
},
|
||||
|
||||
_cacheConfig: {
|
||||
type: Object,
|
||||
value: {
|
||||
@ -121,6 +138,10 @@
|
||||
};
|
||||
}
|
||||
|
||||
enlarge() {
|
||||
this.large = !this.large;
|
||||
}
|
||||
|
||||
_computeShowStateInfo(stateObj) {
|
||||
return !stateObj || !DOMAINS_NO_INFO.includes(window.hassUtil.computeDomain(stateObj));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<link rel='import' href='../../bower_components/app-localize-behavior/app-localize-behavior.html'>
|
||||
<link rel="import" href='../../bower_components/paper-dialog/paper-dialog-behavior.html'>
|
||||
<link rel="import" href='../../bower_components/paper-dialog-behavior/paper-dialog-behavior.html'>
|
||||
|
||||
<script>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user