1

I am trying to create proper PDF of my HTML page. I have managed to make everything be included in PDF except SVG. I tried figuring out what the problem was so tried this and it worked fine:

<svg id="testSVG" width="100" height="100" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
  Sorry, your browser does not support inline SVG.
</svg>

However, if I do something like that:

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
  <use xlink:href="#testSVG" width="100" height="100"/>
</svg>

it does not anymore. It does show on browser and on media="print" so I doubt it could be syntax. Does anyone know if SVG <use> element is actually supported by xeponline.jqPlugin.js (or css2pdf)?

Be Brave Be Like Ukraine
  • 7,596
  • 3
  • 42
  • 66
M. Paulikas
  • 840
  • 10
  • 14
  • Where in your second example does the id named #testSVG live? In another ... SVG in the page? In something else in the world? – Kevin Brown Mar 08 '17 at 05:46
  • Just cause ... if you think it should work as some browsers do allow that it is in a different SVG on the same page ... then all dynamically generated SVGs that try to use something by ID will break because many others on the same page will have the same ID ... and they might be different ... wouldn't they? – Kevin Brown Mar 08 '17 at 05:50
  • The SVG "use" element takes something inside the SVG are reuses it. It does not take something else from somewhere else and reuse it. By the standard: "The element takes nodes from within the SVG document, and duplicates them somewhere else. " Because some browser allows you to share it is their issue. And it is wrong and would create issue with other things (and does). I have had to fix a few software installations the make use of "use" for dynamic charts in a page and when one chart is drawn screws up the other chart, – Kevin Brown Mar 08 '17 at 05:57
  • Right so the full thing is - I have a massive code and the webpage consists of two parts : 1 for print and pdf only 2 for browser. Please have a look here http://stackoverflow.com/questions/42460809/img-src-svg-in-the-same-document/42464525#42464525 . The accepted answer worked fine with chrome, firefox, edge and @media="print" (tested with all browsers too, even preview shows it correctly). However, when I try to use this library it does not show the svg unless I am not using the "use" element as the library tries not to convert svg to raster image. – M. Paulikas Mar 08 '17 at 09:12
  • What I really want is the most basic way possible to get the same results as with @media="print" just given into pdf. I am fully aware I can just use that and then select "print to pdf" instead of printer, but most of my customers do not so I want both buttons - 1 for printing another for saving as pdf. – M. Paulikas Mar 08 '17 at 09:16
  • Also talking about this https://github.com/Xportability/css-to-pdf/issues/11 , I am also facing the issue of "If @media='print' is pointing to external style sheet, the default style is not being overridden with it, but if it is internally set in the header of the web page - it works." – M. Paulikas Mar 08 '17 at 10:16

1 Answers1

1

The Cloudformatter plugin is scraping the DOM and assembling it into structured content to send to the server. It does a few manipulations, mostly to make sure that the content is structured as XML.

I think you are asking why in that structure, you have an SVG somewhere with an ID of #whatever, it is not used inside another SVG in that structure who "uses" that structure named #whatever.

The answer is, it doesn't because it shouldn't. SVG use is for reusing content inside an SVG in multiple locations inside that SVG. You are trying to reuse an SVG from the DOM into another location inside an SVG inside that DOM.

If that works for browsers, well good for them. But that is not what the standard is. SVG use in the standard is clear that it is for reuse of content within that same SVG.

Personally I am lost as to why it works in the first place. Like you have five dynamic charts on the same page and that code creates #gradient1, #gradient2 in each chart and they are all different. Which #gradient1 should my chart use? The one inside? Or the one in the other chart? Or the first chart?

Take a simple case where I have 2 charts on the same page. They are dynamically created from Javascript so they internally do things that alone, inside itself, understand the nature and structure of the SVG itself. They can create a set of IDs internally that apply internally, but of course they have no idea of what exists on the page.

Chart 1 has this inside:

<rect id=”rect1” x="0" y="0" width="720" height="400" strokewidth="0" fill="#FFFFFF" class=" highcharts-background"/>

Chart 2 has this inside:

<rect id=”rect1” x="0" y="0" width="220" height="200" strokewidth="0" fill="#FFFFFF" class=" highcharts-background"/>

Now, internally that id “rect1” is referenced inside the first SVG and it is also in the second SVG. But note that they are different sizes. Now, this works because they are internal to each SVG and they are different. Ask yourself this:

Why does chart 1 not reference the second one when it is drawn?

Why does chart 2 not reference the first one when it is drawn?

Now as you have done, you create a third SVG and use “rect1” in it – which "rect1" will it use? Afterall, there are now two of them.

You certainly could attempt to modify the Javascript to try and resolve use like this BUT it would be a totally one off solution for the reasons above. In the third example – you would not know which one to copy into your SVG.

Kevin Brown
  • 8,805
  • 2
  • 20
  • 38
  • The standard clearly says that **can** point to external content. It does not have to be in the same SVG at all. Here's an example from the official w3c SVG testsuite: https://www.w3.org/Graphics/SVG/Test/20110816/harness/htmlObjectApproved/struct-use-05-b.html – Robert Longson Mar 16 '17 at 19:37
  • You are correct but that is not a bookmark link. That is ../images/svgRef1.svg#rect2, an explicit link to an external asset. Using just #rect2 and being in the same page is not definite because there could be 20 #rect2's in the same page and which one is picked? – Kevin Brown Mar 16 '17 at 20:02
  • It's invalid to have duplicate ids in the same page. – Robert Longson Mar 16 '17 at 20:03
  • So how does one stop that when they use say a JS charting application generating two different charts .... which uses #gradient1, #gradient2 ... when one SVG does not know of the other? – Kevin Brown Mar 16 '17 at 20:10
  • Embed the charts using object or iframe tags so the ids are in separate documents, or use a charting engine that generates unique ids e.g. guids or some kind of timestamp based id. – Robert Longson Mar 16 '17 at 20:13
  • When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element's tree and must contain at least one character. The value must not contain any ASCII whitespace. HTML elements is key --- it mean by the standard -- "The term "HTML elements", when used in this specification, refers to any element in that namespace, even in XML documents". SVG is not in that namespace – Kevin Brown Mar 16 '17 at 21:27
  • Well yes, you're right in the sense that that says nothing about the uniqueness of SVG IDs. That's here http://www.w3.org/TR/SVG/struct.html#IDAttribute and says that they must be unique. It does not mention unique within a namespace, it's unique period. – Robert Longson Mar 16 '17 at 21:49
  • OK, well I have already took the conversation off line with the OP. The simple fact is that our software does not (and will not) support that. We cannot wait in the composition for an SVG on page one that references something on page 10,001 in order to draw and then determine page flow. No more editorializing whether it is right or wrong ... we don;t do it in our software and for good reason. – Kevin Brown Mar 17 '17 at 00:14
  • The way I solved the problem was to use JQuery to change the location and size of my original SVG (the one with all the content in it) in HTML DOM whenever the "Save as PDF" button is pressed and revert all changes straight after the job is done. It happens so fast that user cannot even notice the SVG to even blink. I agree with Robert and it is a shame that Kevins PDF converted does not support the feature, but apart from that it is still one of the best HTML to PDF converters out there. Thank you both very much. :) – M. Paulikas Mar 21 '17 at 16:09