Creating a d3 selection over an existing, detached SVG element - javascript

I have a component in JavaScript that will provide an <svg> element to its host. I want to populate the SVG element using d3.js.
If I let d3.js create the SVG element and add it to the <body>, then things work as expected:
var chart = d3.select('body').append('svg');
However I already have an SVG element. I want my code to more closely resemble:
var svg = document.createElement('svg'),
chart = d3.select(svg);
This latter approach populates the SVG element (as seen in the elements panel of Chrome's developer tools) but it does not render properly.
Am I going about this incorrectly?
I don't mind if d3 creates the SVG element, so long as it doesn't attach it to the DOM and I can access it.
EDIT I've created a jsFiddle that reproduces my problem. You can toggle the APPROACH variable between 1 and 2 to see alternate approaches. I see this issue in both Chrome and Firefox (latest versions on Ubuntu 13.04.)
EDIT 2 I've created a screenshot showing the working and non-working versions side by side:
You can see that the element trees are largely the same. However on the non-working version (left) the Styles panel (to the right of the element tree) is missing some user agent rules. I have no idea why this should be different. I'd suggest it was a bug in Chrome, but the same behaviour is visible in Firefox.

The problem is that you're creating the SVG element in the HTML namespace where it gets interpreted incorrectly. If you replace
var svg = document.createElement('svg');
with
var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
it works fine. D3 takes care of this for you by setting the namespace automatically.

Related

leaflet-dvf markers won't render in IE11

I unfortunately need to have a leaflet-dvf app that uses Chart Markers that needs to also work in IE 11. It works fine in Chrome and Firefox. The markers example here doesn't render in IE 11 either:
http://humangeo.github.io/leaflet-dvf/examples/html/markers.html
Is there a workaround ? I tried added the meta X-UA-Compatible IE=edge to my app but that doesn't seem to help.
The fact it doesn't work in IE is because the custom SVG markers are an experimental feature (it's written in source code), and the error comes from
var children = gradient.children;
var childLength = children.length; // Cannot read property length of undefined, line 2739 of the file
So the only solution at the moment is to modify yourself the source code.
The gradient is just a gradient SVG element.
I guess that's because IE does not support children property on DOM elements, but instead you should try to use the childNodes property.
var children = gradient.childNodes;
var childLength = children.length;
I can't test it right now but it might do the trick, or perhaps you will go around these step and find a further issue with IE. Just note that childNodes is different from children because it returns all the nodes of an element, and not just the elements of it, so the length will differ.
See here.
If you don't want to get your hands dirty by debugging the code step by step to make it work on IE (even if I think it's just a little effort to do), use a DOM Shim like this and it will get rid of the issues you face.
One of the project authors here.
This issue should be fixed in the 1.0dev branch (compatible with Leaflet 1.0), but I'll make the same fix in the master branch and push that up. Thanks for pointing this out!

Broken interaction between Qualtrics and D3 javascript in Internet Explorer 11

I'm putting together a d3 visualisation using force layouts for use in in the Qualtrics questionnaire website. Everything seems to be working across the different browsers in a jsfiddle. Its possible to drag exemplars from the exemplar box (African male for e.g.) onto the main canvas. One can right-click on a node in the main canvas to bring up a right-click menu to change the node properties or drag the nodes around the canvas.
javascript too large to paste.
Note that the jsfiddle works in Internet Explorer 11. However, when I add this visualisation to the Qualtrics website it breaks in IE11. Far more SVG elements are added than there is data, as shown in the image below.
Note that this combination of Qualtrics and d3 visualisation works fine in Firefox, Chrome and Safari. Unfortunately the Qualtrics support team doesn't support custom code and I'm not proficient enough in javascript to track this down. Any ideas on what might cause this?
For this to work in Qualtrics:
Add the d3.js library in the Qualtrics header
Uncomment Qualtrics.SurveyEngine.addOnload
Comment out create_d3_interaction(false);
Update 1
I've debugged this a bit more.
In the update_svg_node method I do a selection of the SVG element:
var svg = d3.select('.' + svg_class);
var nodes = svg.selectAll('.' + class_id)
.data(f.nodes());
The problem seems to occur in the selectAll -- for some reason it is not matching the class selection with the data. Note this only happens in Qualtrics and IE11 but works fine in IE11 in the fiddle. Note this is an updated version of the fiddle, but the problem still occurs the same way.
So nodes that should be in the UPDATE class are in the ENTER class for some reason.

