Blurry Svgs when small

Hello,

In my application, it is possible to add SVGs to the canvas. They can be resized. Oddly, when I make those SVGs very small, this happens:
image

Notice that the circle around the rectangle has this strange cuts in it.
I experimented with diagram.scale and this is what I found out:
The SVG always has the size 26.

It looks fine with diagram.scale>=1.72:
image

It starts to get those cuts when diagram .scale <=1.71:
image
In the image above you can see that those cuts in the outer circle start to appear in the bottom left and top left “corners” of the circle.

If you zoom out even more, this happens: (diagram.scale==1):
image

I checked by changing the zoom by 0.01 with keys:
image

And I can for sure say that it will always have those cuts when the scale is smaller than 1.72 (only for this element which has a size of 26 units)

For elements with size 100, it starts to get those cuts after diagram.scale<=0.44:
image

But here, it behaves differently. It might be difficult to see, but the left and right corners of the triangle have some kind of edge which should not be there. For this scenario, it also will always have some kind of cuts after scale=0.45.

I read this topic:Blurriness in all browsers
But I am pretty sure this is some SVG-specific behaviour.

Here is the SVG: https://svgur.com/s/GfK

I had to manually edit the SVG, because as you state here:https://gojs.net/latest/intro/pictures.html
The SVG has to have “width” and “height” attributes defined, otherwise it will not display properly. Maybe it has to do with this?

Best regards
Martin

I’m not seeing a problem.

<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="https://unpkg.com/gojs"></script>
<script id="code">
  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
          { "undoManager.isEnabled": true });

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        { resizable: true, resizeObjectName: "PIC" },
        $(go.Picture, 'https://svgshare.com/i/GfK.svg',
          { name: "PIC", width: 180, height: 180 })
      );

    myDiagram.model = new go.GraphLinksModel(
    [
      { key: 1 },
      { key: 2 }
    ],
    [
      { from: 1, to: 2 }
    ]);
  }
</script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
</body>
</html>

After resizing the second node:
image

Hmm thats interesting, so that basically means something in my diagram is not working properly. However, I really do not know where to look. This is a bug that exists for a long time already which I never was able to solve.

What I found out: If I set the browser to any scaling other than 100%, (for example 90% or 110%) it looks perfectly fine. I also found out that it looks good in Firefox, but not in Edge or Chrome. Do you have any other ideas what i could try?

That’s also odd, because I normally use Firefox, yet I explicitly tested it on Chrome too because I didn’t know what you were using. I did not see a problem in Chrome either. I don’t remember if I tried Edge.

I really cannot understand why it shows some different behaviour in my diagram.

Another thing i found out: if i resize the browser to 90% or 110% and reset it to 100%, it is not blurry anymore:
When starting (with 100%):
image
After resizing to 110% and immediatly resizing to 100%:
image

This icon here is an SVG too, so this bug applies to all SVGs in Chrome/Edge

So my solution would be to programmatically trigger a rerender event (or whatever is happening when resizing) in order to get rid of this bug. Is there some function in goJS allowing to rerender everything? “rebuildParts()” did not work

What version of GoJS are you using? What is the value of https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio ?
Are you using Firefox and Chrome and Edge with a screen that would cause the devicePixelRatio to be something other than 1?
Can you reproduce the problem on other devices: laptops, tablets, smartphones?

I am using GoJS v2.0.2 .
My devicePixelRatio is 1, it is the same for every browser(did not check on phone though)
I tested with:
Chrome,Firefox,Edge on my PC
Chrome,Edge on notebook,
Chrome,default browser on Android
it is always blurry, except for Firefox

I do not know about the behaviour on tablets as I do not own a tablet

Part of the problem is that:

The SVG always has the size 26.

The SVG’s native width and height are 180, and it is almost always best, for cross-browser behavior to work consistently, that the go.Picture using this SVG have the exact same size of the .svg object.

On the SVG, can you put data bindings for width, height, and scale on the go.Picture, and then try:

  { key: "Alpha", width: 26, height: 26, scale: 1 },
  { key: "Beta",  width: 180, height: 180, scale: 0.1444 }

