I am trying to render an svg image in typescript. I got this element from https://observablehq.com/@erikbrinkman/d3-dag-sugiyama website. I rewrote this so that it runs in react. I can render the element, when I serialise it using:
var s = new XMLSerializer();
var str = s.serializeToString(this.Image);
console.log("image text", str)
then I can render the resulting image if I paste the html back into javascript (and I can see the image), so the svg is correct.
My App.tsx looks like this:
// this function is copied modified a bit from the website
export const DrawGraph = ()=>{
const nodeRadius = 20;
...
.attr("alignmentBaseline", "middle")
.attr("fill", "white");
return svgNode;
}
export default class App extends React.Component {
Image = DrawGraph()
render(){
// I serialized and console.logged here
return (
<object data={this.Image} type="image/svg xml"/>
)
}
}
And my index.tsx is:
import App from './App';
const doc = document.getElementById('root')
const root = client.createRoot(doc!);
root.render(
<App/>
);
The Image element looks like this when console.logged:
<svg width="360" height="180">
assignedSlot: null
attributes: NamedNodeMap [ width="360", height="180" ]
autofocus: false
baseURI: "http://localhost:3000/"
childElementCount: 3
....
transform: SVGAnimatedTransformList { baseVal: SVGTransformList, animVal: SVGTransformList }
viewBox: SVGAnimatedRect { baseVal: null, animVal: null }
viewportElement: <svg xmlns="http://www.w3.org/2000/svg">
width: SVGAnimatedLength { baseVal: SVGLength, animVal: SVGLength }
x: SVGAnimatedLength { baseVal: SVGLength, animVal: SVGLength }
y: SVGAnimatedLength { baseVal: SVGLength, animVal: SVGLength }
zoomAndPan: 2
<prototype>: SVGSVGElementPrototype { suspendRedraw: suspendRedraw(), unsuspendRedraw: unsuspendRedraw(), unsuspendRedrawAll: unsuspendRedrawAll(), … }
I tried to rewrite the content of App to return the the raw string of the svg copied from console, in which case I saw the image. However I could not reproduce this programmatically, i.e. trying to render the variable, or the raw string of the variable did not work.
Currently the image does not render, and I get no compile/runtime errors.
I have not been able to figure out what to write into the app.tsx or index.tsx that would make the image render. I have also not found any links which when copied would make the image render.
P.S. I also looked at: How to render a code-generated SVG in Reactjs?
CodePudding user response:
I was able to solve this with the help of these two answers:
Render SVGSVGElement in React JS without dangerouslySetInnerHtml
Property 'click' does not exist on type 'never'. TS2339
So the code that displays the image is:
export const App2 =() =>{
const svg = React.useRef<HTMLDivElement>(null);
React.useEffect(()=>{
if (svg.current){
svg.current.appendChild(DrawGraph())
}
}, []);
return (
<div ref={svg}/>
);
}