Customizing Google Chart's svg using JS not works on iPhone

I'm using Google Charts to create charts on my app.
Due to some limitations of the api, after the generation of the svg I change some elements using direct JS manipulation. I do things like add text and move elements.
This works perfectly on Android, but on iOS my changes are ignored.
Here is the expected result using Android. I moved the label and update it after the svg generation.
And here the result on iOS. Label not moved and not updated.
How to fix this issue? I read something about add xmlns="http://www.w3.org/2000/svg" version="1.1", but the generation of the svg is responsability of Google API.
The problem was that everytime I was comparing a text or change a text I was using innerHTML and not textContent. The right was is always use textContent when dealing with the <text> element of SVG.

SVG clipPath rendering bug in Firefox

First of all, look at images:
Before:
After:
Circle is made by dynamic included SVG.
Generated circle SVG code:
http://jsfiddle.net/n9nb7/
Used libraries:
jQuery, svgweb
What I do:
First, after page load, I dynamically created inline SVG with using svgweb for IE8.
Then I fully removed it with it's parent div conteinter.
Then I re-created this SVG code and I get that you see on second picture.
Why I need this: for fully AJAXed site.
Problem:
You see it on second picture. Problem occupies only in Firefox. Even in IE8 it works normal.
In fact clipPath stopped to work.
UPDATE
Live code http://vseslava.ru/?firefox=1.
My solution you can see here: http://vseslava.ru/ but I need solution without any timeouts.
Just to clarify the above, I was able to resolve the issue using underscore's defer function.
Here's a D3 snippet that works in Firefox (23, at least):
var clippedRect = svg.append('rect');
_.defer(function(){
clippedRect.attr('clip-path', function(d,i){
return "url(#clippingPath"+i+")";
});
});

Is it possible to use webkit css masks with SVG without an external file?

Webkit allows the use of an external SVG file as a mask for any HTML element. Ie:
<img src="kate.png" style="-webkit-mask-image: url(circle.svg)">
Resulting in:
(More information here: http://webkit.org/blog/181/css-masks/)
Does anyone know if there's a way to do it without an external SVG file? More specifically, can it be done with SVG generated from javascript?
Well, two years have passed since I asked this question and the browser landscape changed a lot. Here's an example of exactly what I wanted to do, which works only in Firefox for now: http://mozilla.seanmartell.com/persona/
As you can see there's a div with id chameleon which has the following style:
<div id="chameleon" style="clip-path:url(#clip1); -webkit-mask-box-image: url(mask.png);">
#clip1 points to a clipPath element inside an inline SVG element which links to a shape.
<clipPath id="clip1"><use xlink:href="#shape1"/></clipPath>
So now it's doable in Firefox.
Thanks #mart3ll for the practical example!
I'm not sure about the WebKit specific extension but Mozilla allow you to apply SVG effects like masks and filters on HTML elements. These can be defined in external files or directly in the markup. See this post. This isn't in any spec at the moment, but the SVG and CSS working groups are working together to spec this approach. See the Working Group's page (although only filters, not masks are mentioned explicitly there).
You can usually link to something in SVG by including the id of the element in the url value (e.g. url(#someID)). You could try generating the SVG via JS, giving it an id and inject it into the document and see if it works. There is no spec as it is a WebKit extension so it is hard to say without trying it out.
Yes I believe it's possible. Recently I used PHP to generate the SVG file.
Here is an example that I made:
http://jsfiddle.net/brokeneye/ygsKm/
Also check out http://raphaeljs.com/

Categories

Resources