SVG is not displayed correctly when adding it to pdfmake pdf

34 views Asked by At

I have a react project with pdfmake added by yarn, a component draws a chart (svg) using d3, I use an id to get the svg. This is how I get the svg and add it to an empty document:

const svgElement = document.getElementById('svgConcrete');
const svgString = svgElement.outerHTML;

const docDefinition = {
  content: [           
    {
      columns: [
        { width: '*', text: '' },
        {
          svg: svgString,
          width: 175,
          height: 175
        },
        { width: '*', text: '' },
      ]
    }
  ],
}

The image that should be displayed is this:

enter image description here

The image that i get is: enter image description here

The svg from the HTML is:

<svg id="svgConcrete" width="400" height="300" viewBox="-80 -10 400 300" style="overflow: visible; margin-bottom: 40px;"><g fill="none" font-size="10" font-family="sans-serif" text-anchor="middle" transform="translate(0,240)"><path class="domain" stroke="currentColor" d="M0,0H310"></path><g class="tick" opacity="1" transform="translate(0,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">0.0</text></g><g class="tick" opacity="1" transform="translate(38.75,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">0.5</text></g><g class="tick" opacity="1" transform="translate(77.5,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">1.0</text></g><g class="tick" opacity="1" transform="translate(116.25,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">1.5</text></g><g class="tick" opacity="1" transform="translate(155,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">2.0</text></g><g class="tick" opacity="1" transform="translate(193.75,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">2.5</text></g><g class="tick" opacity="1" transform="translate(232.5,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">3.0</text></g><g class="tick" opacity="1" transform="translate(271.25,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">3.5</text></g><g class="tick" opacity="1" transform="translate(310,0)"><line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">4.0</text></g></g><g fill="none" font-size="10" font-family="sans-serif" text-anchor="end"><path class="domain" stroke="currentColor" d="M0,240V0"></path><g class="tick" opacity="1" transform="translate(0,240)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">0</text></g><g class="tick" opacity="1" transform="translate(0,205.71428571428572)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">5</text></g><g class="tick" opacity="1" transform="translate(0,171.42857142857144)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">10</text></g><g class="tick" opacity="1" transform="translate(0,137.14285714285714)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">15</text></g><g class="tick" opacity="1" transform="translate(0,102.85714285714286)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">20</text></g><g class="tick" opacity="1" transform="translate(0,68.57142857142857)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">25</text></g><g class="tick" opacity="1" transform="translate(0,34.2857142857143)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">30</text></g><g class="tick" opacity="1" transform="translate(0,0)"><line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">35</text></g></g><g fill="none" font-size="10" font-family="sans-serif" text-anchor="middle" transform="translate(0,240)" stroke-width="0.1"><path class="domain" stroke="currentColor" d="M0,0H310"></path><g class="tick" opacity="1" transform="translate(0,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(38.75,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(77.5,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(116.25,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(155,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(193.75,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(232.5,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(271.25,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g><g class="tick" opacity="1" transform="translate(310,0)"><line stroke="currentColor" y2="-240"></line><text fill="currentColor" y="3" dy="0.71em"></text></g></g><g fill="none" font-size="10" font-family="sans-serif" text-anchor="end" stroke-width="0.1"><path class="domain" stroke="currentColor" d="M0,240V0"></path><g class="tick" opacity="1" transform="translate(0,240)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g><g class="tick" opacity="1" transform="translate(0,205.71428571428572)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g><g class="tick" opacity="1" transform="translate(0,171.42857142857144)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g><g class="tick" opacity="1" transform="translate(0,137.14285714285714)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g><g class="tick" opacity="1" transform="translate(0,102.85714285714286)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g><g class="tick" opacity="1" transform="translate(0,68.57142857142857)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g><g class="tick" opacity="1" transform="translate(0,34.2857142857143)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g><g class="tick" opacity="1" transform="translate(0,0)"><line stroke="currentColor" x2="310"></line><text fill="currentColor" x="-3" dy="0.32em"></text></g></g><text x="155" y="280" font-size="12" text-anchor="middle" fill="gray">ε [×10⁻³]</text><text x="-75" y="120" font-size="12" fill="gray">σ [MPa]</text><path d="M0,240L13.563,220.875L27.125,203.5L40.688,187.875L54.25,174L67.813,161.875L81.375,151.5L94.937,142.875L108.5,136L122.063,130.875L135.625,127.5L149.188,125.875L162.75,125.714L176.312,125.714L189.875,125.714L203.437,125.714L217,125.714L230.562,125.714L244.125,125.714L257.687,125.714L271.25,125.714" fill="none" stroke="green" stroke-width="2"></path><path d="M0,240L13.563,211.313L27.125,185.25L40.688,161.813L54.25,141L67.813,122.813L81.375,107.25L94.937,94.313L108.5,84L122.063,76.313L135.625,71.25L149.188,68.813L162.75,68.571L176.312,68.571L189.875,68.571L203.437,68.571L217,68.571L230.562,68.571L244.125,68.571L257.687,68.571L271.25,68.571" fill="none" stroke="blue" stroke-width="2"></path><path d="M0,240L13.563,211.313L27.125,185.25L40.688,161.813L54.25,141L67.813,122.813L81.375,107.25L94.937,94.313L108.5,84L122.063,76.313L135.625,71.25L149.188,68.813L162.75,68.571L176.312,68.571L189.875,68.571L203.437,68.571L217,68.571L230.562,68.571L244.125,68.571L257.687,68.571L271.25,68.571" fill="none" stroke="red" stroke-width="2" style="stroke-dasharray: 3, 3;"></path><rect x="12" y="10" width="137" height="56" fill="#fff" stroke="#333" stroke-width="0.5"></rect><rect x="12" y="10" width="137" height="56" fill="#fff" stroke="#333" stroke-width="0.5"></rect><rect x="12" y="10" width="137" height="56" fill="#fff" stroke="#333" stroke-width="0.5"></rect><rect width="12" height="2" transform="translate(20, 20)" style="fill: green;"></rect><rect width="12" height="2" transform="translate(20, 36)" style="fill: blue;"></rect><rect width="12" height="2" transform="translate(20, 52)" style="fill: red;"></rect><text x="37" y="26" font-size="12" fill="gray">ULS</text><text x="37" y="42" font-size="12" fill="gray">Accidental damage</text><text x="37" y="58" font-size="12" fill="gray">Fire (t=0)</text></svg>

Why does this happen? How con I fix it?

EDIT: by adding this lines in the html

xmlns="http://www.w3.org/2000/svg"
version='1.1'
xmlnsXlink='http://www.w3.org/1999/xlink'

and converting the svg to png (and then base64) using this function:

async function getBase64Image() {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const svgElement = document.getElementById('svgConcrete');
    const imageBlobURL = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgElement.outerHTML);
    console.log("url: " + imageBlobURL)
    img.onload = () => {
      var canvas = document.createElement('canvas');
      canvas.width = img.width;
      canvas.height = img.height;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0);
      const dataURL = canvas.toDataURL('image/png');
      resolve(dataURL);
    };
    img.onerror = (error) => {
      reject(error)
    };
    img.src = imageBlobURL;
  });
}

the result I get is:

enter image description here

1

There are 1 answers

0
Crocio On

I did not found a way to solve this. But I got around it by using "canvg" library. By appending the svg to a canvas I was then able to convert that png to a base64 string.