如何用d3中的div包围所有选定的SVG路径元素?

时间:2016-03-03 15:06:04

标签: html d3.js svg

我预先创建了svg图片。我的javascript选择具有某些类的元素,如果我将它们鼠标悬停,则添加html工具提示。 我有一组其他元素通过类名链接到这些可暂停元素。 如果我鼠标悬停,我想用边框(不是一个一个,但所有这些一起)包围这些元素。

你知道如何在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,

1 个答案:

答案 0 :(得分: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>元素的样式(它们用于对元素进行分组),您必须将一个矩形附加到容器并替代它。

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

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

返回x,y,width,height。

现在附加一个带有这些属性的矩形并完成:

 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/

现在你只想在鼠标悬停时显示边框?并在mouseout上删除?

鼠标悬停时:

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

关于mouseout:

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

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