在d3中动态创建图例

时间:2016-08-11 14:18:12

标签: javascript d3.js svg

我正在使用d3.scale.quantize()colorBrewer来获取色阶。

....
var extent = d3.extent(collection.features, function(d) {
        return d.properties.mean;
    });

var colorScale = d3.scale.quantize()
    .domain(extent)
    .range(colorbrewer.RdYlBu[8]);
...

这给了我8种不同的颜色,对应于给定值的某些范围。 然后我使用coloScale填充svg

....
.attr("fill-opacity", 0.1)
.attr("stroke", "grey")
.style("fill", function(d) {
    return colorScale(d.properties.mean);
});
...

我如何知道哪个值范围对应于颜色"#fdae61""#fee090"?我如何访问这些值? 我想创建一个在我更改输入颜色数量时动态变化的图例,即从83以及颜色标度中使用的颜色,即从RdYlBu到{ {1}}。

我想我非常接近。 我有这个

YlGn

我只需要用var scale = d3.scale.ordinal() .domain() .range(colorScale.range()); 填充相应的值,然后我可以使用它来轻松创建我的传奇...... 但是,我不知道如何动态提取它们。 像domain这样的东西是静态的,因为每当我改变色阶时我都需要改变颜色等。

2 个答案:

答案 0 :(得分:1)

如果您想创建自动图例,我的建议是您根据colorScale域和范围创建数据集,并将此数据集绑定到图例。这样,只要您更改域或缩放范围,数​​据集就会更改。

例如,如果你有这个比例,域名从0到500:

var colorScale = d3.scale.quantize()
    .domain([0, 500])
    .range(["#d73027", "#f46d43", "#fdae61", "#fee090", "#e0f3f8",
           "#abd9e9", "#74add1", "#4575b4"]);//this is colorBrewer.RdYlBu[8]

您可以创建一个包含所有值范围的数组。这将是我们的数据集,名为colorRange

var colorRange = [];    
for(var i = 0; i < colorScale.range().length; i++){
    colorRange.push(colorScale.invertExtent(colorScale.range()[i])[0]);
};

根据前面的代码,如果我们在console.log这个数组中,我们得到:

console.log(colorRange);// returns [0, 62.5, 125, 187.5, 250, 312.5, 375, 437.5]

其中包含8种颜色的相应域值。例如,如果我们从colorScale范围中移除两种颜色,我们现在就拥有:

console.log(colorRange);// returns [0, 83.333, 166.666, 250, 333.333, 416.666]

拥有此colorRange数组后,您不仅拥有图例的域值,还可以使用以下方法轻松设置颜色:

colorScale(colorRange[i])

i从第一个值到最后一个值。

PS:如果您使用的是分位数比例,我们可以放弃繁琐的for循环,只需使用[0].concat(colorScale.quantiles())来创建数组。

答案 1 :(得分:0)

您也可以在数据对象上设置任何动态属性。然后,访问数据对象值以检索这些属性。

类似的东西:

.style("fill", function(d) {
    var color = colorScale(d.properties.mean);
    // put the generated color on your data object 
    d.properties.myFillColor = color;
    return color
});

然后,无论您需要什么,都可以从基础数据对象中检索此myFillColor,例如:在传奇