Я работаю с диаграммой рассеивания в d3. Точки на графике представляют собой бумагу. При правом щелчке точки у меня есть контекстное меню, в котором есть 2 варианта: 1) добавить эту бумагу в библиотеку (тип изменения в In_library) и 2) Удалить из библиотеки (полностью удалить бумагу из данных).Функция обновления не называется должным образом d3
Я вызываю функцию refreshGraph() после каждого из этих обновлений, которое перерисовывает график с обновленными данными. Но ничего не происходит, что я предполагаю, потому что refreshGraph() не называется должным образом? Или для библиотеки типов 1-го типа не устанавливается должным образом? Когда refreshGraph вызывается после опции 1, точка должна стать синей, а при вызове для опции 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, поэтому спасибо заранее!
Вы забыли обновить 'allData' в своей функции' addTolibrary'? – Quarter2Twelve
@ Quarter2Twelve yes good point Вы имеете в виду push (d) во всеДата? Если так, что не должно быть так, как если бы точка отображалась и ее можно было щелкнуть, она означает, что она уже находится во всехData .. так что, если я нажимаю эту бумагу во всеДата, она рисует другой экземпляр этой бумаги поверх нее, вместо которой я бы хотел тип, который следует распознать как In_library, и изменить цвет существующей точки. Я попробовал это и увидел голубую точку, но понял, что это просто покрывает другую точку. –
Когда вы вызываете refreshGraph, что вы делаете с кругами, которые уже построены? – James