map - 创建在配色方案中正确显示分位数类范围值和相关颜色的等值统计图图例?

标签 map d3.js legend colorbrewer

我是一名新手程序员,正在尝试制作交互式等值线图。在已经就几个问题获得帮助后,最后一个大问题是 map 图例不正确。图例应该为每个分位数类别显示不同的颜色,但是,截至目前,将最暗的颜色与第二大类别相关联(而不是仅针对最大类别),然后为最大类别重复该颜色。此外,对于大多数可用的分位数选择选项,图例中没有最浅的阴影。这是一个 screenshot这表明所有颜色(示例中的 5 个类别)在 map 本身上正确显示,但在图例上显示不正确。

我认为问题出在以下代码中的某处,尤其是在“根据下拉菜单中的选择计算分位数并更新图例”标题下的最后一长段代码中。我想知道将值标签添加到图例的方式是否有问题,这可能会混淆颜色的关联方式。任何见解将不胜感激!

下拉菜单:

    <div id="mapcontrols" style="position:absolute; top: 35px; left:625px;">
    <div>
        <p>Data to map:
        <select id="NumerSelection" class="MainData" style="width:225px;">
        <option value="d.OneFill" selected>Inverse (numerator set to 1)</option>
        <option value="d.pop11">County Population, July 2011</option>
        <option value="d.Members">Total Enrollees</option>
        <option value="d.Patients">Total Patients</option>
        <option value="d.MemberMonths">Member-months of Enrollment</option>
        <option value="d.AvgMembers">Average Number of Enrollees</option>

        <option value="d.id">County ID</option>
        </select></p>
        <p>Denominator:         
        <select id="DenomSelection" class="MainData" style="width:225px;">
        <option value="d.OneFill" selected>raw rate</option>
        <option value="d.pop11">County Population, July 2011</option>
        <option value="d.Members">Total Enrollees</option>
        <option value="d.Patients">Total Patients</option>
        <option value="d.MemberMonths">Member-months of Enrollment</option>
        <option value="d.AvgMembers">Average Number of Enrollees</option>
        <option value="d.id">County ID</option>
        </select></p>

        <p>Color Scheme: 
        <select id="ColorSelection">
        <option value="Blues" selected>Blues</option>
        <option value="Greys">Greys</option>
        <option value="Greens">Greens</option>
        <option value="Oranges">Oranges</option>
        <option value="Reds">Reds</option>
        <option value="Purples">Purples</option>
        <option value="YlGn">Yellow-Green</option>
        <option value="YlGnBu">Yellow-Green-Blue</option>
        <option value="GnBu">Green-Blue</option>
        <option value="BuGn">Blue-Green</option>
        <option value="PuBuGn">Purple-Blue-Green</option>
        <option value="PuBu">Purple-Blue</option>
        <option value="BuPu">Blue-Purple</option>
        <option value="RdPu">Red-Purple</option>
        <option value="PuRd">Purple-Red</option>
        <option value="OrRd">Orange-Red</option>
        <option value="YlOrRd">Yellow-Orange-Red</option>
        <option value="YlOrBr">Yellow-Orange-Brown</option>
        </select></br>

        Number of quantiles:            
        <select id="TileSelection" class="MainData"">
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5" Selected>5</option>
        <option value="6">6</option>
        <option value="7">7</option>
        <option value="8">8</option>
        </select></p>
    </div>
    <div id="legenddiv"><p>Legend:</p></div>
    </div>

设置图例 SVG 和默认配色方案:

    var LegendContainer = d3.select('div#legenddiv')
.append('svg')
.attr('width', 100) 
.attr('height', 300)
.attr('id', 'Legendsvg')
.attr('class', 'Blues')
;

根据配色方案下拉菜单中的选择,同时更新 map 多边形和图例框的配色方案:

    d3.select("select#ColorSelection")
.on("keyup", function() {d3.selectAll("svg#Mapsvg, svg#Legendsvg").attr("class", this.value)})
.on("change", function() {d3.selectAll("svg#Mapsvg, svg#Legendsvg").attr("class", this.value)});

