How to use RaphaelJS to draw an existing vector image - vector-graphics

I am starting to learn RaphaelJS, but it does seem to be a steep learning curve as I am not very versed in javascript. But it seems like such a good library that I am willing to put the time in to learning it.
What I would like to know is:
How can one use an existing vector image in RaphaelJS
(If I download a "vector" image can I tell RaphaelJS to draw the coordinates?)
Is there a way to convert an image (jpg, gif or whatever) into a vector graphic that RaphaelJS can use.
My confusion is that on the sample pages the images are drawn in coordinates which makes sense to me. However, if a download a vector image from the net, where are the coordinates?
I am aiming to make images on my web page that are clickable, much like the RaphaelJS example of the map of Australia that has a hover event on it.

The easiest vector image format to read is svg since svg is XML and XML is just plain text.
Convert your vector image to svg using something like Illustrator or Inkscape and then open it in your text editor. You'll find that most of the shapes like <path /> and <rect /> have a direct equivalence in Raphael. For example, the <path /> object defines path coordinates in its d attribute and it has the same syntax as paths in Raphael:
<path
style="fill:none;stroke:#000000;stroke-width:12"
d="m 116.6,832.4 c 0,0 5.8,85.5 127.6,87.0 121.8,1.4 137.7,-79.7244"
/>
You can convert that to Raphael's:
var path = paper.path(
"m 116.6,832.4 c 0,0 5.8,85.5 127.6,87.0 121.8,1.4 137.7,-79.7244"
);
path.attr({fill:'none',stroke:'#000000';'stroke-width':12});
Take note though of any transformations applied to objects and groups (the <g /> element), you'll have to repeat them in Raphael. Say for example you see the following:
<path
style="fill:none;stroke:#000000;stroke-width:12"
d="m 116.6,832.4 c 0,0 5.8,85.5 127.6,87.0 121.8,1.4 137.7,-79.7244"
transform="translate(-124,370)"
/>
then after creating the path in Raphael you'll need to apply the translate():
path.translate(-124,370);
You can probably write a script to convert svg files to Raphael syntax or load the svg file in the browser as text and use the browser's XML DOM parser to process it and draw it using Raphael.

Related

How can you use a symbol from SVG defs.svg as background image in CSS?

