Skip to content

Commit 239987b

Browse files
committed
refactor: Improve MoonHorizon chart responsiveness and resizing
1 parent 1dee82f commit 239987b

File tree

2 files changed

+69
-44
lines changed

2 files changed

+69
-44
lines changed

src/components/moon-horizon.ts

+36-17
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export class MoonHorizon extends LitElement {
3131
@property({ attribute: false }) public hass!: HomeAssistant;
3232
@property({ attribute: false }) moon!: Moon;
3333
@property({ attribute: false }) card!: LunarPhaseCard;
34+
@property({ type: Number }) cardWidth = 0;
3435

3536
@state() _chart!: Chart;
3637
@state() moreInfo = false;
@@ -39,8 +40,6 @@ export class MoonHorizon extends LitElement {
3940

4041
@state() private _timeAnimationFrame: number | null = null;
4142
@state() private _lastTime: string | null = null;
42-
@state() _resizeInitiated = false;
43-
@state() _resizeObserver: ResizeObserver | null = null;
4443

4544
connectedCallback(): void {
4645
super.connectedCallback();
@@ -59,10 +58,17 @@ export class MoonHorizon extends LitElement {
5958

6059
protected async firstUpdated(changedProps: PropertyValues): Promise<void> {
6160
super.firstUpdated(changedProps);
62-
await new Promise((resolve) => setTimeout(resolve, 50));
61+
await new Promise((resolve) => setTimeout(resolve, 20));
6362
this.setupChart();
6463
}
6564

65+
protected updated(changedProps: PropertyValues): void {
66+
super.updated(changedProps);
67+
if (changedProps.has('cardWidth')) {
68+
this._chart?.update('resize');
69+
}
70+
}
71+
6672
static get styles(): CSSResultGroup {
6773
return [
6874
css`
@@ -84,6 +90,7 @@ export class MoonHorizon extends LitElement {
8490
.moon-horizon canvas {
8591
width: 100%;
8692
height: 100%;
93+
display: block;
8794
}
8895
8996
.moon-data-wrapper {
@@ -137,6 +144,7 @@ export class MoonHorizon extends LitElement {
137144
plugins.push(this.timeMarkerPlugin());
138145
plugins.push(this.moonMarkerPlugin());
139146
plugins.push(this.highestAltitudePlugin());
147+
plugins.push(this.expandChartArea());
140148
return plugins;
141149
}
142150

@@ -178,8 +186,9 @@ export class MoonHorizon extends LitElement {
178186
data: data,
179187
options: {
180188
...options,
181-
resizeDelay: 1000,
182-
aspectRatio: 2,
189+
responsive: true, // Make sure chart is responsive
190+
maintainAspectRatio: false, // Allow dynamic resizing
191+
resizeDelay: 0, // Adjust delay for smoother resizing
183192
scales: {
184193
...options.scales,
185194
x: {
@@ -222,13 +231,6 @@ export class MoonHorizon extends LitElement {
222231
// console.log('Clicked on', dataIndex, element);
223232
}
224233
},
225-
onResize: (_chart, size) => {
226-
// Resize the chart if the width has changed
227-
if (this.card._cardWidth !== size.width) {
228-
_chart.resize();
229-
_chart.update('none');
230-
}
231-
},
232234
},
233235

234236
plugins: [...customPlugins],
@@ -250,7 +252,7 @@ export class MoonHorizon extends LitElement {
250252
protected render(): TemplateResult {
251253
return html`
252254
<div class="moon-horizon">
253-
<canvas id="moonPositionChart" width=${this.card._cardWidth}></canvas>
255+
<canvas id="moonPositionChart" width=${this.cardWidth}></canvas>
254256
</div>
255257
<div class="moon-data-wrapper">
256258
<div class="moon-data-header">
@@ -515,11 +517,9 @@ export class MoonHorizon extends LitElement {
515517
};
516518

517519
const layout: ChartOptions['layout'] = {
520+
autoPadding: false,
518521
padding: {
519-
bottom: 10,
520-
left: 4,
521-
right: 4,
522-
top: 10,
522+
left: -8,
523523
},
524524
};
525525
// Options
@@ -758,6 +758,25 @@ export class MoonHorizon extends LitElement {
758758
},
759759
};
760760
};
761+
762+
private expandChartArea = (): Plugin => {
763+
return {
764+
id: 'expandChartArea',
765+
beforeDraw: (chart: Chart) => {
766+
chart.chartArea.left = 0;
767+
chart.chartArea.right = chart.width;
768+
chart.chartArea.top = 0;
769+
chart.chartArea.bottom = chart.height;
770+
},
771+
772+
afterUpdate: (chart: Chart) => {
773+
chart.chartArea.left = 0;
774+
chart.chartArea.right = chart.width;
775+
chart.chartArea.top = 0;
776+
chart.chartArea.bottom = chart.height;
777+
},
778+
};
779+
};
761780
}
762781

763782
declare global {

src/lunar-phase-card.ts

+33-27
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import './components/moon-phase-calendar';
2424
// styles
2525
import style from './css/style.css';
2626

27-
const BASE_REFRESH_INTERVAL = 15 * 1000;
27+
const BASE_REFRESH_INTERVAL = 60 * 1000;
2828
const LOADING_TIMEOUT = 1500;
2929

3030
@customElement('lunar-phase-card')
@@ -44,12 +44,12 @@ export class LunarPhaseCard extends LitElement {
4444
@property({ type: Object }) protected moon!: Moon;
4545
@state() _activeCard: PageType | null = null;
4646
@state() selectedDate: Date | undefined;
47-
@state() _refreshInterval: number | undefined;
4847

4948
@state() _calendarPopup: boolean = false;
50-
@state() _state: MoonState = MoonState.READY;
5149
@state() _resizeInitiated = false;
5250
@state() public _cardWidth = 0;
51+
@state() private _state: MoonState = MoonState.READY;
52+
@state() private _refreshInterval: number | undefined;
5353

5454
@state() _activeEditorPage?: PageType;
5555
@state() _resizeObserver: ResizeObserver | null = null;
@@ -83,13 +83,14 @@ export class LunarPhaseCard extends LitElement {
8383
window.LunarCard = this;
8484
window.Moon = this.moon;
8585
}
86+
this.startRefreshInterval();
87+
8688
if (isEditorMode(this)) {
8789
document.addEventListener('toggle-graph-editor', (ev) => this._handleEditorEvent(ev as CustomEvent));
8890
}
8991
if (!this._resizeInitiated && !this._resizeObserver) {
9092
this.delayedAttachResizeObserver();
9193
}
92-
this.startRefreshInterval();
9394
}
9495

9596
disconnectedCallback(): void {
@@ -107,16 +108,14 @@ export class LunarPhaseCard extends LitElement {
107108
}
108109

109110
attachResizeObserver(): void {
110-
if (this._resizeObserver) {
111-
return;
112-
}
113-
this._resizeObserver = new ResizeObserver(() => {
111+
const ro = new ResizeObserver(() => {
114112
this.measureCard();
115113
});
116114

117115
const card = this.shadowRoot?.querySelector('ha-card') as HTMLElement;
118116
if (card) {
119-
this._resizeObserver.observe(card);
117+
ro.observe(card);
118+
this._resizeObserver = ro;
120119
}
121120
}
122121

@@ -132,11 +131,7 @@ export class LunarPhaseCard extends LitElement {
132131
const header = this.shadowRoot?.getElementById('lpc-header') as HTMLElement;
133132
if (card) {
134133
this._cardWidth = card.clientWidth;
135-
}
136-
137-
if (header) {
138-
const sizes = header.getBoundingClientRect();
139-
// console.log(JSON.stringify(sizes, null, 2));
134+
// console.log('card width', this._cardWidth);
140135
}
141136
}
142137

@@ -257,19 +252,25 @@ export class LunarPhaseCard extends LitElement {
257252
if (this._refreshInterval !== undefined) {
258253
clearInterval(this._refreshInterval);
259254
}
260-
255+
// Calculate the remaining time until the next full minute
256+
const now = new Date();
257+
const remainingMs = (60 - now.getSeconds()) * 1000;
261258
// Set up a new interval
262-
this._refreshInterval = window.setInterval(() => {
263-
if (this._activeCard === PageType.BASE || this._activeCard === PageType.HORIZON) {
264-
this._state = MoonState.LOADING;
265-
setTimeout(() => {
266-
this._state = MoonState.READY;
267-
}, LOADING_TIMEOUT);
268-
this.requestUpdate();
269-
} else {
270-
this.clearRefreshInterval();
271-
}
272-
}, BASE_REFRESH_INTERVAL);
259+
setTimeout(() => {
260+
this._refreshInterval = window.setInterval(() => {
261+
if (this._activeCard === PageType.BASE || this._activeCard === PageType.HORIZON) {
262+
if (this._state !== MoonState.LOADING) {
263+
this._state = MoonState.LOADING;
264+
setTimeout(() => {
265+
// console.log('Refresh interval triggered');
266+
this._state = MoonState.READY;
267+
this.requestUpdate();
268+
}, LOADING_TIMEOUT);
269+
}
270+
}
271+
}, BASE_REFRESH_INTERVAL);
272+
// console.log('Triggering first refresh');
273+
}, remainingMs);
273274
}
274275

275276
private clearRefreshInterval() {
@@ -437,7 +438,12 @@ export class LunarPhaseCard extends LitElement {
437438
}
438439

439440
private renderHorizon(): TemplateResult | void {
440-
return html`<moon-horizon .hass=${this.hass} .moon=${this.moon} .card=${this as any}></moon-horizon>`;
441+
return html`<moon-horizon
442+
.hass=${this.hass}
443+
.moon=${this.moon}
444+
.card=${this as any}
445+
.cardWidth=${this._cardWidth}
446+
></moon-horizon>`;
441447
}
442448

443449
private updateDate(action?: 'next' | 'prev') {

0 commit comments

Comments
 (0)