【问题标题】:Understanding d3.scaleQuantile() for choropleth map了解 d3.scaleQuantile() 的等值线图
【发布时间】:2017-07-16 01:06:30
【问题描述】:

我目前正在使用以下指南在 Angular 2 中构建等值线图: http://cartographicperspectives.org/index.php/journal/article/view/cp78-sack-et-al/1359

到目前为止,除了d3.scaleQuantile().range() 函数之外,一切都运行良好。

在 d3 版本 3 中,上述函数曾经是 d3.scale.quantile().range()

在上面使用版本 3 的地图教程中,d3.scale.quantile().range() 接受颜色列表:[“#D4B9DA”,“#C994C7”, “#DF65B0”, “#DD1C77”, “#980043”]。但是,当我放入相同的列表时,这似乎不适用于版本 4 中的新 d3.scaleQuantile().range() 函数。

控制台给出Type 'string' is not assignable to type 'number'.)的错误,而在Webstorm中,错误显示Argument types do not match parameters

如果有人能指出如何使用范围函数设置颜色的正确方向,我将不胜感激。以下代码的相关部分。

colorScale(csvData: any): any {

    var range = [];

    var color = d3.scaleQuantile()
        .range(range);

    var domainArray = [];

    for (var i in csvData){
        domainArray.push(Number(csvData[i]["PROP"]));
    };

    //pass array of expressed values as domain
    color.domain(domainArray);

    return color;    //return the color scale generator
}

choropleth(d: any, recolorMap: any): any{

    //get data value
    var value = d.properties["PROP"];
    //if value exists, assign it a color; otherwise assign gray
    if (value) {
        return recolorMap(value);
    } else {
        return "#ccc";
    };
};

buildMap(csvData: any){
    //code removed to keep short
   var recolorMap = this.colorScale(csvData);

   this.g = this.svg.append("g")
            .selectAll("path")
            .data(xFeatures)
            .enter()
            .append("path")
            .attr("d", this.geoPath)
            .style("fill", (d) => { //color enumeration units
                return this.choropleth(d, recolorMap)
            });
}

【问题讨论】:

  • csvData 的值是多少?看起来可能存在解析错误,因为您正在将 csvData[i]['PROP'] 转换为数字。
  • csvData 变量是 csv 数据,其中包含应用于每个状态的名称和数字。我查看了它并做了一堆控制台日志语句来查看正在传递的内容并检查了它。范围函数似乎只需要一个数字数组,而不是一个字符串数组。
  • 对于您发布的代码块,您调用d3.scaleQuantile().range(range),但此时range 是一个空数组。那是你遇到问题的地方吗?还是您没有发布代码的其他地方?
  • 我可能不小心把它漏掉了。我正在使用示例中的颜色列表。几个小时后,我找到了解决方案。 d3 的打字稿typings 似乎要求范围内的任何内容都必须是数字数组。所以我将import * as d3 from "d3" 切换到var d3: any = require('d3')(我相信它只是获取了d3 的常规javascript 对象),并且不再有range() 函数的类型限制。感谢您的帮助。

标签: javascript angular d3.js


【解决方案1】:

如果有人能指出我如何使用范围的正确方向 设置颜色的功能,我将不胜感激。

来自 API documentation

如果指定了范围,则设置范围内的离散值。这 数组不能为空,并且可以包含任何类型的值。

因此,您应该能够在 d3 v4 中使用范围数组中的字符串作为分位数,如果没有,则可能存在不同的问题:

var scale = d3.scaleQuantile().domain([0,99]).range(["steelblue","#aaa","lightgreen"]);

var svg = d3.select('body').append('svg').attr('width',500).attr('height',300);

var rects = svg.selectAll('rect')
   .data(d3.range(100))
   .enter()
   .append('rect')
   .attr('width',18)
   .attr('height',18)
   .attr('fill', function(d,i) { return scale(i); })
   .attr('x', function(d,i) { return i%10 * 20 + 30; })
   .attr('y', function(d,i) { return Math.floor(i/10) * 20 + 30; });
   
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

这也应该适用于其他音阶。例如,如果您想通过使用阈值比例来控制等值线中使用的阈值:

var scale = d3.scaleThreshold().domain([10,25,90]).range(["#bae4bc","#7bccc4","#2b8cbe","#0868ac"]);

var svg = d3.select('body').append('svg').attr('width',500).attr('height',300);

var rects = svg.selectAll('rect')
   .data(d3.range(100))
   .enter()
   .append('rect')
   .attr('width',18)
   .attr('height',18)
   .attr('fill', function(d,i) { return scale(i); })
   .attr('x', function(d,i) { return i%10 * 20 + 30; })
   .attr('y', function(d,i) { return Math.floor(i/10) * 20 + 30; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

【讨论】:

  • 感谢您的解释。你的例子让我相信我没有疯!哈哈。在 d3 的打字稿版本中,它似乎将范围的输入类型限制为数字数组。我将import * as d3 from "d3" 切换为var d3: any = require('d3'),这消除了类型限制,并且它开始完美运行。
  • 有时知道自己没有疯就是你所拥有的一切。很高兴您解决了问题。
猜你喜欢
  • 2020-11-09
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多