2016-03-03 47 views
0

我已经预先创建了svg图片。我的JavaScript选择某些类的元素,并添加html工具提示,如果我将它们鼠标悬停。 我有一组其他元素通过类名链接到这些可靠的元素。 我想围绕这些元素与边界(不是一个接一个,但所有的人在一起),如果我mouseover。如何在d3中用div包围所有选定的SVG路径元素?

你有什么想法如何在D3中做到这一点?

我的JavaScript代码如下所示(现在我能只是改变悬停笔触颜色):

var HTMLmouseTip = d3.select("div.mouse.tooltip"); 
var tooltip = d3.selectAll(".tooltip:not(.css)"); 
var g = d3.select("svg").select("g"); 

var clusters = g.selectAll(".showTooltip") 
      .on("mouseover", function(){ 
       tooltip.style("opacity", "1"); 
       heatmap.style("opacity", "1"); 
       tooltip.style("color", this.getAttribute("fill")); 
       var id = this.getAttribute("id"); 
       HTMLmouseTip 
        .html(this.getAttribute("tooltip")) 
        .style("padding", 5 + "px"); 
       g.selectAll("."+id) 
        .style("stroke", "red"); 

      }) 
      .on("mousemove", function() { 
       HTMLmouseTip 
        .style("left", Math.max(0, d3.event.pageX-120) + "px") 
        .style("top", (d3.event.pageY + 20) + "px"); 
      }) 
      .on("mouseout", function() { 
       return tooltip.style("opacity", "0"); 
      }); 

感谢,

L.

+0

只是应用边框的div容器,即追加的所有要素(组)到div和CSS中的div设置样式? – thatOneGuy

+0

我以同样的方式思考,但是如何在所选元素上移动div?或者追加为我做? 就像我有我的HTMLtooltip相似的div和悬停我追加我的所有元素到该div并将边框更改为实体? –

+0

抱歉花了一段时间,你可以把小提琴放在一起,这样我们就可以看到你的问题是什么? – thatOneGuy

回答

0

首先你有问题。这:

var tooltip = d3.selectAll(".tooltip:not(.css)"); 

返回一个数组,所以当你这样做:当你选择了数组不是数组中的元素

tooltip.style("opacity", "1"); 

什么也没有发生。因此,更改为:

tooltip.each(function(d){ 
    d3.select(this).style("opacity", "1").style("color",'red')// 
    }) 

.each(function(d){...穿过阵列和d3.select(this)选择数组中的项目。

现在这显示在您的鼠标悬停提示:https://jsfiddle.net/reko91/csLwqzrc/3/

我们让所有的节点在一个<g>元素。

做一个容器:

var container = d3.select("svg").append("g").attr('id','nodeContainer') 

现在选择所有节点:

var heatmap = document.getElementsByClassName('NODE_424'); 

选择容器追加到:通过所有节点

var thisContainer = document.getElementById('nodeContainer'); 

去,并加入到容器:

for(var i=0;i<heatmap.length;i++){ 
thisContainer.appendChild(heatmap[i]) 
} 

现在你应该可以只添加边框就大功告成:)

更新小提琴:https://jsfiddle.net/reko91/csLwqzrc/5/

对于边界,因为你不能风格<g>元素(他们已经习惯了组元素),您必须将rect附加到容器和样式上。

所以你必须得到容器x和y来定位矩形大小的矩形和宽度和高度。 getBBox()是完成此操作的最佳方法。

var containerBBox = document.getElementById('nodeContainer').getBBox(); 

这将返回x,y,宽度,高度。

现在追加一个矩形与属性和your're完成:

container.append('rect') 
    .attr('x', containerBBox.x) 
    .attr('y', containerBBox.y) 
    .attr('width', containerBBox.width) 
    .attr('height', containerBBox.height) 
    .style('fill', 'none') 
    .style('stroke', 'red') 
    .style('stroke-width', 3) 

更新小提琴:https://jsfiddle.net/reko91/csLwqzrc/6/

现在你只想要显示在鼠标悬停在边界?并在鼠标移除?

鼠标悬停:

container.style('stroke', 'red') 
    .style('stroke-width', 3) 

鼠标移开时:

container.style('stroke', 'none') 

最终小提琴:https://jsfiddle.net/reko91/csLwqzrc/11/

+0

非常感谢你,你救了我的一天。 这正是我想要的:[https://jsfiddle.net/csLwqzrc/10/](https://jsfiddle.net/csLwqzrc/10/) –

+0

关于for循环部分,我注意到它附加了两个节点,因此一些儿童标签似乎从容器中丢失。 (我从网络督察检查) 在某些情况下,这隐藏了容器边界的一些部分。 任何想法,为什么这样? –

+0

你是什么意思'超过两个节点'? – thatOneGuy