我有一些要添加到d3数据集内的文本。 rect的颜色来自对象的填充,该对象将公司名称映射到颜色。我开始注意到的是,我还需要某种逻辑来填充文本,否则在较暗的矩形上将很难阅读文本(因为我使用的是默认黑色)。以这个小片段为例:
var margins = {top:100, left:80, bottom:40, right:20};
var width = 300;
var height = 300;
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 data = [
{'fmc': 'UBS', 'value': 2308.78},
{'fmc': 'Fidelity', 'value': 976.76},
{'fmc': 'JP Morgan', 'value': 837.19},
{'fmc': 'Value Partners', 'value': 787.39}
];
var heightScale = d3.scaleLinear()
.domain([150,2500])
.range([20,130]);
var colorMap = {
'UBS':"#003366",
'Fidelity':"#366092",
'JP Morgan':"#4f81b9",
'Value Partners':"#95b3d7"
};
let counterRect = 0,
counterText = 0;
var column = graphGroup.selectAll('.column')
.data(data)
.attr('class', 'column')
.enter().append("g");
column.append("rect")
.attr("width", 150)
.attr("height", function(d) {
return heightScale(d.value)
})
.attr('x', function(d) {return 10})
.attr('y', function(d, i) {
let previous = counterRect;
return (counterRect += heightScale(d.value)+2, previous)
})
.style('fill',function(d,i) {return colorMap[d.fmc]});
column.append("text")
.attr('x', function(d) {return 75})
.attr('y', function(d, i) {
let previous = counterText;
return (counterText += heightScale(d.value)+2, previous + (heightScale(d.value)/2))
})
.attr("dominant-baseline", "central")
.attr('text-anchor', 'middle')
.text(function(d) {
return d.fmc;
});
<script src="https://d3js.org/d3.v5.min.js"></script>
为简单起见,假设我希望UBS
,Fidelity
和JP Morgan
为"white"
,Value Partners
为"black"
。在我的实际应用程序中,此解决方案需要可扩展,因为我要处理50多种颜色。除了蛮力/预先添加布尔值之外,是否有其他方法可以根据文本的颜色确定文本是白色还是黑色?
我知道d3.select(this).datum()
可以返回元素的原点,从而可以找到匿名矩形的颜色,但是如果我们不知道该如何处理该颜色,这对我们没有帮助。选择白色或黑色字体填充时如何使用该信息。