javascript - d3 工具提示未显示

标签 javascript d3.js tooltip

开始探索D3来完成我的一些工作。尝试通过d3向网络图添加工具提示,但在搜索并尝试了不同的解决方案后,它仍然拒绝显示......

desc:使用 d3 的图表(上网)

添加工具提示:

  1. 在 CSS 中添加样式

    .tooltip {
        position: absolute;
        opacity: 0;
        visibility: hidden;
        width: 300 px;
        height: 200 px;
        padding: 2 px;
        font: 12 px sans - serif;
        background: red;
        border: 0 px;
        border - radius: 8 px;
        z - index: 50;
        pointer - events: none;
    }
    
  2. 初始化了工具提示 block (尝试使用append('g')在svg中添加工具提示,但没有成功'

    var tooltip = d3.select('body').append("div")
        .attr("class", "tooltip")
        .attr("width", 300)
        .attr("height", 200)
        //.style("opacity", .1);
    
  3. 移动到节点时显示。 (尝试“不透明度”和“显示”,但没有成功。)

      tooltipStats.html('<p> OK. I show up </p>') 
    
      tooltip.style("left", (d3.event.pageX + 15) + 'px')
                .style("top", (d3.event.pageY - 30) + 'px')
                //.style("opacity", .9)
                .style('display', 'block')
                .transition()
                .duration(200);
    
  4. 搬出时隐藏

     tooltip.style("block", 'none');
    

我确实尝试在没有子元素tooltipStats的情况下不使用工具提示。没有运气。

我看到的大多数工作示例都在执行这些步骤。但为什么我的不起作用...... 任何人都可以帮助指出我哪里做错了? http://jsfiddle.net/kt67vjvv/2/

graph = {
    "nodes":[
        {"name":"1","rating":90,"id":2951},
        {"name":"2","rating":80,"id":654654},
        {"name":"3","rating":80,"id":6546544},
        {"name":"4","rating":1,"id":68987978},
        {"name":"5","rating":1,"id":9878933},
        {"name":"6","rating":1,"id":6161},
        {"name":"7","rating":1,"id":64654},
        {"name":"8","rating":20,"id":354654},
        {"name":"9","rating":50,"id":8494},     
        {"name":"10","rating":1,"id":6846874},
        {"name":"11","rating":1,"id":5487},
        {"name":"12","rating":80,"id":"parfum_kenzo"},
        {"name":"13","rating":1,"id":65465465},
        {"name":"14","rating":90,"id":"jungle_de_kenzo"},
        {"name":"15","rating":20,"id":313514},
        {"name":"16","rating":40,"id":36543614},
        {"name":"17","rating":100,"id":"Yann_YA645"},
        {"name":"18","rating":1,"id":97413},
        {"name":"19","rating":1,"id":97414},
        {"name":"20","rating":100,"id":976431231},
        {"name":"21","rating":1,"id":9416},
        {"name":"22","rating":1,"id":998949},
        {"name":"23","rating":100,"id":984941},
        {"name":"24","rating":100,"id":"99843"},
        {"name":"25","rating":1,"id":94915},
        {"name":"26","rating":1,"id":913134},
        {"name":"27","rating":1,"id":9134371}
    ],
    "links":[
        {"source":6,"target":5,"value":6, "label":"publishedOn"},
        {"source":8,"target":5,"value":6, "label":"publishedOn"},
        {"source":1,"target":7,"value":4, "label":"containsKeyword"},
        {"source":8,"target":10,"value":3, "label":"containsKeyword"},
        {"source":7,"target":14,"value":4, "label":"publishedBy"},
        {"source":8,"target":15,"value":6, "label":"publishedBy"},
        {"source":9,"target":1,"value":6, "label":"depicts"},
        {"source":10,"target":1,"value":6, "label":"depicts"},
        {"source":16,"target":1,"value":6, "label":"manageWebsite"},
        {"source":16,"target":2,"value":5, "label":"manageWebsite"},     
        {"source":16,"target":3,"value":6, "label":"manageWebsite"},
        {"source":16,"target":4,"value":6, "label":"manageWebsite"},
        {"source":19,"target":18,"value":2, "label":"postedOn"},
        {"source":18,"target":1,"value":6, "label":"childOf"},
        {"source":17,"target":19,"value":8, "label":"describes"},
        {"source":18,"target":11,"value":6, "label":"containsKeyword"},
        {"source":17,"target":13,"value":3, "label":"containsKeyword"},
        {"source":20,"target":13,"value":3, "label":"containsKeyword"},
        {"source":20,"target":21,"value":3, "label":"postedOn"},
        {"source":22,"target":20,"value":3, "label":"postedOn"},
        {"source":23,"target":21,"value":3, "label":"manageWebsite"},
        {"source":23,"target":24,"value":3, "label":"manageWebsite"},
        {"source":23,"target":25,"value":3, "label":"manageWebsite"},
        {"source":23,"target":26,"value":3, "label":"manageWebsite"}
    ]
}


var margin = {top: 5, right: 15, bottom: 15, left: 5};
var width = 1865  - margin.left - margin.right,
    height = 933  - margin.top - margin.bottom;

var color = d3.scale.category20();

var force = d3.layout.force()
        .charge(-200)
        .linkDistance(50)
        .size([width - margin.left - margin.right, height - margin.top - margin.bottom]);

var zoom = d3.behavior.zoom() 
        .scaleExtent([0.1, 6]) // how large scale it can be zoomed
        .on("zoom", zoomed);

var drag = d3.behavior.drag()
        .origin(function(d) { return d; })
        .on("dragstart", dragstarted)
        .on("drag", dragged)
        .on("dragend", dragended);

var svg = d3.select("#map").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
        .call(zoom);

var rect = svg.append("rect")
        .attr("width", width)
        .attr("height", height)
        .style("fill", "none")
        .style("pointer-events", "all");

var container = svg.append("g");

var tooltip = d3.select('body').append("div")
        .attr("class", "tooltip")
        .attr("width", 300)
        .attr("height", 200)
        //.style("opacity", .1);

var tooltipStats = tooltip.append('div')
        .attr('class', 'stats');

/*
d3.json('https://d3js.org/world-50m.v1.json', function(data) {
    container.selectAll('path')
        .data(topojson.feature(data, data.objects.countries).features)
        .enter()
        .append('path')
        .attr('fill', '#5bc0de')
        .attr('stroke', '#1992be')
        .attr('d', path)
});
*/

// d3.json('/data_3.json', function(graph) {
                
                force
                    .nodes(graph.nodes)
                    .links(graph.links)
                    .start();
                
      
        
        var link = container.append("g")
            .attr("class", "links")
            .selectAll(".link")
            .data(graph.links)
            .enter().append("line")
            .attr("class", "link")
            .style("stroke-width", function(d) { return Math.sqrt(d.value); });
 
        var node = container.append("g")
            .attr("class", "nodes")
            .selectAll(".node")
            .data(graph.nodes)
            .enter().append("g")
            .attr("class", "node")
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; })
            .call(drag);

  
        node.append("circle")
            .attr("r", function(d) { return d.weight + 10; })
            .style("fill", function(d) { return color(1/d.rating); });
         
                
                force.on("tick", function() {
                    link.attr("x1", function(d) { return d.source.x; })
                        .attr("y1", function(d) { return d.source.y; })
                        .attr("x2", function(d) { return d.target.x; })
                        .attr("y2", function(d) { return d.target.y; });

                    node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
                });
                
                var linkedByIndex = {};
                graph.links.forEach(function(d) {
                    linkedByIndex[d.source.index + "," + d.target.index] = 1;
                });

                function isConnected(a, b) {
                    return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index];
                }

        node.on("mouseover", function(d){
                    //alert(JSON.stringify(d))
                       
            tooltipStats.html('<p> Please show up </p>') 

            tooltip.style("left", (d3.event.pageX + 15) + 'px')
                .style("top", (d3.event.pageY - 30) + 'px')
                //.style("opacity", .9)
                .style('display', 'block')
                .transition()
                .duration(200);

                        node.classed("node-active", function(o) {
                            thisOpacity = isConnected(d, o) ? true : false;
                            this.setAttribute('fill-opacity', thisOpacity);
                            return thisOpacity;
                        });

                        link.classed("link-active", function(o) {
                            return o.source === d || o.target === d ? true : false;
                        });
                        
                        d3.select(this).classed("node-active", true);
                        d3.select(this).select("circle").transition()
                                .duration(750)
                                .attr("r", (d.weight + 10)*1.5);
                         
                        console.log("X: " + d3.event.pageX + " Y: " + d3.event.pageY + " tip:" + tooltip.text())
                   

                })
        
        .on("mouseout", function(d){
 
                        tooltip.style("block", 'none');
                        
                        node.classed("node-active", false);
                        link.classed("link-active", false);

                        d3.select(this).select("circle").transition()
                                .duration(750)
                                .attr("r", d.weight + 10);
               });
