html - D3.js plot: SVG z-order of foreignelement not working in firefox -
i have basic svg scatter plot d3.js , want have output paragraph @ fixed position in plot. initially, paragraph shows basic usage text once user interacts plot, paragraph should show output includes html features such <sub> tags , special symbols.
i implemented paragraph foreignobject in svg of rather big size include initial text. works fine in safari , chrome, fails in firefox: foreignobject overlaps dots , makes impossible hover on them. idea how fix or how implement avoiding these issues?
see example code below or this bl.ock.org - remember works fine in safari doesn't work in firefox:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>visualization</title> <script type="text/javascript" src="https://rawgit.com/mbostock/d3/master/d3.min.js" charset="utf-8"></script> <style media="screen" type="text/css"> .axis path, .axis line { fill: none; stroke: black; shape-rendering: crispedges } .axis text { font-family: sans-serif; font-size: 12px; } .clicktext { font-family: sans-serif; font-size: 11px; text-align: left; } </style> </head> <body> <script type="text/javascript"> /* test data set */ var dataset = []; (var = 0; < 25; i++) { dataset.push({x:math.random() * 30,y:math.random() * 30}); } /* extend , plot sizes */ var w = 500; var h = 300; var dot; var padding = 60; var def_c_sz = 5; /* description text */ var pclick_txt = '<b>usage</b><br/>'+ '<br>text test text text test text<br/>'+ 'text test text text test text text test text text test text text test text'; /* axes limits */ var x0 = 0.; var x1 = 30.; var y0 = 0; var y1 = 30; /* svg canvas plot */ var svg = d3.select('body').append('svg') .attr('width',w) .attr('height',h) .attr('float','left'); /* scales */ var xscale = d3.scale.linear(); var yscale = d3.scale.linear(); xscale.range([padding,w-padding]).domain([x0,x1]); yscale.range([h-padding,padding]).domain([y0,y1]); /* create axes , paragraph */ function addaxes(){ /* add output paragraph */ pclick=svg.append("foreignobject") .attr("x",xscale(x0)) .attr("y",yscale(y1)) .attr("width", w) .attr("height",h) .append("xhtml:body") .append("p") .attr('class','clicktext label') .attr('style','background-color:rgba(125,125,125,0.75);padding:'+padding/5+'px;font-size:x-small;') .html(pclick_txt); /* add x-axis */ var xaxis = d3.svg.axis() .orient('bottom') .scale(xscale); xaxis.tickformat(d3.format('n')); svg.append('g') .attr('class','axis') .attr('transform','translate(0,'+(h-padding)+')') .call(xaxis); /* add y-axis */ var yaxis = d3.svg.axis() .orient('left') .scale(yscale) svg.append('g') .attr('class','axis') .attr('transform','translate('+(padding)+',0)') .call(yaxis); } circles = svg.selectall(".dots").data(dataset); circlese = circles.enter().append("circle").attr("class","dots"); circlese .attr("cx",function(d){return xscale(d.x)}) .attr("cy",function(d){return yscale(d.y)}) .attr("r",def_c_sz) .attr("fill","orange") .on("mouseover",mouseover) .on("mouseout",mouseout); /* call axes after dots have been drawn */ addaxes(); /* define callbacks */ function mouseover(d){ dot = d3.select(this); dot.transition() .duration(100) .attr('r',2*def_c_sz); pclick.attr('style','background-color:transparent;padding:'+0+'px;font-size:x-small;') .html(function(d){return '<b>y = '+dot.data()[0].y+'</b>'}); } function mouseout(){ d3.select(this) .transition() .duration(700) .attr('r',def_c_sz); pclick.attr('style','background-color:transparent;padding:'+0+'px;font-size:x-small;') .html('<b>not hovering :-(</b>'); } </script> </body> </html>
if add attribute pointer-events="none" foreignobject element become transparent mouse clicks , you'll able hover dots. side effect won't able select text though.
Comments
Post a Comment