3d-force-graph
3d-force-graph copied to clipboard
SVG and Text In Nodes
Is your feature request related to a problem? Please describe. Hi, i'd really love to ability to easily add svg and text inside of node spheres. I don't know webGL or threejs but was wondering if this functionality was available or could be added by a function accessor
Describe the solution you'd like For Text in nodes
.nodeTextContent(node => node.textContent)
This would render text inside of a node sphere
For SVG in nodes
.nodeSvgIcon(node => node.icon)
this would render an icon in the node sphere
Using both would look like
- Graph renders svg icon and then text
Graph
.nodeSvgIcon(node => node.icon)
.nodeTextContent(node => node.textContent)
- Graph render text then svg icon
Graph
.nodeTextContent(node => node.textContent)
.nodeSvgIcon(node => node.icon)
Describe alternatives you've considered I've tried to manually use three-spritetext but the sphere would hide text if it wasn't set to transparent no matter what the opacity and the text wouldn't fit in the sphere
Text fitting in the sphere would be difficult, as the text size would have to get small enough to fit or the sphere would need to grow, and the amount of text could also vary. Text under or over the node would be best practice. This would also fix the problem with spheres needing to be transparent.
If you want to use icons, it is best to not even use the spheres any longer. He has an example of images used for nodes here: https://vasturiano.github.io/3d-force-graph/example/img-nodes/ Code: https://github.com/vasturiano/3d-force-graph/blob/master/example/img-nodes/index.html
In my use case the text and image would become misaligned when moving the camera, so I just created a canvas, added whatever I wanted to make the node look how I wanted, then turned it into a sprite.
const generateNodeThreeObject = node => {
canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
// add image, text etc
const texture = new THREE.Texture(context.canvas);
texture.needsUpdate = true;
const material = new THREE.SpriteMaterial({ map: texture });
const sprite = new THREE.Sprite(material);
sprite.scale.set(32, 32, 1);
return sprite;
}
// include this method in forceGraph3D call
graph
.graphData(data)
...
.nodeThreeObject(generateNodeThreeObject)
...
If you are reloading your graph a lot you may want to create a canvas cache to use inside of that function to save memory.
Is there any solution to this?