Public
Edited
Dec 11, 2023
Importers
Insert cell
Insert cell
svg = htl.svg`<svg style="background: #eeccee;" fill="none" stroke="black">
<polyline points="100,100 150,25 150,75 200,0" />
<polygon points="270,50 240,70 270,30" />
<line x1="140" y1="100" x2="270" y2="140" />
<rect x="20" y="50" width="200" height="20" />
<circle cx="80" cy="70" r="100" />
</svg>`
Insert cell
Insert cell
normalized = normalize(svg)
Insert cell
Insert cell
normalized.outerHTML.replaceAll("<path", "\n <path").replace("</svg>", "\n</svg>")
Insert cell
Insert cell
normalize = svg => {
const node = svg.cloneNode(); // shallow, just to get top-level attributes

for (const polyline of svg.querySelectorAll("polyline")) {
// really similar; just put an M in front of the points
node.appendChild(htl.svg`<path d="M ${polyline.getAttribute("points")}" />`);
}

for (const polygon of svg.querySelectorAll("polygon")) {
// just put an M before and a Z after!
node.appendChild(htl.svg`<path d="M ${polygon.getAttribute("points")} Z" />`);
}

for (const line of svg.querySelectorAll("line")) {
// just bundle up x1,y1 and x2,y2 into an array! the d attribute doesn’t really care about comma between coordinates
const points = ["x1", "y1", "x2", "y2"].map(attr => line.getAttribute(attr));
node.appendChild(htl.svg`<path d="M ${points}" />`);
}

for (const rect of svg.querySelectorAll("rect")) {
// over, down, across, down, back across, up
const [x, y, width, height] = ["x", "y", "width", "height"].map(attr => rect.getAttribute(attr));
node.appendChild(htl.svg`<path d="M ${x} ${y} h ${width} v ${height} h ${-width} z" />`);
}

for (const circle of svg.querySelectorAll("circle")) {
// tricky because drawing an arc from a point to itself collapses to nothing; we draw half a circle across and half a circle back
const [cx, cy, r] = ["cx", "cy", "r"].map(attr => circle.getAttribute(attr));
const x1 = cx - r, y1 = cy;
node.appendChild(htl.svg`<path d="M ${x1} ${y1} a ${r} ${r} 0 1 1 ${2 * r} 0 ${r} ${r} 0 1 1 ${-2 * r} 0 Z" />`);
}

for (const path of svg.querySelectorAll("path")) {
// almost forgot to pass these through too. note im stripping out all other attributes and styles bc that's my use case rn
node.appendChild(htl.svg`<path d="${path.getAttribute("d")}" />`)
}
return node;
}
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more