SVG elements disappear after dynamic updates in Edge - javascript

This issue does not affect Chrome, but is consistent in Edge and Internet Explorer.
I have two svg's defined in my .cshtml:
<div class="row" style="height: 100%;">
<div class="col-sm-1" style="height:inherit;">
<div class="card" style="height:100%">
<svg id="bayLegendSVG" viewBox="0 0 112 900" height="100%" width="100%" style="display:block; margin: auto;">
<g>
<g name="Empty" style="display:none">
<text x="56" y="256" text-anchor="middle">Not Selected</text>
<circle class="zoom" cx="56" cy="300" r="31" stroke="lightgrey" stroke-width="12" fill="white"></circle>
<text name="count" x="56" y="305" text-anchor="middle">81</text>
</g>
<g name="Selected" style="display:none">
<text x="56" y="556" text-anchor="middle">Selected</text>
<circle class="zoom" cx="56" cy="600" r="31" stroke="orange" stroke-width="12" fill="white"></circle>
<text name="count" x="56" y="605" text-anchor="middle">0</text>
</g>
</g>
<additional g's...>
</svg>
</div>
</div>
<div class="col-sm-7" style="height: inherit;">
<div class="card" style="height:100%;">
<svg id="baySVG" viewBox="0 0 788 900" height="100%" width="100%" style="display:block; margin: auto;" >
<g name="bayText">
<circle cx="384" cy="6200" r="6170" stroke="darkgrey" stroke-width="1" fill="none" />
<text x="353" y="20">Top Label</text>
</g>
<g name="bayText">
<circle cx="384" cy="6200" r="5340" stroke="darkgrey" stroke-width="1" fill="none" />
<text x="334" y="885">Bottom Label</text>
</g>
<lots of additional g's...>
</svg>
</div>
<div>
I am making changes to these elements from JavaScript (showing/hiding certain elements, changing colors, changing text, etc.) based on user selections.
The issue is that some or all of the elements in the SVG will not be displayed after user interactions, even interactions that do not initiate dynamic changes to elements. The html for the svg is there, and it is not set to hidden (proof is that it always works in Chrome). And to make everything appear as intended, all that I need to do is resize the browser or even just click anywhere on the SVG (everything immediately appears).
I am fairly new to svg's and love everything they have provided...except for this.
Edit: The issue seems to occur when the height of the page changes (from either hiding or showing divs to the right of the content I have posted). It does not change the height of the SVGs, as thy are set when the page is created. The area to the right changes and is scrollable.
I am wondering if it has something to do with using the collapse hide/show and there being some issue with animation happening after the SVG content has been updated.

Sorry but edge / internet explorer is not a good browser he not support few class css/svg.. is normal , use chrome.

Related

foreignObject display:none in Firefox and Chrome

