Created
November 9, 2022 07:05
-
-
Save LTLA/946cc6d9de7a4608746db0ae5d0a5849 to your computer and use it in GitHub Desktop.
Manual scatterplot to SVG
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function range(x) { | |
let maxed = Number.NEGATIVE_INFINITY; | |
let mined = Number.POSITIVE_INFINITY; | |
for(const y of x) { | |
if (y > maxed) { | |
maxed = y; | |
} | |
if (y < mined) { | |
mined = y; | |
} | |
} | |
return [ mined, maxed ]; | |
} | |
function points(x, y, { col=null, xbound = [0, 100], ybound = [0, 100], radius = 1 } = {}) { | |
let xrange = range(x); | |
let xscale = (xbound[1] - xbound[0]) / (xrange[1] - xrange[0]); | |
let xshift = xbound[0] - xrange[0] * xscale; | |
let yrange = range(y); | |
let yscale = (ybound[1] - ybound[0]) / (yrange[1] - yrange[0]); | |
let yshift = ybound[0] - yrange[0] * yscale; | |
let elements = []; | |
for (var i = 0; i < x.length; i++) { | |
let color = col == null ? "#000000" : col[i]; | |
elements.push(`<circle cx="${x[i] * xscale + xshift}" cy="${y[i] * yscale + yshift}" r="${radius}" style="fill:${color}" />`); | |
} | |
return elements; | |
} | |
function legendCategorical(text, col, { xleft = 0, ybound = [0, 100] } = {}) { | |
let nlevels = text.length; | |
let height = ybound[1] - ybound[0]; | |
let linewidth = height / nlevels; | |
if (linewidth > 5) { | |
linewidth = 5; | |
} | |
let elements = []; | |
let linestart = height/2 + linewidth*nlevels/2; | |
for (var i = 0; i < text.length; i++) { | |
let ypos = linestart - i * linewidth; | |
elements.push(`<circle cx="${xleft}" cy="${ypos}" r="${linewidth/3}" style="fill:${col[i]}" />`); | |
elements.push(`<text x="${xleft + linewidth / 1.5}" y="${ypos}" dominant-baseline="middle" font-family="Arial, Helvetica, sans-serif" font-size="${linewidth}">${text[i]}</text>`); | |
} | |
return elements; | |
} | |
// Making shit up: | |
var colors = ['#ff0000', '#00ff00', '#0000ff']; | |
let text = [ "Aaron", "Jaya", "Ram" ]; | |
let x = []; | |
let y = []; | |
let cols = []; | |
for (var i = 0; i < 100; i++) { | |
x.push(Math.random()); | |
y.push(Math.random()); | |
cols.push(colors[Math.floor(Math.random() * 3)]) | |
} | |
// We'll be creating a 100x100 plot with a width-20 legend on the right. | |
let point_svg = points(x, y, { col: cols, xbound: [ 5, 95 ], ybound: [5, 95] }); | |
let legend_svg = legendCategorical(text, colors, { xleft: 105, ybound: [5, 95] }) | |
let output = `<svg | |
viewBox="0 0 120 100" | |
xmlns="http://www.w3.org/2000/svg"> | |
${point_svg.join("\n")} | |
<rect x="0" y="0" width="100" height="100" stroke="grey" stroke-width="0.1" fill="none" /> | |
${legend_svg.join("\n")} | |
</svg>` | |
console.log(output); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment