GithubHelp home page GithubHelp logo

hervegirod / fxsvgimage Goto Github PK

View Code? Open in Web Editor NEW
40.0 40.0 2.0 1.07 MB

A small self-sufficient library which allows to convert a SVG file to a JavaFX Node tree or an Image (no dependencies)

License: BSD 3-Clause "New" or "Revised" License

Java 99.62% HTML 0.27% JavaScript 0.06% CSS 0.05%
javafx svg

fxsvgimage's People

Contributors

hervegirod avatar pernyfelt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

pernyfelt xjw580

fxsvgimage's Issues

Scale to parent element

(Hope its okay to post questions in the Issues)
I'm not much of an JavaFX expert .. but I'm a bit confused about the library design

I've been trying to get my SVGImage to scale to a parent element (ex: A StackPane). I'd like to avoid manually scaling it or passing around width/height parameters. However the SVGImage seems to refuse to rescale unless passed in a scaling parameter :) I can make a huge SVGImage group, but it'll just spill out of the StackPane or force the parent size to grow

Am I doing something wrong or is this the intended behavior? The library seems to be designed with the SVGImage being scaled itself. (I can see you can also rescale it after it's created as well)

Could you for instance have the SVGImage group as part of StackPane and have it rescale as the window size is changed? or would you need to track the window size and rescale the SVG all the time?

Unfortunately I'm working through Clojure (and cljfx), so I'm not able to make an minimal example here...

Can I use an SVG XML string directly?

I'm programmatically generating SVG maps (using a separate library of mine). I can then serialize those into string of the SVG XML. I can then of course write those to disk, but is there some way I could feed the string directly into [fxsvgimage](https://github.com/hervegirod/fxsvgimage) to get back an SVG Group to display? (ie. bypass needing to make a temp file).

Btw, is there a Javadoc of the library hosted somewhere? I'm only seeing the Sourceforge guide - which is handy but I don't think it's comprehensive. I'm really sorry if I somehow missed what I was looking for here :S

`SVGImage`'s `scaleTo` doesn't seem to override svg `width` `height` parameters

This is a minor bug that's easy to work around (or i could be doing something wrong here)

I'm getting different renders depending on if the input SVG sets a width/height attribute or not

Example 1:

<?xml version="1.0"?>
<svg version="1.1"
     viewBox="0 0 5.0 5.0"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns="http://www.w3.org/2000/svg">
    <circle cx="2.5" cy="2.5" r="1" />
</svg>

Example 2:

<?xml version="1.0"?>
<svg version="1.1"
     viewBox="0 0 5.0 5.0"
     width="1000"
     height="1000"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns="http://www.w3.org/2000/svg">

    <circle cx="2.5" cy="2.5" r="1" />
</svg>

in both cases I just call SVGLoader/load to read in the SVG string.
Then call SVGImage/scaleTo and set the size to say 200

What I expect is that the scaleTo overrides the width/height params on the input svg and that both look identical

I'm not super clear on what actually happens.. but the second one gets huge

URL data:image/png;base64, "... is not well formed" error

A simple SVG such as:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:jfreesvg="http://www.jfree.org/jfreesvg/svg" width="600" height="600" text-rendering="auto" shape-rendering="auto">
<image preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAGKklEQVR4XnWYzWudVRDG34+be29uoq0lENr6EUJN0IIK2QgSyUYxQjbGLAtBNLsugrgQN3Xhn1CkG9ud0nUXKkr8CKgLF7oRDCjdFAUtFASxNL3Ob9553s69yX3hcM85M/OcZ+bMnHOSoiiKylp56dKlamtrq15bW+vQZ35lZWUq+gUy2iTd1M+6lXQTVpl1JWeecbm9vd23iS4C2s7OzhQtFu6YbJpfZBcvXuxJFzl6jIfDYRkkppnLOLEYC3ewF4GsC0Ex64oZwvX19Z6IXLhwYUbEtHAQcV0cEbiNB6FbAI6uiASxAePQdyJBsiEjoQwiCkfAw5OJ4JDK4OhmJ3AK5xjjrHQZRzBq9wBjEQmFYnZ29um6rjetu3nq1KmHmVNUpAuR2B7mfSERYUERP3PmzJxhvQaE4T6lNaSLI9j6RIB3e73iSZv7tKqqYVmW1ophVZVqtwzwTUBYCDuBQYSFhROeFqb/lmHdAqfBqhyrwS4/g1joK+GL6vr163ReQqmuRcT7h2Z8X2OA6rr8HCOMI1+cCKCQ8b3HzbL8onEKIg2u2R8KR81UXya6bkfJ2cQjCDqdGoU7VVW8B2D6ztv8QQLf393dnVg1Jv++ccojcjAzM/NMBjOcd03njnWd0NmzZx/FTMIPgghMTyrcLISc8d7eXsdIfoRn6Ha73fPIFBURmZqaeg55E4HiGnYTEvuEAmD9950In+3tf0HkMuMUbq+EnagaZLbIQejeW1hY8PMpwMvl5eWHDPxekxfFgbCQ0dDVOdOsW30YWP8y9i8mjGXnRXJAIY/fkaoh6WKr7ne79eaVK1dc1+SVRet1IgJWr9db1jYqenG4erJCytZbRTdsmk9J1e/3V5WQ/B5XNaG/3yRgdZ9xSlrPE4v0vuaTc77tIkbfyLygCmvJaMJ+32YchNojfrxqBoPBaS1sObISJ/azqhrk6MYWt1uuiGibjMw7zZYmMlauNwC27i+MARcR8gVAxgI/d+4ci7sDBugOmCO7FhF52W6zohbO+JZDxvBq02U9nLrhRCJcrwh8aWlpTuEUEfQUFYFbBD6Jqvkjxn8GkY9DX4ntSTx+HSwuLp5gTVqvV7/q0Ypz5jGVGUmF4Li7RlsHqB3xjyvxB4O50+pbm8dO24EuTgUR3Wm2u1PPo4/d3NzcEjJfiEqwEH9tQ7JbCUbytQmnu4Z53dSmezdy7XKTQ+VdORJ2nm/8Fs295clMdGmdTrFqAfhWKQEfPSHaCGAU2+RVEL/+mAq5kzQSf0cC/tOQKv9SBcqJcKA97MAGR9isK2wvv0lVIxLyKhOxNm2L39SxEKRuogtmPMLa6AiLpq1CV3L6ikZO1rZqgsiRdw59iJnoqshEeV6F9MbGxnHvHH9eJCKs3eYTMuYI08iri4VUNWF8HDjfG5EznryWd9u5asAREWFhr1s6vSKbQlLYMhEa/cz8GPCq3z/5xIPbuRzOz88vhq68bh/h9COivlURaddl7M7LYyXneNXQF1gACsyTL6rIT17GTCUibSEIi7VYQ6eykjlIF+1LT5O5amSMTIZqQeYw3jl+TyWckaoBR05kh6TvTqPUDsKrsfJsH1HyWPnEZxG5HY+o24ylq4gE6bZqRER/8tBXAPIfXMdWTQbLROhzv1hkfmtu6ur34OdvF0WEPk4osfUUkSytW+s6aO8PnTtjVTMCIPCQ/Rq3vj+m+LDTKc0iuWqwBQeZdHHaDVP4j1RNyLzCMnhET2+Yn+Kc+TmDh157kCJjHLgdsOjnM8nxdFrSR0FhUyLn0zTrNnda+V2Q+YFxrhps6etyzdiKnnR9h1hQEVDVSFktRWSkwvgTx0jsN6Vd7jPW1aIjQnZh274iGQdJxyr4B0RaaGLVMM6VoHwCzL6vIjLfoBvRnI7ftmrkRDjruad1wUeG/ZHrQPvKOKIzUATzXYPcIvJlXAd7RGb8OtDCwtJ1ABFwheXbpMVRFkCEbaQkESLLROhbSV+17o9G6Jr+sEOmfGNR6eZkHQ9Ae84ohBjn7VAIw6D9E0YOIEfGx58siXSbc1lXtnGoevQk5xdbvx8iP7xKMEr54pmePFKVucdJ14HR1ZaO60pexH+0si7tf17chNjsTsgvAAAAAElFTkSuQmCC"  transform="matrix(1.4,0,0,1.4,0,0)" x="30" y="30" width="35" height="35"/>
</svg>

generated by JFreeSVG returns "...not well formed" and does not display. This file works fine in browsers and in online base64 to SVG converters. I also wrote a simple Base64 to BufferedImage decoder stub to display the image in a JFrame and that too worked.

How do I get this to work in SVGLoader.load()/toImage()?

<style> elements are order-sensitive

This SVG:
style
doesn't get styled correctly by fxsvgimage. The yellow circle doesn't get its style applied so defaults to black. The circle style is defined after the circle element so perhaps the fxsvgimage parser needs to be adjusted to cope with different orders? (e.g. pre-parsing of styles).

SvgImage.toImageScaled produces only uneven wide images (for uneven input)

I'm trying to convert an SVG of a QR-Code to an Image. The QR-Code has a size of 25 (which is loaded correctly).
Ultimately there should be several sizes, all powers of 2, to be usable as icons, but the problem happens with any size.

If I enter a scale-factor that would produce the correct width, it instead returns an image with width+1.
E.g. qr.toImageScaled(64 / qr.getWidth) will return an Image with width and height of 65 (instead of the desired 64).
Furthermore, outsmarting the algorithm doesn't work. qr.toImageScaled(63 / 25) produces an image of width 63.

Preliminary testing shows that it snaps to the next uneven number of pixels, rounded up.

Is that a limitation of the rendering? I've seen you use a Scene to render a snapshot into an image, but am currently too tired to debug that far into it.

Scaling does not work

When I load an SVGImage and call scaleTo on it, it does not change its size :/
Using LoaderParameters does work, however!

Units not all handled correctly

This SVG:
units

gets rendered by fxsvgimage as a single large green circle.

Some analysis of what's happening shows that the circles with units cm, em, ex, mm and in aren't rendered at all.
The no-unit and px unit circles render ok but are obscured by an overly large pt unit circle.

Multiple <styles> don't get applied correctly

This SVG:
styledCircles

Doesn't get rendered correctly by fxsvgimage. In the bottom row of circles, 2 and 4 don't get the green fill and 3 doesn't get the yellow outline
circles

The styles for those circles are defined with multiple, comma-separated names so maybe that's something that the fxsvgimage parser doesn't yet handle correctly?

text-anchor attribute doesn't work

This SVG:
textAnchor

Gets rendered by fxsvgimage like this:
text-anchor

The text-anchor attribute seems to be ignored - the text is always anchored to "start".

Fails to correctly interpret matrix attributes

The svg below (github does not allow me to attach it) fails to properly interpret the matrix transform attributes and hence the result from line 850 of SVGLoader ( Transform transform = extractTransform(transforms); ) returns null

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:jfreesvg="http://www.jfree.org/jfreesvg/svg" width="504" height="504" text-rendering="auto" shape-rendering="auto">
<defs><clipPath id="_1195738149651500clip-0"><path d="M 45 45 L 482 45 L 482 449 L 45 449 L 45 45 Z "/></clipPath>
<clipPath id="_1195738149651500clip-1"><path d="M 0 0 L 505 0 L 505 505 L 0 505 L 0 0 Z "/></clipPath>
<clipPath id="_1195738149651500clip-2"><path d="M 453.57 −33 L 453.57 472 L −51.43 472 L −51.43 −33 L 453.57 −33 Z "/></clipPath>
<clipPath id="_1195738149651500clip-3"><path d="M 360.31 −33 L 360.31 472 L −144.69 472 L −144.69 −33 L 360.31 −33 Z "/></clipPath>
<clipPath id="_1195738149651500clip-4"><path d="M 255.05 −33 L 255.05 472 L −249.95 472 L −249.95 −33 L 255.05 −33 Z "/></clipPath>
<clipPath id="_1195738149651500clip-5"><path d="M 161.78 −33 L 161.78 472 L −343.22 472 L −343.22 −33 L 161.78 −33 Z "/></clipPath>
<clipPath id="_1195738149651500clip-6"><path d="M 68.52 −33 L 68.52 472 L −436.48 472 L −436.48 −33 L 68.52 −33 Z "/></clipPath>
<clipPath id="_1195738149651500clip-7"><path d="M 254 −11 L 254 494 L −251 494 L −251 −11 L 254 −11 Z "/></clipPath>
</defs>
<rect x="0" y="0" width="504" height="504" style="fill: rgb(255,255,255); fill-opacity: 1.0" transform="matrix(1,0,0,1,0,0)" /><rect x="0" y="0" width="504" height="504" style="fill: rgb(255,255,255); fill-opacity: 1.0" transform="matrix(1,0,0,1,0,0)" /><g style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;; fill: none" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-0)"><path d="M 61 247 L 65 264 L 69 281 L 73 299 L 77 315 L 81 331 L 85 346 L 89 361 L 94 374 L 98 386 L 102 397 L 106 407 L 110 415 L 114 422 L 118 427 L 122 431 L 126 433 L 130 433 L 134 432 L 138 429 L 142 424 L 146 418 L 150 410 L 154 401 L 158 390 L 162 378 L 166 365 L 170 351 L 174 336 L 178 321 L 182 304 L 186 287 L 190 270 L 194 252 L 198 235 L 202 217 L 207 200 L 211 183 L 215 167 L 219 152 L 223 137 L 227 123 L 231 111 L 235 99 L 239 89 L 243 80 L 247 73 L 251 67 L 255 63 L 259 61 L 263 60 L 267 61 L 271 63 L 275 67 L 279 73 L 283 80 L 287 89 L 291 99 L 295 111 L 299 123 L 303 137 L 307 152 L 311 167 L 315 183 L 319 200 L 324 217 L 328 235 L 332 252 L 336 270 L 340 287 L 344 304 L 348 321 L 352 336 L 356 351 L 360 365 L 364 378 L 368 390 L 372 401 L 376 410 L 380 418 L 384 424 L 388 429 L 392 432 L 396 433 L 400 433 L 404 431 L 408 427 L 412 422 L 416 415 L 420 407 L 424 397 L 428 386 L 432 374 L 437 361 L 441 346 L 445 331 L 449 315 L 453 299 L 457 281 L 461 264 L 465 247"/></g><line x1="110" y1="448" x2="453" y2="448" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="110" y1="448" x2="110" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="196" y1="448" x2="196" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="281" y1="448" x2="281" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="367" y1="448" x2="367" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="453" y1="448" x2="453" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><g transform="matrix(1,0,0,1,0,0)"><text x="95" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-1)">¬ネメ2</text></g><g transform="matrix(1,0,0,1,0,0)"><text x="192" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-1)">0</text></g><g transform="matrix(1,0,0,1,0,0)"><text x="278" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-1)">2</text></g><g transform="matrix(1,0,0,1,0,0)"><text x="364" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-1)">4</text></g><g transform="matrix(1,0,0,1,0,0)"><text x="449" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-1)">6</text></g><line x1="45" y1="433" x2="45" y2="60" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="45" y1="433" x2="40" y2="433" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="45" y1="340" x2="40" y2="340" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="45" y1="247" x2="40" y2="247" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="45" y1="153" x2="40" y2="153" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><line x1="45" y1="60" x2="40" y2="60" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"/><g transform="matrix(−0,−1,1,0,33,453.573522)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-2)">¬ネメ1,0</text></g><g transform="matrix(−0,−1,1,0,33,360.309771)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-3)">¬ネメ0,5</text></g><g transform="matrix(−0,−1,1,0,33,255.04602)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-4)">0,0</text></g><g transform="matrix(−0,−1,1,0,33,161.782269)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-5)">0,5</text></g><g transform="matrix(−0,−1,1,0,33,68.518519)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-6)">1,0</text></g><g style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;; fill: none" transform="matrix(1,0,0,1,0,0)" clip-path="url(#_1195738149651500clip-1)"><path d="M 45 448 L 481 448 L 481 45 L 45 45 L 45 448"/></g><g transform="matrix(1,0,0,1,0,0)"><text x="260" y="491" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-1)">x</text></g><g transform="matrix(−0,−1,1,0,11,254)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_1195738149651500clip-7)">sin</text></g></svg>

The image was created in R as follows:

fileName <- paste0(tempdir(), "plot.svg")
svg(fileName)
plot(sin, -pi, 2*pi)
dev.off()

support Font size and style of Text elements

I have the following text element as the title of a graph:

<text x="222" y="30" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 14px; font-weight: bold;" clip-path="url(#_6956964959000clip-0)">Tree Growth</text>

The text Tree Growth is printer at the proper position but is neither bold nor size 14.

I expect this
orange

But get this:
titleformat

The complete content of the svg is:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:jfreesvg="http://www.jfree.org/jfreesvg/svg" width="504" height="504" text-rendering="auto" shape-rendering="auto">
	<defs>
		<clipPath id="_6956964959000clip-0">
			<path d="M 0 0 L 505 0 L 505 505 L 0 505 L 0 0 Z "/>
		</clipPath>
		<clipPath id="_6956964959000clip-1">
			<path d="M 398.94 −33 L 398.94 472 L −106.06 472 L −106.06 −33 L 398.94 −33 Z "/>
		</clipPath>
		<clipPath id="_6956964959000clip-2">
			<path d="M 301.09 −33 L 301.09 472 L −203.91 472 L −203.91 −33 L 301.09 −33 Z "/>
		</clipPath>
		<clipPath id="_6956964959000clip-3">
			<path d="M 199.74 −33 L 199.74 472 L −305.26 472 L −305.26 −33 L 199.74 −33 Z "/>
		</clipPath>
		<clipPath id="_6956964959000clip-4">
			<path d="M 98.4 −33 L 98.4 472 L −406.6 472 L −406.6 −33 L 98.4 −33 Z "/>
		</clipPath>
		<clipPath id="_6956964959000clip-5">
			<path d="M 301 −11 L 301 494 L −204 494 L −204 −11 L 301 −11 Z "/>
		</clipPath>
		<clipPath id="_6956964959000clip-6">
			<path d="M 45 45 L 482 45 L 482 449 L 45 449 L 45 45 Z "/>
		</clipPath>
	</defs>
	<rect x="0" y="0" width="504" height="504" style="fill: rgb(255,255,255); fill-opacity: 1.0" />
	<rect x="0" y="0" width="504" height="504" style="fill: rgb(255,255,255); fill-opacity: 1.0" />
	<line x1="167" y1="448" x2="442" y2="448" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<line x1="167" y1="448" x2="167" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<line x1="304" y1="448" x2="304" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<line x1="442" y1="448" x2="442" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<g >
		<text x="157" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-0)">500</text>
	</g>
	<g >
		<text x="291" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-0)">1000</text>
	</g>
	<g >
		<text x="429" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-0)">1500</text>
	</g>
	<line x1="45" y1="392" x2="45" y2="88" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<line x1="45" y1="392" x2="40" y2="392" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<line x1="45" y1="291" x2="40" y2="291" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<line x1="45" y1="190" x2="40" y2="190" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<line x1="45" y1="88" x2="40" y2="88" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-0)"/>
	<g transform="matrix(−0,−1,1,0,33,398.942029)">
		<text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-1)">50</text>
	</g>
	<g transform="matrix(−0,−1,1,0,33,301.093398)">
		<text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-2)">100</text>
	</g>
	<g transform="matrix(−0,−1,1,0,33,199.744767)">
		<text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-3)">150</text>
	</g>
	<g transform="matrix(−0,−1,1,0,33,98.396135)">
		<text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-4)">200</text>
	</g>
	<g style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;; fill: none" clip-path="url(#_6956964959000clip-0)">
		<path d="M 45 448 L 481 448 L 481 45 L 45 45 L 45 448"/>
	</g>
	<g >
		<text x="234" y="491" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-0)">Age (days)</text>
	</g>
	<g transform="matrix(−0,−1,1,0,11,301)">
		<text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-5)">Circumference (mm)</text>
	</g>
	<line x1="66" y1="431" x2="157" y2="393" style="stroke-width: 1.5;stroke: rgb(255,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="166" y1="387" x2="208" y2="346" style="stroke-width: 1.5;stroke: rgb(255,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="216" y1="339" x2="301" y2="278" style="stroke-width: 1.5;stroke: rgb(255,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="311" y1="274" x2="363" y2="262" style="stroke-width: 1.5;stroke: rgb(255,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="371" y1="256" x2="403" y2="216" style="stroke-width: 1.5;stroke: rgb(255,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="412" y1="212" x2="459" y2="210" style="stroke-width: 1.5;stroke: rgb(255,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 59 433 L 61 431 L 63 433 L 61 435 Z "/>
	</g>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 160 390 L 162 388 L 164 390 L 162 392 Z "/>
	</g>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 210 342 L 212 340 L 214 342 L 212 344 Z "/>
	</g>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 303 275 L 305 273 L 308 275 L 305 277 Z "/>
	</g>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 366 261 L 368 259 L 370 261 L 368 263 Z "/>
	</g>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 405 212 L 407 210 L 409 212 L 407 214 Z "/>
	</g>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 463 210 L 465 208 L 467 210 L 465 212 Z "/>
	</g>
	<line x1="66" y1="430" x2="157" y2="379" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="166" y1="372" x2="208" y2="322" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="216" y1="315" x2="301" y2="264" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="311" y1="260" x2="363" y2="251" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="372" y1="246" x2="403" y2="210" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="412" y1="205" x2="459" y2="200" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="61.5" cy="433.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="61.5" cy="433.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="162.5" cy="376.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="162.5" cy="376.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="212.5" cy="317.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="212.5" cy="317.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="305.5" cy="261.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="305.5" cy="261.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="368.5" cy="250.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="368.5" cy="250.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="407.5" cy="206.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="407.5" cy="206.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="465.5" cy="200.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="465.5" cy="200.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="66" y1="431" x2="157" y2="396" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="165" y1="390" x2="208" y2="334" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="216" y1="326" x2="301" y2="244" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="310" y1="238" x2="363" y2="209" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="371" y1="201" x2="404" y2="146" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="412" y1="141" x2="459" y2="136" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="62" cy="434" rx="2" ry="2" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="62" cy="434" rx="2" ry="2" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="163" cy="395" rx="2" ry="2" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="163" cy="395" rx="2" ry="2" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="212" cy="330" rx="2" ry="2" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="212" cy="330" rx="2" ry="2" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="306" cy="241" rx="2" ry="2" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="306" cy="241" rx="2" ry="2" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="369" cy="207" rx="2" ry="2" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="369" cy="207" rx="2" ry="2" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="408" cy="142" rx="2" ry="2" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="408" cy="142" rx="2" ry="2" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="465" cy="136" rx="2" ry="2" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="465" cy="136" rx="2" ry="2" style="stroke-width: 1.5;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="66" y1="424" x2="158" y2="357" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="165" y1="349" x2="209" y2="274" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="216" y1="265" x2="302" y2="181" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="310" y1="175" x2="363" y2="148" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="371" y1="140" x2="404" y2="87" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="412" y1="82" x2="459" y2="82" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="61.5" cy="427.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="61.5" cy="427.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="162.5" cy="354.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="162.5" cy="354.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="212.5" cy="269.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="212.5" cy="269.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="305.5" cy="178.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="305.5" cy="178.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="368.5" cy="145.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="368.5" cy="145.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="407.5" cy="82.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="407.5" cy="82.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="465.5" cy="82.5" rx="2.5" ry="2.5" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="465.5" cy="82.5" rx="2.5" ry="2.5" style="stroke-width: 1.5;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;; fill: none" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="66" y1="426" x2="157" y2="371" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="165" y1="363" x2="209" y2="272" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="215" y1="263" x2="302" y2="159" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="311" y1="153" x2="363" y2="133" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="371" y1="126" x2="404" y2="75" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="412" y1="69" x2="459" y2="61" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="59" y1="427" x2="62" y2="427" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="63" y1="427" x2="63" y2="430" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="63" y1="431" x2="60" y2="431" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="59" y1="431" x2="59" y2="428" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="160" y1="366" x2="163" y2="366" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="164" y1="366" x2="164" y2="369" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="164" y1="370" x2="161" y2="370" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="160" y1="370" x2="160" y2="367" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="210" y1="265" x2="213" y2="265" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="214" y1="265" x2="214" y2="268" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="214" y1="269" x2="211" y2="269" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="210" y1="269" x2="210" y2="266" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="304" y1="153" x2="306" y2="153" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="307" y1="153" x2="307" y2="156" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="307" y1="157" x2="305" y2="157" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="304" y1="157" x2="304" y2="154" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="366" y1="129" x2="369" y2="129" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="370" y1="129" x2="370" y2="132" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="370" y1="133" x2="367" y2="133" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="366" y1="133" x2="366" y2="130" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="405" y1="68" x2="408" y2="68" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="409" y1="68" x2="409" y2="71" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="409" y1="72" x2="406" y2="72" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="405" y1="72" x2="405" y2="69" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="463" y1="58" x2="466" y2="58" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="467" y1="58" x2="467" y2="61" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="467" y1="62" x2="464" y2="62" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="463" y1="62" x2="463" y2="59" style="stroke-width: 1.5;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<g >
		<text x="222" y="30" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 14px; font-weight: bold;" clip-path="url(#_6956964959000clip-0)">Tree Growth</text>
	</g>
	<g >
		<text x="212" y="502" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_6956964959000clip-0)">example of line plot</text>
	</g>
	<rect x="61" y="60" width="32" height="76" style="fill: rgb(255,255,255); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="61" y1="60" x2="91" y2="60" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="92" y1="60" x2="92" y2="134" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="92" y1="135" x2="62" y2="135" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="61" y1="135" x2="61" y2="61" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="63" y1="82" x2="76" y2="82" style="stroke-width: 1.0;stroke: rgb(255,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="63" y1="93" x2="76" y2="93" style="stroke-width: 1.0;stroke: rgb(204,255,0);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 4.0, 4.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="63" y1="104" x2="76" y2="104" style="stroke-width: 1.0;stroke: rgb(0,255,102);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="63" y1="115" x2="76" y2="115" style="stroke-width: 1.0;stroke: rgb(0,102,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 1.0, 3.0, 4.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="63" y1="126" x2="76" y2="126" style="stroke-width: 1.0;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;" clip-path="url(#_6956964959000clip-6)"/>
	<g style="fill: rgb(255,0,0); fill-opacity: 1.0; stroke: none" clip-path="url(#_6956964959000clip-6)">
		<path d="M 68 82 L 70 80 L 71 82 L 70 84 Z "/>
	</g>
	<ellipse cx="70" cy="93" rx="2" ry="2" style="fill: rgb(255,0,0); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="69.5" cy="104.5" rx="1.5" ry="1.5" style="fill: rgb(255,0,0); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<ellipse cx="70" cy="115" rx="2" ry="2" style="fill: rgb(255,0,0); fill-opacity: 1.0" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="68" y1="125" x2="70" y2="125" style="stroke-width: 1.0;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="71" y1="125" x2="71" y2="126" style="stroke-width: 1.0;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="71" y1="127" x2="69" y2="127" style="stroke-width: 1.0;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<line x1="68" y1="127" x2="68" y2="126" style="stroke-width: 1.0;stroke: rgb(204,0,255);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_6956964959000clip-6)"/>
	<g >
		<text x="66" y="71" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 10px;" clip-path="url(#_6956964959000clip-6)">Tree</text>
	</g>
	<g >
		<text x="82" y="88" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 10px;" clip-path="url(#_6956964959000clip-6)">1</text>
	</g>
	<g >
		<text x="82" y="99" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 10px;" clip-path="url(#_6956964959000clip-6)">2</text>
	</g>
	<g >
		<text x="82" y="110" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 10px;" clip-path="url(#_6956964959000clip-6)">3</text>
	</g>
	<g >
		<text x="82" y="121" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 10px;" clip-path="url(#_6956964959000clip-6)">4</text>
	</g>
	<g >
		<text x="82" y="132" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 10px;" clip-path="url(#_6956964959000clip-6)">5</text>
	</g>
</svg>

Conversion to Image with transparent background

I am not sure if this is a bug, or a feature request, or me simply being stupid.

I have the following SVG image.

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="18mm" height="18mm" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 1800 1800">
    <path d="M641 1050c15-2 139-52 169-63 13-5 44-19 56-20 4 34-2 69 6 101-12 9-26 18-40 27-12 9-29 18-39 26v43c22-5 93-41 107-41 13 0 85 36 108 40 0-51 8-37-40-68-11-7-29-22-39-26 3-47 3-59 5-103 20 4 203 82 225 84v-53l-57-44c-18-16-37-29-55-44l-113-88c-8-15 8-121-10-158-6-12-11-28-28-27-13 8-25 33-27 52-2 21-2 88-2 115 1 19 0 17-11 26L641 997v53z"/>
    <circle fill="none" stroke="#000" stroke-width="20" cx="900" cy="900" r="325"/>
    <path fill="none" d="M0 0h1800v1800H0z"/>
</svg>

I have the following code in a JavaFX app to show the image in the graphics context of a Canvas.

      public void start(Stage primaryStage) throws Exception {

		var width = 1200;
		var height = 800;

		var canvas = new Canvas(width, height);
		var gc = canvas.getGraphicsContext2D();
		gc.setFill(Color.BLUE);
		gc.fillRect(0, 0, width, height);

		var image = SVGLoader.load(new File("/Users/graham/Desktop/foo.svg").toURI().toURL());
		var img = image.toImage(ScaleQuality.RENDER_QUALITY, 12);

		gc.drawImage(img, 100, 200, 12, 12);
		var scene = new Scene(new StackPane(canvas), width, height);
		primaryStage.setScene(scene);
		primaryStage.show();
	}

The code runs fine, drawing my SVG image in the canvas. But the background of the image is white, when I need it to be transparent.

Is there some way to make this work, or is this a bug, or is a feature request needed. Or am i being dumb?

Path rendering issues

Using ionicons (only with the fill attribute added to the original SVG), some icons with paths are rendered very odd.
At least from what I have used so far, this includes the person-circle and settings icons.

image

The exact SVG causing this:

<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512" fill="#fff">
    <title>Person Circle</title>
    <path d="M256 48C141.31 48 48 141.31 48 256s93.31 208 208 208 208-93.31 208-208S370.69 48 256 48zm-50.22 116.82C218.45 151.39 236.28 144 256 144s37.39 7.44 50.11 20.94c12.89 13.68 19.16 32.06 17.68 51.82C320.83 256 290.43 288 256 288s-64.89-32-67.79-71.25c-1.47-19.92 4.79-38.36 17.57-51.93zM256 432a175.49 175.49 0 01-126-53.22 122.91 122.91 0 0135.14-33.44C190.63 329 222.89 320 256 320s65.37 9 90.83 25.34A122.87 122.87 0 01382 378.78 175.45 175.45 0 01256 432z"/>
</svg>

Project Structure

Just two remarks:

  • why is almost every commit of yours split into 4?
  • if the History.md was reverse-ordered it would be alot more handy ;)

<tspan> elements not rendering correctly

The following SVG doesn't seem to render correctly. In the browsers I've tried (e.g. Edge, Internet Explorer) it looks like this:
tspan

But the JavaFX scene graph created by fxsvgimage looks like this:
tspan(fxsvgimage)

It looks like a combination of problems - perhaps not handling whitespace collapse (see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xml:space) and also not positioning/styling tspan elements correctly (most of them are missing).

I'm new to fxsvgimage so it's possible I haven't set it up correctly but other SVG images seem fine.

Styling an SVG with JavaFX CSS

I use SVGImage object as graphic for a jfx Button.
How I can style this SVG using custom stylesheets?

Currently I tried something like that:

.launcher-root .tabs-panel-buttons .tab-button .svg-image {
	-fx-fill: rgba(255, 255, 255, 0.5);
}

svg-image is a custom style class added to button' SVGImage
I also tried other parameters such as -fx-stroke and other that are available for SVGPath element as described on the CSS Reference Guide, but no results.
Please, help me :(

stroke-dasharray property does not seem to be supported

Hi I tried with some more complex graphs and found that dashed lines are always drawn as solid lines. I think this is because the stroke-dasharray property is not interpreted correctly.

Below is a simple example:
dotline

But when i view it using fxsvgimage it lookes like this:
dotline-fxsvgimage

Below is the svg content:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:jfreesvg="http://www.jfree.org/jfreesvg/svg" width="504" height="504" text-rendering="auto" shape-rendering="auto">
<defs><clipPath id="_8098823727161clip-0"><path d="M 45 45 L 482 45 L 482 449 L 45 449 L 45 45 Z "/></clipPath>
<clipPath id="_8098823727161clip-1"><path d="M 0 0 L 505 0 L 505 505 L 0 505 L 0 0 Z "/></clipPath>
<clipPath id="_8098823727161clip-2"><path d="M 436.98 -33 L 436.98 472 L -68.02 472 L -68.02 -33 L 436.98 -33 Z "/></clipPath>
<clipPath id="_8098823727161clip-3"><path d="M 343.74 -33 L 343.74 472 L -161.26 472 L -161.26 -33 L 343.74 -33 Z "/></clipPath>
<clipPath id="_8098823727161clip-4"><path d="M 250.5 -33 L 250.5 472 L -254.5 472 L -254.5 -33 L 250.5 -33 Z "/></clipPath>
<clipPath id="_8098823727161clip-5"><path d="M 157.26 -33 L 157.26 472 L -347.74 472 L -347.74 -33 L 157.26 -33 Z "/></clipPath>
<clipPath id="_8098823727161clip-6"><path d="M 67.52 -33 L 67.52 472 L -437.48 472 L -437.48 -33 L 67.52 -33 Z "/></clipPath>
<clipPath id="_8098823727161clip-7"><path d="M 250 -11 L 250 494 L -255 494 L -255 -11 L 250 -11 Z "/></clipPath>
</defs>
<rect x="0" y="0" width="504" height="504" style="fill: rgb(255,255,255); fill-opacity: 1.0" /><rect x="0" y="0" width="504" height="504" style="fill: rgb(255,255,255); fill-opacity: 1.0" /><g style="stroke-width: 1.0;stroke: rgb(0,0,255);stroke-opacity: 1.0;stroke-miterlimit: 3;stroke-dasharray: 7.0, 3.0;; fill: none" clip-path="url(#_8098823727161clip-0)"><path d="M 61 433 L 162 340 L 263 247 L 364 153 L 465 60"/></g><line x1="61" y1="448" x2="465" y2="448" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="61" y1="448" x2="61" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="162" y1="448" x2="162" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="263" y1="448" x2="263" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="364" y1="448" x2="364" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="465" y1="448" x2="465" y2="453" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><g ><text x="57" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-1)">1</text></g><g ><text x="158" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-1)">2</text></g><g ><text x="259" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-1)">3</text></g><g ><text x="360" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-1)">4</text></g><g ><text x="461" y="469" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-1)">5</text></g><line x1="45" y1="433" x2="45" y2="60" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="45" y1="433" x2="40" y2="433" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="45" y1="340" x2="40" y2="340" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="45" y1="247" x2="40" y2="247" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="45" y1="153" x2="40" y2="153" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><line x1="45" y1="60" x2="40" y2="60" style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;" clip-path="url(#_8098823727161clip-1)"/><g transform="matrix(-0,-1,1,0,33,436.981481)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-2)">2</text></g><g transform="matrix(-0,-1,1,0,33,343.740741)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-3)">4</text></g><g transform="matrix(-0,-1,1,0,33,250.5)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-4)">6</text></g><g transform="matrix(-0,-1,1,0,33,157.259259)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-5)">8</text></g><g transform="matrix(-0,-1,1,0,33,67.518519)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-6)">10</text></g><g style="stroke-width: 1.0;stroke: rgb(0,0,0);stroke-opacity: 1.0;stroke-linecap: square;stroke-miterlimit: 10;; fill: none" clip-path="url(#_8098823727161clip-1)"><path d="M 45 448 L 481 448 L 481 45 L 45 45 L 45 448"/></g><g ><text x="260" y="491" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-1)">x</text></g><g transform="matrix(-0,-1,1,0,11,250)"><text x="0" y="0" style="fill: rgb(0,0,0); fill-opacity: 1.0; font-family: sans-serif; font-size: 12px;" clip-path="url(#_8098823727161clip-7)">y</text></g></svg>

Inconsistent scaling depending on what's displayed

Again, this might be my misunderstanding of the API

I made a simple test example with a 1x1 viewBox to illustrate the issue.

Here I am displaying 4 circles and a few polylines:

<?xml version="1.0"?>
<svg version="1.1" viewBox="0 0 1.0 1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<g>

    <circle cx="0.25" cy="0.25" r="0.25" />
    <circle cx="0.75" cy="0.25" r="0.25" />
    <circle cx="0.25" cy="0.75" r="0.25" />
    <circle cx="0.75" cy="0.75" r="0.25" />

    <g>
        <polyline fill="none" points="1.00,0.56 0.93,0.44 0.77,0.48 0.71,0.18 0.63,0.22 0.67,0.11 0.52,0.18 0.52,0.11 0.46,0.13 0.44,0.37 0.29,0.30 0.22,0.00 1.00,0.00 1.00,0.56" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.30,0.51 0.30,0.50 0.29,0.30 0.45,0.43 0.42,0.70 0.37,0.66 0.31,0.74 0.30,0.51" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.61,0.51 0.61,0.51 0.60,0.61 0.53,0.39 0.61,0.51" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.57,0.38 0.57,0.38 0.64,0.32 0.62,0.42 0.57,0.38" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.94,0.66 0.94,0.66 0.99,0.72 0.94,0.66" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.76,0.72 0.76,0.71 0.77,0.78 0.76,0.72" stroke-width="0.05px" stroke="black" />
</g>
<g fill="red" />
</g>
</svg>

In-code I'm simply loading the SVG using SVGLoader/load and then I call SVGImage/scaleTo and set the width to be 200.0. The image is then displayed in a v-box but I don't think I'm doing anything too weird here..

What I see is that with the polylines the resulting image is shrunken down

If I remove the polylines then the circles end up displayed significantly larger

<?xml version="1.0"?>
<svg version="1.1" viewBox="0 0 1.0 1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<g>

    <circle cx="0.25" cy="0.25" r="0.25" />
    <circle cx="0.75" cy="0.25" r="0.25" />
    <circle cx="0.25" cy="0.75" r="0.25" />
    <circle cx="0.75" cy="0.75" r="0.25" />

    <!--g>
        <polyline fill="none" points="1.00,0.56 0.93,0.44 0.77,0.48 0.71,0.18 0.63,0.22 0.67,0.11 0.52,0.18 0.52,0.11 0.46,0.13 0.44,0.37 0.29,0.30 0.22,0.00 1.00,0.00 1.00,0.56" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.30,0.51 0.30,0.50 0.29,0.30 0.45,0.43 0.42,0.70 0.37,0.66 0.31,0.74 0.30,0.51" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.61,0.51 0.61,0.51 0.60,0.61 0.53,0.39 0.61,0.51" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.57,0.38 0.57,0.38 0.64,0.32 0.62,0.42 0.57,0.38" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.94,0.66 0.94,0.66 0.99,0.72 0.94,0.66" stroke-width="0.05px" stroke="black" />
        <polyline fill="none" points="0.76,0.72 0.76,0.71 0.77,0.78 0.76,0.72" stroke-width="0.05px" stroke="black" />
</g-->
<g fill="red" />
</g>
</svg>

My expectation would be that the image is scaled solely with the viewBox - and irrespective of what's actually being displayed inside

I haven't found any solution to work around this and it's made it unfortunately impossible to correctly align elements in my GUI. (I may need to resort to using a different SVG->JFX library :( )

Decimal font sizes don't work on the 0.0-1.0 range

I have an SVGs of maps where the units are in degrees (and hence very small). This seems to make the library misbehave.

Here is a minimal example of the axis that I try to draw

<?xml version="1.0"?>
<svg height="1000.0" version="1.1" viewBox="0 0 5.0 5.0" width="1000" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<g>
<g fill="none" stroke="none" />
<g stroke-width="0.005" stroke="black">
<line x1="0.50" x2="0.50" y1="5.00" y2="4.90" />
<line x1="1.50" x2="1.50" y1="5.00" y2="4.90" />
<line x1="2.50" x2="2.50" y1="5.00" y2="4.90" />
<line x1="3.50" x2="3.50" y1="5.00" y2="4.90" />
<line x1="4.50" x2="4.50" y1="5.00" y2="4.90" />
<g fill="black" font-family="Arial, sans-serif" font-size="0.05" stroke="none" text-anchor="start" transform="translate(0.0125 -0.025)">
<text x="0.50" y="5.00">97°</text>
<text x="1.50" y="5.00">98°</text>
<text x="2.50" y="5.00">99°</text>
<text x="3.50" y="5.00">100°</text>
<text x="4.50" y="5.00">101°</text>
</g>
<line x1="0.00" x2="5.00" y1="5.00" y2="5.00" />
</g>
<g stroke-width="0.005" stroke="black">
<line x1="0.00" x2="0.10" y1="5.00" y2="5.00" />
<line x1="0.00" x2="0.10" y1="4.00" y2="4.00" />
<line x1="0.00" x2="0.10" y1="3.00" y2="3.00" />
<line x1="0.00" x2="0.10" y1="2.00" y2="2.00" />
<line x1="0.00" x2="0.10" y1="1.00" y2="1.00" />
<line x1="0.00" x2="0.10" y1="0.00" y2="0.00" />
<g fill="black" font-family="Arial, sans-serif" font-size="0.05" stroke="none" text-anchor="start" transform="translate(0.025 0.00625)">
<text x="-0.00" y="5.05">6°</text>
<text x="-0.00" y="4.05">7°</text>
<text x="-0.00" y="3.05">8°</text>
<text x="-0.00" y="2.05">9°</text>
<text x="-0.00" y="1.05">10°</text>
<text x="-0.00" y="0.05">11°</text>
</g>
<line x1="0.00" x2="0.00" y1="5.00" y2="0.00" />
</g>
</g>
</svg>

I can pare it down further:

<?xml version="1.0"?>
<svg height="1000.0" version="1.1" viewBox="0 0 5.0 5.0" width="1000" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">

<g>
<g fill="none" stroke="none" />
<g stroke-width="0.005" stroke="black">
<g fill="black" font-family="Arial, sans-serif" font-size="0.05" stroke="none" text-anchor="start" transform="translate(0.0125 -0.025)">
<text x="4.50" y="5.00">101°</text>
</g>
<line x1="0.00" x2="5.00" y1="5.00" y2="5.00" />
</g>
<g stroke-width="0.005" stroke="black">
<g fill="black" font-family="Arial, sans-serif" font-size="0.05" stroke="none" text-anchor="start" transform="translate(0.025 0.00625)">
<text x="-0.00" y="0.05">11°</text>
</g>
<line x1="0.00" x2="0.00" y1="5.00" y2="0.00" />
</g>
</g>
</svg>

The parameter font-size seems to work up to the value 1.0 and then subsequently the letters stop shrinking and start to move together and overlap

Thanks for the library! It seems to work instantaneously even with large SVGs I throw at it. Just a few weird rendering edge cases to iron out - and no more Batik! :D

Here is large complex SVG that also fails:

first-year

Arrow marker not rendered correctly

I have an SVG made with inkscape containing arrow heads as markers, which fxsvgimage does not render:
aufstellung-rearranged-plain

So I wanted to convert the arrow to a path via Path>Stroke to Path (as mentioned in https://stackoverflow.com/a/10480412/6723250), but the resulting SVG somehow crashes the SVGLoader.load such that it does not even throw an exception but simply returns null:
aufstellung-rearranged-slim

Converting the SVG via ImageMagick also produces something not understood by SVGLoader :/

Polygons not rendered

Hello,
It seems that in SVGs cannot be rendered properly (returns null SVGImage).
I am able to render a SVG properly.
First SVG with path

fi-rs-a
Second SVG with polygon

fi-ss-plus

I actually have no errors in my console.
Thanks :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.