{"spec_id":"line-stock-comparison","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// line-stock-comparison: Stock Price Comparison Chart\n// Library: highcharts 12.6.0 | JavaScript 22.23.2\n// Quality: 90/100 | Created: 2026-08-26\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Three clean-energy stocks plus a sector benchmark index, one trading year\n// (2024), rebased to 100 at the first date so relative performance is\n// directly comparable regardless of starting price.\n\nconst MS_PER_DAY = 86400000;\n\nfunction tradingDays(year, count) {\n  const days = [];\n  let cursor = Date.UTC(year, 0, 2);\n  while (days.length < count) {\n    const weekday = new Date(cursor).getUTCDay();\n    if (weekday !== 0 && weekday !== 6) days.push(cursor);\n    cursor += MS_PER_DAY;\n  }\n  return days;\n}\n\nfunction makeLcg(seed) {\n  let state = seed >>> 0;\n  return () => {\n    state = (state * 1664525 + 1013904223) >>> 0;\n    return state / 4294967296;\n  };\n}\n\nfunction priceWalk(seed, start, drift, volatility, n) {\n  const rng = makeLcg(seed);\n  const prices = [start];\n  for (let i = 1; i < n; i++) {\n    const shock = (rng() - 0.5) * 2 * volatility;\n    prices.push(prices[i - 1] * (1 + drift + shock));\n  }\n  return prices;\n}\n\nconst dates = tradingDays(2024, 252);\n\nconst stocks = [\n  { name: \"Solaris Power (SOLR)\", ticker: \"SOLR\", seed: 11, start: 42, drift: 0.0009, vol: 0.018 },\n  { name: \"Windfield Energy (WNDF)\", ticker: \"WNDF\", seed: 23, start: 58, drift: 0.0004, vol: 0.022 },\n  { name: \"HydroGen Corp (HYDR)\", ticker: \"HYDR\", seed: 37, start: 76, drift: -0.0003, vol: 0.02 },\n  { name: \"Clean Energy Index (XCEI)\", ticker: \"XCEI\", seed: 51, start: 100, drift: 0.0003, vol: 0.009 },\n];\n\nconst rebasedPrices = stocks.map((s) => {\n  const prices = priceWalk(s.seed, s.start, s.drift, s.vol, dates.length);\n  const basePrice = prices[0];\n  return prices.map((p) => (p / basePrice) * 100);\n});\n\n// Storytelling: locate the trading day where SOLR and WNDF diverge the most\n// and shade that window via core-Highcharts xAxis.plotBands (no annotations\n// module needed) — computed from the data, not hardcoded, so the highlight\n// stays correct if the walk parameters above change.\nlet peakIdx = 0;\nlet peakGap = -Infinity;\nfor (let i = 0; i < dates.length; i++) {\n  const gap = Math.abs(rebasedPrices[0][i] - rebasedPrices[1][i]);\n  if (gap > peakGap) {\n    peakGap = gap;\n    peakIdx = i;\n  }\n}\nconst divergenceBand = {\n  from: dates[Math.max(0, peakIdx - 6)],\n  to: dates[Math.min(dates.length - 1, peakIdx + 6)],\n};\n\nconst series = stocks.map((s, i) => {\n  const values = rebasedPrices[i];\n  const isBenchmark = i === stocks.length - 1;\n  const data = values.map((y, idx) => {\n    if (idx !== values.length - 1) return [dates[idx], y];\n    // Connector-style end label so each line's final ranking reads at a\n    // glance without cross-referencing the legend below the plot.\n    return {\n      x: dates[idx],\n      y,\n      dataLabels: {\n        enabled: true,\n        format: s.ticker,\n        align: \"left\",\n        x: 8,\n        verticalAlign: \"middle\",\n        crop: false,\n        overflow: \"allow\",\n        style: { color: t.ink, fontSize: \"13px\", fontWeight: \"600\", textOutline: \"none\" },\n        backgroundColor: t.elevatedBg,\n        borderRadius: 3,\n        padding: 3,\n      },\n    };\n  });\n  return {\n    name: s.name,\n    data,\n    lineWidth: isBenchmark ? 2 : 2.75,\n    dashStyle: isBenchmark ? \"Dash\" : \"Solid\",\n    // Benchmark recedes behind the individual stocks so the dashed line\n    // doesn't compete for attention at small (mobile-preview) sizes.\n    zIndex: isBenchmark ? 1 : 2,\n  };\n});\n\n// --- Chart -------------------------------------------------------------------\nHighcharts.chart(\"container\", {\n  chart: {\n    type: \"line\",\n    backgroundColor: \"transparent\",\n    animation: false,\n    marginRight: 130,\n    style: { fontFamily: \"inherit\" },\n  },\n  credits: { enabled: false },\n  colors: t.palette,\n  title: {\n    text: \"line-stock-comparison · javascript · highcharts · anyplot.ai\",\n    style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" },\n  },\n  xAxis: {\n    type: \"datetime\",\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    gridLineColor: t.grid,\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" } },\n    title: { text: \"Trading Date (2024)\", style: { color: t.inkSoft, fontSize: \"16px\" } },\n    plotBands: [\n      {\n        from: divergenceBand.from,\n        to: divergenceBand.to,\n        color: Highcharts.color(t.amber).setOpacity(0.12).get(\"rgba\"),\n        label: {\n          text: \"Peak SOLR / WNDF divergence\",\n          align: \"center\",\n          verticalAlign: \"top\",\n          y: 14,\n          style: { color: t.inkSoft, fontSize: \"12px\" },\n        },\n      },\n    ],\n  },\n  yAxis: {\n    title: { text: \"Rebased Price (Start = 100)\", style: { color: t.inkSoft, fontSize: \"16px\" } },\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    gridLineColor: t.grid,\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" } },\n    plotLines: [\n      {\n        value: 100,\n        color: t.inkSoft,\n        dashStyle: \"Dash\",\n        width: 1.5,\n        zIndex: 3,\n        label: {\n          text: \"Start (100)\",\n          align: \"right\",\n          x: -4,\n          y: -6,\n          style: { color: t.inkSoft, fontSize: \"13px\" },\n        },\n      },\n    ],\n  },\n  legend: {\n    itemStyle: { color: t.inkSoft, fontSize: \"14px\" },\n    itemHoverStyle: { color: t.ink },\n  },\n  tooltip: { xDateFormat: \"%b %e, %Y\", valueDecimals: 1 },\n  plotOptions: {\n    series: { animation: false, marker: { enabled: false } },\n  },\n  series,\n});\n"}