How to draw a arc in vml - svg

The following path draws an arc in ie 8 + and firefox. But in vml i cant able to draw the arc. Is there any way to draw the arc in vml without using raphael.
d="M 400 315 A 26 26 0 0 1 423 400 L 400 342 z"
Thanks in advance

The path posted seems like a SVG path. Similarly one can also provide paths to draw sahpes in VML. Try reading this: http://www.w3.org/TR/NOTE-VML.
ex: A sample VML path for an arc would be similar to this: path="m21600,qx,10800,21600,21600xe" But one would also have to define formulas for the rendering application to interpret it. again I would suggest to read the above link to understand VML formulas.

Related

Explanation of SVG path?

I have an SVG path that I'm trying to dynamically create, but the resources I've found on SVG paths don't describe that path I have.
This is the path:
m41.5 1.5v15l-40 10v100h60v-100l-10-10v-15z
I don't even understand the start of it - the m41.6; m moves the pen to a coordinate relative to the last known position. I assume this is the origin? but everywhere I've found says that the syntax is m x,y. If I supply m41.6,0 instead, the svg just disappears - opening in Inkscape doesn't show it either.
I need a step-by-step explanation please of each term.
The full SVG is:
<svg id="svg11" version="1.1" viewBox="0 0 63 128" xmlns="http://www.w3.org/2000/svg">
<path d="m41.5 1.5v15l-40 10v100h60v-100l-10-10v-15z" fill="#ffd42a"/>
</svg>
the resources I've found on SVG paths don't describe that path I have.
Then I guess you didn't consider reading the SVG specification? :)
Try reading the Paths section of the SVG specification . It's all explained quite clearly there.
Explanation
m41.5 1.5
Move to (41.5, 1.5). m is a relative move normally, but the spec says:
If a relative moveto (m) appears as the first element of the path, then it is treated as a pair of absolute coordinates.
Coordinates can be separated by a comma, whitespace, both, or even neither. For example, M1.5.5 is a valid path command, since a coord can't have more than one decimal point, and leading zeros are optional.
M 1.5,0.5, M1.5 0.5, M1.5, 0.5, M 1.5 .5, and M1.5.5 are all equivalent.
v15
Draw a line vertically (downward) by 15 units
l-40 10
Draw a line left by 40 and down by 10 units.
v100
Draw a line down by 100 units
h60
Draw a line right by 60 units
v-100
Draw a line upwards by 100 units
l-10-10
Draw a line diagonally up and left by (10,10)
v-15
Draw a line vertically upwards by 15 units
z
Close the path (ie back to 41.5,1.5)
The path can be rewritten as:
m41.5,1.5 v15 l-40,10 v100 h60 v-100 l-10,-10 v-15 z
or
m41.5 1.5 v15 l-40 10 v100 h60 v-100 l-10 -10 v-15 z
This better separates the individual pen movements which I was confused by when they were all merged together in the original version.

How do SVG/EPS (vectors) clip a path by another path?

