2016-10-14 24 views
0

我正在使用d3根據此示例繪製矩陣:http://bl.ocks.org/ianyfchang/8119685。 在我的矩陣中,每個元素表示來自行[x] =>列[y]的ping RTT值,例如,如果服務器0 ping服務器1並返回100ms,那麼在矩陣節點[0] [1] = 100中,當然要可視化網絡狀態,我將在每個單元中填充綠色,黃色或紅色取決於相應的RTT。如何使用d3更新選擇繪製稀疏矩陣

在這種情況下,不是每個服務器ping其他所有服務器,所以我得到的數據是不完整的網格,從數學上講,它是一個稀疏矩陣,大部分元素爲null,數據看起來是這樣的:

src  dest  RTT 
server0 server1 100 
server150 server10 80 
server100 server100 600 
... 

我也有一個所有服務器的完整列表,我將所有服務器名稱繪製爲行和列標籤,然後將每個記錄的src,dest轉換爲服務器名稱數組中的服務器名稱的索引。

這裏是問題,如果我通過熟(熟意味着我已經將服務器列表數組中的src和dest服務器名稱轉換爲它們的索引)稀疏矩陣到d3,它只繪製單元格,如果有ping記錄,讓d3繪製所有單元即使沒有數據,我需要創建一個完整的網格矩陣。在我讀完d3的更新介紹後,進入退出選擇,我想我可以這樣實現:

  1. 創建一個虛擬全網格矩陣,讓d3繪製所有單元格;
  2. 用我的真實矩陣更新d3.selectAll(「cell」),因此d3會使用真實的RTT值自動更新這些虛擬單元。

這是我的代碼,但它不工作:(有人知道爲什麼嗎?我有一種感覺,我應該控制如何我的真正矩陣加入元素,但我不知道如何使用在。數據鍵功能()。

var svg = d3.select("#matrix") 
.append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
.append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

// create a dummy matrix and a dummy matrix 
var dummy = []; 
for (var i = 0; i < servers.length; ++i) { 
    for (var j = 0; j < servers.length; ++j) { 
     var n = {}; 
     n.x = i; 
     n.y = j; 
     dummy.push(n); 
    } 
} 

var heatmap = svg.append("g").attr("class", "g3") 
    .selectAll(".cellg") 
    .data(dummy) 
    .enter() 
    .append("rect") 
    .attr("x", function (d) { return d.y * cellSize; }) 
    .attr("y", function (d) { return d.x * cellSize; }) 
    .attr("class", function (d) { return "cell cell-border cr" + (d.x - 1) + " cc" + (d.y - 1); }) 
    .attr("width", cellSize) 
    .attr("height", cellSize) 
    .style("fill", function (d) { return d.Item3 === undefined ? "white" : d.m_Item3 >= 5000 ? "red" : d.m_Item3 >= 2000 ? "yellow" : "green"; }) 
    .on("mouseover", function (d) { 
     d3.select(this).classed("cell-hover", true); 
     d3.selectAll(".rowLabel").classed("text-highlight", function (r, ri) { return ri === (d.x); }); 
     d3.selectAll(".colLabel").classed("text-highlight", function (c, ci) { return ci === (d.y); }); 

     d3.select("#tooltip") 
      .style("left", (d3.event.pageX + 10) + "px") 
      .style("top", (d3.event.pageY - 10) + "px") 
      .select("#value") 
      .html("<p>Source: " + servers[d.x] + "</p>" + 
        "<p>Dest: " + servers[d.y] + "</p>" + 
        "<p>RTT: " + (d.m_Item3 === undefined ? "N/A" : d.m_Item3 + "ns") + "</p>"); 

     //Show the tooltip 
     d3.select("#tooltip").classed("hidden", false); 
    }) 
    .on("mouseout", function() { 
     d3.select(this).classed("cell-hover", false); 
     d3.selectAll(".rowLabel").classed("text-highlight", false); 
     d3.selectAll(".colLabel").classed("text-highlight", false); 
     d3.select("#tooltip").classed("hidden", true); 
    }); 

// next, update the update section. 
heatmap.data(matrix); 

回答

0

好,我做它的工作原理,但我不知道爲什麼,怎麼關鍵功能的工作原理。 爲了使它工作,我需要加入數據時添加相同的鍵功能。

使用虛擬矩陣創建完整矩陣時:

.data(dummy, function (d) { return d.x + ":" + d.y; }) 

然後當與真正的矩陣加盟:

.data(matrix, function (d) { return d.x + ":" + d.y; }) 

我仍然不知道什麼是關鍵職能,以及爲什麼它應該返回字符串?在SQL中加入時,鍵功能是否與列名相同?只有鍵功能返回相同的字符串時,數據纔會被連接/更新?