So that they are both sized the same, on-screen. Is there any difference in the visual between the two?

Sorry, I wrote that in a weird way: what I meant is that the SVG in my example which i posted was always size 26.

So what you are saying is: I got an svg with size 180x180, the go.picture also needs size 180x180 and I should only change scale? I am using:
image
on the go.Picture, so I do not really know how to change it in a way so it behaves the same.

I tried changing width, height and scale as you asked but there was no visual difference.

What I did not notice before:
As you might have seen (because I gave you access to the our testin system) There are two different canvas: view mode and edit mode. The blurrieness only happens when using edit mode. I would like to compare those two diagrams with each other to see any differences. Which parameters do you think could affect this?

Antialiasing should be happening all the time, but the results might look different depending on the relative positions of the drawn lines and the pixels.

Can you look at the values of Diagram.position and Diagram.scale in both modes? If they are both exactly the same and yet render differently, that would be interesting.

I looked at scale and position
I saw that scale is 1 for both diagrams
i saw that position has many floating points in the edit canvas, thats why i tested if the image looks better if i force an integer position, but the image remains in bad quality.
like I said, zooming the browser in and out solves the issue.
And I found out something else: after zooming in and out (browser, not diagram) the image looks good. If I pan the diagram, however, it looks bad again. Very odd

I’m not sure, but it’s possible that the diagram doesn’t bother redrawing if the change in the Diagram.position is too small, as might be the case in your experiments if you set the Diagram.position to rounded off values of x or y.

It would be really weird if Diagram.computePixelRatio() was a different value for each, but you could look.

Diagram.computePixelRatio() is the same for both diagram. Its value is 2.

If you use a PNG of that SVG, at say 100x100 resolution, since you tend to draw it much smaller, does that have the same problem? If that fixes it, is it worth switching to a PNG for you?

I’m not sure what else to try, or where exactly this blur is coming from.

I tried using a PNG, but the problem still persists. However, zooming in and out now does not make the picture smooth.

This problem still persists and i really need to fix it. I think the hint about browser resizing helps a lot. I would like to know how the re-render in goJS works because it might solve the problem if I call such a function myself after drawing the canvas

You can explicitly force the Diagram to redraw by calling myDiagram.redraw(). It will do so immediately, whether it needs to or not. This is sometimes useful for fixing drawing bugs, but its still very unclear why this is happening.

Another thing you could try. After setting up your Diagram, call:

myDiagram.setRenderingHint('temporaryPixelRatio', false);

And see if that has any effect. You could also try setting:

myDiagram.setRenderingHint('viewportOptimizations', false);

And see if that makes a difference, also. These are internal flags that GoJS uses to optimize drawing, and turning them off is just a guess at what might be the issue here. It’s still not clear.

Sadly, setting those properties and triggering redraw does not solve the problem :(

I found out another thing: when loading the diagram, i am calling “zoomToRect”. i removed this function for testing. This made the svgs look good. However, after scrolling down (inside the diagram) the pictures got blurry. Scrolling the modal itself does not make the svgs blurry.

I wrote this earlier at some point:

What I did not notice before:
As you might have seen (because I gave you access to the our testin system) There are two different canvas: view mode and edit mode. The blurrieness only happens when using edit mode. I would like to compare those two diagrams with each other to see any differences. Which parameters do you think could affect this?

But I noticed that this is not the case, but was more like a strange coincidence. It does not happen all the time that the svgs get blurry.

I solved the problem!

You suggested the following:

If you use a PNG of that SVG, at say 100x100 resolution, since you tend to draw it much smaller, does that have the same problem? If that fixes it, is it worth switching to a PNG for you?

This did not help, however, I tried to take this approach further and created an SVG with width and height=16. It seems very odd, but this solved the problem. I suspected that those SVG will look ugly again if I make them very big now, but the actually look good, no matter how big I set them.

Conclusion: Using SVGs with high “width” and “height” values and scaling them down very much makes them look very ugly (not in firefox though). Maybe this information proves usefull to you and further development