yWorks / svg2pdf.js

A javascript-only SVG to PDF conversion utility that runs in the browser. Brought to you by yWorks - the diagramming experts
MIT License
654 stars 101 forks source link

svg-diagram does not render on pdf #87

Closed Fadiabb closed 5 years ago

Fadiabb commented 5 years ago

Hallo,

We want to export svg-diagram to pdf, using svg2pdf() with the svg element does not generate a pdf and this causes the browser to stop working (chromium Version 72.0.3626.109, OS: Linux version 4.19.0-4-amd64 , SMP Debian 4.19.28-2 ) Tested with svg2pdf v.1.3.4 and jspdf v.2.0.2

testing with Mozila Firefox 60.5.1esr (64-bit): comes with message : a web page is slowing your browser, what would you like to do (stop, wait)

To Reproduce here is a simple html page with svg-diagram element : https://gist.github.com/Fadiabb/093859a7fdc1e2565ca60db2455885c5

Expected behavior Get the pdf with the svg element (diagram in this case)

Fadiabb commented 5 years ago

Another behavior with another svg-diagram gives the following error:

Uncaught TypeError: Cannot read property 'length' of undefined
    at new i (svg2pdf.min.js:30)
    at e.exports (svg2pdf.min.js:30)
    at new s (svg2pdf.min.js:30)
    at s (svg2pdf.min.js:30)
    at st (svg2pdf.min.js:37)
    at svg2pdf.min.js:37
    at Ot (svg2pdf.min.js:37)
    at svg2pdf.min.js:37
    at ct (svg2pdf.min.js:37)
    at Ct (svg2pdf.min.js:37)

To Reproduce use this simple html file svg_2_pdf_example2 : https://gist.github.com/Fadiabb/18681afcf88c9df0cb48a7625156cd36

HackbrettXXX commented 5 years ago

The issue is a bug where svg2pdf does not support "," in transform attributes. The second is an issue with path elements without d attribute.

Thanks for the reports.

bernhardreiter commented 5 years ago

The second example produces a (partially correct) PDF with the following elements removed:

--- svg_2_pdf_example2-ber1.html        2019-06-05 14:35:57.057549875 +0200
+++ svg_2_pdf_example2-ber3.html        2019-06-05 14:53:13.319171624 +0200
@@ -122 +121,0 @@
-            <path class="prediction-area" fill="steelblue" fill-opacity="0.2" clip-path="url(#waterlevel-clip)"/>
@@ -214 +212,0 @@
-            <path class="prediction-area" fill="steelblue" fill-opacity="0.2" clip-path="url(#waterlevel-clip)"/>

found out by using the following debugging patch:

--- svg2pdf.orig.js     2019-06-05 15:19:17.813442970 +0200
+++ svg2pdf.js  2019-06-05 14:48:24.487972345 +0200
@@ -3134,7 +3134,11 @@

   // draws a path
   var path = function (node, tfMatrix, refsHandler, withinClipPath, attributeState) {
-    var list = getPathSegList(node);
+    try {
+      var list = getPathSegList(node);
+    } catch (e) {
+      console.log('getPathsegList() failed on node:', node);
+    }
     var markerEnd = getAttribute(node, "marker-end"),
         markerStart = getAttribute(node, "marker-start"),
         markerMid = getAttribute(node, "marker-mid");

The result has a black area in the lower part of the diagram, this can be improved further by removing:

--- svg_2_pdf_example2-ber3.html        2019-06-05 14:53:13.319171624 +0200
+++ svg_2_pdf_example2-ber5.html        2019-06-05 15:22:18.229873853 +0200
@@ -309,6 +308,0 @@
-            <g class="brush" fill="none" pointer-events="all" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
-                <rect class="overlay" pointer-events="all" cursor="crosshair" x="0" y="0" width="1247" height="55"/>
-                <rect class="selection" cursor="move" fill="#777" fill-opacity="0.2" stroke="none" shape-rendering="crispEdges" x="1049.328961872208" y="0" width="1.248543208639603" height="55" style=""/>
-                <rect class="handle handle--e" cursor="ew-resize" x="1048.5775050808477" y="-2" width="4" height="59" style="" stroke="rgba(23, 162, 184, 0.5)" fill="rgba(23, 162, 184, 0.5)"/>
-                <rect class="handle handle--w" cursor="ew-resize" x="1047.328961872208" y="-2" width="4" height="59" style="" stroke="rgba(23, 162, 184, 0.5)" fill="rgba(23, 162, 184, 0.5)"/>
-            </g>

it is the following line that still missrenders:

<path class="domain" stroke="black" d="M0.5,6V0.5H1247.5V6"/>
HackbrettXXX commented 5 years ago

The black areas are due to a bug where the fill="none" is not inherited from the surrounding group.

Fadiabb commented 5 years ago

transform="translate(0, 136), rotate(-90)" leads to same problem. removing the , between translate and rotate solves this problem.

HackbrettXXX commented 5 years ago

Is this still an issue or did the commit fix it? Note that you will have to build the files in the dist folder yourself.

mktcode commented 5 years ago

Note that you will have to build the files in the dist folder yourself.

Why? The files are part of the repo...

yGuy commented 5 years ago

Note that you will have to build the files in the dist folder yourself.

Why? The files are part of the repo...

Because it has not yet been released and the repo only contains the previous release.

bernhardreiter commented 5 years ago

@HackbrettXXX thanks for the fast response and the code improvement. This is very helpful!

Note that while attempting to test, we've noticed that the current build instructions do not seem to be current (#91).

Fadiabb commented 5 years ago

Tested after building the files in dist, it works now , thanks for the improvements. Noticed: with the first example : lines from x-axis appears on the generated pdf which are not visible in the diagram in the html page. svg2pdf-line-issue

Is that not fixed with the last improvments : #87: fix inheritance of fill/stroke attributes (e.g. when ="none")`

yGuy commented 5 years ago

Just an idea: This could be due to PDF interpreting zero-height rectangles differently than the browser.

HackbrettXXX commented 5 years ago

I agree with @yGuy. Can't quickly find this in the PDF spec, but as far as I know PDF renders everything that has zero width/height as one device pixel thick.