SVG - reuse a line node with <def> and <use> - svg

My goal is to re-use a line node as follows:
<defs>
<desc>x1 and x2 values never change, would like to provide y1 and y2 in use</desc>
<line id="p" x1="5" x2="1019" stroke-width="1" stroke="#808080" opacity=".3"/>
</defs>
<use xlink:href="#p" y1="718.5" y2="718.5"/>
In learning SVG I thought any parameter provided in the use statement was passed to the template in the defs, but apparently not? According to W3 docs:
The ‘use’ element has optional attributes ‘x’, ‘y’, ‘width’ and ‘height’ which are used to map the graphical contents of the referenced element onto a rectangular region within the current coordinate system
However, 'use' is supposed to support "Any...graphical element...", line included. Well, line doesn't have x,y,width or height attributes; it has x1, y1, x2, y2.
Also this would preclude passing in all sorts of other attributes like stroke, stroke-width, etc.
Is the use statement really limited to just x,y,width, and height or is there another way to get attributes merged into the def template node?

Since line is neither an <svg> element nor a <symbol> element it is covered here:
In the generated content, the ‘use’ will be replaced by ‘g’, where all attributes from the ‘use’ element except for ‘x’, ‘y’, ‘width’, ‘height’ and ‘xlink:href’ are transferred to the generated ‘g’ element. An additional transformation translate(x,y) is appended to the end (i.e., right-side) of the ‘transform’ attribute on the generated ‘g’, where x and y represent the values of the ‘x’ and ‘y’ attributes on the ‘use’ element. The referenced object and its contents are deep-cloned into the generated tree.
So width and height are ignored and x and y become ways to translate the line. That's basically all you can do with it.

Related

How can I use this UTF-8 SVG string to get <svg>?

I am using domtoimage to try to turn my html div into <svg>. The function from domtoimage returns the string:
data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="288" height="1920"> .......... </svg>
I can set this string as the src of an <img>, but the other plugin I'm using (jsPDF) cannot use that, it needs <svg>.
I figured I could strip the beginning part off and add just the svg tag to the document but this results in a really odd svg with "%0A" everywhere, which I cannot strip from the string.
If this is your code; the problem is:
you are stuffing text into the append function which only accepts DOM nodes.
Only .innerHTML converts a string to HTML
If you feed the append function a string.. it will be displayed as a string.
https://developer.mozilla.org/en-US/docs/Web/API/Element/append
Note the documentation: DOMString objects are inserted as equivalent Text nodes.
Solution is to create an SVG DOM element
let svgElem = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgElem.innerHTML = mySvg;
$('body').append(svgElem);

SVG PATH : LineTo path commands Multiple parameters

I got a svg file in which i don't understand how works the multiple parameters given for specifics 'm' and 'v' commands into the 'd' sections for path.
<path d="m-5.1576 3.5189v0.022851h-0.022-0.022v-0.022851-0.021149h0.022 0.022v0.021149m0-1.2951h-0.022-0.022v-0.021149-0.022851h0.022 0.022v0.022851 0.021149m0.019-0.063h-0.0315-0.0315v0.7 0.7h0.0315 0.0315v-0.0096503-0.0093497h-0.0315-0.0315v-0.681-0.681h0.0315 0.0315v-0.0093497-0.0096503m-0.063 0v0.7 0.7-0.0096503-0.0093497-0.681-0.681-0.0093497-0.0096503m-0.187 1e-15 0.187-1e-15v0.016431 0.015569h-0.0935-0.0935v-0.015569-0.016431m0 1.3836v-0.015569h0.0935 0.0935v0.015569 0.016431h-0.0935-0.0935v-0.016431m0.215-1.3206h-6e-3 -6e-3v0.637 0.637h6e-3 6e-3v-0.637-0.637" fill="none" stroke="#000" stroke-width=".005"/>
m-0.187 1e-15 0.187-1e-15 got 4 parameters whereas 2 are expected: how can i operate ?
h-0.022-0.022 got 2 parameters whereas 1 is expected (should I add the 2 parameters?)
v0.7 0.7-0.0096503-0.0093497-0.681-0.681-0.0093497-0.0096503: same thing ?
Thanks
Per the SVG specification
Additional Move values are interpreted as L (or l) commands
Additional values for other commands are treated as another instance of that command. So in your case additional h or v commands.

Why am I failing to rotate a path around a given point in SVG

