我正在使用d3中的散点图。图表上的点代表纸张。右键点击一个点我有一个上下文菜单,其中有两个选项:1)将该纸张添加到库中(将类型更改为In_library)和2)从库中删除(完全从数据中删除纸张)。
我在每次更新之后调用refreshGraph()函数,这些更新使用更新的数据重绘图形。但是我没想到会因为没有正确调用refreshGraph()?或者对于选项1类型库没有正确设置?当在选项1之后调用refreshGraph时,点应该变为蓝色,并且在调用选项2时,点应该从显示中消失,因为它已从alldata中移除,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的新手,所以提前感谢!
答案 0 :(得分:1)
每次单点更改时,您无需重新绘制所有数据。只需更新一点。
function rightClickHandler() {
// if option 1
d3.select(this).style("fill", "blue");
// if option 2
d3.select(this).remove();
}
您的问题可能会出现,因为当您第二次(或第三次)调用refreshGraph时,您显然不是已经绘制的圆圈。您的refreshGraph函数不会更新已经绘制的点,每次都会重新创建它们,如果您没有清除已经存在的点,您将看不到新点(或者没有它们,或者更改为颜色),因为它们隐藏在旧点之后。
修改
如果您想每次重新添加数据,首先必须清除现有数据。在refreshGraph函数开始时,添加以下行:
if(!d3.selectAll("circle").empty()) d3.selectAll("circle").remove();
即。如果有圆形元素,请将其删除。这假设您只在refreshGraph函数中创建圆元素。如果你在其他地方创建它们,你应该使用.dot选择器。