如何在D3中通过匹配名称从visitors对象获取多边形颜色
问题:从动态visitors数组中匹配polys多边形的颜色
现有两个D3构造中用到的对象:
const visitors = [ { name: "polygon 1", total: 342, color: "red" }, { name: "polygon 2", total: 342, color: "blue" }, { name: "polygon 3", total: 342, color: "green" } ] const polys = [{ name: "polygon 1", points:[ {"x":-25, "y":48}, {"x":3,"y":48}, {"x":3,"y":40}, {"x":-25,"y":40}, {"x":-25,"y":48} ] }, { name: "polygon 2", points:[ {"x":5, "y":40}, {"x":23,"y":40}, {"x":23,"y":18}, {"x":5,"y":18}, {"x":5, "y":40} ] }, { name: "polygon 3", points:[ {"x":-25, "y":40}, {"x":5,"y":40}, {"x":5,"y":34}, {"x":-25,"y":34}, {"x":-25, "y":40} ] }]
需求是:根据polys中每个多边形的name,从动态更新的visitors数组中获取对应多边形的color值,给多边形填充颜色。
尝试过以下代码,但无法正确获取颜色:
// d 是 polys 中的单个对象 .attr("fill", function(d, visitors) { for(var key in d){ if (key === 'name' && d.name === visitors.name){ return visitors.color; } } });
解决方案
原代码的问题
- D3的
.attr()回调函数参数顺序是(d, index),第二个参数是当前元素的索引,不是外部的visitors数组; visitors是数组而非单个对象,无法直接通过visitors.name获取属性。
方法1:直接用Array.find()匹配(适合数据量小的场景)
在回调函数中遍历visitors数组,找到与当前多边形name匹配的项,返回其color:
.attr("fill", function(d) { // 匹配name对应的visitors项 const matchedItem = visitors.find(item => item.name === d.name); // 存在匹配项则返回颜色,否则返回默认值(如"gray") return matchedItem ? matchedItem.color : "gray"; });
因为visitors是动态的,每次渲染时都会重新查找数组,自动获取最新的颜色值。
方法2:转换为Map提升查找性能(适合数据量大的场景)
如果visitors数据量较大,每次遍历数组效率较低,可以提前将其转换为以name为键的Map,后续直接通过键取值:
// 提前将visitors转换为Map(数据更新时需重新执行此步骤) const visitorColorMap = new Map(visitors.map(item => [item.name, item.color])); // 填充颜色时直接从Map中取值 .attr("fill", function(d) { // 找不到对应值时返回默认颜色 return visitorColorMap.get(d.name) || "gray"; });
若visitors动态更新,只需重新生成visitorColorMap即可保证颜色同步。
内容的提问来源于stack exchange,提问作者DavidN
相关产品推荐
相关产品推荐

