2017-04-13 95 views
2

在我剛纔的問題後,我問我怎麼能生成產生矩形here在D3中添加具有唯一ID和鏈接的大矩形內的小矩形?一個特定ID

唯一ID現在,我一直在試圖吸引那些矩形內的小矩形。然而,id="rectup0"只能有4個小矩形與唯一的xlink:href屬性 其餘的可以有2個矩形裏面。

<body> 
<div id="chart"> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script> 

    <script type="text/javascript"> 

     var width = 1000, 
      height = 250, 
      margin = 7, 
      nRect = 11, 
      rectWidth = (width - (nRect - 1) * margin)/nRect, 

      svgContainer = d3.select('#chart').append('svg') 
       .attr('width', width) 
       .attr('height', height), 

      svgWalkway = d3.select('#chart').append('svg') 
      .attr('width', '1000') 
      .attr('height', '150'), 

      svgContainer2 = d3.select('#chart').append('svg') 
      .attr('width', width) 
      .attr('height', height); 


// Rectangles scaling 

     var firstRow = d3.range(nRect), 
      posxScale = d3.scaleLinear() 
      .domain(d3.extent(firstRow)) 
      .range([0, width - rectWidth]); 

     var middleRow = d3.range(1), 
      posxScale3 = d3.scaleLinear() 
      .domain(d3.extent(middleRow)) 
      .range([0, width - rectWidth]); 

     var secondRow = d3.range(nRect), 
      posxScale2 = d3.scaleLinear() 
      .domain(d3.extent(secondRow)) 
      .range([0, width - rectWidth]); 

     //Drawing the actual objects HTML rects  
     svgContainer.selectAll('rect.up') 
     .data(firstRow) 
     .enter() 
     .append('rect') 
     .attr("id", function(d,i){ return "rectup" + i }) 
     .attr('x', posxScale) 
     .attr('width', rectWidth) 
     .attr('height', height) 
     .attr('class','up'); 

     svgWalkway.selectAll('rect.middle') 
     .data(middleRow) 
     .enter() 
     .append('rect') 
     .attr('x', posxScale3) 
     .attr('width','1000') 
     .attr('height','150') 
     .attr('class', 'middle'); 


     svgContainer2.selectAll('rect.down') 
     .data(secondRow) 
     .enter() 
     .append('rect') 
     .attr('id', function (d,i) { return "rectdown" + i }) 
     .attr('x', posxScale2) 
     .attr('width', rectWidth) 
     .attr('height', height) 
     .attr('class', 'down') 
     .attr('y', 0); 
    </script> 
</div> 
</body> 

我試圖繪製矩形類似像以前的(使用.append()),但到目前爲止,僅僅把他們旁邊svgContainer。我一直在閱讀一些關於使用分組的帖子,嘗試過但沒有成功。在此先感謝

UPDATE

所以基本上,整個問題就可以恢復,添加一個rect標籤右側rect id="rectup0"所以我可以有

<rect id="rectup0"></rect> 
<rect id="redrect" x="0" width="20" height="40"></rect> 

我知道JQuery讓你增加class屬性到其他類,但不知道D3,這將像編程添加一個新的rect標籤。這甚至有可能嗎?

更新2

我想這是可能的d3.insert,具有以下:

d3.select('#rectup0').insert('rect') 
    .attr('id', 'redrect') 
    .attr('x', 0) 
    .attr('width', '20') 
    .attr('height', '40'); 

但是它得到它在一開始的中間和結束rect標籤這樣

<rect id="rectup0"> 
    <rect id="redrect" x="0" width="20" height="40"></rect> 
</rect> 

不用說這是因爲關閉而不起作用rect t ag

+0

您的問題現在有點混淆。你想要:1.在另一個元素之後追加一個元素? (這沒有視覺差異,順便說一句)2.添加類而不刪除以前的類? 3.在另一個矩形內繪製一個矩形? –

+0

在另一個矩形內繪製一個矩形...其餘的是我試圖解決初始問題 – brohymn

+0

我認爲整個問題都依賴於inisde矩形必須在確定的id之後繪製的事實#rectup0 – brohymn

回答

0

您可以使用each封裝選定數據。它接受3個參數:當前數據d,當前索引i,以及整個數據數組arr。所以,如果你需要某種形式的檢查,你應該追加小rect,或沒有,你可以創建一個輔助函數:

var testIndex = function(d, i, arr) { 
    return 
     // test index 
     i == 5 || 
     // test current data 
     d == 10 || 
     // test other array members, which would be an EnterNode here 
     (i > 0 && arr[i - 1]['__data__'] == 7); 
} 

// do checks in one line: 
var testIndex = function (d, i, arr) { return i == 4 || i == 10 || i == 7; } 

var data = svgContainer.selectAll('rect.up') 
    .data(firstRow); 

data 
    .enter() 
    .each(function (d, i, arr) { 
    // select DOM element to add the rects 
    t = d3.select(this); 

    t 
     .append('rect') 
     // note that here we use empty the parameters list 
     .attr('id', 'rectup' + i) 
     .attr('x', posxScale) 
     .attr('width', rectWidth) 
     .attr('height', height) 
     .attr('class','up'); 

    if (!testIndex(d, i, arr)) { 
     return; 
    } 

    t 
     .append('rect') 
     .attr('id', 'redrect' + i) 
     // note that we need to define x-coord similar to first rect 
     .attr('x', posxScale) 
     .attr('class', 'redrect'); 
}); 

// remove your data before redraw 
data 
    .exit() 
    .remove(); 

輸出:

<svg width="1000" height="250"> 
    <rect id="rectup0" x="0" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup1" x="91.54545454545456" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup2" x="183.09090909090912" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup3" x="274.6363636363636" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup4" x="366.18181818181824" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup5" x="457.72727272727275" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="redrect5" x="457.72727272727275" class="redrect"></rect> 
    <rect id="rectup6" x="549.2727272727273" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup7" x="640.8181818181818" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="redrect7" x="732.3636363636365" class="redrect"></rect> 
    <rect id="rectup8" x="732.3636363636365" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup9" x="823.909090909091" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="rectup10" x="915.4545454545455" width="84.54545454545455" height="250" class="up"></rect> 
    <rect id="redrect10" x="915.4545454545455" class="redrect"></rect> 
</svg> 

這種方法的缺點是,你不能提供attr參數作爲JSON:

// wouldn't work 
.attr({ 
    id: 'redrect', 
    x: posxScale, 
    width: '20', 
    height: '40' 
});