在【入门 - 第 10 章】作了一张中国地图,其中各省份的颜色值都是随意赋值的。如果要将一些值反映在地图上,可以利用颜色的变化来表示值的变化。

1. 思路

例如,有值域的范围为:

[10, 500]

现希望10用浅绿表示,500用深绿表示,10到500之间的值用浅绿和深绿之间的颜色表示。显然,此处需要一个函数,传入的参数是10到500之间的值,返回值是浅绿到深绿之间的颜色值。

【高级 - 第 5.1 章】介绍的颜色插值函数正好可以派上用场。

var palegreen = d3.rgb(66,251,75);  //浅绿
var darkgreen = d3.rgb(2,100,7);       //深绿var color = d3.interpolate(a,b);       //颜色插值函数

这段代码最后得到的color可作为函数使用,参数的范围为[0, 1],当参数为0时,返回浅绿,当参数为1时,返回深绿。但是,现在的值域是[10, 500],范围不是[0, 1]。因此,先定义一个线性比例尺,将[10, 500]按线性关系映射到[0, 1]。

var linear = d3.scale.linear().domain([10, 500]).range([0, 1]);

如此一来,便可结合比例尺来使用颜色插值函数。

color( linear(10) );     //返回浅绿RGB(66,251,75)
color( linear(250) );       //返回浅绿和深绿之间的值
color( linear(500) );       //返回深绿RGB(2,100,7)

2. 绘制完整的中国地图

在【入门 - 第 10 章】有绘制中国地图的方法。

本例中更改为读取 TopoJSON 文件,这种类型的文件更小,能提高读取速度。关于 TopoJSON 和 GeoJSON 的区别,请参见【入门 - 第 10.3 章】。

要使用 TopoJSON 的相关函数,需要引用:

<script src="http://d3js.org/topojson.v1.min.js" charset="utf-8"></script>

读取之后,使用 topojson.feature 将其转换为 GeoJSON 文件,不错,最终使用时还是 GeoJSON 的格式,但是在读取时速度会快很多。

