Simple SVG DOM manipulation

Can anyone explain whether the following code (as the sole content in a cell) should work, and if so, why it doesn’t?

{
  const svg = DOM.svg(128, 128);
  const circle = DOM.element("circle", { r: 120 });
  svg.appendChild(circle);
  console.log(svg);
  return svg;
}

I’m assuming that I’m just missing something very simple here. If I put the svg from the console log into a cell (with an html context) it displays correctly as one quadrant of a black circle, i.e.

html<svg viewBox="0,0,128,128" width="128" height="128"><circle r="120"></circle></svg>

Does the code I posted not return a DOM element? The svg element itself does seem to appear as the content of the cell, but it just displays a white rectangle (i.e. no black circle). The bounding box, however, is highlighted in Chrome when I mouse over the svg tag in the console log.

Thanks,
Emery

You need to use svg:circle so that DOM.element will use createElementNS with the appropriate namespace. See https://github.com/observablehq/stdlib/blob/master/README.md#DOM_element

{
  const pic = DOM.svg(128, 128);
  const circle = DOM.element("svg:circle", { r: 120 });
  pic.appendChild(circle);
  return pic;
}

This is also equivalent to:

{
  const pic = DOM.svg(128, 128);
  const circle = svg`<circle r=120>`;
  pic.appendChild(circle);
  return pic;
}

Or using a tagged template literal for the whole thing:

svg`<svg width=128 height=128 viewBox="0,0,128,128"><circle r=120>`
3 Likes

For more info about namespaces you can see this rather thorough MDN page.

Perfect. That was it. Thanks!