import Chart from "../vendor/chart.js" const M2FT = 3.28084 const KM2MI = 0.621371 export const ElevationProfile = { mounted() { const data = JSON.parse(this.el.dataset.profile) if (!data || !data.points || data.points.length === 0) return this.renderChart(data) }, renderChart(data) { const points = data.points const distances = points.map(p => p.dist_km * KM2MI) const elevations = points.map(p => p.elev * M2FT) const losLine = points.map(p => p.beam * M2FT) const fresnelLower = points.map(p => (p.beam - p.r1) * M2FT) const showFresnel = data.freq_mhz >= 1000 const allElevs = [...elevations, ...losLine] const minElev = Math.min(...allElevs) - 60 const maxElev = Math.max(...allElevs) + 120 const canvas = this.el.querySelector("canvas") const ctx = canvas.getContext("2d") this.chart = new Chart(ctx, { type: "line", data: { labels: distances, datasets: [ { label: "Terrain", data: elevations, borderColor: "#8B6914", backgroundColor: "rgba(139, 105, 20, 0.3)", fill: true, pointRadius: 0, borderWidth: 1.5, tension: 0.1, order: 3 }, { label: "Line of Sight", data: losLine, borderColor: "#2563eb", borderWidth: 2, borderDash: [6, 3], pointRadius: 0, fill: false, order: 1 }, ...(showFresnel ? [ { label: "Fresnel Zone", data: fresnelLower, borderColor: "rgba(239, 68, 68, 0.4)", backgroundColor: "rgba(239, 68, 68, 0.08)", borderWidth: 1, borderDash: [3, 3], pointRadius: 0, fill: "+1", order: 2 }, { label: "_fresnelBase", data: losLine, borderWidth: 0, pointRadius: 0, fill: false, order: 2 } ] : []) ] }, options: { responsive: true, maintainAspectRatio: false, animation: {duration: 300}, plugins: { legend: { display: true, position: "top", labels: { boxWidth: 12, font: {size: 10}, filter: item => !item.text.startsWith("_") } }, tooltip: { callbacks: { title: items => items[0].label + " mi", label: item => { if (item.dataset.label.startsWith("_")) return null return item.dataset.label + ": " + Math.round(item.raw) + " ft" } } } }, scales: { x: { title: {display: true, text: "Distance (mi)", font: {size: 10}}, afterBuildTicks: axis => { const last = distances.length - 1 const totalMi = distances[last] const step = Math.ceil(totalMi / 7) || 1 const ticks = [] for (let mi = 0; mi < totalMi; mi += step) { const idx = distances.findIndex(d => d >= mi) if (idx >= 0) ticks.push({value: idx}) } ticks.push({value: last}) axis.ticks = ticks }, ticks: { font: {size: 9}, autoSkip: false, callback: val => distances[val] !== undefined ? Math.round(distances[val]) : "" } }, y: { title: {display: true, text: "Elevation (ft)", font: {size: 10}}, ticks: {font: {size: 9}}, min: Math.max(0, minElev), max: maxElev } } } }) }, destroyed() { if (this.chart) { this.chart.destroy() this.chart = null } } }