D3JS foreignObject not rendering in Firefox - d3.js

I'm working with D3 and trying to put some HTML in a rectangle. Currently my code looks like this:
node.append("foreignObject")
.attr("display", "block")
.attr("dy", ".35em")
.attr("transform", null)
.html(function(d) { return sidebarInformation(d); })
.attr("x", 12)
.attr("y", 12)
.attr("text-anchor", "start");
function sidebarInformation(_element){ return '<div>foobar</div>'; }
This works as expected on chrome as expected, but fails to render 'foobar' in firefox. I've tried using .attr("requiredExtensions", "http://www.w3.org/1999/xhtml").append("xhtml:div")
as well but haven't had success. Is there something obvious I'm missing?

you've no width and height attributes. They are required in SVG 1.1 (which Firefox implements).
SVG 2 proposes to have a different sizing mechanism where width and height are mapped CSS properties. Chrome/Opera has implemented this, although I don't think any other UA has yet.

Related

round SVG images on Joomla site do not get displayed in Firefox

I try to display round images in a svg. The purpose of it is to display round profile pictures within a graph (like in Gmail). The square images of the people are stored in a spritesheet (profiles.png) and I use d3.js for dynamically generating the svg.
This is the part of the code for the round images
var imgurl = '../../../images/profiles.png';
var svggraph = d3.select("#graph")
.append("svg:svg")
.attr("width", 300)
.attr("height", 300);
var imgRadius = 40;
var profilePos = 1;
var numProfiles = 3;
svggraph.append("defs")
.append("pattern")
.attr("id", "patternId")
.attr("height", 1)
.attr("width", 1)
.attr("x", "0")
.attr("y", "0").append("svg:image")
.attr("xlink:href", imgurl)
.attr("x", -profilePos*2*imgRadius)
.attr("y", 0)
.attr("width", numProfiles*2*imgRadius)
.attr("height", 2*imgRadius);
svggraph.append("circle")
.attr("r", imgRadius)
.attr("cx", imgRadius)
.attr("cy", imgRadius)
.attr("fill", "url(#patternId)");
// to test the imgurl
svggraph.append("svg:image")
.attr("id", "testImage")
.attr("xlink:href", imgurl)
.attr("x", 0)
.attr("y", 100)
.attr("width", 150)
.attr("height", 50);
It worked when I tested it in a plain test HTML, it also worked when I integrated it in my Joomla component in Firefox and Chrome. But if there is a GET query in the url (basically as soon as there is a ? even with no parameters), the round image is not displayed anymore. The svg tags in the "live source code" in the developer tools looks the same if there is a "?" in the url or not. It is always displays correct (with or without query url) in Chrome.
So in summary:
in Chrome -> always works
in FF "plain" HTML with and without ? in url -> works
in FF within Joomla without ? in url -> works
in FF within Joomla with ? in url -> round image not displayed
The test image (#testImage) is always displayed, so the url to the image is apperently correct.
I also tried the same but with clipPath instead of using a pattern, with the same result (not displayed in FF if ? in url and Joomla).
I already did an extensive google search, but the best I could find was this post with the same problem but not an solution.
https://forum.joomla.org/viewtopic.php?t=912784
I don't know what else I could try to fix this.
I had the same issue happening to me for my Joomla 3.6.4 site in Firefox. I resolved it by removing the <base> tag from my template. I added this code to my index.php file in my template:
$doc = JFactory::getDocument();
unset($doc->base);

internal link for using lightbox (fancyBox) in a d3 script

I'm quite new to web programming and its more or less like searching for a funcion and trying until stuff works. So you have an idea of my skill ;)
I'm trying to build a d3 visualization (after Mike Bostocks dendrogramm: http://bl.ocks.org/mbostock/4063570).
Within the tree I want to use internal links to a hidden div (with id='test') that uses a lightbox script (fancyBox: http://fancyapps.com/fancybox/).
So far, my d3 script produces following code for the link (copied from firebug):
<a class="fancybox" x="10" href="#test"><text class="nodeText" dy=".35em" text-anchor="start" style="fill-opacity: 1;" x="10"test</text>
When I'm using this code anywhere else (even in the d3-div) it works fine opening the lightbox div. But when I click on it within the d3 canvas it doesn't work.
The code for setting up the nodes and their properties (to create the code above) is as following:
nodeEnter.append("svg:a")
.attr("x", function(d) {
return d.children || d._children ? -10 : 10;
})
.attr("xlink:href", function(d){return d.url;}) // <-- reading the new "url" property
.attr('class', 'fancybox')
.append("text")
.attr("dy", ".35em")
.attr('class', 'nodeText')
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start";
})
.text(function(d) {
return d.name;
})
.style("fill-opacity", 0);
Furthermore, when I set an external url this works also fine. But when url is '#test' it doesn't.
I cannot find any articles for such an issue (maybe I have to spcial desires? O.o). Is there another way to setup internal links or did I missed any sign? I'm wondering why this works outside d3 but not within.
Thanks for help!
I solved this problem, building my own lightbox after Jim Nielsons tutorial (https://webdesign.tutsplus.com/articles/super-simple-lightbox-with-css-and-jquery--webdesign-3528). Watch out for the comments on recent versions of jquery.
The solution after having a working lightbox as desired is, to include the code into the d3 script somewhere (I put it to the end). Et voila!
It's not good to have blackboxes in your own code :)
Done.
nodeEnter.append("image")
.attr("xlink:href", function(d) { return d.icon; })
.on("click", function(d){
var link=document.createElement("a");
link.id="lightLink";
link.href= d.url;
link.rel="lightbox";
this.appendChild(link);
document.getElementById("lightLink").click();
})
.attr("x", "-12px")
.attr("y", "-12px")
.attr("width", "24px")
.attr("height", "24px");

Does SVG foreignObject work only with static HTML?

As described on http://bl.ocks.org/mbostock/1424037, I have seen the foreignObject feature working only with statically inputted text. What happens if I try something like this:
svg.append("foreignObject")
.attr("width", 400)
.attr("height", 200)
.append("xhtml:body")
.style("font", "16px 'Helvetica Neue'")
.html(function(d) {
return d.name;
})
Does the foreignObject feature work with data returned by functions?
Well, that does work. However one thing that needs to be taken care of is to replace .html with .text.
node.append("foreignObject")
.attr("class", "innerNode")
.text(function (d) {
return d.name; })

Drag nvd3 line graph using drag behaviour

I have been working in nvd3 for sometime.
I faced a situation like, I need to drag and align line graph using mouse. refer here for the pic
I used d3 functionality
"d3.behaviour.drag().on("drag", move)"
and the move function would be
function move(d) {
d3.select(this)
.transition()
//.duration(500)
.ease("linear")
.attr("transform", function(d) {
return "translate("+d3.event.x+")";
});
}
the problem is this is not working in nvd3 graphs because d3.event.x is not available or may be available in different way. I could not find a way to drag.
But if you put hard code number like
return "translate(100)";
its working which is in the picture.
Can anyone help me in this situation please to find out d3.event.x functionality in nvd3.
Any help would be grateful.
I figured out the problem. Just get the d3.event.x in a variable and pass that variable to the translate function. It worked.
function move(d) {
var xevent = d3.event.x;
d3.select(this)
.transition()
.duration(500)
.ease("linear")
.attr("transform", function(d) {
return "translate("+xevent+")";
});
}

How can I add a duration histogram's time data to its bars?

I am working with numerous D3 duration histograms, each with a different duration. I would like to tie in the starting time of the time range each bar represents into a div id inside each bar's HTML. This information would be accessed via jQuery.
Say for example there's a bar at 00:10. I would like to add "00:10" into the bar's div.
What I can't figure out is how to get a hold of these times. Any suggestions on how to do this?
To add an attribute simply use selection.attr() for example:
bar.append("rect")
.attr("x", 1)
.attr("width", x(data[0].dx) - 1)
.attr("height", function(d) { return height - y(d.y); })
.attr("data-time", function(d){return formatMinutes(d.x)})
But, if you simply want to access an API on click, look into d3's selection.on():
bar.append("rect")
.attr("x", 1)
.attr("width", x(data[0].dx) - 1)
.attr("height", function(d) { return height - y(d.y); })
.on("click", function(d){
accessAPI(formatMinutes(d.x))
})
eg. http://jsfiddle.net/3saQW/
I recommend learning about how d3.js binds data. It may even be that jQuery isn't required. This is a good tutorial series: http://alignedleft.com/tutorials/d3/binding-data/

Resources