Javascript d3使用超过1个JSON的力图

Javascript d3使用超过1个JSON的力图,javascript,json,d3.js,force-layout,Javascript,Json,D3.js,Force Layout,我不确定这是否已经做到(或者可以做到),因为我没有看到任何关于它的例子或问题,但我会尽力解释 我有一个d3力图,我试图赋予它“扩展”的功能。示例:我有一个带有 { "nodes": [ {"name":"p1"}, {"name":"p2"}, {"name":"p3"}, {"name":"p4"} ], "links": [ {"source":"p1","target":"p2"}, {"source":"p1","target":"p3"}, {"source":"p3","target

我不确定这是否已经做到(或者可以做到),因为我没有看到任何关于它的例子或问题,但我会尽力解释

我有一个d3力图,我试图赋予它“扩展”的功能。示例:我有一个带有

{
"nodes": [
{"name":"p1"},
{"name":"p2"},
{"name":"p3"},
{"name":"p4"}
],
"links": [
{"source":"p1","target":"p2"},
{"source":"p1","target":"p3"},
{"source":"p3","target":"p2"},
{"source":"p3","target":"p4"}
]}
因此,如果用户选择节点p3并选择展开。它发送一个请求,我们得到一个JSON,它可以包含新的节点和链接(但也可以包含重复项)。即

因为我不确定这是否可以在d3中完成。我通过将新的JSON数据附加到旧的JSON数据(重复和全部)来测试功能。现在我假设d3会检查图中已经存在的重复项(如p3到p4),但是在追加之后,当我运行图时,所有p3 p4 p5和p6都只是在空间中浮动,没有链接,即使我指定了链接,并且它创建了p3 p4节点,即使它已经存在。(带有4个节点的初始图形仍在构建中,并且链接正确)

那么功能是否可以在d3中执行?我见过一些人希望在屏幕上显示多个图形,但我做的更多的是重叠/合并

我已经尝试过创建我的初始图形,然后我使用一个测试,我按下一个按钮,然后在另一个JSON中读取它,但它中断或根本没有创建任何东西

我的代码:

// Define the dimensions of the visualization.
var width = innerWidth,
    height = innerHeight,
    color = d3.scale.category20(),
    root;

// Create an array logging what is connected to what
var linkedByIndex = { };

// Create the SVG container for the visualization and define its dimensions
var svg = d3.select('body').append('svg')
    .attr('width', width)
    .attr('height', height);

var link = svg.selectAll(".link"),
    node = svg.selectAll(".node"),
    linkText;

// Mouse Event Variables
var selected_node = null,
    selected_link = null,
    mousedown_node = null,
    mousedown_link = null,
    mouseup_node = null;

// Create the force layout
var force = d3.layout.force()
    .size([width, height])
    .charge(-650)
    .linkDistance(80);

var jsonStack = { };
var jsonCount = 0;
var jsonPath1 = "../../test/resources/cytoscape.json";
var jsonPath2 = "../../test/resources/cytoscapeexpand.json";

// Read in the JSON data.
d3.json(jsonPath1, function (error, json) {
// expands scope of json
jsonStack[jsonCount] = json;
root = jsonStack[jsonCount];
console.log("Successfully loaded" + json);
//console.log(JSON.stringify(root));
update();
jsonCount += 1;
});

d3.select('#expand').on("click", function() {
d3.json(jsonPath2, function(error, json) {
    // expands scope of json
    root = json

    update();
});
});

function update() {

// sets the source and target to use id instead of index
root.edges.forEach(function(e) {
    var sourceNode = root.nodes.filter(function(n) {
                return n.data.id === e.data.source;
        })[0],
        targetNode = root.nodes.filter(function(n) {
                return n.data.id === e.data.target;
        })[0];

    // push the EDGE attributes in the JSON to the edges array.
    edges.push({
        source: sourceNode,
        target: targetNode,
        label: e.data['label'],
        color: e.data['color']
    });
});

force
        .nodes(root.nodes)
        .links(edges)
        .start();

link = link
        .data(edges)
        .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", 1.5);

node = node
        .data(root.nodes)
        .enter().append("g")
        .attr("class", "node")
    //.attr("fixed", function(d) { return d.fixed=true })
        .call(force.drag)
        .on('mouseover', connectedNodes)
        .on('mouseleave', restore)
        .on('dblclick', highlight);

node.append("circle").attr("r", 11);

node.style("fill", function(d) { return d.data['color'] }).select("circle").style("stroke", "black");
link.style("stroke", function(d) { return d.color });

node.append("text")
        .attr("dx", 12)
        .attr("dy", ".35em")
        .style("fill", "black")
        .text(function (d) { return d.data['label']; });

root.edges.forEach(function (d) {
    linkedByIndex[d.data.source + "," + d.data.target] = 1;
});

resize();
window.addEventListener('resize', resize);

force.on("tick", function() {
    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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

});
}

// Highlighting of selected node.
function highlight(d) {
if (d.selected == false) {
    d.selected = true;
        return d3.select(this).style("fill", "yellow");
}
else {
    d.selected = false;
        return d3.select(this).style("fill", d.data['color']);
}
update();
}

是的,这当然是可能的。要修改力布局,您可以找到help.Hmmmmm的第二部分。因此,我必须
停止
,将我的文件添加到
数据()
,然后再
开始
?我只是尝试了一下,然后运行了我的测试,我点击了一个按钮,读入了另一个JSON文件(在初始化和创建了初始的力图之后),它只会使之前的图冻结并在其上创建一个新的图(带有新的JSON数据)。从技术上讲,你不必停止布局,但你必须调用
.start()
添加所有新数据后。也许会有帮助,就像阿美一样。我试着按照这些例子来做。所以现在,当我在代码中运行测试获得第二个JSON时,它有一个非常奇怪的行为。单击“展开”一次时,只有链接将显示为没有边。然后,再次单击展开按钮后,完整图形显示为一个副本,但如果我将鼠标放在原始图形中的某个节点上,则使用我的高亮显示功能(当鼠标移到上方时,它将显示邻居),如果假设第二个图形中连接了任何相邻节点,则将高亮显示。我还是无法让他们联系上。我已经用部分代码更新了我的问题。
// Define the dimensions of the visualization.
var width = innerWidth,
    height = innerHeight,
    color = d3.scale.category20(),
    root;

// Create an array logging what is connected to what
var linkedByIndex = { };

// Create the SVG container for the visualization and define its dimensions
var svg = d3.select('body').append('svg')
    .attr('width', width)
    .attr('height', height);

var link = svg.selectAll(".link"),
    node = svg.selectAll(".node"),
    linkText;

// Mouse Event Variables
var selected_node = null,
    selected_link = null,
    mousedown_node = null,
    mousedown_link = null,
    mouseup_node = null;

// Create the force layout
var force = d3.layout.force()
    .size([width, height])
    .charge(-650)
    .linkDistance(80);

var jsonStack = { };
var jsonCount = 0;
var jsonPath1 = "../../test/resources/cytoscape.json";
var jsonPath2 = "../../test/resources/cytoscapeexpand.json";

// Read in the JSON data.
d3.json(jsonPath1, function (error, json) {
// expands scope of json
jsonStack[jsonCount] = json;
root = jsonStack[jsonCount];
console.log("Successfully loaded" + json);
//console.log(JSON.stringify(root));
update();
jsonCount += 1;
});

d3.select('#expand').on("click", function() {
d3.json(jsonPath2, function(error, json) {
    // expands scope of json
    root = json

    update();
});
});

function update() {

// sets the source and target to use id instead of index
root.edges.forEach(function(e) {
    var sourceNode = root.nodes.filter(function(n) {
                return n.data.id === e.data.source;
        })[0],
        targetNode = root.nodes.filter(function(n) {
                return n.data.id === e.data.target;
        })[0];

    // push the EDGE attributes in the JSON to the edges array.
    edges.push({
        source: sourceNode,
        target: targetNode,
        label: e.data['label'],
        color: e.data['color']
    });
});

force
        .nodes(root.nodes)
        .links(edges)
        .start();

link = link
        .data(edges)
        .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", 1.5);

node = node
        .data(root.nodes)
        .enter().append("g")
        .attr("class", "node")
    //.attr("fixed", function(d) { return d.fixed=true })
        .call(force.drag)
        .on('mouseover', connectedNodes)
        .on('mouseleave', restore)
        .on('dblclick', highlight);

node.append("circle").attr("r", 11);

node.style("fill", function(d) { return d.data['color'] }).select("circle").style("stroke", "black");
link.style("stroke", function(d) { return d.color });

node.append("text")
        .attr("dx", 12)
        .attr("dy", ".35em")
        .style("fill", "black")
        .text(function (d) { return d.data['label']; });

root.edges.forEach(function (d) {
    linkedByIndex[d.data.source + "," + d.data.target] = 1;
});

resize();
window.addEventListener('resize', resize);

force.on("tick", function() {
    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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

});
}

// Highlighting of selected node.
function highlight(d) {
if (d.selected == false) {
    d.selected = true;
        return d3.select(this).style("fill", "yellow");
}
else {
    d.selected = false;
        return d3.select(this).style("fill", d.data['color']);
}
update();
}