Home > other >  How to render an svg element
How to render an svg element

Time:12-26

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}/>
  );
}
  • Related