Skip to content

Commit

Permalink
refactor: Improve MoonHorizon chart responsiveness and resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
ngocjohn committed Nov 20, 2024
1 parent 1dee82f commit 239987b
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 44 deletions.
53 changes: 36 additions & 17 deletions src/components/moon-horizon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class MoonHorizon extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) moon!: Moon;
@property({ attribute: false }) card!: LunarPhaseCard;
@property({ type: Number }) cardWidth = 0;

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

@state() private _timeAnimationFrame: number | null = null;
@state() private _lastTime: string | null = null;
@state() _resizeInitiated = false;
@state() _resizeObserver: ResizeObserver | null = null;

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

protected async firstUpdated(changedProps: PropertyValues): Promise<void> {
super.firstUpdated(changedProps);
await new Promise((resolve) => setTimeout(resolve, 50));
await new Promise((resolve) => setTimeout(resolve, 20));
this.setupChart();
}

protected updated(changedProps: PropertyValues): void {
super.updated(changedProps);
if (changedProps.has('cardWidth')) {
this._chart?.update('resize');
}
}

static get styles(): CSSResultGroup {
return [
css`
Expand All @@ -84,6 +90,7 @@ export class MoonHorizon extends LitElement {
.moon-horizon canvas {
width: 100%;
height: 100%;
display: block;
}
.moon-data-wrapper {
Expand Down Expand Up @@ -137,6 +144,7 @@ export class MoonHorizon extends LitElement {
plugins.push(this.timeMarkerPlugin());
plugins.push(this.moonMarkerPlugin());
plugins.push(this.highestAltitudePlugin());
plugins.push(this.expandChartArea());
return plugins;
}

Expand Down Expand Up @@ -178,8 +186,9 @@ export class MoonHorizon extends LitElement {
data: data,
options: {
...options,
resizeDelay: 1000,
aspectRatio: 2,
responsive: true, // Make sure chart is responsive
maintainAspectRatio: false, // Allow dynamic resizing
resizeDelay: 0, // Adjust delay for smoother resizing
scales: {
...options.scales,
x: {
Expand Down Expand Up @@ -222,13 +231,6 @@ export class MoonHorizon extends LitElement {
// console.log('Clicked on', dataIndex, element);
}
},
onResize: (_chart, size) => {
// Resize the chart if the width has changed
if (this.card._cardWidth !== size.width) {
_chart.resize();
_chart.update('none');
}
},
},

plugins: [...customPlugins],
Expand All @@ -250,7 +252,7 @@ export class MoonHorizon extends LitElement {
protected render(): TemplateResult {
return html`
<div class="moon-horizon">
<canvas id="moonPositionChart" width=${this.card._cardWidth}></canvas>
<canvas id="moonPositionChart" width=${this.cardWidth}></canvas>
</div>
<div class="moon-data-wrapper">
<div class="moon-data-header">
Expand Down Expand Up @@ -515,11 +517,9 @@ export class MoonHorizon extends LitElement {
};

const layout: ChartOptions['layout'] = {
autoPadding: false,
padding: {
bottom: 10,
left: 4,
right: 4,
top: 10,
left: -8,
},
};
// Options
Expand Down Expand Up @@ -758,6 +758,25 @@ export class MoonHorizon extends LitElement {
},
};
};

private expandChartArea = (): Plugin => {
return {
id: 'expandChartArea',
beforeDraw: (chart: Chart) => {
chart.chartArea.left = 0;
chart.chartArea.right = chart.width;
chart.chartArea.top = 0;
chart.chartArea.bottom = chart.height;
},

afterUpdate: (chart: Chart) => {
chart.chartArea.left = 0;
chart.chartArea.right = chart.width;
chart.chartArea.top = 0;
chart.chartArea.bottom = chart.height;
},
};
};
}

declare global {
Expand Down
60 changes: 33 additions & 27 deletions src/lunar-phase-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import './components/moon-phase-calendar';
// styles
import style from './css/style.css';

const BASE_REFRESH_INTERVAL = 15 * 1000;
const BASE_REFRESH_INTERVAL = 60 * 1000;
const LOADING_TIMEOUT = 1500;

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

@state() _calendarPopup: boolean = false;
@state() _state: MoonState = MoonState.READY;
@state() _resizeInitiated = false;
@state() public _cardWidth = 0;
@state() private _state: MoonState = MoonState.READY;
@state() private _refreshInterval: number | undefined;

@state() _activeEditorPage?: PageType;
@state() _resizeObserver: ResizeObserver | null = null;
Expand Down Expand Up @@ -83,13 +83,14 @@ export class LunarPhaseCard extends LitElement {
window.LunarCard = this;
window.Moon = this.moon;
}
this.startRefreshInterval();

if (isEditorMode(this)) {
document.addEventListener('toggle-graph-editor', (ev) => this._handleEditorEvent(ev as CustomEvent));
}
if (!this._resizeInitiated && !this._resizeObserver) {
this.delayedAttachResizeObserver();
}
this.startRefreshInterval();
}

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

attachResizeObserver(): void {
if (this._resizeObserver) {
return;
}
this._resizeObserver = new ResizeObserver(() => {
const ro = new ResizeObserver(() => {
this.measureCard();
});

const card = this.shadowRoot?.querySelector('ha-card') as HTMLElement;
if (card) {
this._resizeObserver.observe(card);
ro.observe(card);
this._resizeObserver = ro;
}
}

Expand All @@ -132,11 +131,7 @@ export class LunarPhaseCard extends LitElement {
const header = this.shadowRoot?.getElementById('lpc-header') as HTMLElement;
if (card) {
this._cardWidth = card.clientWidth;
}

if (header) {
const sizes = header.getBoundingClientRect();
// console.log(JSON.stringify(sizes, null, 2));
// console.log('card width', this._cardWidth);
}
}

Expand Down Expand Up @@ -257,19 +252,25 @@ export class LunarPhaseCard extends LitElement {
if (this._refreshInterval !== undefined) {
clearInterval(this._refreshInterval);
}

// Calculate the remaining time until the next full minute
const now = new Date();
const remainingMs = (60 - now.getSeconds()) * 1000;
// Set up a new interval
this._refreshInterval = window.setInterval(() => {
if (this._activeCard === PageType.BASE || this._activeCard === PageType.HORIZON) {
this._state = MoonState.LOADING;
setTimeout(() => {
this._state = MoonState.READY;
}, LOADING_TIMEOUT);
this.requestUpdate();
} else {
this.clearRefreshInterval();
}
}, BASE_REFRESH_INTERVAL);
setTimeout(() => {
this._refreshInterval = window.setInterval(() => {
if (this._activeCard === PageType.BASE || this._activeCard === PageType.HORIZON) {
if (this._state !== MoonState.LOADING) {
this._state = MoonState.LOADING;
setTimeout(() => {
// console.log('Refresh interval triggered');
this._state = MoonState.READY;
this.requestUpdate();
}, LOADING_TIMEOUT);
}
}
}, BASE_REFRESH_INTERVAL);
// console.log('Triggering first refresh');
}, remainingMs);
}

private clearRefreshInterval() {
Expand Down Expand Up @@ -437,7 +438,12 @@ export class LunarPhaseCard extends LitElement {
}

private renderHorizon(): TemplateResult | void {
return html`<moon-horizon .hass=${this.hass} .moon=${this.moon} .card=${this as any}></moon-horizon>`;
return html`<moon-horizon
.hass=${this.hass}
.moon=${this.moon}
.card=${this as any}
.cardWidth=${this._cardWidth}
></moon-horizon>`;
}

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

0 comments on commit 239987b

Please sign in to comment.