javascript - d3二图秒杀一图布局

标签 javascript svg d3.js force-layout

当我想显示多个网络可视化图时,我在使用 d3.js 可视化网络库时遇到了一些问题。 由于我绘制了一张新图,只有最后一张图的力布局有效,我无法找出哪里出了问题。

这是 jsfiddle: https://jsfiddle.net/7mn0qy5b/2/

这是我的来源:

HTML

<div id="graph1"></div>
<div id="graph2"></div>

CSS

#graph1, #graph2 {
    width: 250px;
    height: 250px;
    border: 1px solid #000;
}
.link {
    stroke: #626262;
    strokeWidth: 2px;
}

JS

var graph = {};

function myGraph(el) {
    this.link = {};
    this.node = {};
    this.container = el;

    // Add and remove elements on the graph object
    this.addNode = function (id) {
        nodes.push({"id":id});
        update();
    };

    this.removeNode = function (id) {
        var i = 0;
        var n = findNode(id);
        while (i < links.length) {
            if ((links[i]['source'] == n)||(links[i]['target'] == n))
            {
                links.splice(i,1);
            }
            else i++;
        }
        nodes.splice(findNodeIndex(id),1);
        update();
    };

    this.removeLink = function (source,target){
        for(var i=0;i<links.length;i++)
        {
            if(links[i].source.id == source && links[i].target.id == target)
            {
                links.splice(i,1);
                break;
            }
        }
        update();
    };

    this.removeallLinks = function(){
        links.splice(0,links.length);
        update();
    };

    this.removeAllNodes = function(){
        nodes.splice(0,links.length);
        update();
    };

    this.addLink = function (source, target, value) {
        links.push({"source":findNode(source),"target":findNode(target),"value":value});
        update();
    };

    var findNode = function(id) {
        for (var i in nodes) {
            if (nodes[i]["id"] === id) return nodes[i];
        };
        return null;
    };

    var findNodeIndex = function(id) {
        for (var i=0;i<nodes.length;i++) {
            if (nodes[i].id==id){
                return i;
            }
        };
        return null;
    };

    // set up the D3 visualisation in the specified element
    var w = 250,
        h = 250;

    this.vis = d3.select(el)
        .append("svg:svg")
        .attr("width", w)
        .attr("height", h)
        .attr("id","svg")
        .attr("pointer-events", "all")
        .attr("viewBox","0 0 "+w+" "+h)
        .attr("perserveAspectRatio","xMinYMid")
        .append('svg:g');

    this.force = d3.layout.force();

    var nodes = this.force.nodes(),
        links = this.force.links();

    self = this;
    var update = function () {
        self.link = self.vis.selectAll("line")
                .data(links, function(d) {
                    return d.source.id + "-" + d.target.id; 
                });

        self.link.enter().append("line")
            .attr("id",function(d){return d.source.id + "-" + d.target.id;})
            .attr("class","link")
            .append("title")
            .text(function(d){
                return d.value;
            });
        self.link.exit().remove();

        self.node = self.vis.selectAll("g.node")
            .data(nodes, function(d) { 
                return d.id;
            });

        var nodeEnter = self.node.enter().append("g")
            .attr("class", "node")
            .call(self.force.drag);

        nodeEnter.append("svg:circle")
            .attr("r", 16)
            .attr("id",function(d) { return "svgNode_"+self.container+"_"+d.id;})
            .attr("class","nodeStrokeClass");

        nodeEnter.append("svg:text")
            .attr("class","textClass")
            .text( function(d){return d.id;}) ;

        self.node.exit().remove();
        self.force.on("tick", function() {
            //console.log(self.container);
            /*self.node.attr("cx", function(d) { return d.x = Math.max(d.radius, Math.min(svg[spaceId].attr('width') - d.radius, d.x)); })
                    .attr("cy", function(d) { return d.y = Math.max(d.radius, Math.min(svg[spaceId].attr('height') - d.radius, d.y)); })
                    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
            */self.node.attr("transform", function(d) { return "translate("+d.x+","+d.y+")"; });

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

        // Restart the force layout.
        self.force
            .gravity(.06)
            .distance(100)
            .charge(-300)
            .size([w, h])
            .start();
    };
    // Make it all go
    update();
}
graph["#graph1"] = new myGraph("#graph1");
graph["#graph1"].addNode('A');
graph["#graph1"].addNode('B');
graph["#graph1"].addNode('C');
graph["#graph1"].addLink('A','B','10');
graph["#graph1"].addLink('A','C','8');
graph["#graph1"].addLink('B','C','15');
setTimeout(function() {
    graph["#graph2"] = new myGraph("#graph2");
    graph["#graph2"].addNode('D');
    graph["#graph2"].addNode('E');
    graph["#graph2"].addNode('F');
    graph["#graph2"].addLink('D','E','10');
    graph["#graph2"].addLink('D','F','8');
    graph["#graph2"].addLink('E','F','15');
}, 2000);

谢谢你的帮助,我快疯了......

最佳答案

这一行

self = this;

缺少 var 关键字。没有它,self 将分配给全局 window 范围而不是本地 myGraph 范围。在第二次运行 myGraph 构造函数时,首先 myGraphwindow.self 被新值覆盖。因此,两个 myGraph 对象中的事件都引用了第二个 self,这会导致中断。

您可能想要启用 strict mode , 这样编译器就会对这种难以追踪的错误发出警告。

关于javascript - d3二图秒杀一图布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30033330/

相关文章:

javascript - JS : Getting image id using onmouseover

javascript - 类用于对齐ckeditor

javascript - 删除 X 和 Y 轴上的标签并删除 X 轴上的最后一条网格线

jquery - d3.js 抛出错误 't.slice is not a function'

javascript - JQuery 两个图像 slider css 问题

javascript - RIA 中跨浏览器的键盘快捷键约定、可访问性

r - knitr,pandoc:将SVG直接嵌入HTML文档

使用 SVG 中的外部对象创建文本区域的 Javascript 不起作用

php - 在 PHP 中将 SVG 文件渲染为 PNG 或 JPEG

javascript - 如何转义字符串中的所有特殊字符?