How to make a svg element (e.g. rectangle) scrollIntoView? - javascript

I have a svg in graph panel. All nodes in the svg are listed in another panel. I hope that by clicking the node in node list, svg can scroll to that node. Each node is a rectangle. But I found that only the upper border is in view, while the rest part of the node are still out of the view. Is there any way to fix this problem? (either Javascript or Extjs)
This is my code:
function selectRectangle(Id){
var ele = Ext.get(Id);
ele.scrollIntoView(Ext.get('graph-panel-body'), true);}

By whatever reason scrollIntoView seems not to work for SVG elements. This is what I do
suppose the svg is in a
<div id="container">
<svg ...>
...
<path id> ...</path>
</svg>
</div>
then suppose in the variable 'element' you have the element you want to scrollIntoView
var bbox = ele.getBBox()
var top = bbox.y + bbox.y2
top = 50 * Math.floor(top/50)
$("#container").get(0).scrollTop=top
I am not sure, but I observe that getBBox is pretty slow. So take care.

The problem is that the SVG element you are trying to scroll the view to probably has a y or dy attribute which offsets it from the top, and the scrollIntoView method in Chrome doesn't take that into account (in Firefox it does), therefor it will scroll to the top, because it thinks the element is there, because this is how SVG elements positioning works.. elements are all rendered from the very top left and then kind of "transformed" to their positions via x, y, dx, dy attributes.
There is an open bug which you can (and should) star:
https://bugs.chromium.org/p/chromium/issues/detail?id=803440

Related

svg elements being clipped

Does anyone know why the behavior displayed in the above images might be occurring? In the first image, the x and y coordinates of the svgArcs container are set to zero so the center is in the top left corner and only the bottom right corner is displayed, as expected. In the second image, I moved the container, but still only the bottom right corner is displayed. I posted the document structure so maybe you can take a look and tell me what's going on.
By default <svg> elements clip their contents.
You could specify overflow="visible" on them or alternatively (and better) use a <g> element as a container rather than an <svg> element. You'll still need to keep the outermost SVG element an <svg> element.

How to show tooltip next to the mouse cursor on SVG, despite Non-SVG elements on the website?

Aim:
I have a website with some content and svg scheme in the middle of it. When one points to the elements of the scheme, tooltips should appear next to the mouse cursor.
Problems: Based on examples like this (which was shown by Julian Berger in How to get the position of SVG element), I made working SVG. Unfortunately it is working only as long as the SVG scheme is not included into the website. Content other then SVG make evt.clientX and Y coordinates system to fail --> the tooltip starts to appear in some distance from the cursor (it seems that the more of other then SVG content I have, the further tooltip is moved away from cursor). The simple example is shown here, simply by adding couple of <br/> before the actual SVG begins.
And my question:
Do you have some ideas how to fix the position of the tooltip, so that it would appear always next to the moving cursor?
All the best,
Wojtek
All you have to do is alter mousemove handler a little. It should position the tooltip relative to the top left of the SVG, rather than the page. You do that by subtracting the position of the SVG, which we get by surrounding the SVG with a <div> element and accessing its offsetLeft and offsetTop properties.
<div id="mysvg">
<svg>...</svg>
</div>
function ShowTooltip(evt, mouseovertext) {
svg = document.getElementById("mysvg");
tooltip.setAttributeNS(null,"x",evt.clientX+11 - svg.offsetLeft);
tooltip.setAttributeNS(null,"y",evt.clientY+27 - svg.offsetTop);
...
}
Full demo here

Nested SVG elements with Raphael

Trying to implement nested SVG elements with Raphael.
I think this Question is related to
https://groups.google.com/forum/#!topic/raphaeljs/tzdj3y2DDwg
Any solution? Thanks.
Actually, I've maneged to partially implement nested svg approach.
This is a short example:
var outer_svg = Raphael(document.getElementById('container'), paper_width, paper_height);
outer_svg.canvas.setAttribute('id', 'outer_svg');
var inner_svg = Raphael(document.getElementById("outer_svg"), paper_width, paper_height/2);
inner_svg.canvas.setAttribute('y', paper_height/2);
Here we created inner_svg that is half the height of outer_svg and is positioned at the bottom of outer_svg.
The canvas object represent the svg dom element. So if we give it an id attr then we can adress it to be the parent of another svg. And we can set the x,y coords relative to parent svg element.
Now the sad part:seems that canvas doesn't support animation method, so we cannot animate the whole svg child element. Sets don't help here because drawing elements parts that are outside child svg canvas disappear (as they should).

adding padding to svg g element

my d3.js code generates the following HTML (this was taken from inspect element)
The paths render a circle with text at the bottom of it.
Ultimately I want the text to be UNDER the circle within the bounds of the SVG element. If the SVG element is larger, the G element renders larger. I need to control either the size of the G element or the size of the path elements.
How would I add width and height constraints or padding to the G element? It doesn't respond to width, height, x, y in style
cursory google search was not very helpful
thanks for any insight.
The <g> element doesn't really render at all, it's the <path> and <text> elements you need to adjust.

What is the proper way to get bounding box for HTML elements relative to the Window?

I'm writing a Firefox extension. I'm trying to limit it to just XUL+Javascript (no XPCOM). When I get a mouseover event for an HTML element, I need to get its bounding box in the windows coordinate system (that is the built-in XUL document browser.xul).
The obvious place to start is to put something like this in the mouseover event handler:
var rect = e.target.getBoundingClientRect();
Which is great, but that gives me the rect in the HTML document's coordinate system, which is relative to the upper left corner of the HTML drawing area. I want to display a xul:panel element using panel.openPopup() near this image (but not using one of the predefined popup positions), so I need to translate the coordinates.
I've tried doing the following (in the XUL dom) to get the offset's to do the translation, and it works for some sites, but not all, and doesn't seem to take into account the x translation needed for sidebars.
var appcontent = document.getElementById("appcontent");
if (appcontent) {
chromeOffsetX = r.left;
chromeOffsetY = r.top;
}
So, what's the best way to approach this?
Note: for IE extensions I would use (and have used) IDisplayServices::TransformRect()—is there something similar for Firefox?
Now with bounty!
Turns out getting the location is irrelevant because you can position items relative to the element using something like:
hoverPanel.openPopup(someElement, "overlap", offsetX, offsetY, false, false);

Categories