我有一个如下所示的数据集:
var shapes = [
{
type: 'rect', // which shape to draw
size: [ 1, 100 ], // width and height (for rect) or single number for lines, triangles or squares
color: color[0],
orientation: 0 // in degrees in interval [0, 360[
},
{
type: 'triangle',
size: 55,
color: color[1],
orientation: 0
},
{
type: 'triangle',
size: 96,
color: color[0],
orientation: 0
}
// etc …
]
我想要做的是绘制数据集中的所有形状,这些形状具有可变长度并随机生成,由定义形状的不同对象中的各种属性定义。形状应该是均匀分布的,不能相互重叠。
数据绑定到周围的g
- 元素,如下所示:
var viewport = d3.select('body').append('svg').selectAll('g').data(shapes)
var group = viewport.append('g')
我如何以d3方式接近这个?我试过了shapes.filter(shape => shape.type === 'rect').forEach(/* ... */)
,但感觉就像我没有这样做 d3方式。感谢有关如何处理此问题的任何线索!
答案 0 :(得分:2)
我会使用路径,以及一个返回有关d.type属性的路径的函数。
编辑:有点像that,虽然你必须以某种方式指定你想要的符号的位置,因为在这个例子中,它们只是在彼此之上绘制。
var drawers = {
rect: function(d) {
return 'M 0 0 l '+ d.size[0] + ' 0 l 0 ' + d.size[1] + ' l -' + d.size[0] + ' 0 l 0 -' + d.size[1];
},
triangle: function(d) {},
};
var g = d3.select('#mySvg').append('g');
var symbols = g.selectAll('.symbol')
.data(shapes);
symbols.enter()
.append('path')
.classed('symbol', true)
.attr({
d: function(d) {return drawers[d.type](d);}
});
答案 1 :(得分:0)
最终的解决方案是使用d3.svg.symbol()
构造函数(假设shapes
是数组,如介绍帖子中所述,type
与triangle-up
的差别很小},circle
或square
:
const center = [ w / 2, h / 2 ]
const vis = d3.select(container)
.append('svg')
.attr('width', w)
.attr('height', h)
const symbols = vis.selectAll('.symbol').data(shapes)
const getPathForShape = d => d3.svg.symbol().type(d.type).size(d.size)()
const paths = symbols.enter()
.append('path')
.classed('symbol', true)
.attr('d', getPathForShape)
.attr('fill', d => d.color)
.attr('x', center[0])
.attr('y', center[1])
然后使用强制导向图分发它们:
const force = d3.layout.force()
.size([w, h])
.charge(-100)
.nodes(shapes)
.gravity(0.1)
.on('tick', _ => paths.attr('transform', d =>
'translate(' + d.x + ',' + d.y + ')'))
// simulate a static graph:
force.start()
for (var i = 0; i < 100; i++) force.tick()
force.stop()