But it only worked if the cell was manually run after the notebook had loaded.
Any help welcome or thought on doing this a better way.
Would have also liked to add an ID to the SVG but I don;t see a way to do the using the FileAttachment.
A nasty way to resize them is by doing this:
The cell with the div containing the svg images is called fakeVis and so I have another cell that replaces the innerHTML with a copy that has had a string replace all the text of the svg width and heights.
The await waits for, and returns the value of, the last Promise in the chain. If we change your code a bit, it should become clearer where the problems originate:
const mySvgPromise = FileAttachment('composition-15.svg').text()
// The next promise in the chain receives the value returned by the
// previous promise. In this case, the text content of the file.
.then(text => {
// What are you selecting? How would your svg magically appear?
d3.select('#pic0 > svg').attr("width", 400).attr("height", 300);
// You're not returning anything. The final value of
// mySvgPromise ends up being undefined.
return;
});
return html`<div id="pic0"> ${await mySvgPromise}</div>`;
You’re already using d3, so adding the ID is just another call to .attr():
myCell = FileAttachment('composition-15.svg').text()
.then(text => d3.select(html`${text}`)
.attr("id", "pic0")
.attr("width", 400)
.attr("height", 300)
// Return the <svg> DOM element.
.node()
)
Attention: If your SVG file starts with a comment (as is the case for files created with Inkscape), then html`${text}` will return a <span> element. In this case use the following code:
.children[0] gives us the actual <svg> element, while .remove() detaches it from its parent <span> element. The latter is important, because otherwise Observable will display the element as myCell = ▸ SVGSVGElement {}.
Note that you can also render the SVG as an image, either directly:
pic = {
let div = d3
.create('div')
.html(await FileAttachment("temp.svg").text())
.style('height', '100px');
div
.select('svg')
.attr('width', w)
.attr('height', 100);
return div.node();
}
Note that the width is set by the variable w; here it is in action with w specified by a slider:
Two comments:
d3.selections of dom elements by ID or class are generally discouraged in Observable. The preferred technique (as used here) is to select from within a named d3 object. See, for example, this notebook by Tom Macwright.
As much as I like the template literals, I tend to create objects and manipulate theme directly. This leads to more portable code