//    });


        function dottype(d) {
          d.x = +d.x;
          d.y = +d.y;
          return d;
        }

        function zoomed() {
          container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        }

        function dragstarted(d) {
          d3.event.sourceEvent.stopPropagation();
          
          d3.select(this).classed("dragging", true);
          force.start();
        }

        function dragged(d) {
          
          d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
          
        }

        function dragended(d) {
          
          d3.select(this).classed("dragging", false);
        }
.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.node-active{
  stroke: #555;
  stroke-width: 1.5px;
}

.link {
  stroke: #555;
  stroke-opacity: .3;
}

.link-active {
  stroke-opacity: 1;
}

.overlay {
  fill: none;
  pointer-events: all;
}


#map{
    width:1865px;
    height:900px;
}

.tooltip {   
  position: absolute;           
  opacity: 0;
  visibility: hidden;
  width: 300px;                  
  height: 200px;                 
  padding: 2px;             
  font: 12px sans-serif;        
  background: red;   
  border: 0px;      
  border-radius: 8px;           
  z-index: 50;
  pointer-events: none;         
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>
<body>

<div id="map">
</div>
</body>

最佳答案

您的代码中有几个问题。首先,您将可见性设置为隐藏,但从未在鼠标悬停时将其设置为可见。除此之外,您将不透明度设置为 0,但也从未在鼠标悬停时更改它。最后,最重要的事情:您从未将文本设置为显示在工具提示中。

您只需设置其中一个工具提示的显示/隐藏,并使用 html() 设置文本。这是更改不透明度的代码:

graph = {
    "nodes":[
        {"name":"1","rating":90,"id":2951},
        {"name":"2","rating":80,"id":654654},
        {"name":"3","rating":80,"id":6546544},
        {"name":"4","rating":1,"id":68987978},
        {"name":"5","rating":1,"id":9878933},
        {"name":"6","rating":1,"id":6161},
        {"name":"7","rating":1,"id":64654},
        {"name":"8","rating":20,"id":354654},
        {"name":"9","rating":50,"id":8494},     
        {"name":"10","rating":1,"id":6846874},
        {"name":"11","rating":1,"id":5487},
        {"name":"12","rating":80,"id":"parfum_kenzo"},
        {"name":"13","rating":1,"id":65465465},
        {"name":"14","rating":90,"id":"jungle_de_kenzo"},
        {"name":"15","rating":20,"id":313514},
        {"name":"16","rating":40,"id":36543614},
        {"name":"17","rating":100,"id":"Yann_YA645"},
        {"name":"18","rating":1,"id":97413},
        {"name":"19","rating":1,"id":97414},
        {"name":"20","rating":100,"id":976431231},
        {"name":"21","rating":1,"id":9416},
        {"name":"22","rating":1,"id":998949},
        {"name":"23","rating":100,"id":984941},
        {"name":"24","rating":100,"id":"99843"},
        {"name":"25","rating":1,"id":94915},
        {"name":"26","rating":1,"id":913134},
        {"name":"27","rating":1,"id":9134371}
    ],
    "links":[
        {"source":6,"target":5,"value":6, "label":"publishedOn"},
        {"source":8,"target":5,"value":6, "label":"publishedOn"},
        {"source":1,"target":7,"value":4, "label":"containsKeyword"},
        {"source":8,"target":10,"value":3, "label":"containsKeyword"},
        {"source":7,"target":14,"value":4, "label":"publishedBy"},
        {"source":8,"target":15,"value":6, "label":"publishedBy"},
        {"source":9,"target":1,"value":6, "label":"depicts"},
        {"source":10,"target":1,"value":6, "label":"depicts"},
        {"source":16,"target":1,"value":6, "label":"manageWebsite"},
        {"source":16,"target":2,"value":5, "label":"manageWebsite"},     
        {"source":16,"target":3,"value":6, "label":"manageWebsite"},
        {"source":16,"target":4,"value":6, "label":"manageWebsite"},
        {"source":19,"target":18,"value":2, "label":"postedOn"},
        {"source":18,"target":1,"value":6, "label":"childOf"},
        {"source":17,"target":19,"value":8, "label":"describes"},
        {"source":18,"target":11,"value":6, "label":"containsKeyword"},
        {"source":17,"target":13,"value":3, "label":"containsKeyword"},
        {"source":20,"target":13,"value":3, "label":"containsKeyword"},
        {"source":20,"target":21,"value":3, "label":"postedOn"},
        {"source":22,"target":20,"value":3, "label":"postedOn"},
        {"source":23,"target":21,"value":3, "label":"manageWebsite"},
        {"source":23,"target":24,"value":3, "label":"manageWebsite"},
        {"source":23,"target":25,"value":3, "label":"manageWebsite"},
        {"source":23,"target":26,"value":3, "label":"manageWebsite"}
    ]
}


var margin = {top: 5, right: 15, bottom: 15, left: 5};
var width = 1865  - margin.left - margin.right,
    height = 933  - margin.top - margin.bottom;

var color = d3.scale.category20();

var force = d3.layout.force()
        .charge(-200)
        .linkDistance(50)
        .size([width - margin.left - margin.right, height - margin.top - margin.bottom]);

var zoom = d3.behavior.zoom() 
        .scaleExtent([0.1, 6]) // how large scale it can be zoomed
        .on("zoom", zoomed);

var drag = d3.behavior.drag()
        .origin(function(d) { return d; })
        .on("dragstart", dragstarted)
        .on("drag", dragged)
        .on("dragend", dragended);

var svg = d3.select("#map").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
        .call(zoom);

var rect = svg.append("rect")
        .attr("width", width)
        .attr("height", height)
        .style("fill", "none")
        .style("pointer-events", "all");

var container = svg.append("g");

var tooltip = d3.select('body').append("div")
        .attr("class", "tooltip");

var tooltipStats = tooltip.append('div')
        .attr('class', 'stats');

/*
d3.json('https://d3js.org/world-50m.v1.json', function(data) {
    container.selectAll('path')
        .data(topojson.feature(data, data.objects.countries).features)
        .enter()
        .append('path')
        .attr('fill', '#5bc0de')
        .attr('stroke', '#1992be')
        .attr('d', path)
});
*/

// d3.json('/data_3.json', function(graph) {
                
                force
                    .nodes(graph.nodes)
                    .links(graph.links)
                    .start();
                
      
        
        var link = container.append("g")
            .attr("class", "links")
            .selectAll(".link")
            .data(graph.links)
            .enter().append("line")
            .attr("class", "link")
            .style("stroke-width", function(d) { return Math.sqrt(d.value); });
 
        var node = container.append("g")
            .attr("class", "nodes")
            .selectAll(".node")
            .data(graph.nodes)
            .enter().append("g")
            .attr("class", "node")
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; })
            .call(drag);

  
        node.append("circle")
            .attr("r", function(d) { return d.weight + 10; })
            .style("fill", function(d) { return color(1/d.rating); });
         
                
                force.on("tick", function() {
                    link.attr("x1", function(d) { return d.source.x; })
                        .attr("y1", function(d) { return d.source.y; })
                        .attr("x2", function(d) { return d.target.x; })
                        .attr("y2", function(d) { return d.target.y; });

                    node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
                });
                
                var linkedByIndex = {};
                graph.links.forEach(function(d) {
                    linkedByIndex[d.source.index + "," + d.target.index] = 1;
                });

                function isConnected(a, b) {
                    return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index];
                }

        node.on("mouseover", function(d){
                    //alert(JSON.stringify(d))
                       
            tooltipStats.html('<p> Please show up </p>') 

            tooltip.html("I am a tooltip")
            .style("left", (d3.event.pageX + 15) + 'px')
                .style("top", (d3.event.pageY - 30) + 'px')
                .style("opacity", .9)
                .transition()
                .duration(200);

                        node.classed("node-active", function(o) {
                            thisOpacity = isConnected(d, o) ? true : false;
                            this.setAttribute('fill-opacity', thisOpacity);
                            return thisOpacity;
                        });

                        link.classed("link-active", function(o) {
                            return o.source === d || o.target === d ? true : false;
                        });
                        
                        d3.select(this).classed("node-active", true);
                        d3.select(this).select("circle").transition()
                                .duration(750)
                                .attr("r", (d.weight + 10)*1.5);
                         
                    
                   

                })
        
        .on("mouseout", function(d){
 
                        tooltip.style("opacity", 0);
                        
                        node.classed("node-active", false);
                        link.classed("link-active", false);

                        d3.select(this).select("circle").transition()
                                .duration(750)
                                .attr("r", d.weight + 10);
               });
