D3.js: Dynamically generate source and target based on identical json values

雨燕双飞 提交于 2019-12-02 12:13:12

问题


Good day, I am a novice in d3/javascript and this may be an easy/repeated question, but I just cannot get this section of my code to work..

I have this json array here:

var myArray = [{"id": "red", "value":"1"},
 {"id": "orange", "value":"2"},
 {"id": "yellow", "value":"3"},
 {"id": "green", "value":"1"},
 {"id": "blue", "value":"1"},
 {"id": "violet", "value":"3"}];

I understand that for me to create links between nodes in D3, I need an array with a [{"source": "___", "target": "___"} structure.

Is anyone able to guide me in linking the above array items based on their values (i.e. the node graph will link all nodes with identical values together)?

One solution in my mind now is to iterate manually through and create links using the for..if.. loop, but this will iterate many times if I have many nodes (>1000?) and will create duplicates along the way.

Here is a picture of the desired output:


回答1:


This is a solution using nested for loops:

var links = [];

for (var i = 0; i < nodes.length; i++) {
    for (var j = i + 1; j < nodes.length; j++) {
        if (nodes[i].value === nodes[j].value) {
            links.push({
                source: nodes[i].id,
                target: nodes[j].id
            });
        }
    }
}

Here is a demo:

var nodes = [{
    "id": "red",
    "value": "1"
}, {
    "id": "orange",
    "value": "2"
}, {
    "id": "yellow",
    "value": "3"
}, {
    "id": "green",
    "value": "1"
}, {
    "id": "blue",
    "value": "1"
}, {
    "id": "violet",
    "value": "3"
}];

var links = [];

for (var i = 0; i < nodes.length; i++) {
    for (var j = i + 1; j < nodes.length; j++) {
        if (nodes[i].value === nodes[j].value) {
            links.push({
                source: nodes[i].id,
                target: nodes[j].id
            });
        }
    }
}

console.log(links);

And here is a demo of the force, with your array:

var nodes = [{
    "id": "red",
    "value": "1"
}, {
    "id": "orange",
    "value": "2"
}, {
    "id": "yellow",
    "value": "3"
}, {
    "id": "green",
    "value": "1"
}, {
    "id": "blue",
    "value": "1"
}, {
    "id": "violet",
    "value": "3"
}];

var links = [];

for (var i = 0; i < nodes.length; i++) {
    for (var j = i + 1; j < nodes.length; j++) {
        if (nodes[i].value === nodes[j].value) {
            links.push({
                source: nodes[i].id,
                target: nodes[j].id
            });
        }
    }
};

var width = 300, height = 300;

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

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(50))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

  var link = svg.append("g")
      .attr("class", "links")
    .selectAll("line")
    .data(links)
    .enter().append("line")
      .attr("stroke-width", 1)
			.attr("stroke", "gray")
			.attr("fill", "none");

  var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(nodes)
    .enter().append("circle")
      .attr("r", 10)
			.attr("stroke", "gray")
      .attr("fill", function(d) { return d.id; });

  simulation
      .nodes(nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(links);

  function ticked() {
    link
        .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("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  }
<script src="https://d3js.org/d3.v4.min.js"></script>


来源:https://stackoverflow.com/questions/41138515/d3-js-dynamically-generate-source-and-target-based-on-identical-json-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!