【问题标题】:D3 mouse-over of links in node-link diagram, increase 'accepted' rangeD3 将鼠标悬停在节点链接图中的链接上,增加“接受”范围
【发布时间】:2017-03-12 03:50:51
【问题描述】:

有时我需要在节点链接图中以非常小的笔划宽度(

我正在使用.on('mouseover', () => //do stuff) 函数。

有没有一种简单的方法可以增加触发鼠标悬停事件的半径?假设它应该始终假设边缘的笔画宽度至少为 5px。

我正在动态着色边缘,但有没有办法将边缘的颜色设置为类似的颜色(将灰色面板视为边缘,水平布置):

transparent (2px)
color (1px)
transparent (2px)

所以它实际上有 5px 的大小,但只有 1px 是可见的?

或者我真的必须手动计算我的边缘是否与鼠标重叠? (这绝对是可能的,但考虑到有些边缘是弯曲的,有些则不是,......这确实很麻烦)。

【问题讨论】:

    标签: javascript css d3.js


    【解决方案1】:

    有没有一种简单的方法可以增加触发鼠标悬停事件的半径?

    不,事件处理程序已添加到元素中,如果窄元素的笔画宽度为 3px,则该函数只会在鼠标悬停在这些像素上时运行。

    有没有办法将边缘的颜色设置为 [...] 它实际上的大小为 5px,但只有 1px 可见?

    这可以使用路径并将彩色填充与透明笔触相结合。然而,一种更简单的方法是复制选择,具有完全相同的 same 属性,并使顶部路径或行(“顶部”是指代码中稍后出现的选择)透明且具有更大的笔画宽度。

    例如,在这个演示中,有 20px 宽的透明线,在可见的窄线上捕获 mousemove 事件:

    //these lines are painted first
    var links = svg.selectAll("foo")
        .data(edges)
        .enter()
        .append("line")
        .style("stroke", "#ccc")
        .style("stroke-width", 1);
    
    //these transparent lines are painted on top, and they capture the mousemove
    var linksTransparent = svg.selectAll("foo")
        .data(edges)
        .enter()
        .append("line")
        .style("stroke", "none")
        .attr("pointer-events", "all")
        .style("stroke-width", 20)
        .on("mousemove", d => {
            console.log("source: " + d.source.id + ", target: " + d.target.id)
        });
    

    var width = 400;
    var height = 200;
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width", width)
      .attr("height", height);
    
    var nodes = [{
      "id": "One"
    }, {
      "id": "Two"
    }, {
      "id": "Three"
    }, {
      "id": "Four"
    }];
    
    var edges = [{
      "source": 0,
      "target": 1
    }, {
      "source": 0,
      "target": 2
    }, {
      "source": 0,
      "target": 3
    }];
    
    var simulation = d3.forceSimulation()
      .force("link", d3.forceLink().distance(60))
      .force("charge", d3.forceManyBody().strength(-200))
      .force("center", d3.forceCenter(width / 2, height / 2));
    
    var links = svg.selectAll("foo")
      .data(edges)
      .enter()
      .append("line")
      .style("stroke", "#ccc")
      .style("stroke-width", 1);
    
    var links2 = svg.selectAll("foo")
      .data(edges)
      .enter()
      .append("line")
      .style("stroke", "none")
      .attr("pointer-events", "all")
      .style("stroke-width", 20)
      .on("mousemove", d => {
        console.log("source: " + d.source.id + ", target: " + d.target.id)
      });
    
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    
    var node = svg.selectAll("foo")
      .data(nodes)
      .enter()
      .append("g")
      .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));
    
    var nodeCircle = node.append("circle")
      .attr("r", 10)
      .attr("stroke", "gray")
      .attr("fill", (d, i) => color(i));
    
    var texts = node.append("text")
      .style("fill", "black")
      .attr("dx", 20)
      .attr("dy", 8)
      .text(function(d) {
        return d.id;
      });
    
    simulation.nodes(nodes);
    simulation.force("link")
      .links(edges);
    
    simulation.on("tick", function() {
      links.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;
        });
    
      links2.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", (d) => "translate(" + d.x + "," + d.y + ")")
    
    });
    
    function dragstarted(d) {
      if (!d3.event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    }
    
    function dragged(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    }
    
    function dragended(d) {
      if (!d3.event.active) simulation.alphaTarget(0);
      d.fx = null;
      d.fy = null;
    }
    <script src="https://d3js.org/d3.v4.min.js"></script>

    【讨论】:

    • 谢谢!复制边缘是最简单的方法!没想到这个
    猜你喜欢
    • 2014-03-28
    • 2019-09-04
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多