소스 검색

Show elevation gain and loss in elevation profile chart

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
k4be 2 주 전
부모
커밋
ebb10eb407
1개의 변경된 파일25개의 추가작업 그리고 1개의 파일을 삭제
  1. 25 1
      gpx-vis-frontend/js/elevation.js

+ 25 - 1
gpx-vis-frontend/js/elevation.js

@@ -8,6 +8,7 @@ const Elevation = (() => {
   let chartPts = null;  // downsampled
   let bounds = null;    // computed after draw: {cw,ch,minE,eRange,totDist}
   let trackMeta = null; // {name, trackDate, ...} from the track's meta
+  let elevStats = null; // {gain, loss} computed from full-res points
 
   // ===== Public API =====
 
@@ -25,11 +26,12 @@ const Elevation = (() => {
     trackMeta = meta || null;
     chartPts  = downsample(pts, CHART_MAX_PTS);
     bounds    = null;
+    elevStats = computeElevStats(pts);
     raf(draw);
   }
 
   function clear() {
-    points = chartPts = bounds = trackMeta = null;
+    points = chartPts = bounds = trackMeta = elevStats = null;
     hideTooltip();
     if (canvas) {
       canvas.width = canvas.width; // reset context
@@ -91,6 +93,19 @@ const Elevation = (() => {
     return out;
   }
 
+  function computeElevStats(pts) {
+    let gain = 0, loss = 0, prev = null;
+    for (const p of pts) {
+      if (p.ele == null) continue;
+      if (prev != null) {
+        const d = p.ele - prev;
+        if (d > 0) gain += d; else loss -= d;
+      }
+      prev = p.ele;
+    }
+    return { gain: Math.round(gain), loss: Math.round(loss) };
+  }
+
   // ===== Chart drawing =====
 
   function draw() {
@@ -125,6 +140,7 @@ const Elevation = (() => {
 
     drawGrid(ctx, rect, cw, ch, minE, maxE, eRange, totDist);
     drawProfile(ctx, cw, ch, minE, eRange, totDist);
+    if (elevStats) drawStats(ctx, cw);
 
     bounds = { cw, ch, minE, maxE, eRange, totDist };
   }
@@ -191,6 +207,14 @@ const Elevation = (() => {
     ctx.stroke();
   }
 
+  function drawStats(ctx, cw) {
+    const text = `▲ ${elevStats.gain} m  ▼ ${elevStats.loss} m`;
+    ctx.font = '10px sans-serif';
+    ctx.textAlign = 'right';
+    ctx.fillStyle = 'rgba(120,120,120,0.9)';
+    ctx.fillText(text, PAD.left + cw - 2, PAD.top + 10);
+  }
+
   // Draw a vertical cursor + dot at the given point (CSS pixel coords)
   function drawIndicator(point) {
     if (!bounds || !canvas) return;