2014-02-17 26 views
5

我有显示总人口的美国等值线地图。我想在地图上添加一个显示分位数范围值的图例。我已经看到关于此主题的其他类似问题,但似乎无法使其适用于我的具体情况。我知道我需要包含颜色范围或颜色域,但不确定这是否是正确的方法。截至目前,只有一个功能出现在图例中,可能是所有图例功能都堆叠在一起。我怎么知道确切的,我该如何解决这个问题。带有传奇色彩的D3等位地图

//Define default colorbrewer scheme 
var colorSchemeSelect = "Greens"; 
var colorScheme = colorbrewer[colorSchemeSelect]; 

//define default number of quantiles 
var quantiles = 5; 

//Define quantile scale to sort data values into buckets of color 
var color = d3.scale.quantile() 
    .range(colorScheme[quantiles]); 

d3.csv(data, function (data) { 
    color.domain([ 
     d3.min(data, function (d) { 
      return d.value; 
     }), 
     d3.max(data, function (d 
      return d.value 
     }) 
    ]); 

//legend        
var legend = svg.selectAll('rect') 
    .data(color.domain().reverse()) 
    .enter() 
    .append('rect') 
    .attr("x", width - 780) 
    .attr("y", function(d, i) { 
     return i * 20; 
    }) 
    .attr("width", 10) 
    .attr("height", 10) 
    .style("fill", color); 
+0

类似[this](http://bl.ocks.org/KoGor/5685876)?您只需要将输出颜色的范围设置为分位数(即5种颜色)。 –

+0

是的,我希望它与该示例类似。我不想为像图例这样的图例使用硬编码值的变量。我希望它使用color.domain和colorScheme变量来填充图例值。 – bailey

回答

6

,如果你有一个顺序量表,其中域是由那些关联到颜色的范围在一对一的离散值,您使用得很好会工作传奇代码一个基础。但是你使用分位数,所以需要一个不同的方法。

对于d3 quantile scale,域是所有可能的输入值的列表,范围是离散输出值的列表。域列表按升序排序,然后划分为相同大小的组,分配给范围中的每个输出值。组的数量由输出值的数量决定。因此,为了获得每种颜色的一个图例条目,您需要使用颜色比例的范围,而不是域作为图例的数据。然后,您可以使用quantileScale.invertExtent()方法查找使用该颜色绘制的最小和最大输入值。

示例代码,使每个图例条目<g>包含彩色矩形和显示相应值的文本标签。

var legend = svg.selectAll('g.legendEntry') 
    .data(color.range().reverse()) 
    .enter() 
    .append('g').attr('class', 'legendEntry'); 

legend 
    .append('rect') 
    .attr("x", width - 780) 
    .attr("y", function(d, i) { 
     return i * 20; 
    }) 
    .attr("width", 10) 
    .attr("height", 10) 
    .style("stroke", "black") 
    .style("stroke-width", 1) 
    .style("fill", function(d){return d;}); 
     //the data objects are the fill colors 

legend 
    .append('text') 
    .attr("x", width - 765) //leave 5 pixel space after the <rect> 
    .attr("y", function(d, i) { 
     return i * 20; 
    }) 
    .attr("dy", "0.8em") //place text one line *below* the x,y point 
    .text(function(d,i) { 
     var extent = color.invertExtent(d); 
     //extent will be a two-element array, format it however you want: 
     var format = d3.format("0.2f"); 
     return format(+extent[0]) + " - " + format(+extent[1]); 
    }); 
+2

顺便说一下,看看你的代码的其余部分,它看起来像你真正想使用的是[d3 *量化*比例](https://github.com/mbostock/d3/wiki/Quantitative-Scales#维基量化)(不*分位数*),其中域是[最小,最大]范围,并且该尺度将其划分为代表相同大小范围的域变量(而不是相等数量的观察值)的组。上面的图例代码对任何一种类型的比例都适用,因为在这两种情况下,组的数量由范围数组决定,相应的域值可以使用'invertExtent'来访问。 – AmeliaBR

+0

非常感谢您的深思熟虑的答案!我希望我能够为您的答案投票,但我还没有足够的声誉。我只是遇到了示例代码中的.invertExtent()方法问题。它在控制台中给我一个错误,并没有显示与图例相关的文本。 – bailey

+0

您使用的是最新版本的d3吗?它[看起来'只有在版本3.2中为'量化和阈值比例'添加'invertExtent'方法](https://github.com/mbostock/d3/releases/v3.2.0)。使用最新版本:[这是一个带有量化比例尺的实时版本](http://fiddle.jshell.net/jM5H9); [这里是分位数](http://fiddle.jshell.net/jM5H9/1/)。我不得不做一些整理修改(格式化函数和文本对齐,我将更新上面的示例代码),但这些问题都不会导致错误。 – AmeliaBR