Loading the images as files directly into the notebook and trying to cross-reference it using the key data in each of the data objects, but this doesnât work either
How should it work? What is the easiest way to externally host images I want to use in force graphs? Can someone advise please?
Thanks
Youâre nesting the images inside the circles, which is invalid and causes them to not get rendered. Instead youâll want to create a group for each circle and image.
For a large number of files, I would consider zipping the directory. When you extract on the Observable side, you can set up a Map object to retrieve by filename. Something like so:
images = {
let zipped_images = await FileAttachment("icons.zip").zip();
let filenames = zipped_images.filenames.filter((s) => s.slice(-4) == ".svg");
let images = await Promise.all(
filenames.map((f) => zipped_images.file(f).image())
);
return new Map(d3.zip(filenames, images));
}
There are variations though and I did it a bit differently in the notebook linked below.
To address @mootariâs point, you might build your nodes as a group with a circle and nested SVG like so:
I have struck problems trying to implement your code.
the fundamental problem is that i am not too good on JS, and hence have cobbled together slabs of code copied from other code bases. Whereas i look at your code, and it is really nicely organised, but mine is a serious Frankenstein.
There is a lot of very subtle things going on in your code, and i fear i have not been able to copy it that well.
The aim of the prefix variable is to be able to swap between round, rectangular and normal icons with the same name (but different prefixes). In a future version i will setup a radio button for that functionality.
But why is it all going wrong with the loading of the images? Apparently i have the same as you, but it does not work.
Also how do i get rid of the circle and just have the icon? Your clarity over how d3operates is really great, please help
Iâm glad you found the code informative. Iâve only got a few minutes but here are some thoughts on your questions.
If you use your browserâs inspector, you should notice that youâve actually got a bunch of images; they just happen to all be placed at the exact same spot. The reason is that youâre adding each as a group containing a circle and then an SVG. Conceptually, each image looks like so:
Note that the circle has no cx or cy attribute specified; thus, they default to zero,zero or the upper left corner of the figure. The placement is specified by the group transform. Youâre attempting to place the figures using cx and cy in your ticked function, though. I guess thatâs a result of attempting to merge the two code blocks.
That part is easy using the code I provided:
In the data join, simply remove the portion that generates the circle, i.e. the commented portion below:
You might also experiment with opacity. If you take another look at the example I embedded earlier, youâll notice that the circles are there but are somewhat transparent.