Для каждого g
датум является объектом отдела (после передачи его через d3.p ie), если вы хотите, чтобы каждый дочерний объект text
имел данные department.products
, вы можете сделать это, как вы :
.datum(data.products)
Однако теперь датум представляет собой массив, поэтому вы не можете получить доступ к d.name, вместо этого вы можете сделать что-то вроде:
.append('g')
.datum(d => d.data.products)
.append('text')
.text((d, i) => {
return d.filter(function(product) {
return product.margin == 'high';
})
.map(function(product) {
return product.name;
})
})
Как показано ниже:
var WIDTH = 200;
var HEIGHT = 200;
var data = [
{
id: 'department1',
name: 'Electronics',
value: 100,
products: [
{
description: 'latptop computers',
id: 'product1',
name: 'Fast Laptop computers',
margin: 'high',
},
{
description: 'Coaxial Cable',
id: 'product2',
name: 'Gold Coaxial Cable',
margin: 'high',
},
]
},
{
id: 'department2',
value: 100,
name: 'Hardware',
products: [
{
description: 'Power Drill',
id: 'product1',
name: '24 volt power drill',
margin: 'high'
},
{
description: 'Air tool Wrench',
id: 'product2',
name: 'Air Compressor Wrench',
margin: 'high',
},
]
},
{
id: 'department3',
value: 100,
name: 'Lawn and Garden',
products: [
{
description: '24 Volt Weed eater',
id: 'product1',
name: 'Ryobi Weed Eater',
margin: 'high',
},
]
},
{
id: 'department4',
value: 100,
name: 'Grocery',
products: [
{
description: 'Milk',
id: 'product1',
name: 'Whole Milk',
margin: 'high',
},
]
},
];
// Set up pie data:
var prepHighMarginData = d3.pie().value(function(d) { return d.value; })(data);
// Create arc generator:
var createArc = d3.arc()
.innerRadius(0)
.outerRadius(200);
const svg = d3
.select("body")
.append('svg')
.attr('width', WIDTH * 2)
.attr('height', HEIGHT * 2)
.append('g')
.attr('transform', `translate(${WIDTH}, ${HEIGHT})`);
const g = svg
.selectAll('.arc')
.data(prepHighMarginData)
.enter();
g.append('g')
.append('path')
.attr('d', createArc)
.style('fill', "#ccc")
.style('border-color', "#aaa");
g.append('g')
.attr('transform', (d) => {
return `translate(${createArc.centroid(d)})`
})
.append('g')
.datum(d => d.data.products)
.append('text')
.text((d, i) => {
return d.filter(function(product) {
return product.margin == 'high';
})
.map(function(product) {
return product.name;
})
})
.style('fill', '#fff');
text {
text-anchor: middle;
font-size: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Однако вы можете просто пропустить установку данных, потому что у отдела уже есть эти данные как часть его:
.append('g')
//.datum(d => d.data.products)
.append('text')
.text((d, i) => {
// updating to account for the filtered array's location:
return d.data.products.filter(function(product) {
return product.margin == 'high';
})
.map(function(product) {
return product.name;
})
})
Оба этих подхода работают, если вам нужен только один текстовый элемент на p ie клин. Однако первый вариант немного странен в идиоме d3, поскольку он содержит данные, которые на самом деле являются массивом данных. быть использовать что-то большее, например:
g.append('g')
.attr('transform', (d) => {
return `translate(${createArc.centroid(d)})`
})
.append('g')
.selectAll('text')
.data((d) => d.data.products)
.enter()
.append('text')
.attr("y", (d,i,n) => {
return (i-(n.length/2))*20;
})
.text((d) => d.name)
.style('fill', '#fff');
, как показано ниже. Это дает немного больше гибкости при размещении нескольких текстовых элементов, поскольку разрывы строк не всегда являются простым решением в SVG. Это также метод idiomati c для добавления (нескольких) дочерних элементов к родителю. Шаблон не нужен, если родитель и ребенок имеют отношения 1: 1.
var WIDTH = 200;
var HEIGHT = 200;
var data = [
{
id: 'department1',
name: 'Electronics',
value: 100,
products: [
{
description: 'latptop computers',
id: 'product1',
name: 'Fast Laptop computers',
margin: 'high',
},
{
description: 'Coaxial Cable',
id: 'product2',
name: 'Gold Coaxial Cable',
margin: 'high',
},
]
},
{
id: 'department2',
value: 100,
name: 'Hardware',
products: [
{
description: 'Power Drill',
id: 'product1',
name: '24 volt power drill',
margin: 'high'
},
{
description: 'Air tool Wrench',
id: 'product2',
name: 'Air Compressor Wrench',
margin: 'high',
},
]
},
{
id: 'department3',
value: 100,
name: 'Lawn and Garden',
products: [
{
description: '24 Volt Weed eater',
id: 'product1',
name: 'Ryobi Weed Eater',
margin: 'high',
},
]
},
{
id: 'department4',
value: 100,
name: 'Grocery',
products: [
{
description: 'Milk',
id: 'product1',
name: 'Whole Milk',
margin: 'high',
},
]
},
];
// Set up pie data:
var prepHighMarginData = d3.pie().value(function(d) { return d.value; })(data);
// Create arc generator:
var createArc = d3.arc()
.innerRadius(0)
.outerRadius(200);
const svg = d3
.select("body")
.append('svg')
.attr('width', WIDTH * 2)
.attr('height', HEIGHT * 2)
.append('g')
.attr('transform', `translate(${WIDTH}, ${HEIGHT})`);
const g = svg
.selectAll('.arc')
.data(prepHighMarginData)
.enter();
g.append('g')
.append('path')
.attr('d', createArc)
.style('fill', "#ccc")
.style('border-color', "#aaa");
g.append('g')
.attr('transform', (d) => {
return `translate(${createArc.centroid(d)})`
})
.append('g')
.selectAll('text')
.data((d) => d.data.products)
.enter()
.append('text')
.attr("y", (d,i,n) => {
return (i-(n.length/2))*20;
})
.text((d) => d.name)
.style('fill', '#fff');
text {
text-anchor: middle;
font-size: 14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>