diff --git a/plots/line-yield-curve/implementations/javascript/highcharts.js b/plots/line-yield-curve/implementations/javascript/highcharts.js new file mode 100644 index 0000000000..42e0b6bcfe --- /dev/null +++ b/plots/line-yield-curve/implementations/javascript/highcharts.js @@ -0,0 +1,136 @@ +// anyplot.ai +// line-yield-curve: Yield Curve (Interest Rate Term Structure) +// Library: highcharts 12.6.0 | JavaScript 22.22.3 +// Quality: 91/100 | Created: 2026-06-10 + +//# anyplot-orientation: landscape + +const theme = window.ANYPLOT_THEME; +const t = window.ANYPLOT_TOKENS; + +// U.S. Treasury yield curve snapshots (maturity years → annualized yield %) +const matValues = [0.083, 0.25, 0.5, 1, 2, 3, 5, 7, 10, 20, 30]; +const matLabels = ["1M", "3M", "6M", "1Y", "2Y", "3Y", "5Y", "7Y", "10Y", "20Y", "30Y"]; + +// Log-transform x-positions for proper time spacing on a linear axis +// (equivalent to a log axis, but avoids Highcharts' auto label-culling on log axes) +const logX = matValues.map((v) => Math.log10(v) * 10); +// logX ≈ [-10.8, -6.0, -3.0, 0.0, 3.0, 4.8, 7.0, 8.5, 10.0, 13.0, 14.8] + +// Three historical U.S. Treasury snapshots showing different curve shapes +const jan2021 = [0.05, 0.04, 0.05, 0.07, 0.13, 0.21, 0.46, 0.73, 1.07, 1.63, 1.83]; // Normal +const nov2022 = [3.42, 4.32, 4.60, 4.75, 4.57, 4.43, 4.13, 4.01, 3.96, 4.13, 3.93]; // Inverted +const jun2024 = [5.27, 5.37, 5.38, 5.10, 4.73, 4.48, 4.31, 4.30, 4.28, 4.52, 4.41]; // Flat + +const toPoints = (yields) => logX.map((lx, i) => ({ x: lx, y: yields[i] })); + +// Title length = 84 chars → fontSize = round(22 * 67 / 84) = 18px +Highcharts.chart("container", { + chart: { + type: "line", + backgroundColor: "transparent", + animation: false, + style: { fontFamily: "inherit" } + }, + credits: { enabled: false }, + colors: t.palette, + + title: { + text: "U.S. Treasury Yield Curves · line-yield-curve · javascript · highcharts · anyplot.ai", + style: { color: t.ink, fontSize: "18px", fontWeight: "600" } + }, + + xAxis: { + tickPositions: logX, + labels: { + formatter: function () { + // Map log-transformed tick back to maturity label + const idx = logX.reduce( + (best, v, i) => Math.abs(v - this.value) < Math.abs(logX[best] - this.value) ? i : best, + 0 + ); + return matLabels[idx]; + }, + style: { color: t.inkSoft, fontSize: "13px" } + }, + title: { + text: "Maturity", + style: { color: t.inkSoft, fontSize: "16px" } + }, + lineColor: t.inkSoft, + tickColor: t.inkSoft, + gridLineColor: "transparent", + plotBands: [ + { + // Shade the short-to-medium term zone where Nov 2022 was deeply inverted + from: logX[0], + to: logX[4], // 1M to 2Y + color: theme === "light" ? "rgba(174,48,48,0.07)" : "rgba(174,48,48,0.15)", + label: { + text: "Inversion zone", + style: { color: t.inkSoft, fontSize: "11px", fontStyle: "italic" }, + align: "center", + verticalAlign: "top", + y: 18 + } + } + ] + }, + + yAxis: { + title: { + text: "Yield (%)", + style: { color: t.inkSoft, fontSize: "16px" } + }, + labels: { + formatter: function () { return this.value.toFixed(1) + "%"; }, + style: { color: t.inkSoft, fontSize: "14px" } + }, + gridLineColor: t.grid, + min: 0 + }, + + legend: { + enabled: true, + layout: "horizontal", + align: "right", + verticalAlign: "top", + itemStyle: { color: t.inkSoft, fontSize: "14px", fontWeight: "normal" }, + itemHoverStyle: { color: t.ink }, + backgroundColor: t.elevatedBg, + borderColor: t.grid, + borderRadius: 4, + borderWidth: 1 + }, + + plotOptions: { + series: { + animation: false, + lineWidth: 2.5, + marker: { + enabled: true, + radius: 5, + symbol: "circle", + lineWidth: 1, + lineColor: "transparent" + } + } + }, + + series: [ + { name: "Jan 2021 — Normal", data: toPoints(jan2021) }, + { name: "Nov 2022 — Inverted", data: toPoints(nov2022) }, + { name: "Jun 2024 — Flat", data: toPoints(jun2024) } + ], + + tooltip: { + formatter: function () { + const idx = logX.reduce( + (best, v, i) => Math.abs(v - this.x) < Math.abs(logX[best] - this.x) ? i : best, 0 + ); + return "" + this.series.name + "
" + + "Maturity: " + matLabels[idx] + "
" + + "Yield: " + Highcharts.numberFormat(this.y, 2) + "%"; + } + } +}); diff --git a/plots/line-yield-curve/metadata/javascript/highcharts.yaml b/plots/line-yield-curve/metadata/javascript/highcharts.yaml new file mode 100644 index 0000000000..056c435fa5 --- /dev/null +++ b/plots/line-yield-curve/metadata/javascript/highcharts.yaml @@ -0,0 +1,244 @@ +library: highcharts +language: javascript +specification_id: line-yield-curve +created: '2026-06-10T00:48:32Z' +updated: '2026-06-10T00:54:26Z' +generated_by: claude-sonnet +workflow_run: 27245126495 +issue: 4664 +language_version: 22.22.3 +library_version: 12.6.0 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/line-yield-curve/javascript/highcharts/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/line-yield-curve/javascript/highcharts/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/line-yield-curve/javascript/highcharts/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/line-yield-curve/javascript/highcharts/plot-dark.html +quality_score: 91 +review: + strengths: + - Accurate historical U.S. Treasury data covering three distinct rate environments + (COVID near-zero, rate-hike inversion, higher-for-longer flat) + - Clever log10 x-axis transform with custom maturity tick formatter — correctly + reflects the non-linear time spacing of bond maturities + - Theme-adaptive inversion zone plot band with correct alpha for light and dark + surfaces + - 'Perfect Imprint palette compliance: brand green first, canonical order, t.palette + for all series' + - 'All spec-required features implemented: log-spaced axis, custom tick labels, + multi-curve comparison, inversion highlighting, dated legend' + weaknesses: + - Inversion zone band label at fontSize 11px CSS is below the recommended minimum + (~13px) — appears slightly small in both renders; increase to 13px for consistency + with tick labels + image_description: |- + Light render (plot-light.png): + Background: Warm off-white #FAF8F1 — correct + Chrome: Title "U.S. Treasury Yield Curves · line-yield-curve · javascript · highcharts · anyplot.ai" in dark text, clearly readable. Axis labels "Maturity" (x) and "Yield (%)" (y) in muted dark text. Tick labels 1M–30Y on x-axis and 0.0%–6.0% on y-axis all readable. Legend top-right with colored markers and descriptive series names. + Data: First series (Jan 2021 Normal) is brand green #009E73 — upward-sloping near-zero rates. Second (Nov 2022 Inverted) is lavender #C475FD — high rates with inversion. Third (Jun 2024 Flat) is blue #4467A3 — flat high-rate curve. Plot band (1M–2Y) shaded light pink/red highlights inversion zone with italic label "Inversion zone". + Legibility verdict: PASS — all text readable, no light-on-light issues + + Dark render (plot-dark.png): + Background: Warm near-black #1A1A17 — correct + Chrome: Title and all axis labels/ticks rendered in light colors against dark background — no dark-on-dark failures. Legend text is light-colored with dark elevated background box. Grid lines are subtle and visible. "Inversion zone" label remains visible. + Data: All three series colors identical to light render — green, lavender, blue (Imprint palette unchanged). Plot band uses darker reddish alpha (rgba(174,48,48,0.15)) visible against dark surface. + Legibility verdict: PASS — all text readable in dark theme, no dark-on-dark failures detected + criteria_checklist: + visual_quality: + score: 29 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: All fonts explicitly set and readable in both themes; minor deduction + for Inversion zone band label at 11px CSS (below recommended ~13px minimum) + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No text or element collisions in either render + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: Lines and markers well-proportioned for 11 data points; lineWidth + 2.5 and marker radius 5 appropriate + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Imprint palette provides good CVD-safe hue separation across green/lavender/blue + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: Plot fills canvas well, balanced margins, legend top-right, no content + clipped + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Yield (%) with units, Maturity descriptive, custom tick formatter + shows meaningful labels + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series #009E73, second #C475FD, third #4467A3 — Imprint canonical + order; transparent background; text and grid via t.ink/t.inkSoft/t.grid + tokens; correct in both renders' + design_excellence: + score: 13 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: 'Above well-configured default: plot band and descriptive curve labels + add narrative sophistication. Doesn''t reach clearly-above-defaults territory' + - id: DE-02 + name: Visual Refinement + score: 4 + max: 6 + passed: true + comment: X-axis gridlines suppressed, Y-axis grid subtle, legend has rounded + corners and border, italic Inversion zone label + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Three curves labeled Normal/Inverted/Flat with dates; plot band creates + focal point at inversion; clear economic narrative + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct multi-series line chart for yield curves + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Log-spaced x-axis, maturity tick labels, 3 curves, inversion band + with label, dated legend + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: maturity_years log-transformed for x, yield % on y, all 11 points + per curve shown + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title follows Descriptive · spec-id · javascript · highcharts · anyplot.ai + format; legend labels describe date and curve shape + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: 'All three canonical yield curve shapes: normal upward-sloping, inverted, + flat' + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Real U.S. Treasury data from three distinct macroeconomic regimes; + neutral financial topic + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Jan 2021 near-zero (0.04-1.83%), Nov 2022 inversion peak (3.42-4.75%), + Jun 2024 flat (4.28-5.38%) — factually accurate + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: Data arrays → log transform → Highcharts.chart() call; toPoints is + a one-liner expression + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: All data hardcoded; fully deterministic + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: No imports; all globals used + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean, no over-engineering; appropriate comment on log transform + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Highcharts.chart(container) with animation:false on chart and series; + credits disabled; no explicit dimensions + library_mastery: + score: 9 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: Expert use of ANYPLOT_TOKENS for chrome; plotBands with label; custom + formatter for ticks and tooltip; legend styling with backgroundColor/borderColor/borderRadius + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: plotBands with theme-adaptive alpha; custom tickPositions with formatter; + tooltip formatter with maturity resolution — strong Highcharts-specific + feature use + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - manual-ticks + - html-export + patterns: + - data-generation + dataprep: [] + styling: + - alpha-blending + - grid-styling