From 22b02db4d4c57234faee35090dc2a8215ecaf4ac Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Mon, 6 Jan 2025 10:24:05 +1100 Subject: [PATCH] Refactored the dots and radius functions into a DotMaker class --- src/components/dots.js | 70 +++++++++++++++++++++++++++------- src/index.md | 85 +++++++++--------------------------------- 2 files changed, 73 insertions(+), 82 deletions(-) diff --git a/src/components/dots.js b/src/components/dots.js index 9f0bbed..4a64985 100644 --- a/src/components/dots.js +++ b/src/components/dots.js @@ -1,22 +1,64 @@ // calculate tiles -export function make_dots(m, n, cell, max) { - if( m - n === 0 ) { - return []; +const RADIUS_OPTS = [ + "const", + "right", + "left", + "up", + "down", + // "RU", + // "RD", + // "LU", + // "LD", + // "circle" +]; + + + +class DotMaker { + constructor(width) { + this.width = width; } - const ps = []; - const imin = -max; - const imax = max / m; - for( let i = imin; i <= imax; i++ ) { - const jmin = m * i + (m - n) * max; - const jmax = m * i; - for( let j = jmin; j <= jmax; j++ ) { - const x = (j - m * i) / (m - n); - const y = m * (x + i); - ps.push({i:i, j:j, x:x, y:y}); + + dots(m, n) { + if( m - n === 0 ) { + return []; } + const ps = []; + const imin = -this.width; + const imax = this.width / m; + for( let i = imin; i <= imax; i++ ) { + const jmin = m * i + (m - n) * this.width; + const jmax = m * i; + for( let j = jmin; j <= jmax; j++ ) { + const x = (j - m * i) / (m - n); + const y = m * (x + i); + if( x > 0 && y > 0 && x < this.width && y < this.width ) { + ps.push({i:i, j:j, x:x, y:y}); + } + } + } + return ps; + } + + radius(d, func, maxr) { + switch (func) { + case "const": + return maxr; + case "right": + return maxr * d.x / this.width; + case "left": + return maxr * (this.width - d.x) / this.width; + case "down": + return maxr * d.y / this.width; + case "up": + return maxr * (this.width - d.y) / this.width; + default: + return maxr; + } } - return ps; } +export { RADIUS_OPTS, DotMaker }; + diff --git a/src/index.md b/src/index.md index 9592c3d..f652102 100644 --- a/src/index.md +++ b/src/index.md @@ -10,18 +10,22 @@ toc: false ```js -import {make_dots, dot_func} from './components/dots.js' +import {RADIUS_OPTS, DotMaker} from './components/dots.js' const CELL = 10; +const MAG = 2; const WIDTH = 20; -const HEIGHT = 20; +const HEIGHT = WIDTH; + +const dm = new DotMaker(WIDTH); + const bg = view(Inputs.color({label: "background", value: d3.color("yellow").formatHex()})) const fg1 = view(Inputs.color({label: "fg1", value: d3.color("red").formatHex()})) const m1 = view(Inputs.range([1, 5], {value: 2, step: 1, label:"m1"})); const n1 = view(Inputs.range([1, 5], {value: 2, step: 1, label:"n1"})); const r1 = view(Inputs.range([0, 0.5], {value: 0.3, step: 0.01, label: "radius"})); -const f1 = view(Inputs.radio(["constant", "right", "left", "up", "down"], {value: "constant"})); +const f1 = view(Inputs.radio(RADIUS_OPTS, {value: RADIUS_OPTS[0]})); const v2 = view(Inputs.toggle({label: "Second grid", value:true})); @@ -38,7 +42,7 @@ const fg2 = view(Inputs.color({ const m2 = view(Inputs.range([1, 5], {value: 1, step: 1, label:"m2", disabled: !v2})); const n2 = view(Inputs.range([1, 5], {value: 3, step: 1, label:"n2", disabled: !v2})); const r2 = view(Inputs.range([0, 0.5], {value: 0.2, step: 0.01, label: "radius"})); -const f2 = view(Inputs.radio(["constant", "right", "left", "up", "down"], {value: "constant"})); +const f2 = view(Inputs.radio(RADIUS_OPTS, {value: RADIUS_OPTS[0]})); ``` @@ -49,25 +53,9 @@ const f2 = view(Inputs.radio(["constant", "right", "left", "up", "down"], {value ```js -const dots1 = make_dots(1 / m1, n1, CELL, WIDTH) -const dots2 = v2 ? make_dots(1 / m2, n2, CELL, WIDTH) : [] +const dots1 = dm.dots(1 / m1, n1) +const dots2 = v2 ? dm.dots(1 / m2, n2) : [] -function radius_func(d, func, maxr) { - switch (func) { - case "constant": - return maxr; - case "right": - return maxr * d.x / WIDTH; - case "left": - return maxr * (WIDTH - d.x) / WIDTH; - case "up": - return maxr * d.y / WIDTH; - case "down": - return maxr * (WIDTH - d.y) / WIDTH; - default: - return maxr; - } -} ``` @@ -75,16 +63,15 @@ function radius_func(d, func, maxr) { const svg = d3.create("svg") - .attr("width", WIDTH * CELL * 2) - .attr("height", HEIGHT * CELL * 2) - .attr("viewBox", [ 0, 0, WIDTH, HEIGHT ]) - .attr("style", "max-width: 100%; height: auto;"); + .attr("width", WIDTH * CELL * MAG) + .attr("height", HEIGHT * CELL * MAG) + .attr("viewBox", [ 0, 0, WIDTH, HEIGHT ]); const background = svg.append("rect") .attr("x", 0) .attr("y", 0) - .attr("width", WIDTH * 20) - .attr("height", WIDTH * 20) + .attr("width", WIDTH) + .attr("height", WIDTH) .attr("fill", bg); const dots_g1 = svg.append("g") @@ -93,7 +80,7 @@ const dots_g1 = svg.append("g") dots_g1.selectAll("circle") .data(dots1) .join("circle") - .attr("r", (d) => radius_func(d, f1, r1)) + .attr("r", (d) => dm.radius(d, f1, r1)) .attr("fill", fg1) .attr("cx", (d) => d.x) .attr("cy", (d) => d.y); @@ -104,7 +91,7 @@ const dots_g2 = svg.append("g") dots_g2.selectAll("circle") .data(dots2) .join("circle") - .attr("r", (d) => radius_func(d, f2, r2)) + .attr("r", (d) => dm.radius(d, f2, r2)) .attr("fill", fg2) .attr("cx", (d) => d.x) .attr("cy", (d) => d.y); @@ -121,43 +108,5 @@ display(svg.node());