{"spec_id":"line-load-duration","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// line-load-duration: Load Duration Curve for Energy Systems\n// Library: highcharts 12.6.0 | JavaScript 22.22.3\n// Quality: 88/100 | Created: 2026-06-10\n\n//# anyplot-orientation: landscape\n\nconst t = window.ANYPLOT_TOKENS;\n\n// Deterministic LCG — browser has no seeded Math.random\nlet _seed = 42;\nfunction rand() {\n  _seed = (_seed * 1664525 + 1013904223) >>> 0;\n  return _seed / 4294967296;\n}\n\n// Generate 8760 hourly loads (MW) with seasonal + morning/evening peak patterns\nconst rawLoads = Array.from({length: 8760}, (_, h) => {\n  const dayOfYear = Math.floor(h / 24);\n  const hourOfDay = h % 24;\n  const seasonal = 200 * Math.cos(2 * Math.PI * dayOfYear / 365);\n  const morning  = 250 * Math.exp(-0.5 * Math.pow((hourOfDay - 9) / 2, 2));\n  const evening  = 220 * Math.exp(-0.5 * Math.pow((hourOfDay - 19) / 2, 2));\n  const noise    = 60 * (rand() * 2 - 1);\n  return 700 + seasonal + morning + evening + noise;\n});\n\n// Sort descending to form the load duration curve\nrawLoads.sort((a, b) => b - a);\n\n// Generation capacity thresholds (MW)\nconst BASE_CAP  = 600;\nconst INTER_CAP = 900;\nconst PEAK_CAP  = 1200;\n\n// Find hour indices where load first drops below each threshold\nconst interHour = rawLoads.findIndex(v => v < INTER_CAP);\nconst baseHour  = rawLoads.findIndex(v => v < BASE_CAP);\n\n// Stacked series data — each layer's sum equals the total load\nconst baseData  = rawLoads.map(v => Math.min(v, BASE_CAP));\nconst interData = rawLoads.map(v => Math.max(0, Math.min(v, INTER_CAP) - BASE_CAP));\nconst peakData  = rawLoads.map(v => Math.max(0, v - INTER_CAP));\n\n// Total annual energy (sum of hourly MWh → TWh)\nconst totalTWh = rawLoads.reduce((s, v) => s + v, 0) / 1e6;\n\n// Semantic colors: green = base (always-on), ochre = intermediate, red = peak (critical)\nconst GREEN = t.palette[0];  // #009E73\nconst OCHRE = t.palette[3];  // #BD8233\nconst RED   = t.palette[4];  // #AE3030\n\nHighcharts.chart(\"container\", {\n  chart: {\n    type: \"area\",\n    backgroundColor: \"transparent\",\n    animation: false,\n    style: { fontFamily: \"inherit\" },\n  },\n  credits: { enabled: false },\n  title: {\n    text: \"line-load-duration · javascript · highcharts · anyplot.ai\",\n    style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" },\n  },\n  subtitle: {\n    text: \"Total annual energy consumption: \" + totalTWh.toFixed(2) + \" TWh\",\n    style: { color: t.inkSoft, fontSize: \"14px\" },\n  },\n  xAxis: {\n    title: {\n      text: \"Hours of the Year (sorted by descending demand)\",\n      style: { color: t.inkSoft, fontSize: \"16px\" },\n    },\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" } },\n    // Vertical dashed dividers at region boundaries\n    plotLines: [\n      { value: interHour, color: t.inkSoft, dashStyle: \"ShortDash\", width: 1, zIndex: 3 },\n      { value: baseHour,  color: t.inkSoft, dashStyle: \"ShortDash\", width: 1, zIndex: 3 },\n    ],\n    // Region labels — y offset positions label within its respective colored band\n    plotBands: [\n      {\n        from: 0, to: interHour, color: \"transparent\",\n        label: {\n          text: \"Peak Load\",\n          style: { color: RED, fontSize: \"14px\", fontWeight: \"700\" },\n          align: \"center\", y: 180,\n        },\n      },\n      {\n        from: interHour, to: baseHour, color: \"transparent\",\n        label: {\n          text: \"Intermediate Load\",\n          style: { color: OCHRE, fontSize: \"14px\", fontWeight: \"700\" },\n          align: \"center\", x: -260, y: 360,\n        },\n      },\n      {\n        from: baseHour, to: 8760, color: \"transparent\",\n        label: {\n          text: \"Base Load\",\n          style: { color: GREEN, fontSize: \"14px\", fontWeight: \"700\" },\n          align: \"center\", y: 560,\n        },\n      },\n    ],\n  },\n  yAxis: {\n    min: 0,\n    max: 1300,\n    title: {\n      text: \"Power Demand (MW)\",\n      style: { color: t.inkSoft, fontSize: \"16px\" },\n    },\n    gridLineColor: t.grid,\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" } },\n    // Horizontal dashed lines at capacity tiers\n    plotLines: [\n      {\n        value: BASE_CAP,\n        color: GREEN,\n        dashStyle: \"Dash\",\n        width: 2,\n        zIndex: 4,\n        label: {\n          text: \"Base capacity — \" + BASE_CAP + \" MW\",\n          style: { color: GREEN, fontSize: \"13px\", fontWeight: \"600\" },\n          align: \"right\",\n          x: -5,\n          y: -6,\n        },\n      },\n      {\n        value: INTER_CAP,\n        color: OCHRE,\n        dashStyle: \"Dash\",\n        width: 2,\n        zIndex: 4,\n        label: {\n          text: \"Intermediate capacity — \" + INTER_CAP + \" MW\",\n          style: { color: OCHRE, fontSize: \"13px\", fontWeight: \"600\" },\n          align: \"right\",\n          x: -5,\n          y: -6,\n        },\n      },\n      {\n        value: PEAK_CAP,\n        color: RED,\n        dashStyle: \"Dash\",\n        width: 2,\n        zIndex: 4,\n        label: {\n          text: \"Peak capacity — \" + PEAK_CAP + \" MW\",\n          style: { color: RED, fontSize: \"13px\", fontWeight: \"600\" },\n          align: \"right\",\n          x: -5,\n          y: -6,\n        },\n      },\n    ],\n  },\n  legend: {\n    enabled: true,\n    itemStyle: { color: t.inkSoft, fontSize: \"14px\" },\n    itemHoverStyle: { color: t.ink },\n  },\n  plotOptions: {\n    series: { animation: false, turboThreshold: 0 },\n    area: {\n      stacking: \"normal\",\n      lineWidth: 0,\n      marker: { enabled: false },\n      fillOpacity: 0.88,\n    },\n  },\n  series: [\n    {\n      name: \"Base Load\",\n      data: baseData,\n      color: GREEN,\n    },\n    {\n      name: \"Intermediate Load\",\n      data: interData,\n      color: OCHRE,\n    },\n    {\n      name: \"Peak Load\",\n      data: peakData,\n      color: RED,\n    },\n    {\n      type: \"line\",\n      name: \"Load Duration Curve\",\n      data: rawLoads,\n      color: t.ink,\n      lineWidth: 1.5,\n      marker: { enabled: false },\n      showInLegend: false,\n      enableMouseTracking: false,\n      zIndex: 10,\n    },\n  ],\n});\n"}