scryber.core icon indicating copy to clipboard operation
scryber.core copied to clipboard

SVG Text is not properly aligned

Open bykka opened this issue 1 year ago • 14 comments

Describe the bug Text on svg charts is not properly aligned(displayed on the wrong possiition)

To Reproduce SVG chart for adding to the document

<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" style="position:absolute;left:0;top:0;user-select:none">
  <rect width="300" height="300" x="0" y="0" id="0" fill="none" fill-opacity="1"/>
  <g>
    <path d="M152.3598 90.0464L152.9497 75.058L167.9497 75.058" fill="none" stroke="#5470c6"/>
    <path d="M153.2294 209.913L154.0368 224.8913L169.0368 224.8913" fill="none" stroke="#91cc75"/>
    <path d="M141.2714 90.6383L105.6399 93.2045L90.6399 93.2045" fill="none" stroke="#fac858"/>
    <path d="M146.8331 90.0836L146.0414 75.1045L131.0414 75.1045" fill="none" stroke="#ee6666"/>
    <path d="M150 90A60 60 0 0 1 154.7159 90.1856L150 150Z" fill="#5470c6" stroke="white" stroke-linejoin="round"/>
    <path d="M154.7159 90.1856A60 60 0 1 1 138.8819 91.0391L150 150Z" fill="#91cc75" stroke="white" stroke-linejoin="round"/>
    <path d="M138.8819 91.0391A60 60 0 0 1 143.675 90.3343L150 150Z" fill="#fac858" stroke="white" stroke-linejoin="round"/>
    <path d="M143.675 90.3343A60 60 0 0 1 150 90L150 150Z" fill="#ee6666" stroke="white" stroke-linejoin="round"/>
    <text dominant-baseline="central" text-anchor="start" style="font-size:8px;font-family:sans-serif;" xml:space="preserve" transform="translate(172.9497 75.058)" fill="black">No Value: 1.25%</text>
    <text dominant-baseline="central" text-anchor="start" style="font-size:8px;font-family:sans-serif;" xml:space="preserve" transform="translate(174.0368 224.8913)" fill="black">Airplane: 95.78%</text>
    <text dominant-baseline="central" text-anchor="end" style="font-size:8px;font-family:sans-serif;" xml:space="preserve" transform="translate(85.6399 93.2045)" fill="black">Car: 1.29%</text>
    <text dominant-baseline="central" text-anchor="end" style="font-size:8px;font-family:sans-serif;" xml:space="preserve" transform="translate(126.0414 75.1045)" fill="black">Train: 1.68%</text>
  </g>
</svg>

Expected behavior image

Screenshots image

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: Firefox

bykka avatar Oct 09 '23 09:10 bykka

Hi Pavlo, thank you for this. Currently Scryber does not support the text-anchor attribute, so the text is rendered from the left position, rather than the right position on the SVG. It's definitely something I can look at this week

richard-scryber avatar Oct 09 '23 10:10 richard-scryber

or maybe you can give a hint in what class to look for fixing

bykka avatar Oct 17 '23 06:10 bykka

After looking at this, the strategy I have in mind for this is as follows. I have added to the project items too so it is not lost.

Add a new StyleKey for a TextAnchor enumeration Add a new Property to SVGText class for the text-anchor style value, storing within the style dictionary.

In the CanvasLayoutEngine after laying out a child, if the instance is SVGText then check the full style for the TextAnchor value.

Position the bounds of the associated relative PDFLayoutBlock, based on its width to the TextAnchor value (start - no action, middle - half width, end - full width)

richard-scryber avatar Oct 17 '23 09:10 richard-scryber

uh, it not that easy

bykka avatar Oct 18 '23 08:10 bykka

I can sort the fix tomorrow Pavlo

richard-scryber avatar Oct 18 '23 20:10 richard-scryber

