2016-03-10 75 views
0

我正在使用d3中的散點圖。圖表上的點代表一張紙。點擊右鍵點擊我有一個上下文菜單,其中有2個選項:1)將該論文添加到庫(將類型更改爲In_library)和2)從庫中刪除(完全從數據中刪除紙張)。未正確調用刷新函數d3

在每次這些更新之後,我會調用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,所以在此先感謝!

+0

你忘了在函數addTolibrary中更新'allData'嗎? – Quarter2Twelve

+0

@ Quarter2Twelve是的好點你的意思是推(D)到allData?如果是這樣,不應該是這樣的情況,就好像一個點被顯示,並且可以被點擊,這意味着它已經在allData ..所以如果我將該紙張推入allData,它將在該文件的頂部繪製另一個實例,而不是我想要的該類型將被識別爲In_library並更改現有點的顏色。我確實嘗試過,看到一個藍點,但意識到它只是覆蓋另一個點。 –

+0

當你調用refreshGraph時,你在用已經繪製的圓圈做什麼? – James

回答

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選擇器。

+0

啊好吧我想我知道你從哪裏來。添加數據不是問題,所以問題在於當我需要將一個點更改爲不同類型時,我需要先刪除它然後重新繪製它(我希望refreshgraph以它能夠識別類型的顏色重新繪製它 - 因此我不會如果我能避免它,真的想使用你的setAttribute(this))。和從庫中刪除相同,我可能已從數據中刪除它,但我沒有將它從顯示中刪除。對不起,我正在通過我的想法在這裏談論,所以你會能夠給我指示我如何可以刪除原來的和重繪? –

+0

當然,請參閱編輯。 – James

+0

優秀!真的很感激,只是問你一個問題..當我選擇從庫中刪除選項和調用刷新圖時,當我只需要選中的圓被刪除時,所有東西都會從顯示中刪除......我該如何去做這件事在removeFromLibrary函數內?我的循環是正確的還是必要的?你首先編輯'd3.select(this)。remove();'對我有意義,但是當我將它放在removeFromLibrary函數中時,它不起作用。我希望你能幫助我,我真的很感激這些反饋@James –