I try to understand how SVG programs (like browsers) draw a shape by the given paths. I struggle to understand how a path is drawn and one clips part of a shape.
For example, consider the letter Å, and A with a top ring. The SVG code is like
<svg viewBox="0 0 1800 1800" xmlns="http://www.w3.org/2000/svg">
<path
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M426 822q0 -47 -24 -71.5t-80 -24.5q-104 0 -104 96q0 46 25.5 71t78.5 25q56 0 80 -25t24 -71z
M319 515h-1l-85 -264h169z
M374 822q0 51 -52 51q-50 0 -50 -51q0 -49 50 -49q52 0 52 49z
" />
</svg>
JSFIDDLE
First line: draws the body of an A.
Second line: draws a top circle.
Third line: clips a triangle from the first line.
Fourth line: clips a small circle from the second line.
My question is: how do SVG programs understand to draw a shape by the second line, but clip a shape from an existing shape?
Obviously the answer is: if the path is within another path, it clips otherwise it draws.
There are two reasons that I think this not the whole picture:
It needs huge calculations to find if a path is within another path.
The order of lines is not important (the clipping path does not necessarily come after the drawing path).
This is, of course, not limited to SVG, as other vector formats such as EPS does the same.
To add a pragmatic perspective, please read the question as: how can we parse (in any programming language) the above d element to find out which path is drawing (black) and which is clipping (white) out of the four paths given in the above SVG?
Broadly speaking, you don't parse the paths at all.
Instead you 'scan convert' each path to a series of rectangles, at the current resolution. Each reactangle may be as little as one pixel high, and there may be more than one rectangle at a given y value.
Do this for both the path to be filled or stroked and the path to apply as a clip, then intersect the series of rectangles. This is, obviously, a much simpler task. Then fill the rectangles.
This does, of course, produce a result which is only correct at a given resolution. Change the resolution and you get a different series of rectangles. However it produces the correct output at a decent speed. Intersecting two arbitrary paths to produce a new arbitrary path is obviously a much more complex task, and for the purpose of drawing the result, not one we need to perform.
In the next examples I'm using the path for the letter A in your example.
In the first svg element the letter A is drawn from right to left while the hole of is drawn in the opposite dirrection: you get the "clipping".
In the second example I've reversed the part that is drawing the hole. Now this part is drawn in the same direction as the main part of the letter A. Now you won't get the "clipping"
In the third example I'm using the reversed path as before but I'm adding fill-rule="evenodd" Now the hole is clipped since the "fill-rule attribute is a presentation attribute defining the algorithm to use to determine the inside part of a shape".
svg{width:30%;border:solid}
<svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
<path
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M319 515h-1l-85 -264h169z
" />
</svg>
<svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
<path
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M319,515L402,251L233,251L318,515L319,515z
" />
</svg>
<svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M319,515L402,251L233,251L318,515L319,515z
" />
</svg>
Whether a given path is "filled" or "clipped" depends on the "winding" algorithm being used, which is determined by the SVG fill-rule property, which defaults to nonzero.
For the nonzero mode:
This rule determines the "insideness" of a point on the canvas by drawing a ray from that point to infinity in any direction and then examining the places where a segment of the shape crosses the ray. Starting with a count of zero, add one each time a path segment crosses the ray from left to right and subtract one each time a path segment crosses the ray from right to left. After counting the crossings, if the result is zero then the point is outside the path. Otherwise, it is inside. The following drawing illustrates the nonzero rule:
The nonzero default is why you'll often hear that rotational direction is important, because clockwise creates fills and counterclockwise creates clips. (This is how it works in GeoJSON as well.)
For the evenodd mode:
This rule determines the "insideness" of a point on the canvas by drawing a ray from that point to infinity in any direction and counting the number of path segments from the given shape that the ray crosses. If this number is odd, the point is inside; if even, the point is outside. The following drawing illustrates the evenodd rule:
The evenodd mode is a simpler to understand for basic shapes with holes, but not as flexible for clipping arbitrary chunks out that may not be completely isolated as islands.
Here's a great article called Understanding the SVG fill-rule Property that explains it further with code examples.

How can I draw this kind of SVG

I am working on someone else's code and there's no way of contacting them, and here's my issue:
<g
ng-attr-transform="translate({{node.width-18}}, 0) scale(0.6)"
ng-mouseover="showArrowMenuTooltip($event, node);"
ng-click="showArrowMenuTooltip($event, node);"
ng-mouseleave="hideArrowMenuTooltip($event);"
ng-attr-class="{{'flowchart-arrow-show-'+node.activity.act_task +' flowchart-arrow-set'}}">
<!--Circle-->
<path
class="flowchart-arrow-circle"
d="M16,1.466C7.973,1.466,1.466,7.973,1.466,16c0,8.027,6.507,14.534,14.534,14.534c8.027,0,14.534-6.507,14.534-14.534C30.534,7.973,24.027,1.466,16,1.466z"
></path>
<!--Arrow-->
<path
class="flowchart-arrow"
d="M13.665,25.725l-3.536-3.539l6.187-6.187l-6.187-6.187l3.536-3.536l9.724,9.723L13.665,25.725z"
></path>
</g>
That's some code inside an SVG tag that draws an arrow with a circle around it, my question is, suppose I want to draw an explanation mark, how would I do that?
I'm sure the d="M13... part is not written manually, yet i can't find online any documentation or tool that would help.
What you're after is called a 'Path' element.
Check this documentation out:
https://www.w3.org/TR/SVG/paths.html#PathData
A path is defined by including a ‘path’ element which contains a
d="(path data)" attribute, where the ‘d’ attribute contains the
moveto, line, curve (both cubic and quadratic Béziers), arc and
closepath instructions.
Example triangle01 specifies a path in the shape of a triangle. (The M
indicates a moveto, the Ls indicate linetos, and the z indicates a
closepath).

