【问题标题】:D3: enter(), exit() on mouseover/mouseoutD3:在鼠标悬停/鼠标移出时进入(),退出()
【发布时间】:2026-02-03 17:40:01
【问题描述】:

我有一个函数,当鼠标悬停在线图上的某个点时,它会调用 Twitter API 并获取与其时间戳关联的推文。然后它添加与数据相对应的嵌套 div 和元素。我的问题是,在 mouseout 时,我想从 DOM 中删除该 div 及其相关数据,以便当我将鼠标悬停在另一个点上时,会使用相关数据创建一个新面板。

我的鼠标悬停如下:

.on("mouseover", function(d,i){
    var tweetDivs = d3.select(".panel").selectAll("div.panel-body")
                      .data(tweet_list)
                      .enter()
                      .append("div")
                      .attr("id", function(d){return "p"+d['id_str']})
                      .classed("panel-body", true);

                tweetDivs.append("img")
                    .attr("width", 20)
                    .attr("height", 20)
                    .attr("src", function(d){return d['user']['profile_image_url']})
                    .classed("panel-tweet-img-profile", true);

                tweetDivs.append("p")
                    .text(function(d){
                        var tweet_created_format = d3.timeFormat("%-I:%M%p, %e %b %Y")(d3.timeParse("%a %b %d %H:%M:%S %Z %Y")(d['created_at']));
                        return "@"+d['user']['screen_name']+"    ("+tweet_created_format+")";
                    })
                    .classed("panel-tweet-text-header", true);

                tweetDivs.append("p")
                    .text(function(d){return d['text'];})
                    .classed("panel-tweet-text-body", true);

                var infoBlock = tweetDivs.append("p")
                                .classed("panel-tweet-info-block", true);

                infoBlock.append("img")
                    .attr("src", imgRetweet)
                    .classed("panel-tweet-img-retweet", true);
                infoBlock.append("text")
                    .text(function(d){
                        return d['retweet_count'];
                    })
                    .classed("panel-tweet-text-retweet", true);

                infoBlock.append("img")
                        .attr("src", imgFav)
                        .classed("panel-tweet-img-favorite", true);
                infoBlock.append("text")
                    .text(function(d){
                        return d['favorite_count'];
                    })
                .classed("panel-tweet-text-favorite", true);
});

我的 mouseout 函数旨在删除它,具有以下 exit() 函数:

    .on("mouseout", function(d,i){
        // exit()
        var panelRemove = d3.select(".panel-body");

        panelRemove.data(tweet_list)
                    .exit()
                    .remove();
    });

我不确定我做错了什么,因为我传递了相同的数据以在此处删除。我也尝试过d3.select(".panel").selectAll("div.panel-body"),但没有任何反应。

初始面板看起来非常好,包含所有相关数据。但是 mouseout 不会删除它,我也无法显示新面板。

【问题讨论】:

    标签: javascript jquery html d3.js


    【解决方案1】:

    由于您将相同的tweet_list 数据传递给panelRemove 选择,exit() 代码将找不到任何要删除的节点。 exit().remove() 将删除不再在数据中表示的现有节点。如果您要传入一个空的推文列表作为新数据,exit().remove() 应该删除节点。

    【讨论】: