mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-10 19:11:58 +03:00
extract sparkline SVG rendering into its own module
This commit is contained in:
parent
a384b98dcb
commit
edfa55e4dc
2 changed files with 46 additions and 46 deletions
|
|
@ -5,6 +5,7 @@ import { EditorState, StateEffect, StateField, RangeSetBuilder } from "@codemirr
|
||||||
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
||||||
import { autocompletion, CompletionContext, CompletionResult, acceptCompletion } from "@codemirror/autocomplete";
|
import { autocompletion, CompletionContext, CompletionResult, acceptCompletion } from "@codemirror/autocomplete";
|
||||||
import { SumEngine, LineResult } from "../engine";
|
import { SumEngine, LineResult } from "../engine";
|
||||||
|
import { buildSparkline } from "./sparkline";
|
||||||
|
|
||||||
export interface EditorCallbacks {
|
export interface EditorCallbacks {
|
||||||
onChange(text: string): void;
|
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 {
|
export class SumEditor {
|
||||||
view: EditorView;
|
view: EditorView;
|
||||||
private resultsEl: HTMLElement;
|
private resultsEl: HTMLElement;
|
||||||
|
|
|
||||||
45
src/ui/sparkline.ts
Normal file
45
src/ui/sparkline.ts
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue