D3 js длина ссылки между узлами изображения

1

Имея следующий график: Изображение 174551

При 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;
}
  • 0
    Можете ли вы поделиться gSharedActivityGraphEdges ?
  • 0
    @GerardoFurtado уверен, моя ошибка, добавил
Показать ещё 1 комментарий
Теги:
d3.js
svg

1 ответ

1
Лучший ответ

Я собирался опубликовать ответ, показывающий, как пересчитать позицию x и y. Однако, поскольку вы сказали в комментариях, что просто изменение непрозрачности изображения (без изменения непрозрачности круга) вам подходит, это то, что вам нужно:

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>
  • 0
    @GerardoFutado Я обнаружил проблему с этим решением, когда позже добавил новые ссылки и узлы и merge . Новые ссылки появляются над старыми узлами. Есть идеи, как это исправить?
  • 0
    Пожалуйста, отправьте новый вопрос, со всеми соответствующими деталями. Таким образом, будет легче отлаживать его, и вам будет помогать больше пользователей.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню