'Add image to react d3 tree renderCustomNodeElement attribute
I wish to add some images to my JSON data from it the tree data is taking all the data..
I just couldnt do it
Do someone has had any experience in that area..?
const renderRectSvgNode = ({ nodeDatum, toggleNode }) => (
<g>
<circle cx="0" cy="10" r="10" fill="blue" onClick={toggleNode} />
<text fill="blue" strokeWidth="1" x="20">
{nodeDatum.name}
</text>
{nodeDatum.attributes?.department && (
<text fill="green" x="20" dy="20" strokeWidth="1">
Department: {nodeDatum.attributes?.department}
</text>
)}
</g>
);
export default function App() {
const [translate, containerRef] = useCenteredTree();
return (
<div style={containerStyles} ref={containerRef} >
<Tree
data={orgChartJson}
translate={translate}
renderCustomNodeElement={renderRectSvgNode}
orientation="vertical"
/>
</div>
);
}
export const useCenteredTree = (defaultTranslate = { x: 0, y: 0 }) => {
const [translate, setTranslate] = useState(defaultTranslate);
const containerRef = useCallback((containerElem) => {
if (containerElem !== null) {
const { width, height } = containerElem.getBoundingClientRect();
setTranslate({ x: width / 2, y: height / 2 });
}
}, []);
return [translate, containerRef];
};
Solution 1:[1]
I assume you've figured out a solution since your question was six months ago, but for posterity:
You'd want to create a < foreignObject x="20" y="20" width="160" height="160"> tag (you can set your own x, y, width, and height, of course) and place the img tag in there.
You can store your image in the src directory, import it into the file where the renderRectSvgNode component is, and refer to it by imported name in your image tag (import MyImage from "../assets/images/MyImage.jpg") if you have trouble rendering it from your public directory:
const renderRectSvgNode = ({ nodeDatum, toggleNode,
foreignObjectProps = {} }) => (
<React.Fragment>
<foreignObject {...foreignObjectProps}>
<img src={MyImage} height="200" width="200"/>
</foreignObject>
<g>
<circle cx="0" cy="10" r="10" fill="blue" onClick={toggleNode} />
<text fill="blue" strokeWidth="1" x="20">
{nodeDatum.name}
</text>
{nodeDatum.attributes?.department && (
<text fill="green" x="20" dy="20" strokeWidth="1">
Department: {nodeDatum.attributes?.department}
</text>)}
</g>
</React.Fragment>
);
Notice the foreignObjectProps prop that is brought in and also passed to . Essentially, it just needs a width and a height or else it won't be viewable (i.e., < foreignObject width=100 height=100>).
You may want to check out react-d3-dag library as well, it's a friendlier version built on top of react-d3-tree. I just came across it and will be using for representing a dag with less startup work involved. MixedNodeElement is a great example of the above.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |