Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
234 views
in Technique[技术] by (71.8m points)

javascript - 使用d3js的图形中的污染(Contamination in a graph using d3js)

I'm trying to simulate the diffusion of a virus in a network.

(我正在尝试模拟病毒在网络中的传播。)

I've modified a random graph generator to create a graph in which each node represents an individual.

(我修改了一个随机图生成器,以创建一个其中每个节点代表一个人的图。)

Now I would like to be able to click on a node (which infects him) and to see the propagation of the virus in the graph.

(现在,我希望能够单击一个节点(感染他),并在图中查看病毒的传播。)

For exemple, each neighbour of an infected node is infected with a probability p chosen before.

(例如,被感染节点的每个邻居都被感染了之前选择的概率p。)

For the moment, I can only click on a node and it turns red, but that's it.

(目前,我只能单击一个节点,它变为红色,仅此而已。)

Any ideas ?

(有任何想法吗 ?)

Here is the javascript code :

(这是javascript代码:)


var width = 1300, 
height = 1000; 

n = 30
m = 100
charge = -2000
z = 0,7 // contamination parameter

function changevalue() {
n = document.getElementById("numberofnodes").value;
m = document.getElementById("numberoflinks").value;
charge = document.getElementById("chargenumber").value;
}

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .on("dblclick", create);


create();

function create () {
  svg.selectAll(".link, .node").remove();
  randomGraph(n, m, charge);
}

function randomGraph (n, m, charge) {
  var nodes = d3.range(n).map(Object),
      list  = randomChoose(unorderedPairs(d3.range(n)), m),
      links = list.map(function (a) { return {source: a[0], target: a[1]} });

  var force = d3.layout.force()
      .size([width, height])
      .nodes(nodes)
      .links(links)
      .charge(charge)
      .on("tick", tick)
      .start();

  var svgLinks = svg.selectAll(".link").data(links)
    .enter().append("line")
      .attr("class", "link");

  var svgNodes = svg.selectAll(".node").data(nodes)
    .enter().append("circle")
      .attr("class", "node")
      .attr("r", 2)
      .style("fill", "green")
      .style("fill", function(d) {return d.color; })
      .each(function() {
    var sel = d3.select(this);
    var state = false;
    sel.on("click", function() {
      state = !state;
      if (state) {
        sel.style("fill", "red");
      } else {
        sel.style("fill", function(d) { return d.color; });
      }
    });
  });

  svgNodes.transition().duration(2000)
      .attr("r", function (d) { return 0.8 * d.weight })

  svgLinks.transition().duration(20000)
      .style("stroke-width", 1);

  function tick () {
    svgNodes
        .attr("cx", function(d) { return d.x })
        .attr("cy", function(d) { return d.y });

    svgLinks
        .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 });

  }
}


function randomChoose (s, k) { 
  var a = [], i = -1, j;
  while (++i < k) {
    j = Math.floor(Math.random() * s.length);
    a.push(s.splice(j, 1)[0]);
  };
  return a;
}

function unorderedPairs (s) {
  var i = -1, a = [], j;
  while (++i < s.length) {
    j = i;
    while (++j < s.length) a.push([s[i],s[j]])
  };
  return a;
}


  ask by Hello translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A possible approach is to create a function that takes in an array 'infected' nodes and for each infected node:

(一种可能的方法是创建一个函数,该函数接受数组“感染”节点,并为每个感染节点:)

  • examines the links to look for this node is linked

    (检查链接以查找此节点是否已链接)

  • where a link is found, randomly add the linked node to the array of newly infected nodes, and repeat the function.

    (在找到链接的地方,将链接的节点随机添加到新感染节点的数组中,然后重复该功能。)

    The random can be based on whatever probability you want - currently the example below uses 0.5.

    (随机可以基于您想要的任何概率-当前下面的示例使用0.5。)

  • repeat this function a limited number of times, else it will continue forever

    (重复此功能几次,否则它将永远持续下去)

The example below assigns a colour to the infected nodes based on which iteration of the function that node is infected.

(下面的示例根据该节点被感染的函数的哪个迭代为被感染的节点分配颜色。)

 console.clear() var width = 600, height = 500; n = 30 m = 100 charge = -2000 z = 0, 7 // contamination parameter var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) var count = 0 var iterations = 5 var links, nodes var colour = d3.scaleLinear() .domain([1, 10]) .range(["red", "steelblue"]) .interpolate(d3.interpolateHcl); create(); function create() { svg.selectAll(".link, .node").remove(); randomGraph(n, m, charge); } function randomGraph(n, m, charge) { var nodes = d3.range(n).map(function(d) { let obj = {} obj.r = 15 obj.state = false return obj }); list = randomChoose(unorderedPairs(d3.range(n)), m), links = list.map(function(a) { return { source: a[0], target: a[1] } }); var force = d3.forceSimulation(nodes) .force("link", d3.forceLink(links)) .force("collide", d3.forceCollide(30)) .force("center", d3.forceCenter(width / 2, height / 2)) .on("tick", tick) var svgLinks = svg.selectAll(".link") .data(links) .enter() .append("line") .attr("class", "link") var svgNodes = svg.selectAll(".node") .data(nodes) .enter() .append("circle") .attr("id", d => "node-" + d.index) .attr("class", "node") .attr("r", 2) .style("fill", "grey") .on("click", startVirus) svgNodes.transition().duration(2000) .attr("r", function(d) { return 0.8 * dr }) svgLinks.transition().duration(2000) .style("stroke-width", 1); function tick() { svgNodes .attr("cx", function(d) { return dx }) .attr("cy", function(d) { return dy }); svgLinks .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 }); } } function startVirus(node) { d3.selectAll('circle').style("fill", function(d) { d.state = false return "grey" }) let id = node.index count = 0; console.clear() infectCircles([id]) } function infectCircles(carrierIDs) { count = count + 1 let potentialInfections = [] carrierIDs.forEach(function(c) { let circleID = "#node-" + c d3.select(circleID) .transition(2000) .style("fill", function(d) { if (d.state == true) { return d.colour } else { d.state = true d.colour = colour(count) return d.colour } }) links.forEach(function(l) { if (l.source.index == c) { if (Math.random() < 0.5) { console.log("infect! " + l.target.index) potentialInfections.push(l.target.index) } } if (l.target.index == c) { if (Math.random() < 0.5) { console.log("infect! " + l.source.index) potentialInfections.push(l.source.index) } } }) if (count <= iterations) { infectCircles(potentialInfections) } }) } function randomChoose(s, k) { var a = [], i = -1, j; while (++i < k) { j = Math.floor(Math.random() * s.length); a.push(s.splice(j, 1)[0]); }; return a; } function unorderedPairs(s) { var i = -1, a = [], j; while (++i < s.length) { j = i; while (++j < s.length) a.push([s[i], s[j]]) }; return a; } 
 circle { stroke: white; stroke-width: 2; } line { fill: none; stroke: grey; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script> 


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...