Как извлечь forceSimulation? - PullRequest
0 голосов
/ 11 апреля 2019

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

Различная функция

function draw_network(nodes, links){
    var graph = {};
    graph.links = links;
    graph.nodes = nodes;
    graph = JSON.stringify(graph);
    graph = JSON.parse(graph);
    console.log(graph);

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

    var simulation = d3.forceSimulation()
        .nodes(graph.nodes)
        .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(100))
        .force('charge', d3.forceManyBody()
            .strength(-2500)
            .theta(0.8)
        )
        .force("center", d3.forceCenter(width / 2, height / 2));

    var g = svg.append("g")
        .attr("class", "everything");

    //add zoom capabilities 
    var zoom_handler = d3.zoom()
        .on("zoom", zoom_actions);

    zoom_handler(svg);

    //Zoom functions 
    function zoom_actions(){
        g.attr("transform", d3.event.transform)
    }

    // Load network
    run(graph, simulation);

};

function run(graph, simulation) {
    graph.links.forEach(function(d){
        d.source = d.Source;    
        d.target = d.Target;
    });           

    var g = d3.select(".everything");

    // Set links
    var link = g.append("g")
        .attr("class", "links")
        .selectAll("line")
        .data(graph.links)
        .enter().append("line")
            .attr("class", "link")
            .on('mouseout', fade(1))
            .attr("stroke-width", 2);

    // Set nodes
    var node = g.append("g")
        .attr("class", "nodes")
        .selectAll("g")
        .data(graph.nodes)
        .enter()
            .append("circle")
            .attr("class", "circle");

    // Set rectangle begind label
    var rect = g.append("g")
        .attr("class", "rects")
        .selectAll("rect")
        .data(graph.nodes)
        .enter().append("rect")
            .attr("class", "rect")
            .attr("rx", 5) // round shape
            .attr("ry", 5);

    // Set labels
    var label = g.append("g")
        .attr("class", "labels")
        .selectAll("text")
        .data(graph.nodes)
        .enter().append("text")
            .attr("class", "label")
            .attr("dx", 0)
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .text(function(d) { return d.id; });

    /* Configuration of simulation */
    simulation
        .nodes(graph.nodes)
        .on("tick", ticked(graph, node, link, rect, label));

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

} // End function run


//////////////////////////////////////
/* Set position of network element */
/////////////////////////////////////
function ticked(data, node, link, rect, label) {
    d3.select("svg").selectAll("text").each(function(d, i) {
        data.nodes[i].bb = this.getBBox(); // get bounding box of text field and store it in texts array
    });

    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; })
        .style("stroke", "#aaa");

    node
        .attr("cx", function (d) { return d.x; })
        .attr("cy", function (d) { return d.y; })
        .attr("r", 30)
        .attr("fill", function(d){ 
            if(d.search == true) {
                return "black";
            }else{
                return "grey";
            }
        })
        .on('mouseover', fade(0.1, node, link, data))
        .on('mouseout', fade(1, node, link, data))
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));

    rect
        .attr("x", function(d) { return d.x - d.bb.width/2-2; })
        .attr("y", function(d) { return d.y - d.bb.height/2; })
        .attr("width", function(d) { return d.bb.width + 4; })
        .attr("height", function(d) { return d.bb.height; })
        .style("fill", "white")
        .style("opacity", 0.7);


    label
        .attr("x", function(d) { return d.x; })
        .attr("y", function (d) { return d.y; })
        .style("font-size", "14px")
        .style("fill", "#000");

} // end function ticked


function fade(opacity, node, link, graph) {
    return d => {
        node.style('stroke-opacity', function (o) {
          const thisOpacity = isConnected(d, o, graph) ? 1 : opacity;
          this.setAttribute('fill-opacity', thisOpacity);
          return thisOpacity;
        });

        link.style('stroke-opacity', o => (o.source === d || o.target === d ? 1 : opacity));
    };
};


function isConnected(a, b, graph) {

    /* On node mouseover, highlight connected node */
    const linkedByIndex = {};
        graph.links.forEach(d => {
        linkedByIndex[`${d.source.index},${d.target.index}`] = 1;
    });
    return linkedByIndex[`${a.index},${b.index}`] || linkedByIndex[`${b.index},${a.index}`] || a.index === b.index;
}

function dragstarted(d) {
    if (!d3.event.active) simulation.alphaTarget(0.3).restart()
    d.fx = d.x
    d.fy = d.y
    // simulation.fix(d);
}

function dragged(d) {
    d.fx = d3.event.x
    d.fy = d3.event.y
}

function dragended(d) {
    d.fx = d3.event.x
    d.fy = d3.event.y
    if (!d3.event.active) simulation.alphaTarget(0);
    setTimeout(function(){
        simulation.stop();
    }, 2000);
}

В моем основном коде я звоню:

draw_network(nodes, links);

В настоящее время я получаю узлы, но они не были смоделированы, и связи между узлами расположены в верхнем левом углу, когда они должны соединять узлы вместе.

...