SVG path element rendered inconsistently between different versions of Chrome

Good morning,
I've created a chord diagram using D3. But I've encountered a problem with the output that causes paths to be rendered poorly in some versions of Chrome.
Here's an example of a problematic path generated by D3:
<svg height="1000px" width="1000px">
<g transform="translate(400,400)">
<path d="M329.2336690603744,-46.49130195040491A332.5,332.5 0 0,1 329.2336694247276,-46.491299370194035Q 0,0 -25.421977592957564,-331.5267305290222A332.5,332.5 0 0,1 -25.42197499477598,-331.5267307282548Q 0,0 329.2336690603744,-46.49130195040491Z" class="chord" fill="#c8cfdc" stroke-width="1px" stroke="#000000"></path>
</g>
</svg>
In most browsers, I see a single arc, which is what I'd expect. But on my dev machine running Chrome version 36.0.1985.125 on Ubuntu 14.04 I see the arc on top of a big gray circle. The big circle kind of ruins the rest of the diagram.
Is there anything particularly problematic about this path's d attribute that could cause it to get painted inconsistently by the browser?
Many thanks.
Here's an image of what I'm seeing when it goes wrong:
Expanding on #jshanley's comment, the breakdown of the path data is as follows (long decimals trimmed for readability):
d="M 329,-46
//Move the pen to the starting point (329,-46)
A 332.5,332.5 0 0,1 329,-46
//draw a circular arc (radius in both directions 332.5 with 0 degrees rotation),
//in a clockwise direction taking the shortest route (flags 0,1)
//ending at point (329,-46).
//In a normal chord diagram, this is the edge of the chord, which follows the
//arc of the large circle.
//However, in this case the start and end points are the same
//and nothing should be drawn
Q 0,0 -25,-331
//draw a quadratic curve to point (-25, -331) using control point (0,0)
//this is the curve you see, connecting different points on the large circle
A 332.5,332.5 0 0,1 -25,-331
//another arc with the same start and end points, which shouldn't be drawn
Q 0,0 329,-46
//Another quadratic curve, the exact same shape as the previous one
//but going back in the opposite direction;
//this is what causes the curve to look like a single line, no fill
Z"
//close the shape
This is a definite bug in the Ubuntu Chrome version you're using. Path arc segments that start and end at the same point are supposed to be skipped, regardless of what the flag settings are, because they are not clearly defined. Even if the browser wasn't automatically skipping it, you'd think they would still respect the "short arc" flag and draw a zero-length arc.
If support for that particular browser version is important, you'll need to add in an error-check in your code, so that you don't draw the chords at all when they have zero width on both ends, or manually edit the path data to remove the empty arc commands.

get actual height of svg bezier curved path

This is more of a bezier question than an SVG question, but here goes...
given the following code:
<svg xmlns="http://www.w3.org/2000/svg" baseProfile="full" viewBox="0 0 400 400" baseProfile="full">
<path d="M0,0 C20,400 30,200 50,100" fill="#FF0000" stroke="#000000"/>
</svg>
Using [path].getBBox() returns me a height of 400, since the 1st control point of the curve is at 400 y, and this makes sense(ish).
But what I really need is the actual height of the object as rendered, not the box that contains all points used in its drawing.
I'm assuming I'm just going to have to figure it out myself? And if that's the case, does anybody have any suggestions for where to go to find such mathy things? I did some googling, but I'm not really coming up with anything (it's very possible I'm not phrasing the question correctly, some help in that regard would be super nice as well).
You are doing it right, it's a WebKit bug. If you try getBBox on Firefox or even Internet Explorer, it's fine.
If you need a workaround, give a look at the implementation done for SVG-edit.

Resources