【问题标题】:How to make mouseover functionality permanent如何使鼠标悬停功能永久化
【发布时间】:2018-05-17 20:31:37
【问题描述】:

我想制作一个力图,其中节点上的文本和链接上的文本永久可见。

这个snippet 在节点上提供标签。

Show tool-tip on links of force directed graph in d3js 答案的第二个 sn-p 在链接和节点上提供鼠标悬停标签。

我目前正在尝试扩展第二个以使鼠标悬停节点标签永久化。

var width = 400;
var height = 125;
var margin = 20;
var pad = margin / 2;

var graph = {  "nodes":[ { "name": "A"}, { "name": "B"}] };
drawGraph(graph);

function drawGraph(graph) {
  var svg = d3.select("#force").append("svg")
    .attr("width", width)
    .attr("height", height);

  // create an area within svg for plotting graph
  var plot = svg.append("g")
    .attr("id", "plot")
    .attr("transform", "translate(" + pad + ", " + pad + ")");

  var layout = d3.layout.force()
    .size([width - margin, height - margin])
    .charge(-120)
    .nodes(graph.nodes)
    .start();

  drawNodes(graph.nodes);

  // add ability to drag and update layout
  d3.selectAll(".node").call(layout.drag);

  layout.on("tick", function() {
    d3.selectAll(".node")
      .attr("cx", d =>  { return d.x; })
      .attr("cy", d =>  { return d.y; });
      
  });
}

// Draws nodes on plot
function drawNodes(nodes) {

  d3.select("#plot").selectAll(".node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("id", (d, i) => { return d.name;  })
    .attr("cx", (d, i) => { return d.x;  })
    .attr("cy", (d, i) => { return d.y;  })
    .attr("r",  4)
    .style("fill", "#EE77b4")
    .on("mouseover", function(d, i) {

      var x = d3.mouse(this)[0];
      var y = d3.mouse(this)[1];
      var tooltip = d3.select("#plot")
        .append("text")
        .text(d.name)
        .attr("x", x)
        .attr("y", y)
        .attr("id", "tooltip");

    })
    .on("mouseout", function(d, i) {
      d3.select("#tooltip").remove();
    });
}
body {
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 300;
}
b {
  font-weight: 900;
}
.outline {
  fill: none;
  stroke: #888888;
  stroke-width: 1px;
}
#tooltip {
  font-size: 10pt;
  font-weight: 900;
  fill: #000000;
  stroke: #ffffff;
  stroke-width: 0.25px;
}
.node {
  stroke: #ffffff;
  stroke-weight: 1px;
}
.highlight {
  stroke: red;
  stroke-weight: 4px;
  stroke-opacity: 1.0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div align="center" id="force"></div>

我尝试将鼠标悬停功能替换为:

.each( function(d, i) {
      var x = d.x; //d3.mouse(this)[0];
      var y = d.y; //d3.mouse(this)[1];
      var tooltip = d3.select("#plot")
        .append("text")
        .text(d.name)
        .attr("x", x)
    .attr("y", y)
    .attr("id", "tooltip");

    })

但是现在标签不动所以我添加了

d3.selectAll("text").attr( "x", d => { return d.x; })
                    .attr( "y", d => { return d.y; });

layout.on("tick", function() ...

但现在它都在一个地方不动,我得到TypeError: d is undefined

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    以这种方式重写您的代码(注意 cmets):

      layout.on("tick", function() {
        tooltips // here we set new position for tooltips on every tick
          .attr("x", (d, i) => { return d.x;  })
          .attr("y", (d, i) => { return d.y;  });
    
        d3.selectAll(".node")
          .attr("cx", d =>  { return d.x; })
          .attr("cy", d =>  { return d.y; });
    
      });
    
    ...
    
    function drawNodes(nodes) {
      tooltips = d3.select("#plot").selectAll(".node")
        .data(nodes)
        .enter()
        .append("circle")
        .attr("class", "node")
        .attr("id", (d, i) => { return d.name;  })
        .attr("cx", (d, i) => { return d.x;  })
        .attr("cy", (d, i) => { return d.y;  })
        .attr("r",  4)
        .style("fill", "#EE77b4")
        .select(function() { return this.parentNode }) // returns to parent node
        .append('text') // append svg-text elements for tooltip
        .data(nodes)
        .text(function(d) { return d.name; }) // set text
        .attr("x", (d, i) => { return d.x;  }) // set initial x position
        .attr("y", (d, i) => { return d.y;  }) // set initial y position
        .attr("id", function(d,i) { return "tooltip-" + i; }) // set unique id
        .attr("class", "d3-tooltip");
    }
    

    工作演示:

    var width = 400;
    var height = 125;
    var margin = 20;
    var pad = margin / 2;
    var tooltips = null;
    
    var graph = {  "nodes":[ { "name": "A"}, { "name": "B"}] };
    drawGraph(graph);
    
    function drawGraph(graph) {
      var svg = d3.select("#force").append("svg")
        .attr("width", width)
        .attr("height", height);
    
      // create an area within svg for plotting graph
      var plot = svg.append("g")
        .attr("id", "plot")
        .attr("transform", "translate(" + pad + ", " + pad + ")");
    
      var layout = d3.layout.force()
        .size([width - margin, height - margin])
        .charge(-120)
        .nodes(graph.nodes)
        .start();
    
      drawNodes(graph.nodes);
    
      // add ability to drag and update layout
      d3.selectAll(".node").call(layout.drag);
    
      layout.on("tick", function() {
        tooltips
          .attr("x", (d, i) => { return d.x;  })
          .attr("y", (d, i) => { return d.y;  });
        
        d3.selectAll(".node")
          .attr("cx", d =>  { return d.x; })
          .attr("cy", d =>  { return d.y; });
          
      });
    }
    
    // Draws nodes on plot
    function drawNodes(nodes) {
      tooltips = d3.select("#plot").selectAll(".node")
        .data(nodes)
        .enter()
        .append("circle")
        .attr("class", "node")
        .attr("id", (d, i) => { return d.name;  })
        .attr("cx", (d, i) => { return d.x;  })
        .attr("cy", (d, i) => { return d.y;  })
        .attr("r",  4)
        .style("fill", "#EE77b4")
        .select(function() { return this.parentNode })
        .append('text')
        .data(nodes)
        .text(function(d) { return d.name; })
        .attr("x", (d, i) => { return d.x;  })
        .attr("y", (d, i) => { return d.y;  })
        .attr("class", "d3-tooltip")
        .attr("id", function(d,i) { return "tooltip-" + i; });
    }
    body {
      font-family: 'Source Sans Pro', sans-serif;
      font-weight: 300;
    }
    b {
      font-weight: 900;
    }
    .outline {
      fill: none;
      stroke: #888888;
      stroke-width: 1px;
    }
    .d3-tooltip {
      font-size: 20pt;
      font-family: 'Comic Sans MS';
      font-weight: 900;
      fill: #000000;
      stroke: #ffffff;
      stroke-width: 0.25px;
    }
    .node {
      stroke: #ffffff;
      stroke-weight: 1px;
    }
    .highlight {
      stroke: red;
      stroke-weight: 4px;
      stroke-opacity: 1.0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <div align="center" id="force"></div>

    【讨论】:

    • 非常感谢!如何仅为tooltip 设置font-family?我尝试将线路从body 移动到#tooltip,但它没有用...
    • @peer 我更新了答案,检查一下。您可以为工具提示添加“类”属性(在我们的例子中为d3-tooltip)并在您的css中定义此类的样式。
    猜你喜欢
    • 2011-07-07
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    相关资源
    最近更新 更多