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.
Related
I need to replace part of SVG image (map of hall seats) and it doesn't work as I would expect.
I have <g transform="translate(383.25,-48.882672)"><g .. node containing few rect and path elements which build an icon. I can find g by class with jQuery and .html(other_path_content) which makes content appear in the original size (too big to fit the original item spot). When I resize new icon <path d=.. manually and html it again, it goes off the place and appears in different location than original icon.
The problem here is that SVG images I get are random so I can't calculate place of the original icon and transform it to be there as it will be different everytime.
Is that possible to somehow calculate position of the original element and its size (mind it contains of few rects and pathes) and put new one on exact same place? Or maybe I'm missing something in my approach (do I need to re-init svg after appending new node etc.)?
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
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
I have a resizable div. It has two inner divs. One of the inner divs has an svg element in it.
In the svg element I am adding and removing the content dynamically such that each time I add something in my svg. I increase its height by adding 20px to it and when I remove I subtract the height by 20px. When my svg height become greater than its parent div a scroll bar appears in the parent div. Similarly scroll bar is removed when svg height is less than parent div.
The problem starts when I do the resizing. I have added a viewbox option in my svg for resizing. But when I increase the size some of my svg elements are not visible.
And when I decrease the size my svg get placed at a lower position leaving empty space.
Its all messed up in my mind that how to deal svg position/height with viewbox property.
I have tried to make a fiddle to simulate the behavior somehow. But here elements in svg are not adding dynamically and the svg height is constant.
Link to my code
Any help will be appreciated
LATEST UPDATE:
Most important if you're going to use SVG it is better to be acquainted with spec or read a definite guide like "SVG Essentials" by J. Eisenberg, cause it is not such a trivial thing you might think at first.
Then if I understood you right, there is another approach jsFiddle.
First, set correctly the value of the viewBox attribute. In your current example in should be viewBox="0 0 130 220" so that all you content be visible (you have to specify at least 220 as the last number cause your last group <g> is translated i.e. it's coordinate system moved down to 200 units, if you don't do that your content will be not visible cause it is far beyond the outmost y-point of your viewbox, which in your jsfiddle is set to 70).
Second, specify the correct value for preserveAspectRatio which should be preserveAspectRatio="xMinYMax meet", which means (courtesy of the "SVG Essentials" by J. Eisenberg):
Align minimum x of viewBox with left corner of
viewport.
Align maximum y value of viewBox with bottom
edge of viewport.
meet means meet the content, not slice it, if it doesn't fit.
Third, if you are going to add elements to the bottom of your svg you have to change the viewBox value accordingly, cause if you will insert into it smth like:
<g transform="translate(0, 300)">
<text>text 55 </text>
</g>
it will occur beyound your viewBox, which has a max y-point at 220 (if you would set it as I said earlier)
For now hope that helps, let me know.
OLD STUFF
remove style="height:200px" from your svg
Then if you need height, you can dynamically change the height of your svg
var $wrapper = $('#resize'),
$svg = $('#svg2');
$wrapper.resizable({
handles: 'se',
aspectRatio: 400/200,
resize: function(ev, ui) {
$svg.css('height', ui.size.height);
}
});
'#resize' - is the id of the wrapper of the svg
I'm now very confused of what you want. You specified viewbox attr on the svg. That means that only a part of your svg will be visible. Try to remove viewbox and see whether result looks satisfactory for you.
It then be all visible and normally adjusted to parent div
I had been using nested <svg/> and <g/> elements to center an SVG graphic within my browser frame. The outer svg element had width and height of 100%, the inner had x and y set to 50%. An inner g element had negative offset of half image size. This was working fine but I now want to add pan and zoom functionality.
The nested SVG approach seems to be incompatible with SVGPan which gets confused.
SVGPan will only work if I start with the graphic at top-left. I think I'll have to write a script that runs when SCG is loading/loaded to add a transform to center the top-level g in a way that is compatible with SVGPan.
How can I initialize my <g /> with a matrix transformation that translates it thusly?
((viewport.width - g.width)/2, (viewport.width - g.width)/2)
The size of the viewport is not known when the SVG is created but I can drop some script in there to create the transform or translation. Where should the script live and what should it do? It needs to be compatible with SVGPan.
Talos solved this issue for me, see https://github.com/talos/jquery-svgpan/issues/3
Instead of
<svg><svg><g></g></svg></svg>
I'm now using
<svg><g><svg></svg></g></svg>
and that allows a centered graphic to work with [jquery-]svgpan.
To fill an SVG element in any HTML element:
Put position:relative (or position:absolute or position:fixed, if appropriate) on the wrapping HTML element.
Put position:absolute on the SVG element (and top:0; left:0; width:100%; height:100% if necessary).
With this your SVG element will always fill the HTML element. Position/size/center this element as desired.
To get your SVG content centered within the SVG viewport
Set the viewBox on your SVG to be centered around the center of your content.
For example, if your content is a circle of radius 30 centered at 175,300 then set viewBox="145 270 60 60".
Omit the preserveAspectRatio attribute on the SVG element, or ensure that it uses xMidYMid so that the center of the viewbox is always centered in the SVG viewport.
To pan and drag your SVG content
Adjust the viewBox accordingly, or else transform elements.