Let's consider this SVG file from Openclipart (link to raw SVG file). For reference, it looks like this:
I now want to rotate the hands so that I can make the clock show some arbitrary time.
I have determined that the hour hand is encoded by this path element:
<path
d="m 458.13588,295.06406 c 1.74675,-16.11195 25.92429,-46.33386 37.207,-59.62773 l -0.0945,-0.0895 c -12.66188,11.97753 -41.49863,37.74816 -57.33149,40.35684 -30.58445,5.03466 -23.84883,26.09555 -19.57494,34.86553 l -52.97792,55.87976 6.16814,5.91214 53.02794,-55.93477 c 9.10302,3.92158 30.23513,9.51278 33.57547,-21.36261 z"
id="path526"
inkscape:connector-curvature="0"
style="fill:url(#linearGradient4636);display:inline"
inkscape:transform-center-y="-65.845483"
sodipodi:nodetypes="cccccccccc"
inkscape:transform-center-x="-63.497113" />
I have also determined that the central circle where both hands cross is encoded by this ellipse element:
<ellipse
cx="150.233"
cy="151.011"
rx="8.0819998"
ry="8.125"
id="ellipse542"
sodipodi:cx="150.233"
sodipodi:cy="151.011"
sodipodi:rx="8.0819998"
sodipodi:ry="8.125"
style="fill:url(#radialGradient4393)"
d="m 158.315,151.011 c 0,4.48732 -3.61843,8.125 -8.082,8.125 -4.46356,0 -8.082,-3.63768 -8.082,-8.125 0,-4.48731 3.61844,-8.125 8.082,-8.125 4.46357,0 8.082,3.63769 8.082,8.125 z" />
Since this ellipse element has attributes cx="150.233" and cy="151.011" I reason that this ellipse's center is located at point (150.233, 151.011) and, with a reasonable accuracy, I can assume that both hands cross at this point and this is the exact point I should rotate the hands about.
So for starters let's try rotating the hour clock by, let's say, 10°. Having read the MDN documentation of the transform attribute I reason this can be done by adding the attribute transform="rotate(10 150.233 151.011)" to the aforementioned path element, obtaining the following code:
<path
d="m 458.13588,295.06406 c 1.74675,-16.11195 25.92429,-46.33386 37.207,-59.62773 l -0.0945,-0.0895 c -12.66188,11.97753 -41.49863,37.74816 -57.33149,40.35684 -30.58445,5.03466 -23.84883,26.09555 -19.57494,34.86553 l -52.97792,55.87976 6.16814,5.91214 53.02794,-55.93477 c 9.10302,3.92158 30.23513,9.51278 33.57547,-21.36261 z"
id="path526"
inkscape:connector-curvature="0"
style="fill:url(#linearGradient4636);display:inline"
inkscape:transform-center-y="-65.845483"
sodipodi:nodetypes="cccccccccc"
inkscape:transform-center-x="-63.497113"
transform="rotate(10 150.233 151.011)" />
Unfortunately, the results prove my assumption wrong:
What am I failing to understand and how to rotate this hand?
SVG works with the notion of a "userspace" for coordinates. If an element has a transform attribute, the coordinates expressed in its attributes refer to a local coordinate system, the userspace, that is transformed from that of its parent element, just as the transform attribute describes. Consequently it also differs from the coordinate system of the root <svg> element.
The same happens when a parent of an element has a transform attribute: the userpace coordinate system derives from the parent and differs from that of the root. (It gets more complicated with elements "establishing a viewport", but lets skip this here.)
What you failed to notice is that the ellipse you identified for the center has a parent <g> element with an attribute transform="scale(2.4444516,2.4444516)" If you multiply the cx and cy values with these scaling factors, you get
cx = 367.23729
cy = 369.13908
That is a pretty good fit with the size of the SVG as a whole. It has attributes width="734.47461" height="738.27081", which, if you halve them, differ only insignificantly from the values for the ellipse.
Having checked that the coordinate systems of the hands elements or their parents are not transformed, you can now set the rotation as
transform="rotate(10 367.23729 369.13908)"
If you continue to work with SVGs, reading the chapter about coordinate systems and transformations in the spec is certainly a good idea.

Why am I getting an array of NANs when trying to plot a map with D3.js?

I am tring to plot a map with d3.js using GeoJSON, but the paths generated look like this:
<path d="MNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,‌​NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,N‌​aNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,Na‌​NLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaN‌​LNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNL‌​NaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLN‌​aN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNZ">
the code and data are in this Gist:
https://gist.github.com/4157853
I can load the data just fine on QGIS.
Does any one know what is causing this?
The way you have specified the offset in the Mercator projection doesn't seem right. The projection.translate method expects a two element array:
https://github.com/mbostock/d3/wiki/Geo-Projections#wiki-mercator_translate
So instead of:
proj.translate(-43.8,-23.2).scale(10);
you would need to say:
proj.translate([-43.8,-23.2]).scale(10);
-- edit --
See source of projection.translate: https://github.com/mbostock/d3/blob/3.0/src/geo/projection.js#L139
projection.translate = function(_) {
if (!arguments.length) return [x, y];
x = +_[0];
y = +_[1];
return reset();
};
If the argument _ is not an array then +_[0] will return a NaN and therefore the x and y will become NaNs. (This is because trying to get one element from a number (e.g. 213[0]) returns undefined and casting undefined to a number (e.g. +undefined) yields NaN.)
If the code you posted in the gist is everything you're trying to run, then the data you show in data.json is not being loaded anywhere. Anyway, your draw function is acting on the data defined by the variable map (line 16), which refers to a simulation variable which isn't set anywhere. And even if it did, line 34 then refers to a features property of the object passed in as json, which map does not have.
In summary, you need to pass the JSON you posted in the gist to your draw function. Then it might well work. If you don't pass in valid data to the d3 SVG helpers, you'll get a bunch of NaN out.

XSD: how to define type with (1) attributes, (2) nested elements and (3) plain text content?

Is it possible to define such element as HTML's "font" tag, which can contain all three types of subelements?
For example, I can write
<font size=3>This is <b>the</b> text</font>
How can I define is XSD, that font can contain:
1) attribute size
2) nested element B
3) text arount it
?
Thanks
Define the type as Content Type Mixed.

Resources