@bykka - this is now checked in to support the text-anchor attribute.

          <svg width=""500"" height=""400""
                xmlns=""http://www.w3.org/2000/svg"" xmlns:xlink=""http://www.w3.org/1999/xlink"" version=""1.1"" baseProfile=""full""
                style=""position:absolute;left:10;top:10;user-select:none; border: solid 1px navy;"">
                <path d=""M 100 50 L400 50 M 100 80 L 400 80 M 100 110 L 400 110 M 100 140 L 400 140"" fill=""none"" stroke=""#5470c6"" stroke-width=""0.5""></path>
                <path d=""M 250 0 L250 200"" fill=""none"" stroke=""#5470c6"" stroke-width=""0.5""></path>
                <g>
              
                  <text x=""250"" y=""50"" text-anchor=""start"" style=""font-size:12px;font-family:sans-serif;"" fill=""black"">Start</text>
                  <text x=""250"" y=""80"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" fill=""black"">Middle</text>
                  <text x=""250"" y=""110"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" fill=""black"">End</text>
                  <text x=""250"" y=""140"" style=""font-size:12px;font-family:sans-serif;text-anchor:middle"" fill=""black"">CSS Middle</text>
                </g>
            </svg>

Is now rendering correctly for the start, middle and end values.

Screenshot

SVGTextAnchor.pdf

Looks to be working on the samples of the charts I have from you. Let me know and I can push a release.

richard-scryber avatar Oct 19 '23 16:10 richard-scryber

Could you please push your changes into some branch? Then I will check on few new svg charts.

bykka avatar Oct 19 '23 21:10 bykka

Looks better but still there small issue - gap between label and line image

svg for the example

<svg width="951" height="752" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" viewBox="0 0 951 752">
<rect width="951" height="752" x="0" y="0" id="0" fill="none"></rect>
<polyline points="214.9 112.4 227.9 104.9 242.9 104.9" fill="none" stroke="#5470c6"></polyline>
<polyline points="173.3 221.3 177.9 235.6 192.9 235.6" fill="none" stroke="#91cc75"></polyline>
<polyline points="87 190.7 74.4 198.8 59.4 198.8" fill="none" stroke="#fac858"></polyline>
<polyline points="83.8 114.8 70.5 107.8 55.5 107.8" fill="none" stroke="#ee6666"></polyline>
<polyline points="127.9 78.3 123.4 64 108.4 64" fill="none" stroke="#73c0de"></polyline>
<path d="M150 75A75 75 0 0 1 215.0266 187.3702L150 150Z" fill="rgb(84,112,198)"></path>
<path d="M215.0266 187.3702A75 75 0 0 1 119.5358 218.5342L150 150Z" fill="#91cc75"></path>
<path d="M119.5358 218.5342A75 75 0 0 1 75.0011 149.5882L150 150Z" fill="rgb(250,200,88)"></path>
<path d="M75.0011 149.5882A75 75 0 0 1 107.7157 88.0562L150 150Z" fill="#ee6666"></path>
<path d="M107.7157 88.0562A75 75 0 0 1 150 75L150 150Z" fill="#73c0de"></path>
<text dominant-baseline="central" text-anchor="start" style="font-size:12px;font-family:sans-serif;" transform="translate(247.8973 104.9222)" fill="black">Sear...</text>
<text dominant-baseline="central" text-anchor="start" style="font-size:12px;font-family:sans-serif;" transform="translate(197.9226 235.5589)" fill="black">Direct</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(54.4 198.8328)" fill="black">Email</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(50.5333 107.7502)" fill="black">Unio...</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" xml:space="preserve" transform="translate(103.4475 64.006)" fill="black">Video Ads</text>
</svg>

bykka avatar Oct 23 '23 20:10 bykka

After commenting the line 39 in the TSpanLayoutEngine image

I have got the proper result image

bykka avatar Oct 23 '23 20:10 bykka

Interesting - let me take a look at the maths :-D

richard-scryber avatar Oct 24 '23 09:10 richard-scryber

Looks like the text block width is twice wider that text width itself. If to assume that text width is 10 pt then line.Width returns 20pt. That is why we see the blank gap with the same width as the text image

bykka avatar Oct 26 '23 20:10 bykka

I have just checked in for the text-anchor branch updates that I hope work for you. There was a set of code that used the transform style to move elements to the centre of their content for rotation, so ultimately text layout was offset by half.

I have added the dominant-baseline property too, so the labels should be in the centre as well. Let me know :-) SVGTextAnchorChart.pdf

richard-scryber avatar Oct 30 '23 21:10 richard-scryber

Thank you - pie charts looks good now. But there still some issues with line charts. image

  1. lines do not have a small circles
  2. legend icons moved somewhere far to left
  3. x axis label are too close

I tried typical example image

SVG

