我正在使用d3根据称为type
的属性对圆形填充进行颜色编码。它可能只有一种类型,或者最多可能有两种。我的数据是这样的:
var data = [{'company':'companyA','products':23,'aum':25997692757,'type':['Industry senior exe'],'date':'2015-02'},
{'company':'companyB','products':24,'aum':3548692757,'type':['Industry senior exe','Star'],'date':'2016-02'}
];
请注意,type
属性是一个列表。
var colorMap = {
'Industry senior exe':'blue',
'Star':'Gray'
};
如果只有一个type
,则圆圈的填充是微不足道的:
.style('fill', function(d) { return colorMap[d.type[0]})
然而,似乎有点高大的是如何处理列表长度较长的情况-d.type[1]
。我的目标是:如果 type
不止一个,则圆圈将是蓝色的一半和灰色的一半。听起来很简单,但确实让我感到难过。
如何处理上面d3中所述的动态填充逻辑?
答案 0 :(得分:3)
简而言之:您(在当前规范下)不能用一种以上的颜色填充<circle>
之类的元素。因此,一种可能的解决方案是使用SVG <linearGradient>
。
该方法的缺点是,假设您有多个具有不同颜色选择的不同圆,给出了大量组合,则需要创建相同数量的线性渐变。
例如,在输入选择后使用each
:
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient" + i)
.attr("x1", "0%")
.attr("x2", "100%")
gradient.append("stop")
.attr("offset", "50%")
.attr("stop-color", colorMap[d.type[0]])
gradient.append("stop")
.attr("offset", "50%")
.attr("stop-color", d.type.length === 2 ? colorMap[d.type[1]] : colorMap[d.type[0]]);
以下是使用您的数据的演示:
var data = [{
'company': 'companyA',
'products': 23,
'aum': 25997692757,
'type': ['Industry senior exe'],
'date': '2015-02'
},
{
'company': 'companyB',
'products': 24,
'aum': 3548692757,
'type': ['Industry senior exe', 'Star'],
'date': '2016-02'
}
];
var colorMap = {
'Industry senior exe': 'blue',
'Star': 'gray'
};
var svg = d3.select("svg");
var circles = svg.selectAll(null)
.data(data)
.enter()
.append("circle")
.attr("cy", 50)
.attr("cx", (_, i) => 50 + i * 100)
.attr("r", 40);
circles.each(function(d, i) {
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient" + i)
.attr("x1", "0%")
.attr("x2", "100%")
gradient.append("stop")
.attr("offset", "50%")
.attr("stop-color", colorMap[d.type[0]])
gradient.append("stop")
.attr("offset", "50%")
.attr("stop-color", d.type.length === 2 ? colorMap[d.type[1]] : colorMap[d.type[0]]);
d3.select(this)
.attr("fill", "url(#gradient" + i + ")")
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
另一方面,如果只有两种组合(全是蓝色和蓝灰色),则只需要两个线性渐变。