我基本上有一些嵌套数据,例如:
const shapeGroups = [
{
title: 'shapeGroup_01',
color: 'blue',
shapes: [
{
shape:'rect',
width: 30,
height: 100,
x: 250,
y: 450
}
]
},
{
title: 'shapeGroup_01',
color: 'blue',
shapes: [
{
shape:'rect',
width: 10,
height: 40,
x: 350,
y:50
}
]
}
]
我感兴趣的是按照shapeGroup的rect
属性中的定义在每个color
中设置颜色。
const shapeGroups = [{
title: 'shapeGroup_01',
color: 'blue',
shapes: [{
shape: 'rect',
width: 30,
height: 100,
x: 250,
y: 450
}]
},
{
title: 'shapeGroup_01',
color: 'blue',
shapes: [{
shape: 'rect',
width: 10,
height: 40,
x: 350,
y: 50
}]
}
]
const stage = d3.select('#stageContainer')
.append('svg')
.attr('id', '#stage')
.attr('width', 1000)
.attr('height', 1000)
const groups = stage
.selectAll('.group')
.data(shapeGroups)
const groupEnter = groups
.enter()
.append('g')
.attr('class', 'group');
const getGroup = group => group.shapes;
const createShape = shape => document.createElementNS(d3.namespaces.svg, shape.shape)
groupEnter
.selectAll('.shape')
.data(getGroup)
.enter()
.append(createShape)
.attr('fill', 'red') // I want the color as defined in the current group
.attr('width', d => d.width)
.attr('height', d => d.height)
.attr('x', d => d.x)
.attr('y', d => d.y)
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="stageContainer"></div>
换句话说,我需要一种在组级别设置color
的方法,或者在我附加单个datum
时以某种方式访问父.shape
对象的方法。
答案 0 :(得分:3)
正如您在我的answer here中所读到的那样,您无法从D3 v4 / v5中的所选内容中访问父级的基准或其索引。
一种解决方案是获取parentNode
的数据:
.attr('fill', (_, i, n) => d3.select(n[i].parentNode).datum().color)
这是您所做的更改(我将两个具有不同颜色的矩形和SVG缩小,以便更好地可视化):
const shapeGroups = [{
title: 'shapeGroup_01',
color: 'blue',
shapes: [{
shape: 'rect',
width: 30,
height: 100,
x: 250,
y: 50
}]
},
{
title: 'shapeGroup_01',
color: 'green',
shapes: [{
shape: 'rect',
width: 10,
height: 40,
x: 350,
y: 20
}]
}
];
const stage = d3.select('body')
.append('svg')
.attr('width', 400)
.attr('height', 400)
const groups = stage
.selectAll('.group')
.data(shapeGroups)
const groupEnter = groups
.enter()
.append('g')
.attr('class', 'group');
const getGroup = group => group.shapes;
const createShape = shape => document.createElementNS(d3.namespaces.svg, shape.shape)
groupEnter
.selectAll('.shape')
.data(getGroup)
.enter()
.append(createShape)
.attr('fill', (_, i, n) => d3.select(n[i].parentNode).datum().color)
.attr('width', d => d.width)
.attr('height', d => d.height)
.attr('x', d => d.x)
.attr('y', d => d.y)
<script src="https://d3js.org/d3.v5.min.js"></script>
但是,到目前为止,最简单的解决方案是将fill
设置为父选项本身:
const groupEnter = groups
.enter()
.append('g')
.attr('class', 'group')
.attr('fill', d => d.color);
这是演示:
const shapeGroups = [{
title: 'shapeGroup_01',
color: 'blue',
shapes: [{
shape: 'rect',
width: 30,
height: 100,
x: 250,
y: 50
}]
},
{
title: 'shapeGroup_01',
color: 'green',
shapes: [{
shape: 'rect',
width: 10,
height: 40,
x: 350,
y: 20
}]
}
];
const stage = d3.select('body')
.append('svg')
.attr('width', 400)
.attr('height', 400)
const groups = stage
.selectAll('.group')
.data(shapeGroups)
const groupEnter = groups
.enter()
.append('g')
.attr('class', 'group')
.attr('fill', d=>d.color);
const getGroup = group => group.shapes;
const createShape = shape => document.createElementNS(d3.namespaces.svg, shape.shape)
groupEnter
.selectAll('.shape')
.data(getGroup)
.enter()
.append(createShape)
.attr('width', d => d.width)
.attr('height', d => d.height)
.attr('x', d => d.x)
.attr('y', d => d.y)
<script src="https://d3js.org/d3.v5.min.js"></script>