<svg width="498" height="305" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" viewBox="0 0 498 305">
<rect width="498" height="305" x="0" y="0" id="0" fill="none"></rect>
<path d="M52.9693 276.5L478.08 276.5" fill="none" stroke="#E0E6F1"></path>
<path d="M52.9693 240.5L478.08 240.5" fill="none" stroke="#E0E6F1"></path>
<path d="M52.9693 204.5L478.08 204.5" fill="none" stroke="#E0E6F1"></path>
<path d="M52.9693 168.5L478.08 168.5" fill="none" stroke="#E0E6F1"></path>
<path d="M52.9693 132.5L478.08 132.5" fill="none" stroke="#E0E6F1"></path>
<path d="M52.9693 96.5L478.08 96.5" fill="none" stroke="#E0E6F1"></path>
<path d="M52.9693 60.5L478.08 60.5" fill="none" stroke="#E0E6F1"></path>
<path d="M52.9693 276.5L478.08 276.5" fill="none" stroke="#6E7079" stroke-linecap="round"></path>
<path d="M53.5 275.85L53.5 280.85" fill="none" stroke="#6E7079"></path>
<path d="M124.5 275.85L124.5 280.85" fill="none" stroke="#6E7079"></path>
<path d="M194.5 275.85L194.5 280.85" fill="none" stroke="#6E7079"></path>
<path d="M265.5 275.85L265.5 280.85" fill="none" stroke="#6E7079"></path>
<path d="M336.5 275.85L336.5 280.85" fill="none" stroke="#6E7079"></path>
<path d="M407.5 275.85L407.5 280.85" fill="none" stroke="#6E7079"></path>
<path d="M478.5 275.85L478.5 280.85" fill="none" stroke="#6E7079"></path>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(44.9693 275.85)" fill="#6E7079">0</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(44.9693 239.875)" fill="#6E7079">500</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(44.9693 203.9)" fill="#6E7079">1,000</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(44.9693 167.925)" fill="#6E7079">1,500</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(44.9693 131.95)" fill="#6E7079">2,000</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(44.9693 95.975)" fill="#6E7079">2,500</text>
<text dominant-baseline="central" text-anchor="end" style="font-size:12px;font-family:sans-serif;" transform="translate(44.9693 60)" fill="#6E7079">3,000</text>
<text dominant-baseline="central" text-anchor="middle" style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(52.9693 283.85)" fill="#6E7079">Mon</text>
<text dominant-baseline="central" text-anchor="middle" style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(123.8211 283.85)" fill="#6E7079">Tue</text>
<text dominant-baseline="central" text-anchor="middle" style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(194.6729 283.85)" fill="#6E7079">Wed</text>
<text dominant-baseline="central" text-anchor="middle" style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(265.5246 283.85)" fill="#6E7079">Thu</text>
<text dominant-baseline="central" text-anchor="middle" style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(336.3764 283.85)" fill="#6E7079">Fri</text>
<text dominant-baseline="central" text-anchor="middle" style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(407.2282 283.85)" fill="#6E7079">Sat</text>
<text dominant-baseline="central" text-anchor="middle" style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(478.08 283.85)" fill="#6E7079">Sun</text>
<g clip-path="url(#zr0-c0)">
<path d="M52.9693 267.216L123.8211 266.3526L194.6729 268.583L265.5247 266.2087L336.3764 269.3745L407.2282 259.3015L478.08 260.7405" fill="none" stroke="rgb(84,112,198)" stroke-width="2" stroke-linejoin="bevel"></path>
</g>
<g clip-path="url(#zr0-c1)">
<path d="M52.9693 251.387L123.8211 253.2577L194.6729 254.8406L265.5247 249.3724L336.3764 248.509L407.2282 235.558L478.08 238.436" fill="none" stroke="rgb(145,204,117)" stroke-width="2" stroke-linejoin="bevel"></path>
</g>
<g clip-path="url(#zr0-c2)">
<path d="M52.9693 240.5945L123.8211 236.5653L194.6729 240.3786L265.5247 238.2921L336.3764 234.8385L407.2282 211.8145L478.08 208.9365" fill="none" stroke="rgb(250,200,88)" stroke-width="2" stroke-linejoin="bevel"></path>
</g>
<g clip-path="url(#zr0-c3)">
<path d="M52.9693 217.5705L123.8211 212.6779L194.6729 218.7217L265.5247 214.2608L336.3764 206.778L407.2282 188.071L478.08 185.9125" fill="none" stroke="rgb(238,102,102)" stroke-width="2" stroke-linejoin="bevel"></path>
</g>
<g clip-path="url(#zr0-c4)">
<path d="M52.9693 158.5715L123.8211 145.6205L194.6729 153.8947L265.5247 147.0595L336.3764 113.9625L407.2282 92.3775L478.08 90.9385" fill="none" stroke="rgb(115,192,222)" stroke-width="2" stroke-linejoin="bevel"></path>
</g>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,52.9693,267.216)" fill="#fff" stroke="#5470c6"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,123.8211,266.3526)" fill="#fff" stroke="#5470c6"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,194.6729,268.583)" fill="rgb(255,255,255)" stroke="#5470c6"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,265.5247,266.2087)" fill="#fff" stroke="#5470c6"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,336.3764,269.3745)" fill="#fff" stroke="#5470c6"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,407.2282,259.3015)" fill="#fff" stroke="#5470c6"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,478.08,260.7405)" fill="#fff" stroke="#5470c6"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,52.9693,251.387)" fill="#fff" stroke="#91cc75"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,123.8211,253.2577)" fill="#fff" stroke="#91cc75"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,194.6729,254.8406)" fill="rgb(255,255,255)" stroke="#91cc75"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,265.5247,249.3724)" fill="#fff" stroke="#91cc75"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,336.3764,248.509)" fill="#fff" stroke="#91cc75"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,407.2282,235.558)" fill="#fff" stroke="#91cc75"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,478.08,238.436)" fill="#fff" stroke="#91cc75"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,52.9693,240.5945)" fill="#fff" stroke="#fac858"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,123.8211,236.5653)" fill="#fff" stroke="#fac858"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,194.6729,240.3786)" fill="rgb(255,255,255)" stroke="#fac858"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,265.5247,238.2921)" fill="#fff" stroke="#fac858"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,336.3764,234.8385)" fill="#fff" stroke="#fac858"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,407.2282,211.8145)" fill="#fff" stroke="#fac858"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,478.08,208.9365)" fill="#fff" stroke="#fac858"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,52.9693,217.5705)" fill="#fff" stroke="#ee6666"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,123.8211,212.6779)" fill="#fff" stroke="#ee6666"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,194.6729,218.7217)" fill="rgb(255,255,255)" stroke="#ee6666"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,265.5247,214.2608)" fill="#fff" stroke="#ee6666"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,336.3764,206.778)" fill="#fff" stroke="#ee6666"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,407.2282,188.071)" fill="#fff" stroke="#ee6666"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,478.08,185.9125)" fill="#fff" stroke="#ee6666"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,52.9693,158.5715)" fill="#fff" stroke="#73c0de"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,123.8211,145.6205)" fill="#fff" stroke="#73c0de"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,194.6729,153.8947)" fill="rgb(255,255,255)" stroke="#73c0de"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,265.5247,147.0595)" fill="#fff" stroke="#73c0de"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,336.3764,113.9625)" fill="#fff" stroke="#73c0de"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,407.2282,92.3775)" fill="#fff" stroke="#73c0de"></path>
<path d="M1 0A1 1 0 1 1 1 -0.0001" transform="matrix(2,0,0,2,478.08,90.9385)" fill="#fff" stroke="#73c0de"></path>
<path d="M-5 -5l454.9199 0l0 23.2l-454.9199 0Z" transform="translate(26.54 5)" fill="rgb(0,0,0)" fill-opacity="0" stroke="#ccc" stroke-width="0"></path>
<path d="M0 7L25 7" transform="translate(27.54 4.6)" fill="#000" stroke="#5470c6" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<path d="M18.1 7A5.6 5.6 0 1 1 18.1 6.9994" transform="translate(27.54 4.6)" fill="#fff" stroke="#5470c6" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<text dominant-baseline="central" text-anchor="start" style="font-size:12px;font-family:sans-serif;" x="30" y="7" transform="translate(27.54 4.6)" fill="#333">Email</text>
<path d="M0 7L25 7" transform="translate(98.5459 4.6)" fill="#000" stroke="#91cc75" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<path d="M18.1 7A5.6 5.6 0 1 1 18.1 6.9994" transform="translate(98.5459 4.6)" fill="#fff" stroke="#91cc75" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<text dominant-baseline="central" text-anchor="start" style="font-size:12px;font-family:sans-serif;" xml:space="preserve" x="30" y="7" transform="translate(98.5459 4.6)" fill="#333">Union Ads</text>
<path d="M0 7L25 7" transform="translate(194.9111 4.6)" fill="#000" stroke="#fac858" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<path d="M18.1 7A5.6 5.6 0 1 1 18.1 6.9994" transform="translate(194.9111 4.6)" fill="#fff" stroke="#fac858" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<text dominant-baseline="central" text-anchor="start" style="font-size:12px;font-family:sans-serif;" xml:space="preserve" x="30" y="7" transform="translate(194.9111 4.6)" fill="#333">Video Ads</text>
<path d="M0 7L25 7" transform="translate(290.4033 4.6)" fill="#000" stroke="#ee6666" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<path d="M18.1 7A5.6 5.6 0 1 1 18.1 6.9994" transform="translate(290.4033 4.6)" fill="#fff" stroke="#ee6666" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<text dominant-baseline="central" text-anchor="start" style="font-size:12px;font-family:sans-serif;" x="30" y="7" transform="translate(290.4033 4.6)" fill="#333">Direct</text>
<path d="M0 7L25 7" transform="translate(362.7393 4.6)" fill="#000" stroke="#73c0de" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<path d="M18.1 7A5.6 5.6 0 1 1 18.1 6.9994" transform="translate(362.7393 4.6)" fill="#fff" stroke="#73c0de" stroke-width="2" stroke-linecap="butt" stroke-miterlimit="10"></path>
<text dominant-baseline="central" text-anchor="start" style="font-size:12px;font-family:sans-serif;" xml:space="preserve" x="30" y="7" transform="translate(362.7393 4.6)" fill="#333">Search Engine</text>
<path d="M-5 -5l10 0l0 10l-10 0Z" transform="translate(5 5)" fill="rgb(0,0,0)" fill-opacity="0" stroke="#ccc" stroke-width="0"></path>
<defs >
<clipPath id="zr0-c0">
<path d="M51 59l427 0l0 217.85l-427 0Z" fill="#000"></path>
</clipPath>
<clipPath id="zr0-c1">
<path d="M51 59l427 0l0 217.85l-427 0Z" fill="#000"></path>
</clipPath>
<clipPath id="zr0-c2">
<path d="M51 59l427 0l0 217.85l-427 0Z" fill="#000"></path>
</clipPath>
<clipPath id="zr0-c3">
<path d="M51 59l427 0l0 217.85l-427 0Z" fill="#000"></path>
</clipPath>
<clipPath id="zr0-c4">
<path d="M51 59l427 0l0 217.85l-427 0Z" fill="#000"></path>
</clipPath>
</defs>
</svg>

