Forum How do I...?

Sizing SVG

jhoweaa
I'm using Highcharts to generate some SVG charts for a report I'm producing. This report is produced in both HTML and PDF formats. I've got a Highchart definition which is the proper size for my HTML (in this case it is 300 x 180) but if I use the same SVG in the PDF produced by Prince, the chart is displayed as an image not much larger than very tiny character (think 6pt font). I figured when i was generating the chart that I would have to use different sizing options for the PDF vs the HTML, I'm just not sure how best to compute the values (other than by trial and error)

This is the first time I've tried including SVG into my Prince document so any guidance people can offer would be most appreciated.

Thanks!

Jim
mikeday
Can you paste the initial <svg> tag, showing the width/height/viewBox attributes?
jhoweaa
Here is the top part of the SVG which gets generated by Highcharts:

<svg 
		xmlns="http://www.w3.org/2000/svg" 
		style="font-family: &quot;Lucida Grande&quot;, &quot;Lucida Sans Unicode&quot;, Arial, Helvetica, sans-serif; font-size: 9px;" 
		width="300" 
		height="190" 
		version="1.1">
	<desc>Created with Highcharts 4.0.1</desc>
	<defs>
		<clipPath id="highcharts-1">
			<rect x="0" y="0" width="248" height="103" />
		</clipPath>
	</defs>


Also, if you want to see the full SVG, you can see it at http://jsfiddle.net/jhoweaa/9VfbP/

When we generate the report, we make a call out to a server based Highcharts and we get back SVG which we then embed in the HTML before invoking Prince to process the content. The chart displays at the proper size in the HTML, but is microscopic in the PDF.

When you generate a chart with Highcharts, you can specify the width/height of the chart in pixels. The 300 x 190 works for HTML display, but I experimented with much larger sizes to see how it would look in the PDF. While it did get larger, it was still very tiny.

Thanks.

Jim
mikeday
If I extract the SVG and convert it to PDF with Prince, it appears about the same size as in the browser. (See attached files below). How are you including the SVG in your document?
  1. chart.pdf31.2 kB
  2. chart.svg13.3 kB
jhoweaa
The chart in question is displayed inside of a three cell table, something along the lines of:

<table style="width: 100%">
   <tbody>
      <tr>
         <td style="width: 33%; height: 45mm">first cell</td>
         <td style="width: 33%; height: 45mm; text-align: center; vertical-align: top>
            <div style="width: 100%; height: 40mm">
                ... svg content ...
            </div>
         </td>
         ... 


When the HTML is displayed, the chart looks fine, it's in the proper place and the size is right. In the PDF it is nearly invisible.

Some of the Prince page options are:

@page {
   prince-background-image-resolution: auto;
   size: US-Letter;
   margin: 1.2in .3in 1in .3in;
}


I should also mention that this is using Prince 8.1.

Since you are able to get the chart to display at a proper resolution, I'm sure that there is something about my configuration/CSS/layout which is messing things up. I just need help figuring out what that is. :-)

Thanks!

Jim
jhoweaa
I was just looking at the messages that I get from Prince when it tries to generate the report. I'm seeing a bunch of errors like this:

msg|err|-:2192|Tag svg invalid
msg|err|-:2192|Tag desc invalid
msg|err|-:2192|Tag defs invalid
msg|err|-:2192|Tag clippath invalid
msg|err|-:2192|Tag rect invalid
msg|err|-:2192|Tag rect invalid
msg|err|-:2192|Tag g invalid
msg|err|-:2192|Tag g invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag g invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag g invalid
msg|err|-:2192|Tag g invalid
msg|err|-:2192|Tag g invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag g invalid
msg|err|-:2192|Tag path invalid
msg|err|-:2192|Tag path invalid
...


The line in question is the <svg> tag from this bit of html (which I shortened for this message):

[code]
<div class="chart">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" style="font-family:Calibri, Helvetica, Arial, sans-serif;font-size:11px;" xmlns="http://www.w3.org/2000/svg" width="300" height="180"><desc>Created with Highcharts 4.0.1</desc><defs><clipPath id="highcharts-1"><rect x="0" y="0" width="253" height="104"></rect></clipPath></defs><rect x="0" y="0" width="300" height="180" strokeWidth="0" fill="#FFFFFF" class=" highcharts-background"></rect><g class="highcharts-grid" zIndex="1"></g><g class="highcharts-grid" zIndex="1"><path fill="none" d="M 37 39.5 L 290 39.5" stroke="#C0C0C0" stroke-width="1" zIndex="1" opacity="1"></path><path fill="none" d="M 37 61.5 L 290 61.5" stroke="#C0C0C0" stroke-width="1" zIndex="1" opacity="1"></path><path fill="none" d="M 37 82.5 L 290 82.5" stroke="#C0C0C0" stroke-width="1" zIndex="1" opacity="1"></path><path fill="none" d="M 37 102.5 L 290 102.5" stroke="#C0C0C0" stroke-width="1" zIndex="1" opacity="1"></path><path fill="none" d="M 37 123.5 L 290 123.5" stroke="#C0C0C0" stroke-width="1" zIndex="1" opacity="1"></path><path fill="none" d="M 37 144.5 L 290 144.5" stroke="#C0C0C0" stroke-width="1" zIndex="1" opacity="1"></path></g><g class="highcharts-axis" zIndex="2"><path fill="none" d="M 108.5 144 L 108.5 154" stroke="#C0D0E0" stroke-width="1" opacity="1"></path><path fill="none" d="M 144.5 144 L 144.5 154" stroke="#C0D0E0" stroke-width="1" opacity="1"></path><path fill="none" d="M 181.5 144 L 181.5 154" stroke="#C0D0E0" stroke-width="1" opacity="1"></path><path fill="none" d="M 217.5 144 L 217.5 154" stroke="#C0D0E0" stroke-width="1" opacity="1"></path><path fill="none" d="M 253.5 144 L 253.5 154" stroke="#C0D0E0" stroke-width="1" opacity="1"></path><path fill="none" d="M 290.5 144 L 290.5 154" stroke="#C0D0E0" stroke-width="1" opacity="1"></path><path fill="none" d="M 72.5 144 L 72.5 154" stroke="#C0D0E0" stroke-width="1" opacity="1"></path><path fill="none" d="M 36.5 144 L 36.5 154" stroke="#C0D0E0" stroke-width="1" opacity="undefined"></path><path fill="none" d="M 37 144.5 L 290 144.5" stroke="#C0D0E0" stroke-width="1" zIndex="7" visibility="visible"></path></g><g class="highcharts-axis" zIndex="2"></g><g class="highcharts-series-group" zIndex="3"> ...
</div>

