2016-02-26 65 views
5

我正在嘗試在圖表區域之外獲取圖表的圖例。d3.js獲取圖表以外的圖例

這裏有邊距:

var margin = {top: 50, right: 200, bottom: 50, left: 40}; 
     var width = 960 - margin.left - margin.right, 
      height = 500 - margin.top - margin.bottom; 

首先,我創建了SVG:

var svg = d3.select("body").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 + ")"); 

所以,從我的理解,我現在有SVG canvas元素和Ag它裏面持有的圖表。我正在嘗試向右邊添加更多,所以我可以在svg畫布和附加到它的g之間留出一些空間,該空間用於保存圖表。然後我想把我的傳奇放在那個空白的空間裏。

這裏就是我加入我的傳說:

//add legend 
      var legend = svg.append("g") 
       .attr("class", "legend") 
       .attr("height", 300) 
       .attr("width", 200) 
       .attr("transform", "translate(-1000,50"); 

即使我追加到SVG元素,它被附加到SVG元素中的克所以,無論我翻譯多少或試圖讓它在屏幕上更加正確,它永遠不會超過內部g的寬度。

排除故障時,我看到外部SVG元素的高度爲960,寬度爲500.附加到g的元素具有40,50的變換/平移。寬度最終爲839像素433.223像素(不知道我明白這一點)。外部svg現在有一堆空間,因爲內置了保證金。

所以我試圖增加g的寬度,所以我可以把我的傳奇作爲孩子的g並將其移動到由邊距創建的空白區域。或者,我正在嘗試創建另一個g,它是第一個g的兄弟,然後我可以使用邊距創建的空白空間。

我無法上班,也不知道哪條路最好。

+0

g元素沒有寬度和高度屬性,他們總是放大以包含他們的子女 –

+0

您的第一條語句不會返回'svg',而是返回附加的'g'。這就是爲什麼你的傳奇語句嵌套在第一個下面的下一個g。 d3使用方法鏈接,所以調用.append()返回新的選擇。通過將您的svg創建語句分成兩個單獨的語句來修復,一個是創建'svg',另一個是爲您的圖表創建'g'。 –

回答

2

注意,當你以後執行var legend = svg.append("g"),你實際上是附加的傳說作爲上述<g>的孩子。這就是你所描述的在開發工具中看到的。

一個含義是所述translate()變換你施加到外<g>影響內<g>(即,所述的innter legend<g>被添加到外<g>的翻譯)。

可能的是,你要拆東西,像這樣:

var svg = d3.select("body").append("svg") 
      .attr("width", width + margin.left + margin.right) 
      .attr("height", height + margin.top + margin.bottom); 

var inner = svg.append("g") 
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

然後改變你的代碼,以現有的圖表繪製成inner而非svg

結果,var legend = svg.append("g")將追加傳說的那樣的inner兄弟,和(相對於inner的左上角,這是由margin翻譯)

您申請 legend任何翻譯是相對於SVG的左上角

而且可能要像這樣翻譯legend

var legend = svg.append("g") 
       .attr("transform", "translate(" + width - margin.right + "," + margin.top + ")"); 

即移動圖例到圖表的右端,減去margin.right。這樣,您可以調整margin.rightlegend創建足夠的空間。

最後,注意調用

legend 
    .attr("height", 300) 
    .attr("width", 200) 

沒有做任何事情,因爲對SVG <g>,沒有明確設置寬度和高度的方式。這些並不意味着太多,因爲svg沒有html佈局的「流動」行爲。開發工具中顯示的寬度和高度是由<g>的子項的邊界產生的隱式邊界。 (如果需要,有一種方法可以使用getBBox()函數在javascript中獲得這些計算的邊界)。

-1

通過查看您所提供的代碼,你實際上是在這條線連接傳說VAR到組「G」,而不是「SVG」,
var legend = svg.append("g")

你告訴D3讓你的傳奇變數以「G」,這是附加到SVG,如果我理解正確的,你應該嘗試這樣的事:

var legend = svg.selectAll(".legend") 
.enter().append("g") 

創建另一個組「G」爲你的傳說。 我爲我的壞英語道歉。該變種svg被分配到嵌套在<svg>

svg = d3.select("body").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom) 
     .append("g") // <-- This is what svg is currently being assigned to 
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

所以裏面<g>