+
+
${escapeHtml(chart.title)}
- ${escapeHtml(lastVal)} ${unit} · ${escapeHtml(lastDate)}
+ ${escapeHtml(lastVal)} ${unit} · ${escapeHtml(lastDate)}
- ${barChart(chart.series)}
+
${barChart(chart.series, color, unit)}
`;
}
export class HormuzPanel extends Panel {
private data: HormuzTrackerData | null = null;
+ private tooltipBound = false;
constructor() {
super({ id: 'hormuz-tracker', title: 'Hormuz Trade Tracker', showCount: false });
@@ -72,6 +75,7 @@ export class HormuzPanel extends Panel {
}
this.data = data;
this.renderPanel();
+ this.bindTooltip();
return true;
} catch (e) {
this.showError(e instanceof Error ? e.message : 'Failed to load', () => void this.fetchData());
@@ -79,29 +83,52 @@ export class HormuzPanel extends Panel {
}
}
+ private bindTooltip(): void {
+ if (this.tooltipBound || !this.element) return;
+ this.tooltipBound = true;
+
+ this.element.addEventListener('mousemove', (e: Event) => {
+ const target = e.target as Element;
+ if (!target.classList?.contains('hbar')) return;
+ const date = (target.getAttribute('data-date') ?? '').slice(5);
+ const val = target.getAttribute('data-val') ?? '';
+ const unit = target.getAttribute('data-unit') ?? '';
+ const tip = this.element?.querySelector
('.hz-tip');
+ if (!tip) return;
+ const barRect = (target as SVGRectElement).getBoundingClientRect();
+ tip.style.left = `${barRect.left + barRect.width / 2}px`;
+ tip.style.top = `${Math.max(8, barRect.top - 28)}px`;
+ tip.style.transform = 'translateX(-50%)';
+ tip.style.opacity = '1';
+ tip.textContent = `${date} ${val} ${unit}`;
+ });
+
+ this.element.addEventListener('mouseleave', () => {
+ const tip = this.element?.querySelector('.hz-tip');
+ if (tip) tip.style.opacity = '0';
+ });
+ }
+
private renderPanel(): void {
if (!this.data) return;
const d = this.data;
- const color = statusColor(d.status);
+ const sColor = statusColor(d.status);
const charts = d.charts.length
- ? d.charts.map(c => renderChart(c)).join('')
+ ? d.charts.map((c, i) => renderChart(c, i)).join('')
: 'Chart data unavailable
';
const dateStr = d.updatedDate ? `${escapeHtml(d.updatedDate)}` : '';
- const summary = d.summary ? `${escapeHtml(d.summary)}
` : '';
const html = `
-
-
-
${statusLabel(d.status)}
+
+
+
+ ${d.status.toUpperCase()}
${dateStr}
- ${summary}
-
- ${charts}
-
-
`;