代码之家  ›  专栏  ›  技术社区  ›  ItayB

D3 js图像节点之间的链接长度

  •  1
  • ItayB  · 技术社区  · 7 年前

    具有以下图表: enter image description here

    mouseover 在节点上,我只显示它的相邻节点,所有其他节点的不透明度为0.2(透明度)-这很好。 问题是其他节点(不透明度为0.2)之间的链接现在出现了,看起来很糟糕,因为它覆盖了图像的中心。如何使这些链接收缩到图像/圆形边缘?

    var gSharedActivityGraphNodes = [{
        "id": 0,
        "image": "1285700-410.png",
        "height": 40,
        "width": 40,
        "adjacents": [1, 2, 3],
        "data": {
            "name": "Product1",
            "groupId": "Bla1",
            "desc": "Desc1",
            "leaderId": "123-123"
        }
    }, {
        "id": 1,
        "image": "1228539-009.png",
        "height": 100,
        "width": 100,
        "adjacents": [0],
        "data": {
            "name": "Product1",
            "groupId": "Bla2",
            "desc": "Desc1",
            "leaderId": "123-123"
        }
    }, {
        "id": 2,
        "image": "1277422-001.png",
        "height": 50,
        "width": 50,
        "adjacents": [0],
        "data": {
            "name": "Product1",
            "groupId": "Bla3",
            "desc": "Desc1",
            "leaderId": "123-123"
        }
    }, {
        "id": 3,
        "image": "1272178-540.png",
        "height": 40,
        "width": 40,
        "adjacents": [0],
        "data": {
            "name": "Product1",
            "groupId": "Bla4",
            "desc": "Desc1",
            "leaderId": "123-123"
        }
    }];
    
    var gSharedActivityGraphNodesMap = {};
    
    var gSharedActivityGraphEdges = [{
        "source": 0,
        "target": 1,
        "width": 5
    }, {
        "source": 0,
        "target": 2,
        "width": 10
    }, {
        "source": 0,
        "target": 3,
        "width": 1
    }];
    
    var width = 1300;
    var height = 500;
    
    var svg = d3.select("#sharedActivityGraph")
        .append("svg")
        .attr("width", width)
        .attr("height", height);
    
     var simulation = d3.forceSimulation()
        .force("link", d3.forceLink())
        .force("charge", d3.forceManyBody().strength(-2000))
        .force("center", d3.forceCenter(width / 2, height / 2));
    
    
    var links = svg.selectAll("foo")
        .data(gSharedActivityGraphEdges)
        .enter()
        .append("line")
        .style("stroke", "#ccc")
        .style("stroke-width", function (e) { return e.width });
    
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    
    var node = svg.selectAll("foo")
        .data(gSharedActivityGraphNodes)
        .enter()
        .append("g")
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));
    
    node.on('mouseover', function (d) {
           console.log(d);
           SharedActivityShowInfo(d);
    
           node.filter(function (d1) { return (d !== d1
           && d1.adjacents.indexOf(d.id) == -1);
           }).style("opacity", 0.2);
           node.filter(function (d1) { return (d == d1
           || d1.adjacents.indexOf(d.id) !== -1);
           }).style("opacity", 1);
        })
        .on('mouseout', function () {
           SharedActivityHideInfo();
            node.style("opacity", 1);
        });
    
    var nodeCircle = node.append("circle")
        .attr("r", function (d) { return 0.5 * Math.max(d.width, d.height) })
        .attr("stroke", "gray")
        .attr("stroke-width", "2px")
        .attr("fill", "white");
    
    var nodeImage = node.append("image")
            .attr("xlink:href", function (d) { return d.image })
            .attr("height", function (d) { return d.height + "" })
            .attr("width", function (d) { return d.width + "" })
            .attr("x", function (d) {return -0.5 * d.width })
            .attr("y", function (d) {return -0.5 * d.height })
            .attr("clip-path", function (d) { return "circle(" + (0.48 * Math.max(d.width, d.height)) + "px)"});
    
    simulation.nodes(gSharedActivityGraphNodes);
    simulation
        .force("link")
        .links(gSharedActivityGraphEdges);
    
    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;
            })
        node.attr("transform", function (d) { return "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;
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Gerardo Furtado    7 年前

    我正要发布一个答案,说明如何重新计算x和y线的位置。然而,既然你说 in the comments 只要更改图像的不透明度(而不更改圆的不透明度)就适合您,这就是您需要的:

    node.on('mouseover', function(d) {
        node.filter(function(d1) {
          return (d !== d1 && d1.adjacents.indexOf(d.id) == -1);
        }).select("image").style("opacity", 0.2);
        node.filter(function(d1) {
          return (d == d1 || d1.adjacents.indexOf(d.id) !== -1);
        }).select("image").style("opacity", 1);
      })
      .on('mouseout', function() {
        node.select("image").style("opacity", 1);
      });
    

    这是您的更新代码:

    var gSharedActivityGraphNodes = [{
      "id": 0,
      "image": "https://www.guidedogsvictoria.com.au/wp-content/uploads/2016/09/guide-dog-710x570.jpg",
      "height": 40,
      "width": 40,
      "adjacents": [1, 2, 3],
      "data": {
        "name": "Product1",
        "groupId": "Bla1",
        "desc": "Desc1",
        "leaderId": "123-123"
      }
    }, {
      "id": 1,
      "image": "https://www.guidedogsvictoria.com.au/wp-content/uploads/2016/09/guide-dog-710x570.jpg",
      "height": 100,
      "width": 100,
      "adjacents": [0],
      "data": {
        "name": "Product1",
        "groupId": "Bla2",
        "desc": "Desc1",
        "leaderId": "123-123"
      }
    }, {
      "id": 2,
      "image": "https://www.guidedogsvictoria.com.au/wp-content/uploads/2016/09/guide-dog-710x570.jpg",
      "height": 50,
      "width": 50,
      "adjacents": [0],
      "data": {
        "name": "Product1",
        "groupId": "Bla3",
        "desc": "Desc1",
        "leaderId": "123-123"
      }
    }, {
      "id": 3,
      "image": "https://www.guidedogsvictoria.com.au/wp-content/uploads/2016/09/guide-dog-710x570.jpg",
      "height": 40,
      "width": 40,
      "adjacents": [0],
      "data": {
        "name": "Product1",
        "groupId": "Bla4",
        "desc": "Desc1",
        "leaderId": "123-123"
      }
    }];
    
    var gSharedActivityGraphNodesMap = {};
    
    var gSharedActivityGraphEdges = [{
      "source": 0,
      "target": 1,
      "width": 5
    }, {
      "source": 0,
      "target": 2,
      "width": 10
    }, {
      "source": 0,
      "target": 3,
      "width": 1
    }];
    
    var width = 500;
    var height = 300;
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width", width)
      .attr("height", height);
    
    var simulation = d3.forceSimulation()
      .force("link", d3.forceLink())
      .force("charge", d3.forceManyBody().strength(-2000))
      .force("center", d3.forceCenter(width / 2, height / 2));
    
    
    var links = svg.selectAll("foo")
      .data(gSharedActivityGraphEdges)
      .enter()
      .append("line")
      .style("stroke", "#ccc")
      .style("stroke-width", function(e) {
        return e.width
      });
    
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    
    var node = svg.selectAll("foo")
      .data(gSharedActivityGraphNodes)
      .enter()
      .append("g")
      .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));
    
    node.on('mouseover', function(d) {
        node.filter(function(d1) {
          return (d !== d1 && d1.adjacents.indexOf(d.id) == -1);
        }).select("image").style("opacity", 0.2);
        node.filter(function(d1) {
          return (d == d1 || d1.adjacents.indexOf(d.id) !== -1);
        }).select("image").style("opacity", 1);
      })
      .on('mouseout', function() {
        node.select("image").style("opacity", 1);
      });
    
    var nodeCircle = node.append("circle")
      .attr("r", function(d) {
        return 0.5 * Math.max(d.width, d.height)
      })
      .attr("stroke", "gray")
      .attr("stroke-width", "2px")
      .attr("fill", "white");
    
    var nodeImage = node.append("image")
      .attr("xlink:href", function(d) {
        return d.image
      })
      .attr("height", function(d) {
        return d.height + ""
      })
      .attr("width", function(d) {
        return d.width + ""
      })
      .attr("x", function(d) {
        return -0.5 * d.width
      })
      .attr("y", function(d) {
        return -0.5 * d.height
      })
      .attr("clip-path", function(d) {
        return "circle(" + (0.48 * Math.max(d.width, d.height)) + "px)"
      });
    
    simulation.nodes(gSharedActivityGraphNodes);
    simulation
      .force("link")
      .links(gSharedActivityGraphEdges);
    
    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;
        })
      node.attr("transform", function(d) {
        return "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>