4
votes

I need scalable schema in SVG. But some elements, like arrows, should be in the same size on the schema regardless of the schema's scale.
I'm implementing schema scalability via SVG transform attribute and arrows via SVG markers.
But I'm getting trouble: when transform=scale(s) is applied to shapes then their markers are scales as well.

Is there any way in SVG to apply marker to scaled shape so that marker is not scaled according to shape's transformation?
Or am I using the wrong approach for that?

See example here:

<svg id="svg-root" class="drawing" width="100%" height="500" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <marker id="myMarker" refX="6" refY="6" markerWidth="12" markerHeight="12" stroke-width="1" stroke="blue" orient="auto" fill="none" markerUnits="strokeWidth">
            <circle cx="6" cy="6" r="5" />
        </marker>
    </defs>
    <g transform="scale(2)">
        <line id="line1" x1="20" y1="50" x2="200" y2="50" stroke="green" stroke-width="1" marker-start="url(#myMarker)" vector-effect="non-scaling-stroke"/>
    </g>
    <g transform="scale(3)">
        <line id="line2" x1="20" y1="50" x2="200" y2="50" stroke="green" stroke-width="1" marker-start="url(#myMarker)" vector-effect="non-scaling-stroke"/>
    </g>
</svg>

Both lines line1 and line2 should have circles with radius="6" and circles stroke width="1".
For now radiuses are "12" and "18". Widths are "2" and "3" accordingly. That is not suitable.

I'm trying to apply vector-effect="non-scaling-stroke" to shapes. Then shapes stroke width is not scaled. And I'm applying markerUnits="strokeWidth" to marker.
But that doesn't help.

The only one workaround, I can imagine for a moment, is to stop usage transform for schema scaling. In that case shape's coordinates are to be recalculated manually after schema scale is updated. That doesn't look good, actually.

1
Sounds like you should file a few bugreports.Erik Dahlström
Yes, it probaly does. But, unfortunately, I can't find in W3C Recommendation anything what specifies that shape's vector-effect="non-scaling-stroke" shold (or should not) be considered when marker with markerUnits="strokeWidth" is being instantiated for particular shape. Is it some kind of unspecified behavior?Alexander Stepaniuk
Did you find a solution to this? I'm up against the same issue. I will probably keep using transform, and then apply an inverse transform to the shapes I want to maintain, which at least means that positional units within the SVG will be what I want them to be... but it would be nice if there was a way to have non-scaling markers natively.pancake
@pancake. Nope, I didn't. I use the same solution, you've described: marker_scale = 1/schema_scale.Alexander Stepaniuk

1 Answers

0
votes

From here:

To avoid the automatic scaling of markers to fit the stroke width of the path using it, set the markerUnits attribute to userSpaceOnUse. That way the markers will keep their size regardless of the stroke width of the path using it.

For example:

<marker id="myMarker" markerUnits="userSpaceOnUse">
  ...
</marker>