2017-03-16 57 views
1

我想根據節點值分配形狀。我的代碼是這樣的:在D3中以編程方式將形狀分配給節點

// some variables from the UI 
var anodezoom = d3.select("#nodezoom").property("value"); 
var asize = d3.select("#ona").property("value"); 
var acolor = d3.select("#color").property("value"); 
var ameasure = d3.select("#shape").property("value"); 
// build, resize, recolor and reshape the nodes 
nodes = svg.selectAll('.node') 
    .data(graph.nodes.filter(function (d) { 
     return d.degree > 0; 
    })) 
    .enter() 
    .append(function (d) { 
     shaping(ameasure, d); 
    }) 
    .attr('class', 'node') 
    .attr('r', function (d) { 
     return resizing(anodezoom, asize, d); 
    }) 
    .style('fill', function (d) { 
     return coloring(acolor, d); 
    }) 
    .style('stroke', function (d) { 
     return coloring(acolor, d); 
    }) 
    .call(force.drag); 

我得到的錯誤是:

TypeError: Argument 1 ('node') to Node.appendChild must be an instance of Node 

,這是因爲我在整形功能,這是返回一個節點對象失敗:

function shaping(ashape, anode) { 
    var shape = null; 
    if (ashape === "gender") { 
     if (anode.gender === "M") { 
      shape = d3.svg.symbolTypes[0]; 
     } else if (anode.gender === "F") { 
      shape = d3.svg.symbolTypes[1]; 
     } else { 
      shape = d3.svg.symbolTypes[2]; 
     } 
    return shape; 
}; 

我基本上返回一個字符串,這對我來說聽起來不錯,因爲它是合法的:

.append('circle') 

但它不工作,那麼有沒有辦法返回一個節點對象,在我的shaping()函數中分配了正確的形狀?

編輯

我已經改變了我的代碼:

nodes = svg.selectAll('path') 
        .data(graph.nodes.filter(function (d) { 
         return d.degree > 0; 
        })) 
        .enter() 
        .append('path') 
        .attr('d', d3.svg.symbol().type(function (d) { 
         return shaping(ashape, d); 
        })) 
        .attr('class', 'node') 
        .attr('r', function (d) { 
         return resizing(anodezoom, asize, d); 
        }) 
        .style('fill', function (d) { 
         return coloring(acolor, d); 
        }) 
        .style('stroke', function (d) { 
         return coloring(acolor, d); 
        }) 
        .call(force.drag); 

但同時鏈接按預期顯示,所有的節點都在左上角,隱約可見......什麼我在這裏想念嗎?

回答

1

您需要添加一個路徑,而不是一個D3形狀,設置路徑數據時,那麼您指定的形狀:

.append('path') 
.attr('d', function(d) { return d3.symbol().type(/* shape */) }); 

下面是使用形狀的順序量表(var shape = d3.scaleOrdinal(d3.symbols);)一個簡單的例子:

.append('path') 
.attr("d", d3.symbol().type(function(d) { return shape(d.group);})) 

它在這個block執行。答案是d3v4,d3v3代碼會有點不同。

D3V3:

var svg = d3.select('body') 
 
    .append('svg'); 
 

 
svg.selectAll('path') 
 
    .data(d3.range(6)) 
 
    .enter() 
 
    .append('path') 
 
    .attr('transform',function(d,i) { return 'translate('+(i * 30 + 30) + ',20)'; }) 
 
    .attr('d',d3.svg.symbol() 
 
       .type(function(d,i){ return d3.svg.symbolTypes[i]; }) 
 
       .size(function(d,i){ return i * 30 + 30; }) 
 
     )
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

d3v4:

var svg = d3.select('body').append('svg').attr('width',400).attr('height',200); 
 

 
svg.selectAll('.symbol') 
 
    .data(d3.range(6)) 
 
    .enter() 
 
    .append('path') 
 
    .attr('transform',function(d,i) { return 'translate('+(i*30+30)+','+30+')';}) 
 
    .attr('d',d3.symbol() 
 
      .type(function(d,i){ return d3.symbols[i];}) 
 
      .size(function(d,i){ return i * 30 + 30; }) 
 
    )
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

+0

而我覺得你把我兩個碼在一個最小的例子比較在裏ght track,請看看我編輯的問題,如果你有一秒鐘 – user299791

+0

你需要在符號路徑上應用一個變換來正確放置它們,參見上面的片段。而對於大小,而不是r,你需要在符號本身上使用'.size',我已經編輯了答案,在這兩個片段中都包含一個size參數。 –

+0

變換的東西對我來說不是很清楚,現在我根據我的tick()函數爲它們分配位置,但是力佈局的默認位置是什麼? – user299791

相關問題