2013-03-05 98 views
1

我一直在探索如何將圖例添加到繪圖並在繪製新類型的轉換之後更新圖例。我遇到了兩個問題,我一直無法解決問題。d3圖例,缺少文本標籤和重複值

塊是這裏http://bl.ocks.org/natemiller/df4b96809580fe7d00a6

樣品JSON數據集包括幾個不同的變量(溫度,pH值,名稱,Y等),我試圖開發是改變哪個變量被繪製在一塊土地上x軸和哪個變量確定單擊按鈕時數據點的填充。到目前爲止,我的x軸變化,點適當移動,圖例顏色正常變化。但是,我有兩個問題。

  1. 我錯過了圖例文本(標籤)。我不清楚他們爲什麼沒有被展示,但我認爲它缺少一個小細節。我會很感激任何幫助。

  2. 正如您在數據集中可以看到的那樣,有幾個來自同一地點或具有相同pH(7.2,8.0,7.2,7.2,8.0,8.0,7.6)的「樣品」,或者具有相同的溫度( 30,25,25,30,30,25,25)。因此,當我生成的傳說,如這裏的代碼...

    varlegend = svg.selectAll('rect') 
        .data(data) 
        .enter().append("rect") 
        .attr('x', width-50) 
        .attr('y', function(d,i) {return i*20;}) 
        .attr('width', 10) 
        .attr('height', 10) 
        .style('fill', function(d) { 
        return color(d.name); 
        }); 
    

...並設置使用顏色d.name我得到7個矩形(每個值),通過當填充顏色由網站或pH設置(如果填充由temp設置),我寧願有3個矩形,因爲某些值是重複的。有沒有辦法做到這一點?我已經考慮過d3.nest,但是當我啓動轉換時,我不再需要名稱嵌套的數據,而是通過pH(所以填充由d.pH設置)。我會很感激這方面的任何評論。我是以一種太複雜的方式來做這件事嗎?有沒有更簡單的方法我應該考慮完成這個相同的目標?

感謝您的時間和幫助, 內特

回答

2

2 - 當您提供的。數據值,您也可以提供一個返回唯一標識值的函數。是這樣的:

varlegend = svg.selectAll('rect') 
    .data(data, function(d) { return d.name }) 
//... 

selection.data的文檔:「爲了控制數據是如何接合的元件,可以被指定的密鑰功能這個替換默認由折射率行爲」

1 - 關於沒有出現的文字,我認爲這個問題是缺少「中風」屬性。你可能白底白。然而,另一種考慮的方法是使用'g'標籤來保存rect和文本。類似這樣的:

var legend = svg.selectAll('.legend') 
     .data(data, function(d) { return d.name; }) 
     .enter().append('g') 
     .attr('class', 'legend') 
     .attr('ID', function(d) { return d.name }) 
     .attr("transform", function(d,i) { 
     return "translate(" + 800 + "," + i*20 + ")"; 
     }); 

legend.append("rect") 
     .attr('width', 10).attr('height', 10) 
     .style('fill', function(d) { 
     return color(d.name); 
     }); 

legend.append("text") 
     .attr('x', 25).attr('y', 10) 
     .text(function(d) { return d.name; }) 
     .attr("font-family","sans-serif") 
     .attr("font-size","11px") 
     .attr("stroke","black"); 
+0

感謝您的幫助!我已經使用「g」標籤更新了代碼,以保存圖例的矩形和文本。這是更清潔,似乎很好地工作。 – 2013-03-08 20:04:39

+0

對不起......在我最後的評論中意外打了ENTER。我也使用了你的建議,並在提供.data值時應用了一個函數。這適用於初始繪圖和轉換後,填充顏色和圖例中的文本都會更改,但其中一個pH(填充顏色和圖例文本)級別丟失,我有兩個級別。我已經玩了很多,不能破譯錯誤。新區塊在這裏http://bl.ocks.org/natemiller/41253b4413b176033e61 – 2013-03-08 20:09:21

1

問題1:文本沒有顯示出來,因爲您不能在SVG中將文本附加到矩形。也就是說,矩形不能像容器一樣起作用。你的問題是你已經指定了legend = svg.selectAll('rect'),這意味着在legend.append("text")以下不起作用。因此解決方案如下所示:將數據連接到g(組),然後將rect和文本分別附加到該組。

問題2:一種方法是首先創建一個刪除重複條目的數組,然後將該數組用於圖例數據連接。這裏有一個例子:

var legendData = d3.values(data.map(function (d) { return d.temp; })) 

var unique = legendData.filter(function (elem, pos) { 
    return legendData.indexOf(elem) == pos; }) 

這你unique數組,其中包含:[30, 25]

爲了緩解頭痛,我建議您將所有.enter()和.transition()放入一個可以傳遞數據的重繪函數中。所以你可以先用pH或temp過濾你的圖例數據,然後將新創建的數組傳遞到重繪函數中,並且圖例將轉換,同時刪除舊的/不需要的元素。有關如何佈置重繪功能的信息,請參閱General Update Pattern上的Mike Bostock的文章。

+0

感謝您的幫助!我一直在試圖將General Update模式加入到我的代碼中,但是我不清楚Mike Bostock的例子在哪裏放置更新函數以及在函數中包含哪些代碼。數據加載後更新函數是否啓動?然後包括初始繪圖代碼和轉換? – 2013-03-08 20:12:12

+0

在D3中轉換的方式非常簡單和巧妙。將新數據傳遞給現有對象時,它會在舊值和新值之間切割插值。所以如果舊/新值相同,沒有任何反應。所以需要改變的是數據連接中使用的數據。你可以創建一個'function redraw(thing)',然後使用'.data(thing)'來進行數據連接。所以redraw()或update()函數應該包含:data-join,.enter(),append()以及所需的任何轉換。 [Here is](http://tributary.io/inlet/5127223)是一個非常簡單的例子來說明這一點。 – nsonnad 2013-03-10 05:16:29