From a92ad2b817b2c28b26e869897e03c14d30d0f991 Mon Sep 17 00:00:00 2001 From: Petri Hienonen Date: Fri, 14 Nov 2025 13:23:58 +0200 Subject: Add histogram --- app/svg.js | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'app/svg.js') diff --git a/app/svg.js b/app/svg.js index 92bd825..d977ead 100644 --- a/app/svg.js +++ b/app/svg.js @@ -25,6 +25,85 @@ export class SvgOptions { } export class Svg { + /** + * Create a rectangle with explicit coordinates + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @param {SvgOptions} [options=new SvgOptions()] + * @returns {SVGRectElement} + */ + static rectXY(x, y, width, height, options = new SvgOptions()) { + const element = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + for (const [key, value] of Object.entries({ + height: String(height), + width: String(width), + x: String(x), + y: String(y), + ...options.attributes, + })) { + element.setAttribute(key, value); + } + Object.assign(element.style, options.styles); + if (options.id) element.id = options.id; + if (options.classes.length) element.classList.add(...options.classes.filter(Boolean)); + element.append(...options.children.filter(Boolean)); + return element; + } + + /** + * Create a text element at specific coordinates + * @param {number} x + * @param {number} y + * @param {string} text + * @param {SvgOptions} [options=new SvgOptions()] + * @returns {SVGTextElement} + */ + static textXY(x, y, text, options = new SvgOptions()) { + const element = document.createElementNS("http://www.w3.org/2000/svg", "text"); + element.textContent = text; + for (const [key, value] of Object.entries({ + x: String(x), + y: String(y), + ...options.attributes, + })) { + element.setAttribute(key, value); + } + Object.assign(element.style, options.styles); + if (options.id) element.id = options.id; + if (options.classes.length) element.classList.add(...options.classes.filter(Boolean)); + element.append(...options.children.filter(Boolean)); + return element; + } + + /** + * Create a line element + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {SvgOptions} [options=new SvgOptions()] + * @returns {SVGLineElement} + */ + static line(x1, y1, x2, y2, options = new SvgOptions()) { + const element = document.createElementNS("http://www.w3.org/2000/svg", "line"); + for (const [key, value] of Object.entries({ + x1: String(x1), + x2: String(x2), + y1: String(y1), + y2: String(y2), + ...options.attributes, + })) { + element.setAttribute(key, value); + } + Object.assign(element.style, options.styles); + if (options.id) element.id = options.id; + if (options.classes.length) element.classList.add(...options.classes.filter(Boolean)); + element.append(...options.children.filter(Boolean)); + return element; + } + /** * Create an SVG element * @param {SvgOptions} [options=new SvgOptions()] -- cgit v1.2.3-70-g09d2