bykka avatar Oct 31 '23 16:10 bykka

Hi Pavlo - I have just checked in an update that supports the use of both explicit position and a translation matrix. The output is looking pretty good, but can't support the matrix transformation with scale on the small circles. PDF uses cartesian co-ordinates for rendering (bottom left is the origin, rather than top left). This means a scale of a point (or shape will include an offset as it is not at point 0,0 when the matrix scaling is applied.

e.g: a circle of 1 unit radius positioned at the origin (0,0) in svg will be positioned at 0,841 on the page. If we apply a transformation matrix to scale that circle to 2 units (2,0,0,2,0,0) then the result will be centred at 0,1682 out side the page boundaries.

In your sample, if you take the path transform matrices that scale '2,0,0,2..' and instead make the scale '1,0,0,1...' and the path 'M1 0A2 2 0 1....'

What I can look at is applying the transformation matrices internally, but I would want to do this independently of this issue, as I'm working on having SVG as inline and referenced images.

<svg width=""498"" height=""305"" xmlns=""http://www.w3.org/2000/svg"" xmlns:xlink=""http://www.w3.org/1999/xlink"" version=""1.1"" baseProfile=""full"" viewBox=""0 0 498 305"">

<rect width=""498"" height=""305"" x=""0"" y=""0"" id=""0"" fill=""none""></rect>
<!-- Axes -->
<path d=""M52.9693 276.5L478.08 276.5"" fill=""none"" stroke=""#E0E6F1""></path>
<path d=""M52.9693 240.5L478.08 240.5"" fill=""none"" stroke=""#E0E6F1""></path>
<path d=""M52.9693 204.5L478.08 204.5"" fill=""none"" stroke=""#E0E6F1""></path>
<path d=""M52.9693 168.5L478.08 168.5"" fill=""none"" stroke=""#E0E6F1""></path>
<path d=""M52.9693 132.5L478.08 132.5"" fill=""none"" stroke=""#E0E6F1""></path>
<path d=""M52.9693 96.5L478.08 96.5"" fill=""none"" stroke=""#E0E6F1""></path>
<path d=""M52.9693 60.5L478.08 60.5"" fill=""none"" stroke=""#E0E6F1""></path>
<path d=""M52.9693 276.5L478.08 276.5"" fill=""none"" stroke=""#6E7079"" stroke-linecap=""round""></path>
<path d=""M53.5 275.85L53.5 280.85"" fill=""none"" stroke=""#6E7079""></path>
<path d=""M124.5 275.85L124.5 280.85"" fill=""none"" stroke=""#6E7079""></path>
<path d=""M194.5 275.85L194.5 280.85"" fill=""none"" stroke=""#6E7079""></path>
<path d=""M265.5 275.85L265.5 280.85"" fill=""none"" stroke=""#6E7079""></path>
<path d=""M336.5 275.85L336.5 280.85"" fill=""none"" stroke=""#6E7079""></path>
<path d=""M407.5 275.85L407.5 280.85"" fill=""none"" stroke=""#6E7079""></path>
<path d=""M478.5 275.85L478.5 280.85"" fill=""none"" stroke=""#6E7079""></path> 
<!-- Labels -->
<text dominant-baseline=""central"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" transform=""translate(44.9693 275.85)"" fill=""#6E7079"">0</text>
<text dominant-baseline=""central"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" transform=""translate(44.9693 239.875)"" fill=""#6E7079"">500</text>
<text dominant-baseline=""central"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" transform=""translate(44.9693 203.9)"" fill=""#6E7079"">1,000</text>
<text dominant-baseline=""central"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" transform=""translate(44.9693 167.925)"" fill=""#6E7079"">1,500</text>
<text dominant-baseline=""central"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" transform=""translate(44.9693 131.95)"" fill=""#6E7079"">2,000</text>
<text dominant-baseline=""central"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" transform=""translate(44.9693 95.975)"" fill=""#6E7079"">2,500</text>
<text dominant-baseline=""central"" text-anchor=""end"" style=""font-size:12px;font-family:sans-serif;"" transform=""translate(44.9693 60)"" fill=""#6E7079"">3,000</text>
<text dominant-baseline=""central"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" y=""6"" transform=""translate(52.9693 283.85)"" fill=""#6E7079"">Mon</text>
<text dominant-baseline=""central"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" y=""6"" transform=""translate(123.8211 283.85)"" fill=""#6E7079"">Tue</text>
<text dominant-baseline=""central"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" y=""6"" transform=""translate(194.6729 283.85)"" fill=""#6E7079"">Wed</text>
<text dominant-baseline=""central"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" y=""6"" transform=""translate(265.5246 283.85)"" fill=""#6E7079"">Thu</text>
<text dominant-baseline=""central"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" y=""6"" transform=""translate(336.3764 283.85)"" fill=""#6E7079"">Fri</text>
<text dominant-baseline=""central"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" y=""6"" transform=""translate(407.2282 283.85)"" fill=""#6E7079"">Sat</text>
<text dominant-baseline=""central"" text-anchor=""middle"" style=""font-size:12px;font-family:sans-serif;"" y=""6"" transform=""translate(478.08 283.85)"" fill=""#6E7079"">Sun</text>
<!-- Data lines -->
<g clip-path=""url(#zr0-c0)"">
<path d=""M52.9693 267.216L123.8211 266.3526L194.6729 268.583L265.5247 266.2087L336.3764 269.3745L407.2282 259.3015L478.08 260.7405"" fill=""none"" stroke=""rgb(84,112,198)"" stroke-width=""2"" stroke-linejoin=""bevel""></path>
</g>
<g clip-path=""url(#zr0-c1)"">
<path d=""M52.9693 251.387L123.8211 253.2577L194.6729 254.8406L265.5247 249.3724L336.3764 248.509L407.2282 235.558L478.08 238.436"" fill=""none"" stroke=""rgb(145,204,117)"" stroke-width=""2"" stroke-linejoin=""bevel""></path>
</g>
<g clip-path=""url(#zr0-c2)"">
<path d=""M52.9693 240.5945L123.8211 236.5653L194.6729 240.3786L265.5247 238.2921L336.3764 234.8385L407.2282 211.8145L478.08 208.9365"" fill=""none"" stroke=""rgb(250,200,88)"" stroke-width=""2"" stroke-linejoin=""bevel""></path>
</g>
<g clip-path=""url(#zr0-c3)"">
<path d=""M52.9693 217.5705L123.8211 212.6779L194.6729 218.7217L265.5247 214.2608L336.3764 206.778L407.2282 188.071L478.08 185.9125"" fill=""none"" stroke=""rgb(238,102,102)"" stroke-width=""2"" stroke-linejoin=""bevel""></path>
</g>
<g clip-path=""url(#zr0-c4)"">
<path d=""M52.9693 158.5715L123.8211 145.6205L194.6729 153.8947L265.5247 147.0595L336.3764 113.9625L407.2282 92.3775L478.08 90.9385"" fill=""none"" stroke=""rgb(115,192,222)"" stroke-width=""2"" stroke-linejoin=""bevel""></path>
</g> 
<!-- Data circles  with changed matrix -->
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1 0 0 1 52.9693 267.216)"" fill=""#fff"" stroke=""#5470c6""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1 0 0 1 123.8211 266.3526)"" fill=""#fff"" stroke=""#5470c6""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1 0 0 1 194.6729 268.583)"" fill=""rgb(255,255,255)"" stroke=""#5470c6""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1 0 0 1 265.5247,266.2087)"" fill=""#fff"" stroke=""#5470c6""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,336.3764,269.3745)"" fill=""#fff"" stroke=""#5470c6""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,407.2282,259.3015)"" fill=""#fff"" stroke=""#5470c6""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,478.08,260.7405)"" fill=""#fff"" stroke=""#5470c6""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,52.9693,251.387)"" fill=""#fff"" stroke=""#91cc75""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,123.8211,253.2577)"" fill=""#fff"" stroke=""#91cc75""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,194.6729,254.8406)"" fill=""rgb(255,255,255)"" stroke=""#91cc75""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,265.5247,249.3724)"" fill=""#fff"" stroke=""#91cc75""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,336.3764,248.509)"" fill=""#fff"" stroke=""#91cc75""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,407.2282,235.558)"" fill=""#fff"" stroke=""#91cc75""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,478.08,238.436)"" fill=""#fff"" stroke=""#91cc75""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,52.9693,240.5945)"" fill=""#fff"" stroke=""#fac858""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,123.8211,236.5653)"" fill=""#fff"" stroke=""#fac858""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,194.6729,240.3786)"" fill=""rgb(255,255,255)"" stroke=""#fac858""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,265.5247,238.2921)"" fill=""#fff"" stroke=""#fac858""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,336.3764,234.8385)"" fill=""#fff"" stroke=""#fac858""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,407.2282,211.8145)"" fill=""#fff"" stroke=""#fac858""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,478.08,208.9365)"" fill=""#fff"" stroke=""#fac858""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,52.9693,217.5705)"" fill=""#fff"" stroke=""#ee6666""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,123.8211,212.6779)"" fill=""#fff"" stroke=""#ee6666""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,194.6729,218.7217)"" fill=""rgb(255,255,255)"" stroke=""#ee6666""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,265.5247,214.2608)"" fill=""#fff"" stroke=""#ee6666""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,336.3764,206.778)"" fill=""#fff"" stroke=""#ee6666""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,407.2282,188.071)"" fill=""#fff"" stroke=""#ee6666""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,478.08,185.9125)"" fill=""#fff"" stroke=""#ee6666""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,52.9693,158.5715)"" fill=""#fff"" stroke=""#73c0de""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,123.8211,145.6205)"" fill=""#fff"" stroke=""#73c0de""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,194.6729,153.8947)"" fill=""rgb(255,255,255)"" stroke=""#73c0de""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,265.5247,147.0595)"" fill=""#fff"" stroke=""#73c0de""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,336.3764,113.9625)"" fill=""#fff"" stroke=""#73c0de""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,407.2282,92.3775)"" fill=""#fff"" stroke=""#73c0de""></path>
<path d=""M1 0A2 2 0 1 1 1 -0.0001"" transform=""matrix(1,0,0,1,478.08,90.9385)"" fill=""#fff"" stroke=""#73c0de""></path> 
<!-- Legend  -->
<path d=""M-5 -5l454.9199 0l0 23.2l-454.9199 0Z"" transform=""translate(26.54 5)"" fill=""rgb(0,0,0)"" fill-opacity=""0"" stroke=""#ccc"" stroke-width=""0""></path>
<path d=""M0 7L25 7"" transform=""translate(27.54 4.6)"" fill=""#000"" stroke=""#5470c6"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<path d=""M18.1 7A5.6 5.6 0 1 1 18.1 6.9994"" transform=""translate(27.54 4.6)"" fill=""#fff"" stroke=""#5470c6"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<text dominant-baseline=""central"" text-anchor=""start"" style=""font-size:12px;font-family:sans-serif;"" x=""30"" y=""7"" transform=""translate(27.54 4.6)"" fill=""#333"">Email</text>
<path d=""M0 7L25 7"" transform=""translate(98.5459 4.6)"" fill=""#000"" stroke=""#91cc75"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<path d=""M18.1 7A5.6 5.6 0 1 1 18.1 6.9994"" transform=""translate(98.5459 4.6)"" fill=""#fff"" stroke=""#91cc75"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<text dominant-baseline=""central"" text-anchor=""start"" style=""font-size:12px;font-family:sans-serif;"" xml:space=""preserve"" x=""30"" y=""7"" transform=""translate(98.5459 4.6)"" fill=""#333"">Union Ads</text>
<path d=""M0 7L25 7"" transform=""translate(194.9111 4.6)"" fill=""#000"" stroke=""#fac858"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<path d=""M18.1 7A5.6 5.6 0 1 1 18.1 6.9994"" transform=""translate(194.9111 4.6)"" fill=""#fff"" stroke=""#fac858"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<text dominant-baseline=""central"" text-anchor=""start"" style=""font-size:12px;font-family:sans-serif;"" xml:space=""preserve"" x=""30"" y=""7"" transform=""translate(194.9111 4.6)"" fill=""#333"">Video Ads</text>
<path d=""M0 7L25 7"" transform=""translate(290.4033 4.6)"" fill=""#000"" stroke=""#ee6666"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<path d=""M18.1 7A5.6 5.6 0 1 1 18.1 6.9994"" transform=""translate(290.4033 4.6)"" fill=""#fff"" stroke=""#ee6666"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<text dominant-baseline=""central"" text-anchor=""start"" style=""font-size:12px;font-family:sans-serif;"" x=""30"" y=""7"" transform=""translate(290.4033 4.6)"" fill=""#333"">Direct</text>
<path d=""M0 7L25 7"" transform=""translate(362.7393 4.6)"" fill=""#000"" stroke=""#73c0de"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<path d=""M18.1 7A5.6 5.6 0 1 1 18.1 6.9994"" transform=""translate(362.7393 4.6)"" fill=""#fff"" stroke=""#73c0de"" stroke-width=""2"" stroke-linecap=""butt"" stroke-miterlimit=""10""></path>
<text dominant-baseline=""central"" text-anchor=""start"" style=""font-size:12px;font-family:sans-serif;"" xml:space=""preserve"" x=""30"" y=""7"" transform=""translate(362.7393 4.6)"" fill=""#333"">Search Engine</text> 
<path d=""M-5 -5l10 0l0 10l-10 0Z"" transform=""translate(5 5)"" fill=""rgb(0,0,0)"" fill-opacity=""0"" stroke=""#ccc"" stroke-width=""0""></path>
<defs >
<clipPath id=""zr0-c0"">
<path d=""M51 59l427 0l0 217.85l-427 0Z"" fill=""#000""></path>
</clipPath>
<clipPath id=""zr0-c1"">
<path d=""M51 59l427 0l0 217.85l-427 0Z"" fill=""#000""></path>
</clipPath>
<clipPath id=""zr0-c2"">
<path d=""M51 59l427 0l0 217.85l-427 0Z"" fill=""#000""></path>
</clipPath>
<clipPath id=""zr0-c3"">
<path d=""M51 59l427 0l0 217.85l-427 0Z"" fill=""#000""></path>
</clipPath>
<clipPath id=""zr0-c4"">
<path d=""M51 59l427 0l0 217.85l-427 0Z"" fill=""#000""></path>
</clipPath>
</defs>
</svg>

Then the output is as expected - see attached. SVGLineChart.pdf

richard-scryber avatar Nov 07 '23 18:11 richard-scryber