From 5c576aba494f99475976726450ef69312102d7e3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 9 Aug 2026 10:23:35 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20Extract=20SVG=20sparkline=20rend?= =?UTF-8?q?ering=20to=20separate=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted `buildSparkline` from `src/ui/editor.ts` into a new file `src/ui/sparkline.ts`. This separates the data processing and generic editor logic from the visual presentation layer. Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> --- src/ui/editor.ts | 47 +-------------------------------------------- src/ui/sparkline.ts | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 46 deletions(-) create mode 100644 src/ui/sparkline.ts diff --git a/src/ui/editor.ts b/src/ui/editor.ts index d31295d..44cf173 100644 --- a/src/ui/editor.ts +++ b/src/ui/editor.ts @@ -5,6 +5,7 @@ import { EditorState, StateEffect, StateField, RangeSetBuilder } from "@codemirr import { defaultKeymap, history, historyKeymap } from "@codemirror/commands"; import { autocompletion, CompletionContext, CompletionResult, acceptCompletion } from "@codemirror/autocomplete"; import { SumEngine, LineResult } from "../engine"; +import { buildSparkline } from "./sparkline"; export interface EditorCallbacks { onChange(text: string): void; @@ -141,52 +142,6 @@ const varHighlightPlugin = ViewPlugin.fromClass( } ); -function buildSparkline(pts: number[], top: number): SVGSVGElement { - const NS = "http://www.w3.org/2000/svg"; - const W = 80, H = 20, pad = 2; - const svg = document.createElementNS(NS, "svg") as SVGSVGElement; - svg.setAttribute("width", String(W)); - svg.setAttribute("height", String(H)); - svg.setAttribute("viewBox", `0 0 ${W} ${H}`); - svg.classList.add("result-sparkline"); - svg.style.top = `${top}px`; - const min = Math.min(...pts), max = Math.max(...pts); - if (min === max) { - const line = document.createElementNS(NS, "line"); - line.setAttribute("x1", String(pad)); - line.setAttribute("y1", String(H / 2)); - line.setAttribute("x2", String(W - pad)); - line.setAttribute("y2", String(H / 2)); - line.setAttribute("stroke", "var(--result)"); - line.setAttribute("stroke-width", "1.5"); - svg.appendChild(line); - } else { - const coords = pts.map((v, i) => { - const x = pad + (i / (pts.length - 1)) * (W - 2 * pad); - const y = pad + (1 - (v - min) / (max - min)) * (H - 2 * pad); - return `${x.toFixed(1)},${y.toFixed(1)}`; - }).join(" "); - const poly = document.createElementNS(NS, "polyline"); - poly.setAttribute("points", coords); - poly.setAttribute("fill", "none"); - poly.setAttribute("stroke", "var(--result)"); - poly.setAttribute("stroke-width", "1.5"); - poly.setAttribute("stroke-linecap", "round"); - poly.setAttribute("stroke-linejoin", "round"); - svg.appendChild(poly); - const last = pts[pts.length - 1]; - const cx = (W - pad).toFixed(1); - const cy = (pad + (1 - (last - min) / (max - min)) * (H - 2 * pad)).toFixed(1); - const dot = document.createElementNS(NS, "circle"); - dot.setAttribute("cx", cx); - dot.setAttribute("cy", cy); - dot.setAttribute("r", "2"); - dot.setAttribute("fill", "var(--result)"); - svg.appendChild(dot); - } - return svg; -} - export class SumEditor { view: EditorView; private resultsEl: HTMLElement; diff --git a/src/ui/sparkline.ts b/src/ui/sparkline.ts new file mode 100644 index 0000000..c410158 --- /dev/null +++ b/src/ui/sparkline.ts @@ -0,0 +1,45 @@ +export function buildSparkline(pts: number[], top: number): SVGSVGElement { + const NS = "http://www.w3.org/2000/svg"; + const W = 80, H = 20, pad = 2; + const svg = document.createElementNS(NS, "svg") as SVGSVGElement; + svg.setAttribute("width", String(W)); + svg.setAttribute("height", String(H)); + svg.setAttribute("viewBox", `0 0 ${W} ${H}`); + svg.classList.add("result-sparkline"); + svg.style.top = `${top}px`; + const min = Math.min(...pts), max = Math.max(...pts); + if (min === max) { + const line = document.createElementNS(NS, "line"); + line.setAttribute("x1", String(pad)); + line.setAttribute("y1", String(H / 2)); + line.setAttribute("x2", String(W - pad)); + line.setAttribute("y2", String(H / 2)); + line.setAttribute("stroke", "var(--result)"); + line.setAttribute("stroke-width", "1.5"); + svg.appendChild(line); + } else { + const coords = pts.map((v, i) => { + const x = pad + (i / (pts.length - 1)) * (W - 2 * pad); + const y = pad + (1 - (v - min) / (max - min)) * (H - 2 * pad); + return `${x.toFixed(1)},${y.toFixed(1)}`; + }).join(" "); + const poly = document.createElementNS(NS, "polyline"); + poly.setAttribute("points", coords); + poly.setAttribute("fill", "none"); + poly.setAttribute("stroke", "var(--result)"); + poly.setAttribute("stroke-width", "1.5"); + poly.setAttribute("stroke-linecap", "round"); + poly.setAttribute("stroke-linejoin", "round"); + svg.appendChild(poly); + const last = pts[pts.length - 1]; + const cx = (W - pad).toFixed(1); + const cy = (pad + (1 - (last - min) / (max - min)) * (H - 2 * pad)).toFixed(1); + const dot = document.createElementNS(NS, "circle"); + dot.setAttribute("cx", cx); + dot.setAttribute("cy", cy); + dot.setAttribute("r", "2"); + dot.setAttribute("fill", "var(--result)"); + svg.appendChild(dot); + } + return svg; +}