SVG image is cut off when exporting diagram as SVG

Hi,

I have a diagram with a node containing an SVG icon. The diagram is displayed correctly.
However, when I export the diagram as an SVG, the icon is cut off at the borders.

Do you know why this gets cut off? Is there some configuration missing?

We’ll look into this.

By the way, that SVG is poorly implemented – it embeds a raster image.

Thank you for the hint, wasn’t aware of this. Seems like we’re using an embedded png to create the shadow effect, while there are probably better ways to achieve this.

And it’s about 200KB! Exactly what you don’t want to use when you want to get what looks like a relatively simple image of a truck.

The problem appears to be related to how the SVG’s viewport and width and height do not match in aspect ratio. After decoding the base64 and removing all of the HUGE <image> elements, here is the SVG:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     viewBox="0 0 203.04 148.32" width="72" height="72">
  <defs><style>.cls-1{isolation:isolate;}.cls-2{opacity:0.75;mix-blend-mode:multiply;}.cls-3{fill:#fff;}.cls-4,.cls-6{fill:none;stroke:#1d1d1b;}.cls-4{stroke-width:5px;}.cls-5{fill:#1d1d1b;}.cls-6{stroke-width:0.75px;}</style></defs><title>Transport_extern_SimPlan_Icon_S</title><g class="cls-1"><g id="Ebene_2" data-name="Ebene 2"><g id="Ebene_1-2" data-name="Ebene 1">
  <rect class="cls-3" x="10.52" y="10.72" width="117.84" height="71.29"/><rect class="cls-4" x="10.52" y="10.72" width="117.84" height="71.29"/>
  <path class="cls-5" d="M180.6,87.62v19.6H173l-.13-.76a18.45,18.45,0,0,0-36.34,0l-.13.76H82.21c0-.25-.08-.5-.13-.76a18.44,18.44,0,0,0-36.33,0l-.13.76H20.75V87.62Z"/><path class="cls-6" d="M180.6,87.62v19.6H173l-.13-.76a18.45,18.45,0,0,0-36.34,0l-.13.76H82.21c0-.25-.08-.5-.13-.76a18.44,18.44,0,0,0-36.33,0l-.13.76H20.75V87.62Z"/>
  <path class="cls-5" d="M163.57,31.55H134.15V87.62h43.59V66Zm4.09,40.77H142V39.73h17.28l8.35,21.88Z"/><path class="cls-6" d="M163.57,31.55H134.15V87.62h43.59V66Zm4.09,40.77H142V39.73h17.28l8.35,21.88Z"/>
  <path class="cls-3" d="M78.15,109.65a14.17,14.17,0,0,1-28.33,0,12.13,12.13,0,0,1,.25-2.53,14.12,14.12,0,0,1,27.82,0A12.12,12.12,0,0,1,78.15,109.65Z"/><path class="cls-4" d="M78.15,109.65a14.17,14.17,0,0,1-28.33,0,12.13,12.13,0,0,1,.25-2.53,14.12,14.12,0,0,1,27.82,0A12.12,12.12,0,0,1,78.15,109.65Z"/>
  <path class="cls-3" d="M169,109.65a14.17,14.17,0,0,1-28.33,0,12.84,12.84,0,0,1,.25-2.53,14.13,14.13,0,0,1,27.83,0A12.13,12.13,0,0,1,169,109.65Z"/><path class="cls-4" d="M169,109.65a14.17,14.17,0,0,1-28.33,0,12.84,12.84,0,0,1,.25-2.53,14.13,14.13,0,0,1,27.83,0A12.13,12.13,0,0,1,169,109.65Z"/>
  <polygon class="cls-3" points="142.03 39.73 159.31 39.73 167.66 61.61 167.66 72.32 142.03 72.32 142.03 39.73"/></g></g></g>
</svg>

Note that the width and height are 72, whereas the viewBox has 203.04 and 148.32.
Change the width and height to match the viewBox (at least in aspect ratio, if not exactly the same numbers), and the rendering will be fine.

So that is a work-around for now.

Hello @walter,
it seems to be a mistake in our SVGs that the width and height are different from the viewport dimensions. There is no requirement for them to be different.
I thought it is an issue with the export as it looked fine in the diagram, but setting the width and height to the same as the viewBox solves the issue!

Thanks for your support!

We just found out that the bug is only in Firefox and the old version of Edge. It’s not a problem in Chrome or Edgium.

While I can probably work with the workaround, this is strange. I can confirm it works with Chrome, but it doesn’t seem to work with the latest Electron (8.2.5), which uses a quite recent version of Chromium.
Here is the Electron fiddle: https://gist.github.com/6d2288821de8acceffd120a09f138365

The next release will have a bug fix for this. I’m not sure when it will come out, since we’re trying to fix an unrelated bug as well.

I have no idea about Electron.

1 Like

@walter Should the above codepen (https://codepen.io/dominic-simplan/pen/JjYpewO) work with 2.1.16? Seems like in Firefox and Electron the Icon still get’s cut off, or am I missing something?

Odd, I cannot explain that. Here is the test code that I used:

<!DOCTYPE html>
<html>
<head>
<script src="https://gojs.net/latest/release/go-debug.js"></script>
<script>
  function init() {
    var $ = go.GraphObject.make;
    myDiagram = $(go.Diagram, "myDiagramDiv");

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        $(go.Shape, "RoundedRectangle", { strokeWidth: 0 },
          new go.Binding("fill", "color")),
        $(go.Picture, "svgimgBug.svg")
      );

    myDiagram.model = new go.GraphLinksModel(
      [
        { color: "lightblue" }
      ]);
  }

  function makeSvg() {
    var svg = myDiagram.makeSvg({ scale: 1, background: "white" });
    document.body.appendChild(svg);
  }
</script>
</head>
<body onload="init()">
<div id="sample">
  <div id="myDiagramDiv" style="border: solid 1px black; width:400px; height:400px"></div>
  <button onclick="makeSvg()">Make SVG</button>

  <img src="svgimgBug.svg">
</div>
</body>
</html>

where svgimgBug.svg is:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     viewBox="0 0 203.04 148.32" width="72" height="72">
  <defs><style>.cls-1{isolation:isolate;}.cls-2{opacity:0.75;mix-blend-mode:multiply;}.cls-3{fill:#fff;}.cls-4,.cls-6{fill:none;stroke:#1d1d1b;}.cls-4{stroke-width:5px;}.cls-5{fill:#1d1d1b;}.cls-6{stroke-width:0.75px;}</style></defs><title>Transport_extern_SimPlan_Icon_S</title><g class="cls-1"><g id="Ebene_2" data-name="Ebene 2"><g id="Ebene_1-2" data-name="Ebene 1">
  <rect class="cls-3" x="10.52" y="10.72" width="117.84" height="71.29"/><rect class="cls-4" x="10.52" y="10.72" width="117.84" height="71.29"/>
  <path class="cls-5" d="M180.6,87.62v19.6H173l-.13-.76a18.45,18.45,0,0,0-36.34,0l-.13.76H82.21c0-.25-.08-.5-.13-.76a18.44,18.44,0,0,0-36.33,0l-.13.76H20.75V87.62Z"/><path class="cls-6" d="M180.6,87.62v19.6H173l-.13-.76a18.45,18.45,0,0,0-36.34,0l-.13.76H82.21c0-.25-.08-.5-.13-.76a18.44,18.44,0,0,0-36.33,0l-.13.76H20.75V87.62Z"/>
  <path class="cls-5" d="M163.57,31.55H134.15V87.62h43.59V66Zm4.09,40.77H142V39.73h17.28l8.35,21.88Z"/><path class="cls-6" d="M163.57,31.55H134.15V87.62h43.59V66Zm4.09,40.77H142V39.73h17.28l8.35,21.88Z"/>
  <path class="cls-3" d="M78.15,109.65a14.17,14.17,0,0,1-28.33,0,12.13,12.13,0,0,1,.25-2.53,14.12,14.12,0,0,1,27.82,0A12.12,12.12,0,0,1,78.15,109.65Z"/><path class="cls-4" d="M78.15,109.65a14.17,14.17,0,0,1-28.33,0,12.13,12.13,0,0,1,.25-2.53,14.12,14.12,0,0,1,27.82,0A12.12,12.12,0,0,1,78.15,109.65Z"/>
  <path class="cls-3" d="M169,109.65a14.17,14.17,0,0,1-28.33,0,12.84,12.84,0,0,1,.25-2.53,14.13,14.13,0,0,1,27.83,0A12.13,12.13,0,0,1,169,109.65Z"/><path class="cls-4" d="M169,109.65a14.17,14.17,0,0,1-28.33,0,12.84,12.84,0,0,1,.25-2.53,14.13,14.13,0,0,1,27.83,0A12.13,12.13,0,0,1,169,109.65Z"/>
  <polygon class="cls-3" points="142.03 39.73 159.31 39.73 167.66 61.61 167.66 72.32 142.03 72.32 142.03 39.73"/></g></g></g>
</svg>

Clicking the “Make SVG” button produced the wrong SVG image before on Firefox, but it works now with GoJS 2.1.16.

Hi @walter, this is your code on codepen: https://codepen.io/dominic-simplan/pen/NWGBdQB. Still the same for me. Maybe some caching issue?!

Only thing I changed is that I’ve inlined the svg.

No, it seems to be using GoJS v2.1.16. We’ll investigate.

But the sample I just gave you works for you by itself in Firefox, doesn’t it?

Interesting, the code you provided works locally with the separate svg file, but with the inlined svg the edges are cut off…

We’ll keep investigating and see what we can do.

When we makeSVG we set the attribute preserveAspectRatio on some images so that they look identical to makeImage, but this presents a problem with images that have SVG sources, since SVG has its own aspect ratio rules. My solution was naive, to simply look at the image source and if it was an SVG file (containing ".svg" in the href) we could decline to set an aspect ratio. This won’t work in your case, since you are using a base64 uri instead of referring to an image.

I could change the code to also detect something like "image/svg+xml" in the href string, and might do that, but that also might be too simplistic to capture all cases. I will consider other possibilities.

In the meantime, if you know what each of your Pictures is doing, you can easily remove the preserveAspectRatio attribute when you make the SVG. So this is an acceptable workaround:

function makeSvg() {
  var svg = myDiagram.makeSvg({
    scale: 1,
    background: "white",
    elementFinished: function(graphObject, SVGElement) {
      if (graphObject instanceof go.Picture) {
        // If you know its an SVG:
        SVGElement.removeAttribute("preserveAspectRatio");
      }
    }
  });
  document.body.appendChild(svg);
}

Of course you may only want to do it on your Pictures that are using SVG.

Thank you for the workaround, this worked nicely!