Moving SVG objects using Javascript and CSS - javascript

I am currently working on a animated SVG, this includes elements being rotated, moving, etc.
I am facing the problem that I am unable to move certain elements that use a path to get its position.
My existing Javascript code moves some elements using the x attribute, this is working, but still leaves the elements that work with the paths.
Example SVG object:
<path id="XMLID_1418_" d="m1247.8 933c0 17.3-14 31.4-31.4 31.4-17.3 0-31.4-14-31.4-31.4h62.8z" class="st103"></path>
Margins, position or adding a x attribute doesnt move it, how can I do this?

You could wrap the element in a 'g' element and translate that object to move the whole path.
<g transform="translate(x,y)"></g>

Related

How to get element using startPosition and endPosition by JavaScript

I have a rectangle that is drawn using canvas. I know its startPosition(x: 731, y: 13) and endPosition(x: 768, y: 113). Can I get this element using JavaScript?
Here I got a JavaScript function document.elementFromPoint(x, y), but it doesn't serve my purpose, because it doesn't accept start and end position.
Can anybody give me idea of how can I retrieve my HTML rectangle element?
You can't "get" elements from a canvas as you can with dom elements, as they aren't actually elements. The canvas just stores the pixel data rather than the individual objects that make up the image (eg lines and rectangles). Source.
If you're set on using the canvas, the typical method is to clear the parts being updated and re-draw anything being changed. You might store the canvas "elements" as a series of points which you reference when you redraw
Can anybody give me idea of how can I retrieve my HTML rectangle element?
You can't, because it's not an element in the first place. Drawing in the canvas doesn't create any elements, it just changes the pixels in the canvas buffer.
If you want to draw shapes using JavaScript that you can later modify, I would suggest using the DOM with SVG.

How can I add a sub svg tag in a raphael.js document?

I'm using Raphael.js to produce an SVG drawing from Javascript (actually Coffeescript)
However, I'd like to be able to include subdrawings, automatically scaled, by putting them inside a second <svg> tag nested inside the first. Unfortunately the Raphael Paper object which allows me to add rects and paths etc. doesn't have an option for adding svgs.
I've tried to add the tag directly to the DOM in javascript with the following code :
res = document.createElement("svg")
res.setAttribute("x",x)
res.setAttribute("y",y)
res.setAttribute("width",width)
res.setAttribute("height",height)
res.setAttribute("viewBox","0 0 100 100")
res.innerHTML = someInnerSVG
#paper.canvas.appendChild(res)
This seems to update the DOM as expected, adding my new SVG tag as a child of the main outer SVG. However, nothing in this inner actually appears on the screen. (My inner SVG path is scaled within 0 0 100 100 so is within the viewBox.)
The rest of the drawing in the outer SVG, as produced by Raphael, is visible. But nothing of the inner one is.
Should what I'm trying be possible? Any idea what I'm doing wrong?
You should place these sub elements into a Raphael set. From there, you will be able to apply transformations to the set. To transform the set, you would call the transform() method and use the s attribute:
set.transform('s[sx],[sy]');
Where sx is the horizontal scale amount and sy is the vertical scale amount. Remove the brackets when you insert the numbers.
Please refer to the documentation here: http://raphaeljs.com/reference.html#Element.transform
The methods for elements apply to sets because sets are pseudo elements.

Is it possible to have layered svg elements that interact with each other in d3?

I have a bar graph that is basically a navigational element, so I need easy predictable rollover behavior over the bars. Essentially I need to make sure that the small bars are as easily clicked on as the big ones, so I've made the entire column a clickable rollover.
Here is an example of the behavior I am referring to:
screenshot http://img6.imageshack.us/img6/6674/screengraph.png
I'd tried to do this with d3 and svg, but found that it was difficult to manage the z-indexes between svg elements and divs (or svg elements and other svg elements, honestly I forget the exact nature of where this was a sticking point). But I remember concluding that the only effective way to make what I was looking for happen was to have each column be 3 separate svg elements, essentially a top background, the bar, and then a bottom background, and to manually fire all 3 items to show the rollover change whenever one of them is hovered over.
I eventually just ditched svg and ended up using all divs just using d3 for the scale methods and drawing everything by hand using knockout.js templates. But now I'm looking at 200 lines of refactored javascript and I'm wondering if perhaps d3 would have given me a cleaner solution. Was I missing anything in d3 that could have accomplished what I am looking for easily?
Good on you for making the columns easily hoverable! The technique I would use for this is an invisible overlay with pointer-events: all, and optionally assigning the mouseover listener to a parent svg:g element rather than one of the rects.
The structure for each bar would look like this:
<g class="bar" transform="translate(0,…)">
<rect class="green"></rect>
<rect class="overlay"></rect>
</g>
(You probably have other things you might want to add, like the highlighted "14" in your screenshot, which you implement as another rect with rounded corners and a text element.)
The overlay rect is the full-height of the chart (70px, in your example). It has the following style:
.overlay {
fill: none;
pointer-events: all;
}
The green rect is just the height of the bar, and offset vertically so the bottom of the bar is at y=0. Same deal for the red negative rects.
In a nutshell, the invisible rect with pointer-events all receives all of the pointer-events for that bar. So you can use :hover styles on the parent g elements, say tweaking the bar color on hover:
.bar:hover .green {
fill: lightgreen;
}
Likewise, you can register "mouseover" and "mouseout" events on the parent g element, or the overlay rect.

Drawing lines between elements

How can I draw a line between every h2 element on my HTML page so that I can receive the effect in the picture below? Initially, I would presume you would go about this by working out the size of the line required in-between the divs (divs are separated by the 1px horizontal line) + the distance between each of the h2s, but i'm not entirely sure how one could work out this distance.
You can try something like:
a) find the position w.r.t document (i.e. by calling $(element).offset()) of the 2 elements you want to connect, call the positions p1 and p2
b) Append an absolutely positioned canvas to the body with a z-index to ensure it is displayed on top of everything else.
c) Draw a line between p1 and p2 on the canvas
This is assuming the elements can be anywhere on screen. If the line you need to draw is assured to be always horizontal or vertical, it can probably be done in a simpler manner.
Just use offset() method. You can easily find the distance between elements using it.

How to write on polygons that are in turn drawn in svg element?

I have a "map" that is a set of polygons drawn by JavaScript on svg element. Is there any way to draw text inside (on top of) polygon that is drawn inside of svg element?
Should I try to draw text on the svg element on the same coordinates were polygon is drawn?
Thank you!
P.S. either clean JavaScript or jquery both will help.
Yes. The way of doing that is to simply add a <text> element using its x and y attributes to position it where you want on a given polygon (using whichever same JS way that you're using to add polygons, just creating a text element instead of a polygon element).
Be sure to put the text element after the polygon in the tree so that it paints on top of it.
Second option is to draw polygons and texts:
a) at 0,0 for top left corner
b) -x,-y for center
And then translate each polygon/text where you want them to be.

Categories

Resources