D3.js中的链接转换(强制布局)

时间:2019-01-03 10:37:49

标签: javascript animation d3.js

我需要创建一个数据可视化,以一次又一次地更改相关对象(圆圈)的颜色。并且当所有圆圈都设置为动画后,可以从第一个对象再次开始。

例如:将颜色更改为绿色->延迟->将颜色更改为灰色->为下一个对象设置动画

我的当前状态是在这里找到:JSfiddle

var test = [9, 8, 2056, 3080, 3084, 1575948, 1575946, 1575947, 1575939, 1576643,
    1576899, 1576931, 1708003, 2039779, 2064355, 2097123, 2097091, 2097107, 2097115,
    2097114, 2097098, 2097099, 2064329, 12233, 4041, 3657, 2057]

var links = [

    {source: 9, target: 8, type: "licensing"},

    {source: 8, target: 3080, type: "licensing"},
    {source: 8, target: 2056, type: "resolved"},

    {source: 3080, target: 3084, type: "licensing"},

    {source: 3084, target: 1575948, type: "licensing"},
    {source: 3084, target: 1051660, type: "resolved"},

    {source:1575948, target: 1575946, type: "licensing"},
    {source:1575948, target: 1575944, type: "resolved"},

    {source:1575946, target: 1575947, type: "licensing"},
    {source:1575946, target: 1575939, type: "resolved"},

    {source:1575947, target: 1575939, type: "licensing"},

    {source:1575939, target: 1576067, type: "licensing"},
    {source:1575939, target: 1576643, type: "resolved"},

    {source:1576067, target: 1576579, type: "resolved"},
    {source:1576067, target: 1576899, type: "resolved"},
    {source:1576067, target: 1576643, type: "licensing"},

    {source:1576579, target: 1576899, type: "resolved"},
    {source:1576579, target: 1576643, type: "licensing"},

    {source:1576899, target: 1576931, type: "licensing"},

    {source:1576931, target: 1708003, type: "licensing"},

    {source:1708003, target: 2039779, type: "resolved"},
    {source:1708003, target: 2064355, type: "resolved"},
    {source:1708003, target: 1777635, type: "licensing"},
    {source:1708003, target: 2056163, type: "licensing"},

    {source:2039779, target: 2064355, type: "licensing"},

    {source:2064355, target: 2097123, type: "licensing"},

    {source:2097123, target: 2097091 , type: "licensing"},

    {source:2097091, target: 2097107, type: "licensing"},

    {source:2097107, target: 2097115, type: "licensing"},

    {source:2097115, target: 2097114, type: "licensing"},

    {source:2097114, target: 2097098, type: "licensing"},

    {source:2097098, target: 2097099, type: "licensing"},

    {source:2097099, target: 2064331, type: "licensing"},
    {source:2097099, target: 2064329, type: "resolved"},
    {source:2097099, target: 2097097, type: "resolved"},

    {source:2064331, target: 12235, type: "resolved"},
    {source:2064331, target: 4043, type: "resolved"},
    {source:2064331, target: 1015755, type: "resolved"},
    {source:2064331, target: 2064329, type: "licensing"},

    {source:12235, target: 4043, type: "licensing"},

    {source:4043, target: 4041, type: "licensing"},


    {source:4041, target: 3785, type: "licensing"},
    {source:4041, target: 2057, type: "resolved"},
    {source:4041, target: 3593, type: "resolved"},
    {source:4041, target: 3657, type: "resolved"},
    {source:4041, target: 2569, type: "resolved"},

    {source:3785, target: 2057, type: "licensing"},
    {source:3785, target: 3593, type: "resolved"},
    {source:3785, target: 3657, type: "resolved"},
    {source:3785, target: 2569, type: "resolved"},

    {source:2056, target: 3080, type: "licensing"},

    {source:1576643, target: 1576899, type: "licensing"},
    {source:1576643, target: 1576675, type: "resolved"},

    {source:1777635, target: 2056163, type: "resolved"},
    {source:1777635, target: 2039779, type: "resolved"},
    {source:1777635, target: 2064355, type: "licensing"},

    {source:1015755, target: 12235, type: "licensing"},

    {source:2064329, target: 4041, type: "resolved"},
    {source:2064329, target: 12233, type: "licensing"},
    {source:2064329, target: 1015753, type: "resolved"},

    {source:12233, target: 4041, type: "licensing"},

    {source:3593, target: 2057, type: "licensing"},

    {source:3657, target: 2057, type: "licensing"},

    {source:1576131, target: 1576899, type: "resolved"},
    {source:1576131, target: 1576643, type: "licensing"},

    {source:2056163, target: 2064355, type: "licensing"},

    {source:1015753, target: 4041, type: "licensing"},

    {source:2569, target: 2057, type: "licensing"},

    {source:1051660, target: 1575948, type: "licensing"},

    {source:2097097, target: 2064329, type: "licensing"},

    {source:1576675, target: 1576931, type: "licensing"},

    {source:1575944, target: 1575946, type: "licensing"}

];

var nodes = {};
let i = 0;

links.forEach(function(link) {
    link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});

var width = 1280,
    height = 1024;


var force = d3.layout.force()
    .nodes(d3.values(nodes))
    .links(links)
    .size([width, height])
    .linkDistance(100)
    .charge(-700)
    .chargeDistance(-700)
    .gravity(0.4)
    .on("tick", tick)
    .start();

// Width and height of the svg
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

// Append arrows to indicate the direction of the processes 
svg.append("defs").selectAll("marker")
    .data(["suit", "licensing", "resolved"])
    .enter().append("marker")
    .attr("id", function(d) { return d; })
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", -1.5)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
    .append("path")
    .attr("d", "M0,-5L10,0L0,5");

var path = svg.append("g").selectAll("path")
    .data(force.links())
    .enter().append("path")
    .attr("class", function(d) { return "link " + d.type; })
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; });

// List of all object-nodes that are active
var activeNodes = force.nodes().filter(d => test.includes(d.name))


// Append the circles that demonstrate the processes
var circle = svg.append("g").selectAll("circle")
    .data(force.nodes())
    .enter().append("circle")
    .attr("r", function(d) {
        if (d.name === 9 | d.name === 2057) {
            return 15;
        } else {
             return 10;
        }
    })
    .style("stroke-width", function(d) {
        if (d.name === 9 | d.name === 2057){
                return '5.2px';}    
        })
    .call(force.drag);

// Append the Process-ID in numbers
var text = svg.append("g").selectAll("text")
    .data(force.nodes())
    .enter().append("text")
    .attr("x", 8)
    .attr("y", ".31em")
    .text(function(d) { return d.name; });

// Use elliptical arc path segments to doubly-encode directionality.
function tick(d) {
    var index = 0
    path.attr("d", linkArc);
    circle.attr("transform", transform);
    text.attr("transform", transform);
    circle.transition()
        .duration(3000)
        .style("fill", function(d) {
            if (activeNodes.includes(d)){
                return 'green';}    
        })
        .transition()
        .duration(4000)
        .style("fill", function(d) {
            if (activeNodes.includes(d)){
                return "#9B9798";}
        })
}

function linkArc(d) {
    var dx = d.target.x - d.source.x,
        dy = d.target.y - d.source.y,
        dr = Math.sqrt(dx * dx + dy * dy);
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

function transform(d) {
    return "translate(" + d.x + "," + d.y + ")";
}

目前我正面临动画问题。我无法弄清楚如何防止所有相关对象同时更改颜色。

我的问题是:

  • 如何独立设置节点动画

  • 到达最后一个对象时如何继续动画循环

谢谢你的想法。

0 个答案:

没有答案