D3.js情节:SVG z-order of foreignelement在firefox中不起作用

时间:2014-08-18 20:53:17

标签: html svg d3.js

我有一个带d3.js的基本SVG散点图,并希望在绘图中的固定位置有一个输出段落。最初,该段落显示了一些基本用法文本,但一旦用户与绘图交互,该段落应显示包含html标记和特殊符号等<sub>功能的输出。

我在相当大的SVG中将该段落实现为foreignobject以包含初始文本。它在Safari和Chrome中运行良好,但在Firefox中失败:foreignobject与点重叠,无法将鼠标悬停在它们上面。任何想法如何解决或如何实现它避免这些问题?

请参阅下面的示例代码或this bl.ock.org - 请记住它在Safari中正常工作但在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 = []; 
        for (var i = 0; i < 25; i++) {
            dataset.push({x:Math.random() * 30,y:Math.random() * 30});
        }

        /* extend and 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;

        /* the SVG canvas for the plot */   
        var svg = d3.select('body').append('svg')
            .attr('width',w)
            .attr('height',h)
            .attr('float','left');

        /* the 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 AND PARAGRAPH */
        function addaxes(){

            /* add the 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 the 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>

1 个答案:

答案 0 :(得分:0)

如果添加属性pointer-events =&#34; none&#34;对于foreignObject元素,它将对鼠标点击变得透明,因此您可以将光点悬停在其上。副作用是您无法选择文本。