您可以使用序数比例将颜色映射到不同的节点名称。实现它只需要对现有代码进行一些小的更改。
第 1 步。为颜色创建一个序数比例
colors
不再是简单的颜色名称列表,硬编码为特定名称,而是使用d3.scale.ordinal()
并将 设置为.range()
要使用的颜色数组。例如:
var colors = d3.scale.ordinal()
.range(["#5687d1","#7b615c","#de783b","#6ab975","#a173d1","#bbbbbb"]);
这将创建一个使用与原始可视化相同颜色的序数比例。由于您的数据需要更多颜色,因此您需要在范围内添加更多颜色,否则颜色将重复。
作为快捷方式,您可以使用d3.scale.category20()
d3 为您选择 20 种分类颜色。
现在,在为元素弧和面包屑设置填充颜色时path
,您只需使用colors(d.name)
而不是colors[d.name]
.
步骤 2. 使用您的数据构建规模域
一旦我们有了数据,就会设置这个.domain()
比例,因为它取决于数据中包含的唯一名称列表。为此,我们可以遍历数据,并创建一个唯一名称数组。可能有几种方法可以做到这一点,但这里有一种效果很好:
var uniqueNames = (function(a) {
var output = [];
a.forEach(function(d) {
if (output.indexOf(d.name) === -1) {
output.push(d.name);
}
});
return output;
})(nodes);
这将创建一个空数组,然后循环遍历数组的每个元素,nodes
如果新数组中不存在该节点的名称,则将其添加。
然后您可以简单地将新数组设置为色标的域:
colors.domain(uniqueNames);
步骤 3. 使用比例域构建图例
由于图例将取决于域,因此请确保在drawLegend()
设置域后调用该函数。
您可以通过调用找到域中元素的数量(用于设置图例的高度)colors.domain().length
。然后对于图例的.data()
,您可以使用域本身。最后,要设置图例框的填充颜色,您可以调用色标,d
因为域中的每个元素都是name
. 以下是传说中的这三个变化在实践中的样子:
var legend = d3.select("#legend").append("svg:svg")
.attr("width", li.w)
.attr("height", colors.domain().length * (li.h + li.s));
var g = legend.selectAll("g")
.data(colors.domain())
.enter().append("svg:g")
.attr("transform", function(d, i) {
return "translate(0," + i * (li.h + li.s) + ")";
});
g.append("svg:rect")
.attr("rx", li.r)
.attr("ry", li.r)
.attr("width", li.w)
.attr("height", li.h)
.style("fill", function(d) { return colors(d); });
就是这样。希望有帮助。
这是更新的JSFiddle。