{"spec_id":"map-route-path","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// map-route-path: Route Path Map\n// Library: highcharts 12.6.0 | JavaScript 22.23.2\n// Quality: 88/100 | Created: 2026-09-02\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data: a hiking trail GPS track (in-memory, deterministic) -------------\n// Small LCG so the meander is reproducible without a network-fetched track.\nfunction lcg(seed) {\n  let state = seed;\n  return () => {\n    state = (1103515245 * state + 12345) % 2147483648;\n    return state / 2147483648;\n  };\n}\nconst rand = lcg(42);\n\nconst WAYPOINTS = 140;\nconst START_LAT = 40.3428; // Bear Lake trailhead, Rocky Mountain National Park\nconst START_LON = -105.6836;\nconst BASE_BEARING_DEG = 55; // roughly north-east climb toward the summit\n\nconst path = [];\nlet lat = START_LAT;\nlet lon = START_LON;\nfor (let i = 0; i < WAYPOINTS; i++) {\n  const progress = i / (WAYPOINTS - 1);\n  const meanderDeg = Math.sin(progress * Math.PI * 5.5) * 55 + (rand() - 0.5) * 30;\n  const bearing = ((BASE_BEARING_DEG + meanderDeg) * Math.PI) / 180;\n  const stepKm = 0.045 + rand() * 0.02;\n  path.push({ lat, lon, sequence: i });\n  lat += (stepKm / 111) * Math.cos(bearing);\n  lon += (stepKm / (111 * Math.cos((lat * Math.PI) / 180))) * Math.sin(bearing);\n}\n\n// --- Color gradient along the path (elapsed time: seq[0] -> seq[1]) --------\nfunction hexToRgb(hex) {\n  const n = parseInt(hex.slice(1), 16);\n  return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\nfunction interpolateHex(hexA, hexB, frac) {\n  const [ar, ag, ab] = hexToRgb(hexA);\n  const [br, bg, bb] = hexToRgb(hexB);\n  const mix = (a, b) => Math.round(a + (b - a) * frac);\n  return `rgb(${mix(ar, br)}, ${mix(ag, bg)}, ${mix(ab, bb)})`;\n}\n\nconst SEGMENTS = 9;\nconst pathSegments = [];\nfor (let s = 0; s < SEGMENTS; s++) {\n  const startIdx = Math.floor((s * (WAYPOINTS - 1)) / SEGMENTS);\n  const endIdx = Math.floor(((s + 1) * (WAYPOINTS - 1)) / SEGMENTS);\n  pathSegments.push({\n    type: \"line\",\n    name: `Segment ${s}`,\n    data: path.slice(startIdx, endIdx + 1).map((p) => ({ x: p.lon, y: p.lat, seq: p.sequence })),\n    color: interpolateHex(t.seq[0], t.seq[1], s / (SEGMENTS - 1)),\n    lineWidth: 3.5,\n    marker: { enabled: false, states: { hover: { enabled: true, radius: 5 } } },\n    enableMouseTracking: true,\n    showInLegend: false,\n  });\n}\n\nconst start = path[0];\nconst finish = path[path.length - 1];\n\n// --- Chart -------------------------------------------------------------------\nconst title = \"Hiking Trail GPS Track · map-route-path · javascript · highcharts · anyplot.ai\";\nconst titleFontSize = Math.max(15, Math.round(22 * Math.min(1, 67 / title.length)));\n\nHighcharts.chart(\"container\", {\n  chart: {\n    type: \"line\",\n    backgroundColor: \"transparent\",\n    animation: false,\n    zoomType: \"xy\",\n    style: { fontFamily: \"inherit\" },\n  },\n  credits: { enabled: false },\n  colors: t.palette,\n  title: {\n    text: title,\n    style: { color: t.ink, fontSize: `${titleFontSize}px`, fontWeight: \"600\" },\n  },\n  subtitle: {\n    text: \"Line color traces elapsed time from start (green) to finish (blue) · drag to zoom\",\n    style: { color: t.inkSoft, fontSize: \"14px\" },\n  },\n  xAxis: {\n    title: { text: \"Longitude (°)\", style: { color: t.inkSoft, fontSize: \"16px\" } },\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    gridLineColor: t.grid,\n    gridLineWidth: 1,\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" }, format: \"{value:.3f}\" },\n  },\n  yAxis: {\n    title: { text: \"Latitude (°)\", style: { color: t.inkSoft, fontSize: \"16px\" } },\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    gridLineColor: t.grid,\n    gridLineWidth: 1,\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" }, format: \"{value:.3f}\" },\n  },\n  tooltip: {\n    formatter() {\n      return `Waypoint ${this.point.seq}<br/>Lon: ${this.x.toFixed(4)}°<br/>Lat: ${this.y.toFixed(4)}°`;\n    },\n  },\n  legend: {\n    itemStyle: { color: t.inkSoft, fontSize: \"14px\" },\n    itemHoverStyle: { color: t.ink },\n  },\n  plotOptions: {\n    series: { animation: false },\n  },\n  series: [\n    ...pathSegments,\n    {\n      type: \"scatter\",\n      name: \"Start\",\n      data: [{ x: start.lon, y: start.lat, seq: start.sequence }],\n      color: t.palette[0],\n      marker: { symbol: \"circle\", radius: 11, lineColor: t.pageBg, lineWidth: 2 },\n      dataLabels: {\n        enabled: true,\n        format: \"Start\",\n        y: -18,\n        style: { color: t.ink, fontSize: \"14px\", fontWeight: \"600\", textOutline: \"none\" },\n      },\n      showInLegend: true,\n    },\n    {\n      type: \"scatter\",\n      name: \"Finish\",\n      data: [{ x: finish.lon, y: finish.lat, seq: finish.sequence }],\n      color: \"#AE3030\",\n      marker: { symbol: \"square\", radius: 10, lineColor: t.pageBg, lineWidth: 2 },\n      dataLabels: {\n        enabled: true,\n        format: \"Finish\",\n        y: -18,\n        style: { color: t.ink, fontSize: \"14px\", fontWeight: \"600\", textOutline: \"none\" },\n      },\n      showInLegend: true,\n    },\n  ],\n});\n"}