{"spec_id":"line-yield-curve","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// line-yield-curve: Yield Curve (Interest Rate Term Structure)\n// Library: highcharts 12.6.0 | JavaScript 22.22.3\n// Quality: 91/100 | Created: 2026-06-10\n\n//# anyplot-orientation: landscape\n\nconst theme = window.ANYPLOT_THEME;\nconst t = window.ANYPLOT_TOKENS;\n\n// U.S. Treasury yield curve snapshots (maturity years → annualized yield %)\nconst matValues = [0.083, 0.25, 0.5, 1, 2, 3, 5, 7, 10, 20, 30];\nconst matLabels  = [\"1M\", \"3M\", \"6M\", \"1Y\", \"2Y\", \"3Y\", \"5Y\", \"7Y\", \"10Y\", \"20Y\", \"30Y\"];\n\n// Log-transform x-positions for proper time spacing on a linear axis\n// (equivalent to a log axis, but avoids Highcharts' auto label-culling on log axes)\nconst logX = matValues.map((v) => Math.log10(v) * 10);\n// logX ≈ [-10.8, -6.0, -3.0, 0.0, 3.0, 4.8, 7.0, 8.5, 10.0, 13.0, 14.8]\n\n// Three historical U.S. Treasury snapshots showing different curve shapes\nconst jan2021 = [0.05, 0.04, 0.05, 0.07, 0.13, 0.21, 0.46, 0.73, 1.07, 1.63, 1.83]; // Normal\nconst nov2022 = [3.42, 4.32, 4.60, 4.75, 4.57, 4.43, 4.13, 4.01, 3.96, 4.13, 3.93]; // Inverted\nconst jun2024 = [5.27, 5.37, 5.38, 5.10, 4.73, 4.48, 4.31, 4.30, 4.28, 4.52, 4.41]; // Flat\n\nconst toPoints = (yields) => logX.map((lx, i) => ({ x: lx, y: yields[i] }));\n\n// Title length = 84 chars → fontSize = round(22 * 67 / 84) = 18px\nHighcharts.chart(\"container\", {\n  chart: {\n    type: \"line\",\n    backgroundColor: \"transparent\",\n    animation: false,\n    style: { fontFamily: \"inherit\" }\n  },\n  credits: { enabled: false },\n  colors: t.palette,\n\n  title: {\n    text: \"U.S. Treasury Yield Curves · line-yield-curve · javascript · highcharts · anyplot.ai\",\n    style: { color: t.ink, fontSize: \"18px\", fontWeight: \"600\" }\n  },\n\n  xAxis: {\n    tickPositions: logX,\n    labels: {\n      formatter: function () {\n        // Map log-transformed tick back to maturity label\n        const idx = logX.reduce(\n          (best, v, i) => Math.abs(v - this.value) < Math.abs(logX[best] - this.value) ? i : best,\n          0\n        );\n        return matLabels[idx];\n      },\n      style: { color: t.inkSoft, fontSize: \"13px\" }\n    },\n    title: {\n      text: \"Maturity\",\n      style: { color: t.inkSoft, fontSize: \"16px\" }\n    },\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    gridLineColor: \"transparent\",\n    plotBands: [\n      {\n        // Shade the short-to-medium term zone where Nov 2022 was deeply inverted\n        from: logX[0],\n        to: logX[4],  // 1M to 2Y\n        color: theme === \"light\" ? \"rgba(174,48,48,0.07)\" : \"rgba(174,48,48,0.15)\",\n        label: {\n          text: \"Inversion zone\",\n          style: { color: t.inkSoft, fontSize: \"11px\", fontStyle: \"italic\" },\n          align: \"center\",\n          verticalAlign: \"top\",\n          y: 18\n        }\n      }\n    ]\n  },\n\n  yAxis: {\n    title: {\n      text: \"Yield (%)\",\n      style: { color: t.inkSoft, fontSize: \"16px\" }\n    },\n    labels: {\n      formatter: function () { return this.value.toFixed(1) + \"%\"; },\n      style: { color: t.inkSoft, fontSize: \"14px\" }\n    },\n    gridLineColor: t.grid,\n    min: 0\n  },\n\n  legend: {\n    enabled: true,\n    layout: \"horizontal\",\n    align: \"right\",\n    verticalAlign: \"top\",\n    itemStyle: { color: t.inkSoft, fontSize: \"14px\", fontWeight: \"normal\" },\n    itemHoverStyle: { color: t.ink },\n    backgroundColor: t.elevatedBg,\n    borderColor: t.grid,\n    borderRadius: 4,\n    borderWidth: 1\n  },\n\n  plotOptions: {\n    series: {\n      animation: false,\n      lineWidth: 2.5,\n      marker: {\n        enabled: true,\n        radius: 5,\n        symbol: \"circle\",\n        lineWidth: 1,\n        lineColor: \"transparent\"\n      }\n    }\n  },\n\n  series: [\n    { name: \"Jan 2021 — Normal\",   data: toPoints(jan2021) },\n    { name: \"Nov 2022 — Inverted\", data: toPoints(nov2022) },\n    { name: \"Jun 2024 — Flat\",     data: toPoints(jun2024) }\n  ],\n\n  tooltip: {\n    formatter: function () {\n      const idx = logX.reduce(\n        (best, v, i) => Math.abs(v - this.x) < Math.abs(logX[best] - this.x) ? i : best, 0\n      );\n      return \"<b>\" + this.series.name + \"</b><br/>\" +\n             \"Maturity: \" + matLabels[idx] + \"<br/>\" +\n             \"Yield: \" + Highcharts.numberFormat(this.y, 2) + \"%\";\n    }\n  }\n});\n"}