I'm trying to use a symbol from my defs.svg as a background image in CSS, as opposed to a direct path to an individual SVG file.
So instead of:
background: url(spoon.svg);
I want to do something like this:
background: url(defs.svg#spoon);
With #spoon being a symbol in defs.svg with id="spoon". Unfortunately, this isn't working for me. Has anyone come across a solution that doesn't involve custom JS/etc?
You'd need to define view and use tags inside your defs.svg so CSS would know where to look and what to show.
So, for example, say you have inside your SVG a symbol defined as this:
<symbol id="poop" viewBox="0 0 100 100">
<!-- Your shapes here -->
</symbol>
And before closing the svg tag, you must add the view and use defining tags:
<view id="poop-view" viewBox="0 0 100 100" /><!-- This ID used here is what you'll use in your CSS! -->
<use xlink:href="poop" width="100" height="100" x="0" y="0"></use>
Note that at this point, you can open your raw SVG file in a browser and it will show your drawing - before it showed blank!
And now you can set your SVG symbol in your CSS:
div{background-image:url("defs.svg#poop-view")} /* Remember, it's the ID used on your <view> def! */
Also, be sure your SVG includes a xmlns:xlink namespace on the opening tag, or it won't be supposed to work.
Disclaimer: I'm trying to use this setup at work hosting the SVG file on a server on my university, but for some reason this doesn't work (even SVG files won't show if <?xml>and <!DOCTYPE> tags are missing on the SVG), so be sure to check the sanity of your SVG file.
Find more about this on Jennifer Hiller's codepen blog.

Displaying bar chart with in the Map

I'm using Geo chart to display a map. On page load it gets data from SQLServer and based on logic shows different colors for states inside the map as in the image below:
For example if we take example of deaths caused in India and the reason for it.
Suppose say X state has highest percentage of deaths. So it's marked with highest color. This is already obtained.
Requirement:
Now the cause of death can be many say suicide, natural, accident's e.t.c. I can get these data too from Database. I want to put a Bar chart within this map say much like the one in the image below:
Is there a way I can do it in geo chart or using any other method? Thanks in advance
Well, this is simple.
You need a SVG map of the regions you want to show (google it).
Then you can create SVG rectangles (the different color bars in the chart) on your SVG map.
You can use inkScape to prepare the map, and create bounding rectangles for your charts.
Since SVG is a simple XML file, this you can do entirely in code, or even javaScript, if you fetch the data via AJAX.
Drawing 3 rectangles goes like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
id="svg2"
viewBox="0 0 744.09448819 1052.3622047"
height="297mm"
width="210mm">
<defs id="defs4" />
<g id="charts">
<rect
y="98.076492"
x="82.857178"
height="465.71429"
width="125.71429"
id="rect4140"
style="opacity:0.72123892;fill:#d65757;fill-opacity:0.40211636;stroke:none;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
y="99.505066"
x="242.85713"
height="465.71429"
width="125.71429"
id="rect4140-2"
style="opacity:0.72123892;fill:#6dd657;fill-opacity:0.40211636;stroke:none;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
y="93.790779"
x="399.99997"
height="465.71429"
width="125.71429"
id="rect4140-9"
style="opacity:0.72123892;fill:#5e76ff;fill-opacity:0.40211636;stroke:none;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>
If you don't want to do all the SVG coding yourself, you can use a library, like d3.js.
Here's an advanced example:
http://bl.ocks.org/emeeks/4531633
If you do it all on the server, you can convert the SVG into a PNG, and display this to the users (in case they still use IE8).
See here for more information:
Converting SVG to PNG using C#

How can I prepare an Inkscape SVG file for responsive web design?

I've been doing a tutorial on Treehouse on responsive web design. At this point in the tutorial we are asked to convert an image to an svg so it can scale fully responsively.
Rather than use Adobe Illustrator, which I don't own, I used the freeware Inkscape. Once the image is converted we are asked to open the image in a text editor and remove the height and width requirements from the svg declaration and add the object selector to our max width rule to our style css:
img, object {
max-width: 100%;
}
However, after removing height and width the image is not responsive but instead oddly clipped like so:
Does anyone know what error I have made? Or what I should have removed?
Sorry if the question has been asked before, I can't find it.
edit1, the code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2985"
version="1.1"
inkscape:version="0.48.4 r9939"
width="319"
height="177"
sodipodi:docname="logo.gif">
<metadata
id="metadata2991">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs2989" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview2987"
showgrid="false"
inkscape:zoom="0.94984326"
inkscape:cx="159.5"
inkscape:cy="88.5"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg2985" />
<image
width="319"
height="177"
xlink:href="
It is the "height" and "width" in the first SVG tag that I have removed.
Inkscape now provides an option to enable viewbox if you save the file as "optimized svg".
Very handy!
The fact that you have just put a raster image in your SVG isn't the actual reason for what you are seeing.
All it means is that when the scaling of the SVG works properly (see below), you won't see the benefits of using vector artwork. When you scale up vector artwork, you don't get the "jaggies" (blockiness) that you get when scaling up bitmaps. If your SVG just contains a bitmap, it is pretty much the same as just using the bitmap.
The actual problem here is that Inkscape doesn't include a viewBox attribute in the SVGs it saves.
When you remove the "width" and "height" attributes, they default to "100%". Which tells the browser to scale the SVG to fit the parent container. Unfortunately for this scaling to work, the browser needs to know what the dimensions of the SVG content are. That is what the viewBox attribute is for.
Illustrator adds the viewBox attribute, Inkscape does not.
To see what I mean, add the following to your <svg> tag after removing width and height:
viewBox="0 0 319 177"
You should find that your image is no longer clipped, and will resize when the page is resized.
As you can read it here ( and for completing qed's answer):
Select the object(s) to export
Open the document properties window ( Ctrl+Shift+D)
Select "Resize page to drawing or selection"
File > Save As Copy...
Select Optimized SVG as the format
You've done something wrong if you're "converting" raster to vector graphics. Not having used Inkscape, I can't say, but at least according to Wikipedia it's not capable of performing conversions.
You haven't converted anything, your image is in Graphics Interchange Format!
To see what a "real" SVG file looks like, open up the example from the wiki page.

Creating a heavily segmented ring/circle

I need to recreate the above image using HTML, CSS, SVG, or some other similar means. It'll be solely for visual purposes, not needing any type of actual functionality. Preferably the non-white parts would be transparent so that I could easily change the background color and have other elements within the center
The reason why I cannot use a transparent image is because I need to be able to easily scale it and possibly change the color of the bars with little trouble
I know how to do approximately the same thing using this CSS approach, but that would require a separate element for every single segment which I do not want.
The other option I thought up would be to create a doughnut graph in Raphael.js with a whole lot pieces in it, but that also seems like a lot of work for the simple outcome that I want
So before I start a long and complex process using one of the methods I mentioned, is there a simpler, more optimized way to create the effect I desire? I'm not asking for the finished output, merely insight as to what methods are optimal to create this type of effect
Edit
The optimal solution would be a pure CSS approach that does not require a separate element for each segment. Otherwise the answers provided are great solutions!
You could just do this with stroke-dasharray:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="30" stroke-dasharray="0.628" stroke-width="2"
fill="none" stroke="black"/>
</svg>
Example: http://jsfiddle.net/75WsM/
Easy loop should be enough.
<div id="R">
</div>
<script>
var createCircle = function(step,posX,posY,radius){
var paper = Raphael("R",500,500);
for(var i = 0; i < 360; i=i+step){
var currentRect = paper.rect(posX+radius,posY, 2,20);
currentRect.attr({'fill':'#ffffff',stroke:0});
currentRect.rotate(i,posX+radius,posY + radius);
}
}
createCircle(3,50,50,94);
</script>
http://jsfiddle.net/mBKP4/2/

Write an equivalent <svg> for a <image xlink:href="something.svg" />

Feel free to ask for more context if you're wondering why this is necessary, or want to suggest a better way to solve the bigger problem. (It involves laying out a bunch of building floor plans onto a campus map and finding the absolute location of certain things that are in those building maps; more detail was bogging the question down.)
The short version is that I want to take an SVG file that has <image xlink:href="something.svg" /> references and merge it into one big file with each referenced SVG being embedded with an <svg> and inline SVG XML content.
So, my top-level source file (composed in Inkscape) looks like this:
<image xlink:href="floorplans/bldg1.svg"
width="165.52684" height="107.10559" y="-1937.7657"
x="2507.1565" transform="matrix(0,1,-1,0,0,0)" />
And my attempt at a merged version to inline all the vector data:
<svg x="2507.1565" y="-1937.7657" width="165.52684" height="107.10559"
transform="matrix(0,1,-1,0,0,0)" viewBox="0 0 1224 792">
<g id="surface0">
<path style="fill:none;stroke-width:0.72;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(0%,0%,0%);...
So, basically I'm using a script to replace <image> with <svg> and paste in the contents of the root <svg> of "floorplans/bldg1.svg". (Copying attributes from the <image> to the <svg>, and copying the viewBox attribute from the original <svg> to the new one.)
This technique worked for things that aren't rotated, but Chrome seems to be saying this particular element is off the top of the viewport. I'm new to SVG, but I'm thinking the order of the transformations isn't the same on the <svg> as it is on the <image>. Did I make a dumb mistake I'm not spotting, or is there more involved in converting an <image xlink:href="something.svg" transform=... /> to an <svg> with inline XML?
Thanks.
The transform attribute doesn't apply to the <svg> element according to the SVG specification. You can put the transform that was on the <image> element on the <g> element either outside or inside the <svg> instead.
The reason for transform behaving this way is that the <svg> element sets up the coordinate system, and the transform depends on that (a question that would arise if it did apply is "should the transform be interpreted in the coordinate-space before or after the svg coordinate system is setup?")

Resources