【问题标题】:How to prevent node caching如何防止节点缓存
【发布时间】:2013-01-31 11:49:49
【问题描述】:

我使用 d3.js 创建了一个动态的强制导向网络地图。地图最初获取所有网络节点并正确显示它们,网络接口显示为将节点连接在一起的线。这一切都很好。

当用户决定过滤属于特定项目的网络接口时,这就是我遇到问题的地方。我重复使用相同的 d3.layout.force 实例并运行最初创建地图的相同函数,但使用新数据。为了简单起见,我对源代码进行了很多压缩,删除了所有与问题无关的内容。

var _this = {
    graphLayout     : d3.layout.force(),
    node : null,
    link : null,
    selectedProject : null,

    /*****************************************************
        Initialize engine
     *****************************************************/
    render : function() {
        // Creates the SVG container, sets up markers and gradients and whatnots
        // unnecessary for me to include here I think.

        // Start simulation
        _this.update();

        // Apply event handling and set up onTick
    },

    /*****************************************************
        Perform a data update. This will read data from an
        external url, and redraw all graphics.
     *****************************************************/
    update : function(project) {
        if (project !== undefined) {
            _this.selectedProject = project;
        }

        url = 'someService'+(!project ? '/GetNodes' : '/GetNodesByProjectId?projectId='+project.ProjectNumber);
        d3.json(url, function(json) {
            // Update nodes based on data
            // Apply data to graph layout
            _this.graphLayout
                .nodes(json.nodes)
                .links(json.links)
                // Even more parameters which are unnecessary for this question
                .start();

            // Join lines config
            _this.link = d3.select(" svg > .lineContainer").selectAll("g.link").data(_this.graphLayout.links());
            var group = _this.link.enter().append("svg:g")
                // More attributes and click event handling for the lines
                .attr('id',         function(d) { return d.InterfaceNumber; });
            group.append("svg:line");
            _this.link.exit().remove();

            // Node rendering config
            _this.node = d3.select(" svg > .nodeContainer").selectAll("g.node").data(_this.graphLayout.nodes());
            group = _this.node.enter().append("svg:g")
                // More attributes and click event handling for the nodes
                .attr('id',         function(d) { return d.Id; });
            group.append("svg:path")
                .attr("d", _this.nodeSVGPath)
                .attr("fill",       function(d) { return "url(#blackGradient)"; });

这是我遇到问题的地方:

            // Add label to node
            group.append('svg:text').attr('class', 'label').attr('transform', 'translate(25, 30)').text(function(d,i) { return d.Name; });
            _this.node.exit().remove();
        });
    },

第二次调用 update 时,此处放置在 .text 上的函数(d,i)似乎没有运行。是在 d3 中缓存了一些东西,还是我遗漏了什么?

这里的问题是节点(或行)包含正确的data对象,但是节点上呈现的文本不匹配,这让我相信d3js重用了svg对象完全,但与新更新的数据交换。

【问题讨论】:

    标签: javascript graph d3.js


    【解决方案1】:

    是的,您忽略了这一重要事实。 enter() 函数创建一个数据的子选择,其中还没有元素。你应该这样做:

    // Node rendering config
    _this.node = d3.select(" svg > .nodeContainer").selectAll("g.node").data(_this.graphLayout.nodes());
    group = _this.node.enter().append("svg:g")
    // More attributes and click event handling for the nodes
        .attr('id', function(d) { return d.Id; });
    group.append("svg:path")
        .attr("d", _this.nodeSVGPath)
        .attr("fill",       function(d) { return "url(#blackGradient)"; });
        // Add label to node
    group.append('svg:text').attr('class', 'label').attr('transform', 'translate(25, 30)');
    
    // now set the text for all g.node > g > text elements, new or old
    _this.node.select('g > text').text(function(d,i) { return d.Name; });
    
    _this.node.exit().remove();
    

    因为 group 是 _this.node 的 enter() 子选择,所以它永远不会包含在每次调用之前创建的元素。最后,在您设置文本的位置,使用 _this.node 而不是 group 选择所有新的或旧的文本节点。这有帮助吗?

    【讨论】:

    • 谢谢!这就像一个魅力。整个输入/更新概念有点混乱,在我看来,文档记录很差。
    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 2013-02-20
    相关资源
    最近更新 更多