I have a JavaScript app that works with svg components. I have svg groups as:
<svg id="canvas" width="100%" height="100%" viewBox="0 0 1500 500">
<g class="node-element" x="0" y="0" height="20" width="300" id="node-c87">
<text class="node-element-text" x="12" y="15">person:object</text>
<image x="0" y="4" width="11" height="11" xlink:href="assets/images/object-icon.png"></image>
</g>
<g class="nested-group">
<g class="node-element" x="50" y="100" height="20" width="300" id="node-c87">
<text class="node-element-text" x="12" y="15">person:object</text>
<image x="0" y="4" width="11" height="11" xlink:href="assets/images/object-icon.png"></image>
</g>
</g>
</svg>
And I have defined CSS as follows(CSS on svg groups acts on all child elements of <g>.
.node-element {
display: inline;
}
.node-element :active {
opacity: 0.5;
}
.node-element:hover {
opacity: 0.5;
}
The problem is that it does not work properly in Firefox, whereas it works fine in Chrome. Why and how to fix it?
The node elements are in a tree-like structure where x values differ based on rank. In Firefox, the hover does not properly work on the first couple of node-elements. But works fine on the rest of the node-elements, regardless of the x values.
UPDATE: The problem was actually caused by a foreignObject component, which I have set the elements to display:none. The hover was actually working on the hidden component than the desired element. It was solved by setting the display:none to the foreignObject.
But I would like to know why this was acting differently in the two browsers, Chrome and Firefox?
You probably need to have all look at css pointer-events, documented here. With that you can specify what »region« of your graphic is used for hovers. This can be the AABB (axis aligned Bounding box, nothing or the shape of the graphic).
The problem was actually caused by a foreignObject component, which I have set the elements to display:none. The hover was actually working on the hidden component than the desired element. It was solved by setting the display:none to the foreignObject.

How to append div tag into a SVG rect element?

I couldn't find a correct solution for this problem so I decided to write a new question.
I'm not even sure that this is possible but I hope it is.
So here is my HTML that the browser provides. I'm copying it from the "Elements" tab in the browser.
<svg width="960" height="728" style="margin-left: 0px;">
<g transform="translate(0,24)" style="shape-rendering: crispEdges;">
<g class="depth">
<g>
<g>
<rect class="child" x="0" y="0" width="960" height="704" style="fill: rgb(192, 192, 192);">1.1.1.
<div class="jstree">
<div>TestContent</div>
</div>
</rect>
</g>
</g>
</g>
</g>
(I'm creating everything with JS).
My problem is that I'm creating this div inside the rect tag, but this div and its content doesn't appear on the screen inside the rectangle.
I want to know if it is possible to make it appear and if it is how ?
Unfortunately, it's not possible: you cannot append an HTML element to an SVG element.
The only way for using a div (or a p, h1, li etc) in an SVG is by using foreignObject. In your code, something like this:
<svg width="960" height="728" style="margin-left: 0px;">
<g transform="translate(0,24)" style="shape-rendering: crispEdges;">
<g class="depth">
<g>
<g>
<rect class="child" x="0" y="0" width="960" height="704" style="fill: rgb(192, 192, 192);">
</rect>
<foreignObject x="100" y="100" width="100" height="100">
<div xmlns="http://www.w3.org/1999/xhtml" class="jstree">
<div>TestContent</div>
</div>
</foreignObject>
</g>
</g>
</g>
</g>
Notice that foreignObject comes after the rectangle, not inside it (as in your code). Also, notice that foreignObject does not work in IE: https://developer.mozilla.org/en/docs/Web/SVG/Element/foreignObject

D3.js Text on path not rendered (no height / width)

I am trying to render circles which have a text inside, that runs along a given path.
The markup d3 produces looks fine, but Chrome is not showing the texts.
Upon inspection it says text elements have 0 width and 0 height.
This is sample markup including only two circles:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 950 600">
<g>
<g transform="translate(334.14792673070184,58.96385042366173)">
<defs>
<path id="path-1" d="m5,50 a45,45 0 0 0 90,0"></path>
</defs>
<circle class="circle" fill="#ccc" cx="50" cy="50" r="50"></circle>
<text fill="#333" font-size="15px">
<textpath xlink:href="#path-1" start-offset="0%">123456</textpath>
</text>
<use xlink:href="#path-1" fill="#666" opacity="0.1"></use>
</g>
</g>
<g transform="translate(374.66047394649974,371.7948729806046)">
<defs>
<path id="path-2" d="m5,50 a45,45 0 0 0 90,0"></path>
</defs>
<circle class="circle" fill="#ccc" cx="50" cy="50" r="50"></circle>
<text fill="#333" font-size="15px">
<textpath xlink:href="#path-2" start-offset="0%">123456</textpath>
</text>
<use xlink:href="#path-2" fill="#666" opacity="0.1"></use>
</g>
</svg>
When I inspect the markup in Chrome console and click "Edit as HTML" on the SVG element, make a random change, save & exit - the SVG suddenly renders correctly.
The exact same thing happens in Firefox and Opera.
Copy pasting the generated markup into a jsfiddle renders everything as expected.
I have tried pulling the < defs > tags out of each individual group into a single global < defs > but it did not solve the problem.
I have also looked at user-agent-stylesheet and other CSS rules that might interfere with rendering.
Is this a problem with how the SVG tag is included and/or the container element's width/height properties? I have been trying different things to fix this for a couple of hours now...
Here is the full SVG markup http://pastebin.com/J2Lz8p23
Here are the relevant parts in my code http://pastebin.com/Bym8kJVN

Making a D3 widget scrollable

I'm sticking a D3 tree widget into my web app. It grows children and appends them to the tree. However, when the tree gets to be too big, it starts to go off the page. That's fine since I don't want to the individual tree nodes to get too small, but it would be nice if I could add a scroll bar. However, I've tried doing it the normal way, overflow: auto, but it doesn't work. Maybe it's something to do with the D3 svg stuff.
Here's the code for a tree with 2 nodes:
<div id="Graph">
<svg width="100%" height="10%" id="SVG" overflow="auto" display="block">
<g transform="translate(40,0)">
<path class="link" d="M0,20C213.75,20 213.75,20 427.5,20"></path>
<g class="node" transform="translate(427.5,20)">
<circle r="4.5" style="fill: rgb(255, 255, 255);"></circle>
<text x="10" dy=".35em" text-anchor="start" style="fill-opacity: 1;">1</text>
</g>
<g class="node" transform="translate(0,20)">
<circle r="4.5" style="fill: rgb(255, 255, 255);"></circle>
<text x="-10" dy=".35em" text-anchor="end" style="fill-opacity: 1;">0</text>
</g>
</g>
</svg>
</div>
Once it gets to be more than around 10 or 11 nodes, it goes off the screen. How can I fix this?
Make the width of the svg element > 100%. That will overflow the div and the div will be scrollable. You might also need to set the overflow style to scroll on the <div>

SVG: <use> element not working when nested in g (with fiddle!)

I need to display use elements in my SVG graphic.
When I try to use them from within a g element it doesn't work.
In a little demo it looks like the use element works outside of g elements.
Here the fiddle (you can scroll down to the use elements to see the demo):
http://jsfiddle.net/3dacnxdb/2/
Why is it like this? How can i display them from within a g element?
(My graphic is made out of many modules I need the gs to seperate them)
I appreciate any help!
<svg id="graphic">
<defs>
<clipPath id="icon-cp">
<rect x="0" y="0" width="150" height="100" />
</clipPath>
<image id="icon-sprite" width="969" height="293"
xlink:href="http://i.stack.imgur.com/TPx5h.png" />
<g id="icon2" clip-path="url(#icon-cp)">
<use xlink:href="#icon-sprite" transform="translate(-240,0)" />
</g>
</defs>
<!-- ----------------------------------------
Here is the question:
the first use element is not displayed.
The second one is displayed. (the elements are under this text)
Why does it not work?
How can a use element be used within nested g elements?
(to test it you can comment out the second use element,
even tough both use elements have the same attributes
no icon is visible anymore)
---------------------------------------- -->
<!-- following does not work: -->
<g id="testg">
<use xlink:href="#icon2" x="100" y="50" />
</g>
<!-- following works: -->
<use xlink:href="#icon2" x="100" y="50" />
<!-- why???? -->
It does work. Your jsfiddle is not the same as your inline code (the x and y of the use are not the same).
If you make the x and y values in the <g> the same as outside it will work. In the non-working case you are clipping out the contents of the <use> with your clip-path.
You can't see it because they are superposed... =)
<svg id="graphic">
<defs>
<clipPath id="icon-cp">
<rect x="0" y="0" width="150" height="100" />
</clipPath>
<image id="icon-sprite" width="969" height="293" xlink:href="http://i.stack.imgur.com/TPx5h.png" />
<g id="icon2" clip-path="url(#icon-cp)">
<use xlink:href="#icon-sprite" transform="translate(-240,0)" />
</g>
</defs>
<!-- ----------------------------------------
Here is the question:
the first use element is not displayed.
The second one is displayed. (the elements are under this text)
Why does it not work? How can a use element be used within nested g elements?
(to test it you can comment out the second use element, even tough both use elements have the same attributes no icon is visible anymore)
---------------------------------------- -->
<!-- following does not work: -->
<g id="testg">
<use xlink:href="#icon2" x="0" y="0" />
</g>
<!-- following works: -->
<use xlink:href="#icon2" x="100" y="50" />
<!-- why???? -->

Categories