The entire SVG for one chart is contained in one line of the file.

Don't know if this tells you any more.

Jim
facboy
on a somewhat related note, if you only specify the viewBox size, Prince seems assumes that the SVG element is square rather than having the same aspect ratio as the viewBox. This can make scaling to the svg's container difficult.
jhoweaa
It appears this has to do with a difference between Prince 8.1 and 9.0 rev 5. We are currently using Prince 8.1 for our reports and this morning I downloaded Prince 9 to try it out. Turns out that if I generate the report using Prince 9 I do not get the errors that I listed above, and more importantly, the SVG graphic is the correct size. Looks like we need to upgrade to Prince 9.
mikeday
Right, we fixed a bunch of issues with SVG, and our new HTML5 parser supports SVG inside HTML much better now.
facboy
re the problem with the viewBox with no width/height, i was using prince 9.0.4.
mikeday
Sorry, I missed that comment in this busy thread. We will investigate the viewBox issue.
facboy
hi mike, any update on the viewBox scaling?
mikeday
If an <svg> element is missing width/height attributes, it is equivalent to having width="100%" and height="100%". Unfortunately, web browsers interpret this inconsistently when the SVG is nested within another fixed width element:
<html>
<body>
<div style="width: 3in; border: solid blue thin">
<svg viewBox="0 0 200 400" style="border: solid red thin">
<rect x="0" y="0" width="200" height="400" fill="lightgray" stroke="none"/>
<rect x="0" y="0" width="50" height="50" fill="black" stroke="none"/>
<rect x="150" y="0" width="50" height="50" fill="black" stroke="none"/>
<rect x="0" y="350" width="50" height="50" fill="black" stroke="none"/>
<rect x="150" y="350" width="50" height="50" fill="black" stroke="none"/>
</svg>
</div>
</body>
</html>

For this test document, Firefox scales the SVG to 3x6" as specified by its viewbox, but Chrome scales it to 3" wide x 100% of the viewport tall, as specified by its (implied) width/height attributes. As far as I can tell, Chrome is correct according to the SVG specification in this case.

To keep things interesting, Prince scales the SVG to 3x3", as it resolves width and height percentages relative to the width of the containing block, not the page. :)

facboy
hum...the difference in this example is that both Firefox and Chrome scale the green div height to 100% of the blue div, whereas Prince does not.

<html>
<body>
<div style="width: 6in; height: 6in; border: solid blue thin;">
<div style="width: 3in; border: solid green thin; float: left; box-sizing: border-box; -moz-box-sizing: border-box;">
<svg style="border: solid red thin" viewBox="0 0 200 400" preserveAspectRatio="xMidYMin meet">
<rect fill="lightgray" height="400" stroke="none" width="200" x="0" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="0" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="150" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="0" y="350"/>
<rect fill="black" height="50" stroke="none" width="50" x="150" y="350"/>
</svg>
</div>
<div style="width: 3in; border: solid green thin; float: right; box-sizing: border-box; -moz-box-sizing: border-box;">
<svg style="border: solid red thin" viewBox="0 0 400 200" preserveAspectRatio="xMidYMin meet">
<rect fill="lightgray" height="200" stroke="none" width="400" x="0" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="0" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="350" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="0" y="150"/>
<rect fill="black" height="50" stroke="none" width="50" x="350" y="150"/>
</svg>
</div>
</div>
</body>
</html>
facboy
hmm...actually with the following example (which probably approximates what I'm trying to do a bit better, I think I want the Firefox behaviour where I can alter the aspect ratio of the SVG to alter its height, ie i always get 100% width and the 'height' of the SVG element changes as I change the aspect ratio:

<html>
<body>
<div style="width: 6in; border: solid blue thin;">
<div style="width: 3in; border: solid green thin; float: left; box-sizing: border-box; -moz-box-sizing: border-box;">
<svg style="border: solid red thin" viewBox="0 0 200 400" preserveAspectRatio="xMidYMin meet">
<rect fill="lightgray" height="400" stroke="none" width="200" x="0" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="0" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="150" y="0"/>
<rect fill="black" height="50" stroke="none" width="50" x="0" y="350"/>
<rect fill="black" height="50" stroke="none" width="50" x="150" y="350"/>
</svg>
</div>
<div style="width: 3in; border: solid green thin; float: left; box-sizing: border-box; -moz-box-sizing: border-box;">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
</ul>
</div>
<div style="clear: both;"></div>
</div>
</body>
</html>