diff --git a/panels/history/ha-panel-history.html b/panels/history/ha-panel-history.html index 9f074eb30f..7fd7b47312 100644 --- a/panels/history/ha-panel-history.html +++ b/panels/history/ha-panel-history.html @@ -84,7 +84,8 @@ history-data="[[stateHistory]]" is-loading-data="[[isLoadingData]]" end-time="[[endTime]]" - no-single> + no-single + is-zoomable> diff --git a/src/cards/ha-history_graph-card.html b/src/cards/ha-history_graph-card.html index 98f364293b..66b0c3e3da 100644 --- a/src/cards/ha-history_graph-card.html +++ b/src/cards/ha-history_graph-card.html @@ -42,7 +42,8 @@ history-data="[[stateHistory]]" is-loading-data="[[stateHistoryLoading]]" up-to-now - no-single> + no-single + is-zoomable="[[inDialog]]"> diff --git a/src/components/entity/ha-chart-base.html b/src/components/entity/ha-chart-base.html index 9c16f4dfd8..7bcbebe972 100644 --- a/src/components/entity/ha-chart-base.html +++ b/src/components/entity/ha-chart-base.html @@ -1,4 +1,5 @@ + @@ -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 } diff --git a/src/components/state-history-chart-line.html b/src/components/state-history-chart-line.html index 49d9ca6b71..9815417c02 100644 --- a/src/components/state-history-chart-line.html +++ b/src/components/state-history-chart-line.html @@ -4,7 +4,11 @@