d3.json("china.topojson", function(error, toporoot) {if (error) return console.error(error);//输出china.topojson的对象console.log(toporoot);//将TopoJSON对象转换成GeoJSON,保存在georoot中var georoot = topojson.feature(toporoot,toporoot.objects.china);//输出GeoJSON对象console.log(georoot);//包含中国各省路径的分组元素var china = svg.append("g");//添加中国各种的路径元素var provinces = china.selectAll("path").data( georoot.features ).enter().append("path").attr("class","province").style("fill", "#ccc").attr("d", path );});

此外,南海诸岛的地图是不包含在地图文件里的。但是,中国的南海诸岛,一般只是显示在右下角,用一个方框框起来而已,不一定要做成GeoJSON格式。直接制作一个SVG格式的文件即可。

我制作了一个:southchinasea.svg

添加到代码里,形如:

d3.xml("southchinasea.svg", function(error, xmlDocument) {svg.html(function(d){return d3.select(this).html() + xmlDocument.getElementsByTagName("g")[0].outerHTML;});var gSouthSea = d3.select("#southsea");gSouthSea.attr("transform","translate(540,410)scale(0.5)").attr("class","southsea");});

3. 为各省市添加颜色

假设现在有一组反应各省旅游业发展的数据,保存到文件 tourism.json 里:

{"name": "中国","provinces":[{"name": "北京", "value":   14149    },{"name": "天津", "value":    2226.41},{"name": "河北", "value":  1544.94},{"name": "山西", "value":  3720.24},// 省略]
}

读取此文件后,按照第一节的思路,创建一个颜色插值函数:

                //求最大值和最小值var maxvalue = d3.max(valuedata.provinces, function(d){ return d.value; });var minvalue = 0;//定义一个线性比例尺,将最小值和最大值之间的值映射到[0, 1]var linear = d3.scale.linear().domain([minvalue, maxvalue]).range([0, 1]);//定义最小值和最大值对应的颜色var a = d3.rgb(0,255,255);   //浅蓝色var b = d3.rgb(0,0,255);  //蓝色//颜色插值函数var computeColor = d3.interpolate(a,b);

computeColor 是我们需要的函数。接下来,只需要修改各省份的填充色即可,为了方便,将读取到的数据都放到一个values数组里,令其索引号为各省的名称。

     //将读取到的数据存到数组values,令其索引号为各省的名称var values = [];for(var i=0; i<valuedata.provinces.length; i++){var name = valuedata.provinces[i].name;var value = valuedata.provinces[i].value;values[name] = value;}//设定各省份的填充色provinces.style("fill", function(d,i){var t = linear( values[d.properties.name] );var color = computeColor(t);return color.toString();});

这样,虽然把地图绘制了,填充色也按照值域对应了,但是还需要一个标志,来告诉用户什么颜色对应什么值。

4. 添加颜色标志

【高级 - 第 5.1 章】有提到如何将渐变的颜色填充到一个矩形上,在这里就用此法制作一个颜色标志。

     //定义一个线性渐变var defs = svg.append("defs");var linearGradient = defs.append("linearGradient").attr("id","linearColor").attr("x1","0%").attr("y1","0%").attr("x2","100%").attr("y2","0%");var stop1 = linearGradient.append("stop").attr("offset","0%").style("stop-color",a.toString());var stop2 = linearGradient.append("stop").attr("offset","100%").style("stop-color",b.toString());//添加一个矩形,并应用线性渐变var colorRect = svg.append("rect").attr("x", 20).attr("y", 490).attr("width", 140).attr("height", 30).style("fill","url(#" + linearGradient.attr("id") + ")");//添加文字var minValueText = svg.append("text").attr("class","valueText").attr("x", 20).attr("y", 490).attr("dy", "-0.3em").text(function(){return minvalue;});var maxValueText = svg.append("text").attr("class","valueText").attr("x", 160).attr("y", 490).attr("dy", "-0.3em").text(function(){return maxvalue;});

5. 结果

结果如下如所示,

完整代码打开以下链接,右键选择查看源代码:

http://www.ourd3js.com/demo/G-6.0/range.html

谢谢阅读。

文档信息

  • 版权声明:署名(BY)-非商业性(NC)-禁止演绎(ND)
  • 发表日期:2015 年 5 月 20 日
  • 更多内容:OUR D3.JS - 数据可视化专题站 和 CSDN个人博客
  • 备注:本文发表于 OUR D3.JS ,转载请注明出处,谢谢

【 D3.js 高级系列 — 6.0 】 值域和颜色相关推荐

  1. 【 D3.js 进阶系列 】 进阶总结

    进阶系列的文章从去年10月开始写的,晃眼又是4个多月了,想在年前总结一下. 首先恭祝大家新年快乐.今年是羊年吧.前段时间和朋友聊天,聊到十二生肖里为什么没猫,我张口就道:不是因为十二生肖开会的时候猫迟 ...

  2. html文件中包含相关的d3.js文件,D3.js进阶系列之CSV表格文件的读取详解

    前言 之前在入门系列的教程中,我们常用 d3.json()函数来读取 json 格式的文件.json 格式很强大,但对于普通用户可能不太适合,普通用户更喜欢的是用 Microsoft Excel 或 ...

  3. 【 D3.js 入门系列 --- 4 】 怎样使用scale(比例)

    本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 在上一节中使用了一个非常重要的概念 - scale (这个不知道 ...

  4. 【 D3.js 入门系列 --- 2 】 怎样使用数据和选择元素

    本人的个人博客首页为: http://www.ourd3js.com/  ,csdn博客首页为:http://blog.csdn.net/lzhlzz/. 转载请注明出处,谢谢. 接着上一讲的内容,这 ...

  5. 【 D3.js 入门系列 --- 10 】 地图的绘制

    地图的制作在 D3 中可以说是最重要的一环.因为在进行数据可视化时,很多情况都会和地图联系在一起,如中国各省的人口多少,GDP多少等,都可以和地图联系在一起. D3 中制作地图所需要的文件问 JSON ...

  6. 【 D3.js 入门系列 --- 7 】 理解 update, enter, exit 的使用

    本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 在前面几节中重复出现了例如以下代码: svg.selectAll ...

  7. 【 D3.js 入门系列 --- 10.2 】 你可以拖动地图

    我的个人博客是:www.ourd3js.com csdn博客为:blog.csdn.net/lzhlzz 转载请注明出处.谢谢. 本节是结合9.2节 和10节 的内容制作的一个可力学导向的中国地图,用 ...

  8. 【 D3.js 入门系列 --- 9 】 常见可视化图形

    本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. Layout ,直译为"布局,安排".但在 ...

  9. 数据可视化利器D3.js教程 API

    汇智网 http://xc.hubwiz.com/course/54fd40cfe564e50d50dcf284 D3.js 入门系列 - 选择元素和绑定数据 https://www.cnblogs. ...

最新文章

  1. DWR提示DWRUtil未定义的问题
  2. python中string.digits_python学习笔记五:字符串方法
  3. Spring AOP增强(Advice)
  4. 模板匹配,特征点匹配-全
  5. 辽师大计算机科学与技术专业怎么样,性价比很高的大学,辽师大的优势专业分析!家长请收藏...
  6. 一天搞定CSS:css选择器--07
  7. SQL SERVER 子查询的用法
  8. ECMAScript 2015~2020 语法全解析
  9. 【转载】单片机应用系统断电时的数据保护方法
  10. java中的NIO和IO到底是什么区别?20个问题告诉你答案
  11. angularjs的三种注入方式
  12. 直接读取Excel文件数据
  13. 二进制空间权重矩阵_“生成空间权重矩阵”的工作原理
  14. 让openkore 更节省你的CPU和内存
  15. alpine日志中文乱码的问题解决方案
  16. mapreduce推测执行算法及原理
  17. 教你百度网盘文件转阿里云
  18. hcip难不难?华为认证考试难不难?
  19. 【2389. 和有限的最长子序列】
  20. 三五族异质结的自发极化、压电极化及2DEG

热门文章

  1. ecshop怎么写原生php,ecshop模板中直接写php的方法
  2. 大量域名数据下载地址收集整理
  3. Ubuntu18.04和20.04初始软件安装
  4. 解决Microsoft Office套件 配置注册表数据库损坏 问题【Office】
  5. ner 评估指标_2019-03 NER命令实体识别归纳
  6. Apifox:节省研发团队的每一分钟
  7. python埃及分数式_埃及分数
  8. java emoji过滤_java过滤emoji表情
  9. 客户的管理及分类怎么做?
  10. 【激活函数】Swish激活函数详解