javascript - d3 circle pack - 访问数据(用于文本标签)
问题描述
我有一个修改过的圆形包实现,我在其中添加彼此相邻的根(而不是在一个巨大的圆圈中)。到目前为止,我一直没有想到的是在我创建了圆圈包之后,如果我想向每个圆圈添加文本,我该如何检索数据。这是我正在使用的内容:
var margins = {top:20, bottom:300, left:30, right:100};
var height = 600;
var width = 1080;
var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;
var svg = d3.select('body')
.append('svg')
.attr('width', totalWidth)
.attr('height', totalHeight);
var graphGroup = svg.append('g')
.attr('transform', "translate("+margins.left+","+margins.top+")");
//var tsvData = d3.tsv('circle-pack-data.tsv');
//tsvData.then(function(rawData) {
/*
var data = rawData.map(function(d) {
return {id:d.id, parentId:d.parentId, size:+d.size}
});
*/
var data = [
[
{'id':'1Q19'},
{'id':'pooled','parentId':'1Q19','size':29.5},
{'id':'spv','parentId':'1Q19', 'size':11},
{'id':'single','parentId':'1Q19', 'size':200}
],
[
{'id':'2Q19'},
{'id':'pooled','parentId':'2Q19','size':31},
{'id':'spv','parentId':'2Q19', 'size':15},
{'id':'single','parentId':'2Q19', 'size':171}
],
[
{'id':'3Q19'},
{'id':'pooled','parentId':'3Q19','size':28},
{'id':'spv','parentId':'3Q19', 'size':12},
{'id':'single','parentId':'3Q19', 'size':152}
],
[
{'id':'4Q19'},
{'id':'pooled','parentId':'4Q19','size':25},
{'id':'spv','parentId':'4Q19', 'size':214},
{'id':'single','parentId':'4Q19', 'size':101}
],
];
var colorMap = {
'1Q19':"#e7eef8",
'2Q19':"#e7eef8",
'3Q19':"#e7eef8",
'4Q19':"#e7eef8",
'pooled':"#f6d18b",
'spv':"#366092",
'single':"#95b3d7"
};
for (var j=0; j <(data.length); j++) {
var vData = d3.stratify()(data[j]);
var vLayout = d3.pack().size([250, 250]);
var vRoot = d3.hierarchy(vData).sum(function (d) { return d.data.size; });
var vNodes = vRoot.descendants();
vLayout(vRoot);
var thisClass = "circ"+String(j);
var vSlices = graphGroup.selectAll('.'+thisClass).data(vNodes).attr('class',thisClass).enter().append('g');
//console.log(vNodes)
vSlices.append('circle')
.attr('cx', function(d, i) {
return d.x+(j*300)
})
.attr('cy', function (d) { return d.y; })
.attr('r', function (d) { return d.r; })
.style('fill', function(d) { return colorMap[d.data.id]});
vSlices.append('text')
.attr('x', function(d,i) {return d.x+(j*300)})
.attr('y', function(d) {return d.y})
.attr('text-anchor','middle')
.text(function(d) {return d.data.children.data.size});
}
//})
<script src="https://d3js.org/d3.v5.min.js"></script>
控制台日志显示我尝试访问的对象属性不存在,但具有讽刺意味的是,正是控制台对数据结构的映射导致我d.data.children.data.size
首先进行选择。
我假设我这边有一些用户错误,但我真的没有成功解决问题。我已经尝试过d.data.children[0].data.size
和其他类似的变化,但错误仍然存在。
问题
是否有更简单的万无一失(防垃圾)方法来访问size
似乎深埋的财产vNodes
?我能想到的最好的办法是制作一个可能像这样工作的独立对象:sizeMap[d.data.id]
,但这需要做很多工作,并且违背了使用 d3 的目的,我觉得。
解决方案
并非所有节点都包含对象size
中的属性data
。因此,您可以执行以下操作:
return d.data.data.size ? d.data.data.size : null
这是演示:
var margins = {
top: 20,
bottom: 300,
left: 30,
right: 100
};
var height = 600;
var width = 1080;
var totalWidth = width + margins.left + margins.right;
var totalHeight = height + margins.top + margins.bottom;
var svg = d3.select('body')
.append('svg')
.attr('width', totalWidth)
.attr('height', totalHeight);
var graphGroup = svg.append('g')
.attr('transform', "translate(" + margins.left + "," + margins.top + ")");
//var tsvData = d3.tsv('circle-pack-data.tsv');
//tsvData.then(function(rawData) {
/*
var data = rawData.map(function(d) {
return {id:d.id, parentId:d.parentId, size:+d.size}
});
*/
var data = [
[{
'id': '1Q19'
},
{
'id': 'pooled',
'parentId': '1Q19',
'size': 29.5
},
{
'id': 'spv',
'parentId': '1Q19',
'size': 11
},
{
'id': 'single',
'parentId': '1Q19',
'size': 200
}
],
[{
'id': '2Q19'
},
{
'id': 'pooled',
'parentId': '2Q19',
'size': 31
},
{
'id': 'spv',
'parentId': '2Q19',
'size': 15
},
{
'id': 'single',
'parentId': '2Q19',
'size': 171
}
],
[{
'id': '3Q19'
},
{
'id': 'pooled',
'parentId': '3Q19',
'size': 28
},
{
'id': 'spv',
'parentId': '3Q19',
'size': 12
},
{
'id': 'single',
'parentId': '3Q19',
'size': 152
}
],
[{
'id': '4Q19'
},
{
'id': 'pooled',
'parentId': '4Q19',
'size': 25
},
{
'id': 'spv',
'parentId': '4Q19',
'size': 214
},
{
'id': 'single',
'parentId': '4Q19',
'size': 101
}
],
];
var colorMap = {
'1Q19': "#e7eef8",
'2Q19': "#e7eef8",
'3Q19': "#e7eef8",
'4Q19': "#e7eef8",
'pooled': "#f6d18b",
'spv': "#366092",
'single': "#95b3d7"
};
for (var j = 0; j < (data.length); j++) {
var vData = d3.stratify()(data[j]);
var vLayout = d3.pack().size([250, 250]);
var vRoot = d3.hierarchy(vData).sum(function(d) {
return d.data.size;
});
var vNodes = vRoot.descendants();
vLayout(vRoot);
var thisClass = "circ" + String(j);
var vSlices = graphGroup.selectAll('.' + thisClass).data(vNodes).attr('class', thisClass).enter().append('g');
//console.log(vNodes)
vSlices.append('circle')
.attr('cx', function(d, i) {
return d.x + (j * 300)
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', function(d) {
return d.r;
})
.style('fill', function(d) {
return colorMap[d.data.id]
});
vSlices.append('text')
.attr('x', function(d, i) {
return d.x + (j * 300)
})
.attr('y', function(d) {
return d.y
})
.attr('text-anchor', 'middle')
.text(function(d) {
return d.data.data.size ? d.data.data.size : null
});
}
//})
<script src="https://d3js.org/d3.v5.min.js"></script>
推荐阅读
- mysql - 如何使用单个查询合并两个表
- jquery - Bigcommerce Stencil 的 qtip 工具提示
- java - Android 4.4.2 问题:javax.net.ssl.SSLHandshakeException: SSL 库失败,通常是协议错误
- ios - 如何同步获取 PHAsset URL
- reactjs - 无法读取未定义的属性“_avast_submit”
- angular - 在离子缓存上添加缓存值的正确方法是什么?
- python - 用词袋方法预测文本
- python - Pyqt 表格点击动作错误:(原生 Qt 信号不可调用)
- java - 如何在不更新或创建根节点的情况下通过 oData 创建新的子节点实体
- node.js - 如何在nodejs中发布后执行get?