diff --git a/plots/scatter-connected-temporal/implementations/javascript/echarts.js b/plots/scatter-connected-temporal/implementations/javascript/echarts.js new file mode 100644 index 0000000000..91c56146b7 --- /dev/null +++ b/plots/scatter-connected-temporal/implementations/javascript/echarts.js @@ -0,0 +1,133 @@ +// anyplot.ai +// scatter-connected-temporal: Connected Scatter Plot with Temporal Path +// Library: echarts 5.5.1 | JavaScript 22.22.3 +// Quality: 93/100 | Updated: 2026-06-10 + +const t = window.ANYPLOT_TOKENS; + +// Annual CO₂ concentration (ppm) vs. global temperature anomaly (°C), 1980–2023 +const years = [ + 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, + 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023 +]; + +const co2 = [ + 338.7, 340.1, 341.4, 343.0, 344.4, 345.9, 347.2, 348.9, 351.5, 352.9, + 354.4, 355.6, 356.3, 357.1, 358.9, 360.6, 362.4, 363.8, 366.6, 368.3, + 369.5, 371.1, 373.2, 375.8, 377.5, 379.8, 381.9, 383.8, 385.6, 387.4, + 389.9, 391.6, 394.0, 396.5, 398.6, 400.9, 404.2, 406.5, 408.5, 411.4, + 413.9, 416.2, 418.6, 421.1 +]; + +const tempAnomaly = [ + 0.26, 0.32, 0.14, 0.31, 0.16, 0.12, 0.18, 0.33, 0.40, 0.29, + 0.45, 0.41, 0.22, 0.24, 0.31, 0.45, 0.35, 0.46, 0.61, 0.40, + 0.42, 0.54, 0.63, 0.62, 0.54, 0.68, 0.61, 0.66, 0.54, 0.64, + 0.72, 0.61, 0.64, 0.68, 0.75, 0.87, 1.01, 0.92, 0.83, 0.98, + 1.02, 0.85, 0.89, 1.17 +]; + +const keyYears = new Set([1980, 2000, 2010, 2023]); +const labelPos = { 1980: "left", 2000: "top", 2010: "top", 2023: "right" }; +const n = years.length; + +// Encode temporal index as 3rd dimension for native visualMap coloring +const seriesData = years.map((year, i) => { + const isKey = keyYears.has(year); + return { + value: [co2[i], tempAnomaly[i], i], + name: String(year), + symbolSize: isKey ? 16 : 8, + itemStyle: { borderColor: t.pageBg, borderWidth: 1.5 }, + label: { + show: isKey, + formatter: String(year), + position: labelPos[year] || "top", + color: t.inkSoft, + fontSize: 14, + fontWeight: "bold", + distance: 10 + } + }; +}); + +const titleText = + "Temperature Anomaly vs CO₂ · scatter-connected-temporal · javascript · echarts · anyplot.ai"; +const titleFontSize = Math.max(13, Math.round(22 * (67 / titleText.length))); + +const chart = echarts.init(document.getElementById("container")); + +chart.setOption({ + animation: false, + backgroundColor: "transparent", + // Native ECharts continuous colormap for temporal gradient — no manual lerp needed + visualMap: { + show: false, + type: "continuous", + min: 0, + max: n - 1, + dimension: 2, + inRange: { color: t.seq } + }, + title: { + text: titleText, + left: "center", + top: 18, + textStyle: { color: t.ink, fontSize: titleFontSize, fontWeight: "bold" } + }, + grid: { left: 110, right: 50, top: 80, bottom: 90 }, + xAxis: { + type: "value", + name: "Atmospheric CO₂ (ppm)", + nameLocation: "middle", + nameGap: 45, + nameTextStyle: { color: t.ink, fontSize: 15 }, + min: 334, + max: 426, + axisLabel: { color: t.inkSoft, fontSize: 13 }, + axisLine: { show: false }, + axisTick: { show: false }, + splitLine: { lineStyle: { color: t.grid } } + }, + yAxis: { + type: "value", + name: "Global Temperature Anomaly (°C)", + nameLocation: "middle", + nameGap: 65, + nameTextStyle: { color: t.ink, fontSize: 15 }, + min: -0.1, + max: 1.3, + axisLabel: { + color: t.inkSoft, + fontSize: 13, + formatter: (v) => v.toFixed(1) + }, + axisLine: { show: false }, + axisTick: { show: false }, + splitLine: { lineStyle: { color: t.grid } } + }, + series: [ + { + type: "line", + showSymbol: true, + label: { show: false }, + lineStyle: { width: 2.5, opacity: 0.65 }, + // Arrow at path terminus: ECharts markLine makes time direction unmissable + markLine: { + silent: true, + label: { show: false }, + lineStyle: { color: t.seq[1], width: 2.5, opacity: 0.85 }, + symbol: ["none", "arrow"], + symbolSize: 14, + data: [[ + { coord: [co2[n - 2], tempAnomaly[n - 2]] }, + { coord: [co2[n - 1], tempAnomaly[n - 1]] } + ]] + }, + data: seriesData + } + ] +}); diff --git a/plots/scatter-connected-temporal/metadata/javascript/echarts.yaml b/plots/scatter-connected-temporal/metadata/javascript/echarts.yaml new file mode 100644 index 0000000000..09727f9f27 --- /dev/null +++ b/plots/scatter-connected-temporal/metadata/javascript/echarts.yaml @@ -0,0 +1,268 @@ +library: echarts +language: javascript +specification_id: scatter-connected-temporal +created: '2026-06-09T23:40:59Z' +updated: '2026-06-10T00:03:55Z' +generated_by: claude-sonnet +workflow_run: 27242620346 +issue: 4675 +language_version: 22.22.3 +library_version: 5.5.1 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/echarts/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/echarts/plot-dark.png +preview_html_light: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/echarts/plot-light.html +preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/scatter-connected-temporal/javascript/echarts/plot-dark.html +quality_score: 93 +review: + strengths: + - Excellent use of ECharts visualMap with dimension:2 encoding for temporal gradient + — the 3rd value in each [x, y, t] data tuple drives color from imprint_seq, which + is a distinctively ECharts-native pattern + - Terminal markLine arrow at 2023 makes time direction immediately obvious without + any labeling + - Mixed symbolSize (16 for key years, 8 for others) creates a clear visual hierarchy + along the temporal path + - All chrome (text, axis, grid) is fully theme-adaptive via t.ink/t.inkSoft/t.grid + tokens; both renders are clean and readable + - Excellent real-world dataset (CO₂ ppm vs. temperature anomaly 1980–2023) with + factually accurate values that tells a compelling climate narrative + - 'Clean code structure: flat data → config → setOption, no functions or classes, + fully deterministic' + weaknesses: + - Non-key markers (symbolSize:8) are on the small side for a 44-point connected + scatter — the spec sits just at the <50 boundary where the style guide calls for + more prominent markers; increase to 10–12 for the intermediary points + - 'DE-03 storytelling could be strengthened: a brief annotation (e.g. a text label + near 2015–2023 noting ''Acceleration'') or a bolder emphasis on the rightmost + cluster would let viewers immediately spot the insight rather than having to trace + the path themselves' + - 'DE-02 refinement is strong but not yet perfect: both X and Y split-lines are + drawn; removing X split-lines (keeping only Y) would clean up the grid for a plot + where the primary trend is along Y' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white (#FAF8F1) — correct theme surface, not pure white. + Chrome: Title "Temperature Anomaly vs CO₂ · scatter-connected-temporal · javascript · echarts · anyplot.ai" in dark ink at top-center, clearly readable. X-axis name "Atmospheric CO₂ (ppm)" and Y-axis name "Global Temperature Anomaly (°C)" in dark ink, both readable. Tick labels in inkSoft color at fontSize 13, fully legible. + Data: Connected scatter path spanning CO₂ 338–421 ppm and temperature anomaly -0.1–1.2 °C. Line and markers colored via imprint_seq gradient: starts at brand green (#009E73) in 1980 and transitions to blue (#4467A3) by 2023. Key year markers (1980, 2000, 2010, 2023) rendered larger (symbolSize 16) with bold year labels; non-key markers smaller (symbolSize 8). A markLine arrow at the 2022→2023 segment indicates time direction. + Legibility verdict: PASS — all text is clearly readable against the warm off-white background. No light-on-light issues. + + Dark render (plot-dark.png): + Background: Warm near-black (#1A1A17) — correct theme surface, not pure black. + Chrome: Title in light ink (#F0EFE8), clearly readable against the dark background. X/Y axis names in light ink, readable. Tick labels in inkSoft (#B8B7B0), readable. Year labels (1980, 2000, 2010, 2023) in inkSoft bold, readable. Grid lines visible as subtle warm-gray lines. + Data: Colors are identical to the light render — imprint_seq gradient from teal-green (1980) to blue (2023). Marker halos use t.pageBg (the dark background color) as borderColor, creating a clean dark-theme halo effect. The markLine arrow is in t.seq[1] blue. No data colors have shifted. + Legibility verdict: PASS — all text is clearly readable against the warm near-black background. No dark-on-dark failures observed. The inkSoft tick and year labels provide adequate contrast. + criteria_checklist: + visual_quality: + score: 29 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 8 + max: 8 + passed: true + comment: 'All font sizes explicitly set: title dynamic (fontsize ~17), axis + names 15, tick labels 13, year labels 14 bold. Readable in both themes.' + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: Year labels well-positioned (left/top/right) with no overlap against + data or each other. + - id: VQ-03 + name: Element Visibility + score: 5 + max: 6 + passed: true + comment: Key-year markers at symbolSize 16 are prominent. Non-key markers + at symbolSize 8 are visible but slightly small for a 44-point scatter at + the <50 density threshold. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: imprint_seq (green-to-blue) is CVD-safe; temporal gradient distinguishable + under deuteranopia/protanopia. No red-green sole signal. + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: 'grid: {left:110, right:50, top:80, bottom:90} provides generous + and balanced margins. Plot fills ~75% of canvas.' + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: 'X: ''Atmospheric CO₂ (ppm)'', Y: ''Global Temperature Anomaly (°C)'' + — both descriptive with units.' + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'Sequential temporal gradient via visualMap with t.seq (imprint_seq: + #009E73→#4467A3). Single-polarity temporal data — correct cmap choice. Background + transparent (renders as #FAF8F1/#1A1A17). Chrome fully theme-adaptive.' + design_excellence: + score: 15 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: 'Strong design: temporal gradient + mixed marker sizes + terminal + arrow + theme-adaptive halos places this clearly above defaults. Not quite + FiveThirtyEight level.' + - id: DE-02 + name: Visual Refinement + score: 5 + max: 6 + passed: true + comment: 'Axis lines and ticks hidden, subtle grid with t.grid token, transparent + background, no legend frame. Minor: both X and Y split-lines drawn; removing + X would clean further.' + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Gradient + arrow + year milestones create a clear temporal narrative + about climate trajectory. Good visual hierarchy, but no focal-point annotation + calling out the recent acceleration. + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct connected scatter plot with temporal path using ECharts line + type with showSymbol. + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Points connected chronologically, key time points annotated (1980/2000/2010/2023), + arrow at terminus for time direction, color gradient for temporal progression, + visible markers at each position. + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: 'X: CO₂ ppm (338–421), Y: temperature anomaly (-0.1–1.2°C), 44 annual + points 1980–2023 all shown.' + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title 'Temperature Anomaly vs CO₂ · scatter-connected-temporal · + javascript · echarts · anyplot.ai' is correct {Descriptive Title}·{spec-id}·{language}·{library}·anyplot.ai + format. No legend needed (single continuous series). + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: 'Shows all key aspects: temporal path with directional gradient, + milestone markers, connected scatter (not just line or scatter alone), full + 4-decade dataset capturing non-monotone year-to-year variation.' + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Real, neutral, non-controversial scientific scenario (climate metrics). + CO₂ and temperature anomaly are factual well-known datasets. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: CO₂ values 338.7–421.1 ppm align with real Mauna Loa measurements + for 1980–2023. Temperature anomalies 0.12–1.17°C are consistent with GISS/NOAA + records. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: 'Flat: data arrays → seriesData map → echarts.init → setOption. No + functions, no classes.' + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: Fully hardcoded deterministic data arrays. No RNG. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: Only window.ANYPLOT_TOKENS and window.echarts globals used — both + required. + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean, idiomatic JS. seriesData via .map() with per-point encoding + is well-structured. No over-engineering. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Harness handles plot-{theme}.png and plot-{theme}.html output. Current + ECharts API used. animation:false set. + library_mastery: + score: 9 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: 'Expert ECharts patterns: visualMap with dimension encoding, markLine + with arrow symbols, per-data-point symbolSize and label in data items array, + transparent backgroundColor.' + - id: LM-02 + name: Distinctive Features + score: 4 + max: 5 + passed: true + comment: visualMap dimension:2 for data-driven sequential coloring is distinctly + ECharts-native. markLine arrow approach is also library-specific. Combined + with per-point label/symbolSize, this is well above generic usage. + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - annotations + - html-export + patterns: + - data-generation + dataprep: [] + styling: + - alpha-blending + - custom-colormap