我正在使用 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'
};
如果只有一种类型
,那么圆的填充就很简单:
.style('fill', function(d) { return colorMap[d.type[0]})
然而,似乎有点高深的是如何处理列表长度较长的情况——d.type[1]
。我的目标是:如果 type
超过一个,圆圈将是一半蓝色和一半灰色。听起来很简单,但确实难倒了我。
问题
如何处理上面在 d3 中阐述的动态填充逻辑?
最佳答案
简单地说:(在当前规范下)您不能填充像 <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>
另一方面,如果您只有两种组合 - 全部为蓝色和蓝灰色 - 您将只需要两个线性渐变。
关于javascript - 动态颜色映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57070557/