2017-03-16 69 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

相关问题