【 D3.js 高级系列 — 6.0 】 值域和颜色
在【入门 - 第 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 】 值域和颜色相关推荐
- 【 D3.js 进阶系列 】 进阶总结
进阶系列的文章从去年10月开始写的,晃眼又是4个多月了,想在年前总结一下. 首先恭祝大家新年快乐.今年是羊年吧.前段时间和朋友聊天,聊到十二生肖里为什么没猫,我张口就道:不是因为十二生肖开会的时候猫迟 ...
- html文件中包含相关的d3.js文件,D3.js进阶系列之CSV表格文件的读取详解
前言 之前在入门系列的教程中,我们常用 d3.json()函数来读取 json 格式的文件.json 格式很强大,但对于普通用户可能不太适合,普通用户更喜欢的是用 Microsoft Excel 或 ...
- 【 D3.js 入门系列 --- 4 】 怎样使用scale(比例)
本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 在上一节中使用了一个非常重要的概念 - scale (这个不知道 ...
- 【 D3.js 入门系列 --- 2 】 怎样使用数据和选择元素
本人的个人博客首页为: http://www.ourd3js.com/ ,csdn博客首页为:http://blog.csdn.net/lzhlzz/. 转载请注明出处,谢谢. 接着上一讲的内容,这 ...
- 【 D3.js 入门系列 --- 10 】 地图的绘制
地图的制作在 D3 中可以说是最重要的一环.因为在进行数据可视化时,很多情况都会和地图联系在一起,如中国各省的人口多少,GDP多少等,都可以和地图联系在一起. D3 中制作地图所需要的文件问 JSON ...
- 【 D3.js 入门系列 --- 7 】 理解 update, enter, exit 的使用
本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 在前面几节中重复出现了例如以下代码: svg.selectAll ...
- 【 D3.js 入门系列 --- 10.2 】 你可以拖动地图
我的个人博客是:www.ourd3js.com csdn博客为:blog.csdn.net/lzhlzz 转载请注明出处.谢谢. 本节是结合9.2节 和10节 的内容制作的一个可力学导向的中国地图,用 ...
- 【 D3.js 入门系列 --- 9 】 常见可视化图形
本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. Layout ,直译为"布局,安排".但在 ...
- 数据可视化利器D3.js教程 API
汇智网 http://xc.hubwiz.com/course/54fd40cfe564e50d50dcf284 D3.js 入门系列 - 选择元素和绑定数据 https://www.cnblogs. ...
最新文章
- DWR提示DWRUtil未定义的问题
- python中string.digits_python学习笔记五:字符串方法
- Spring AOP增强(Advice)
- 模板匹配,特征点匹配-全
- 辽师大计算机科学与技术专业怎么样,性价比很高的大学,辽师大的优势专业分析!家长请收藏...
- 一天搞定CSS:css选择器--07
- SQL SERVER 子查询的用法
- ECMAScript 2015~2020 语法全解析
- 【转载】单片机应用系统断电时的数据保护方法
- java中的NIO和IO到底是什么区别?20个问题告诉你答案
- angularjs的三种注入方式
- 直接读取Excel文件数据
- 二进制空间权重矩阵_“生成空间权重矩阵”的工作原理
- 让openkore 更节省你的CPU和内存
- alpine日志中文乱码的问题解决方案
- mapreduce推测执行算法及原理
- 教你百度网盘文件转阿里云
- hcip难不难?华为认证考试难不难?
- 【2389. 和有限的最长子序列】
- 三五族异质结的自发极化、压电极化及2DEG