//    });


        function dottype(d) {
          d.x = +d.x;
          d.y = +d.y;
          return d;
        }

        function zoomed() {
          container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        }

        function dragstarted(d) {
          d3.event.sourceEvent.stopPropagation();
          
          d3.select(this).classed("dragging", true);
          force.start();
        }

        function dragged(d) {
          
          d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
          
        }

        function dragended(d) {
          
          d3.select(this).classed("dragging", false);
        }
.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.node-active{
  stroke: #555;
  stroke-width: 1.5px;
}

.link {
  stroke: #555;
  stroke-opacity: .3;
}

.link-active {
  stroke-opacity: 1;
}

.overlay {
  fill: none;
  pointer-events: all;
}


#map{
    width:1865px;
    height:900px;
}

.tooltip {   
  position: absolute;           
  opacity: 0;
  width: 100px;                  
  height: 50px;                 
  padding: 2px;             
  font: 12px sans-serif;        
  background: red;   
  border: 0px;      
  border-radius: 8px;           
  z-index: 50;
  pointer-events: none;         
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>
<body>

<div id="map">
</div>
</body>

关于javascript - d3 工具提示未显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46552862/

相关文章:

javascript - 监听表单提交

javascript - Jasmine 好像没有调用我的方法

javascript - 使用 D3.js 的 3 维(X、Y 和 Z)图

javascript - 带工具提示的 Highcharts 自定义按钮

javascript - 使用 ng-bind-html 的 ng-click 在 Controller 内部不工作

javascript - 我想创建一个带有按钮的图表

javascript - 相当于链接到字体文件的 JS

javascript - jQuery Blur() 不适用于 click() 函数

javascript - 使用 SASS(Bourbon)或 JavaScript 防止工具提示中出现寡妇?

Javascript cookie 和重定向