格式化要显示的值:

    function makenice(d) {
if(d==0){return 0;}
dec = Math.ceil(Math.log(d < 0 ? -d: d)/Math.log(10))
magnitude = Math.pow(10,3-dec)
n = Math.round(d*magnitude)/magnitude

if(dec>3){ d= numeral(n).format('0,0.[0]');}
    else{ d = numeral(n).format('0.00[0000000000]');}

return d
};

从外部 CSV 文件中获取数据:

    d3.csv('testdata.csv', function(data)
{
    ...

根据下拉菜单中的选择计算分位数并更新图例:

    d3.selectAll('select.MainData').on('change', function() {

    var Nu = document.getElementById('NumerSelection')
        Numer = Nu.options[Nu.selectedIndex].value;

    var Nd = document.getElementById('DenomSelection')
        Denom = Nd.options[Nd.selectedIndex].value;

    var Qt = document.getElementById('TileSelection')
        ntiles = Qt.options[Qt.selectedIndex].value;

    var DataArray =(data.map(function(d, i) {return +eval(Numer) / +eval(Denom);})).sort(function(a,b){return a-b});

    //set up quantiles
    var quants = d3.scale.quantile()
        .domain(DataArray)
        .range(d3.range(0,ntiles).map(function(i) {return 'q' + i + '-' + ntiles;}))
        ;

    var legendquant = quants.copy();

    //regenerate values for legend
    var legend = legendquant.quantiles();
        legend.unshift(d3.min(DataArray));
        legend.push(d3.max(DataArray));
        legend.reverse();


    //Create the legend
    var delabeltext = d3.select('svg#Legendsvg').selectAll('text').remove();
    var delabelboxes = d3.select('svg#Legendsvg').selectAll('rect').remove();

    console.log(legend)
    var legends = d3.select('svg#Legendsvg')
    var legendbars = legends.selectAll('text')
        .data(legend)
        .enter()
        .append('text')
        .attr('x', 40) 
        .attr('y', function(d, i) {return (i*30+30)})
        .text(function (d) {return d})
        ;

    legend.pop();
    legend.reverse();

    if (Nu.options[Nu.selectedIndex].text != 'Inverse (numerator set to 1)') {
       legend.reverse(); }



    var legends = d3.select('svg#Legendsvg')
    var legendbars = legends.selectAll('rect')
        .data(legend)
        .enter()
        .append('rect')
        .attr('x', 5)
        .attr('y', function(d, i) {return (i*30)+25})
        .attr('height',28)
        .attr('width',30)
        .attr('class', function (d) {return quants(d)} )
        ;

最佳答案

分位数尺度的quantiles() 方法返回每个分位数的阈值(参见the documentation)。引用,

Values less than the first element in the thresholds array, quantiles()[0], are considered in the first quantile...

这意味着阈值将被映射到上面的相应区间。在您的情况下,您传入了最后一个分位数阈值,它映射到最高分位数,然后是最大值,它也映射到最高分位数。

解决此问题的最简单方法可能是,不是删除图例数组 (legend.pop()) 的最后一个元素,而是删除第一个元素。也就是说,只需交换弹出最后一个元素并反转数组的行。

关于map - 创建在配色方案中正确显示分位数类范围值和相关颜色的等值统计图图例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15437354/

相关文章:

javascript - d3 svg 绘制矩形条形图在 IE11 中不起作用

css - 如何防止 fieldset 的边框穿过 form 标签包围的图例元素?

Javascript过滤器与 map 问题

javascript - 使用堆叠布局时将自定义值字段映射到 x 值

list - 在 Clojure 中过滤列表

javascript - 具有大(> 500,000)点的 D3.js 散点图?聚类?

r - geom_vline() 图例的位置发生变化

R ggraph/ggplot2 颜色图例显示不正确

scala - 压缩两个 HashMap(或字典)

泛型的 Java Map 编译器错误