刷新函数未正确调用 d3

Refresh function not being called properly d3

本文关键字:调用 d3 函数 刷新      更新时间:2023-09-26

我正在使用 d3 中的散点图。图表上的点代表一张纸。右键单击一个点时,我有一个上下文菜单,其中有 2 个选项:1) 将该纸张添加到库中(将类型更改为 In_library)和 2) 从库中删除(从数据中完全删除纸张)。

我在每次更新后调用 refreshGraph() 函数,该函数使用更新的数据重新绘制图形。但是什么也没发生,我认为这是因为 refreshGraph() 没有被正确调用?或者对于选项 1 类型库设置不正确?在选项 1 之后调用 refreshGraph 时,点应变为蓝色,在为选项 2 调用它时,点应从显示中消失,因为它已从用于绘制圆圈的数据 alldata 中删除。以下是相关代码:

allData = [];
var menu = [{
title: 'Add to Library',
action: function addToLibrary(elem, d, i) {
    d3.json("connection6.php?paperID="+d.ID, function(error, dataJson) {
        for(i=0;i<allData.length;i++){ 
            if (d.type === "In_library")
            {
            alert("The paper: " + d.TITLE + " is already in your Library!"); 
                    return; 
            }
            }
            d.type = "In_library"; // is this the correct way to change the type if the input has a different type??
            refreshGraph();
        })
        refreshGraph();
    }
}, 
{
title: 'Remove from Library',
action: function removeFromLibrary (elem, d, i) {
        d3.json("connection9.php?paperID="+d.ID, function(error, dataJson) {
            //loop through allData and if selected ID has type In_library, remove from allData
            for(i=0;i<allData.length;i++){
                if (d.type == "In_library"){
                    allData.splice(i--,1);      
            }
            }
            refreshGraph();
            })  
    }
}
]
function refreshGraph() { 
// draw dots
var circles = svg.selectAll("circle")
        .data(allData)
    circles.transition()
        .attr("cx", function(d) {return x(YearFn(d))})
        .attr("cy", function(d) {return y(Num_citationsFn(d))})
    circles.enter()
        .append("circle")
        .attr("class", "dot")
        .attr("r", 3.5)
        .attr("cx", function(d) {return x(YearFn(d))})
        .attr("cy", function(d) {return y(Num_citationsFn(d))})
        .style("fill",function(d){
                    var colour = "black"
                    switch(d.type){
                    case "In_library":
                        colour = "blue";
                    break;
                    case "cited by":
                        colour = "red";
                    break;
                    case "cites":
                        colour = "green";
                    break;
                    case "selected":
                        colour = "magenta";
                    break;
                    default:
                        colour = "black";
                    }
                    return colour;
                    }) 
        .on("mouseover", mouseHandler)
        .on("mouseout", mouseoutHandler)
        .on("click", clickHandler)
        .on("contextmenu", rightClickHandler);

svg.select(".y.axis").call(yAxis); 
svg.select(".x.axis").call(xAxis);
//don't want dots overlapping axis, so add in buffer to data domain
x.domain([d3.min(allData, YearFn)-1, d3.max(allData, YearFn)+1]);
y.domain([d3.min(allData, Num_citationsFn)-1, d3.max(allData, Num_citationsFn)+1]);
    }

非常感谢任何帮助,我是d3的新手,所以提前感谢!

您不需要在每次单个点更改时重新绘制所有数据。只需更新这一点。

function rightClickHandler() {
   // if option 1
   d3.select(this).style("fill", "blue");
   // if option 2
   d3.select(this).remove();
}

您的问题可能会出现,因为当您第二次(或第三次)调用 refreshGraph 时,您不清楚已经绘制的圆圈。您的 refreshGraph 函数不会更新已绘制的点,而是每次都重新创建它们,如果您不清除已存在的点,您将看不到新点(或缺少它们,或颜色变化),因为它们隐藏在旧点后面。

编辑:

如果要每次都重新添加数据,则首先必须清除现有数据。在刷新图形函数的开头,添加以下行:

if(!d3.selectAll("circle").empty()) d3.selectAll("circle").remove();

即,如果有圆形元素,请将其删除。这假定您只在 refreshGraph 函数中创建圆形元素。如果您在其他地方创建它们,则可能应该改用 .dot 选择器。