为地图各区域添加颜色.docx
《为地图各区域添加颜色.docx》由会员分享,可在线阅读,更多相关《为地图各区域添加颜色.docx(12页珍藏版)》请在冰豆网上搜索。
为地图各区域添加颜色
为地图各区域添加颜色
为地图各区域添加颜色
摘要:
这一节主要介绍了为地图根据不同区域添加颜色的方法,并给出相关代码。
关键词:
JSON;等值区域;加载数据
1等值区域
等值区域指的是不同区域填充了不同值(深或浅)或颜色,以反映关联数据值的地图。
在,人们常说的“红州,蓝州”等值区域地图,展示的是各个州对共和和民主的倾向,特别是在选举的时候很常见。
但等值区域地图可以基于任何值而不光是派倾向来生成。
这些地图也是使用D3生成最多的地图类型。
尽管等值区域地图非常有实用价值,但也不要忘了它存在一些固有的感知局限性。
因为这种图使用面积来编码值,人口密度低而面积大的州(比如内华达)从视觉上会显得比实际人数多。
标准的等值区域图不能恰当地体现人均指标,内华达州太大了,而特拉华州又太小了。
可是,这种图却能很好地标识地理区域,特别是在地图中,看起来真的非常好看。
2创建比例尺
首先,创建一个比例尺,将数据值作为输入,返回不同的颜色。
这是等值区域地图的核心所在:
varcolor=d3.scale.quantize()
.range(["rgb(237,248,233)","rgb(186,228,179)",
"rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"]);
以量化的比例尺函数作为线性比例尺,但比例尺输出的则是离散的范围。
这里输出的值可以是数值、颜色(这里就是),或者其他你需要的值。
这个比例尺适合把值分类为不同的组(bucket)。
我们这里只分了5个组,实际上你想分几个就分几个。
3加载数据
注意,这里只指定了输出范围,而没有指定输入值域。
接下来,要加载一些数据。
我们有一个文件叫us-ag-productivity-2004.csv,内容类似如下所示:
state,value
Alabama,1.1791
Arkansas,1.3705
Arizona,1.3847
California,1.7979
Colorado,1.0325
Connecticut,1.3209
Delaware,1.4345
...
这些数据来自农业部,报告内容是2004年每个州的农业生产力指标。
这些值的单位是以1996年阿拉巴马州的生产力指标为基准(1.0),更大的值表示生产力更高,更小的值表示生产力更低。
接下来我们就利用这些数据生成一个漂亮的各州生产力地图。
要加载这些数据,使用d3.csv():
d3.csv("us-ag-productivity-2004.csv",function(data){...
然后,在回调函数中,要设置彩色的量化比例尺的输入值域:
color.domain([
d3.min(data,function(d){returnd.value;}),
d3.max(data,function(d){returnd.value;})
]);
这里用到了d3.min()和d3.max()来计算并返回最小和最大的数据值,因此这个比例尺的输出值域是动态计算的。
4加载JSON地理数据
接下来,跟前面一样,加载JSON地理数据。
但不同的是,在这里我想把农业生产力的数据合并到GeoJSON中。
为什么?
因为我们一次只能给元素绑定一组数据。
GeoJSON数据肯定必不可少,因为要据以生成路径,而我们还需要新的农业生产力数据。
为此,就要把它们混合成一个巨大的数组,然后再把混合后的数据绑定到新创建的path元素。
d3.json("us-states.json",function(json){
//混合农业生产力数据和GeoJSON
//循环农业生产力数据集中每个值
for(vari=0;i//取得州名
vardataState=data[i].state;
//取得数据值,并从字符串转换成浮点数
vardataValue=parseFloat(data[i].value);
//在GeoJSON中找到相应的州
for(varj=0;jvarjsonState=json.features[j].properties.name;
if(dataState==jsonState){
//把数据值复制到JSON中
json.features[j].properties.value=dataValue;
//停止循环JSON
break;
}
}
}
大致来说,就是对每个州,我们也找到GeoJSON中相应的值(如“Colorado”)。
然后取得这个州的数据值,把它放到json.features[j].properties.value中,保证它能被绑定到元素,并在将来需要时可以被取出来。
最后,像以前一样创建路径,只是通过style()要设置动态的值:
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d",path)
.style("fill",function(d){
//取得数据值
varvalue=d.properties.value;
if(value){
//如果值存在……
returncolor(value);
}else{
//如果值不存在……
return"#ccc";
}
});
5添加其他数据
这样,地图不再是千篇一律的“钢蓝色”了,每个州的路径都有了不同的填充值。
这里有些小缺漏,因为我们并没有掌握所有州的数据。
数据集里就缺少阿拉斯加、哥伦比亚特区、夏威夷等地的信息。
为了弥补这些缺漏,我们添加了一点小逻辑:
一个if()语句,检查数据值是否有定义。
如果数据值存在,就返回color(value),也就是说我们会把该数据值传递给量化比例尺,由比例尺返回颜色值。
如果数据值不存在,则设置默认的浅灰色#ccc。
图1各州农业生产力等值区域地图
根据数值大小改变图表系列的颜色
假设有一个一季度的库存数据存放在sheet2工作表的A1:
B4区域中,并且由这些数据生成了一张柱形图表
.
图1
再假设目前的库存警戒值设定为50,如果超过这个值,希望图表中对应的柱子变成红色来提醒,不超过50时柱子显示绿色.
如果是针对数据表改变颜色,可以用"条件格式"来实现,但想让图表改变颜色就只能用VBA编写代码了.
在sheet2工作表的底部标签上点鼠标右键,选"查看代码",调出该工作表的VBA窗口,把下面代码粘贴进去
.
图2
PrivateSubWorksheet_Change(ByValTargetAsRange)
x=Target.Row
y=Target.Column
'数值改变的区域为B列的B2:
B4时,生成新的图表
Ify=2Andx>1Andx<5ThenCall生成图表
Target.Select
EndSub
Sub生成图表()
ActiveSheet.DrawingObjects.Delete'先删除表中的所有图表
'下面是生成图表并设置图表格式
Sett=Charts.Add
Witht
.ChartType=xlColumnClustered
.SetSourceDataSource:
=Sheets("Sheet2").Range("A1:
b4"),PlotBy:
=xlColumns'图表的源数据,其中最后一个参数表示系列产生在列
.LocationWhere:
=xlLocationAsObject,Name:
="Sheet2"'图表显示到sheet2工作表中
EndWith
'下面对B2:
B4单元格的值进行判断,如果大于50就变成红色
Fori=2To4
IfRange("B"&i)>50Then
b=3'大于50变红色(3是红色的代码)
Else
b=10'小于50为绿色(10是绿色的代码)
EndIf
ActiveChart.SeriesCollection
(1).Points(i-1).Interior.ColorIndex=b'设置图表的各个柱子的颜色
Next
EndSub
从代码中可以看到,这是使用了sheet2工作表的Change事件来实现的,只要工作表中B2:
B4区域中的数据被修改了,图表就会自动根据库存数改变颜色.
上面的例子中,每次改变数据区域的值,都会删除旧的图表,再生成一个新的图表,有的朋友不喜欢这样,希望只生成一次图表,以后数据改变时,只针对该图表改变颜色,这样图表中的其他设置不受影响.
用下面代码可以实现
执行下面代码前,必须先手工生成一张B2:
B4区域的图表,且该图表在sheet2表中的图表ID为1(最好除这一张图表外,没有其他图表).
PrivateSubWorksheet_Change(ByValTargetAsRange)
x=Target.Row
y=Target.Column
'数值改变的区域为B列的B2:
B4时,生成新的图表
Ify=2Andx>1Andx<5ThenCall图表变色
Target.Select
EndSub
Sub图表变色()
ActiveSheet.ChartObjects
(1).Activate'激活第一张图表
'下面对B2:
B4单元格的值进行判断,如果大于50就变成红色
Fori=2To4
IfRange("B"&i)>50Then
b=3'大于50变红色(3是红色的代码)
Else
b=10'小于50为绿色(10是绿色的代码)
EndIf
ActiveChart.SeriesCollection
(1).Points(i-1).Interior.ColorIndex=b'设置图表的各个柱子的颜色
Next
EndSub
下面是改变颜色后的图表
注意B2单元格与B4单元格中的数值是大于50的,所以图表自动改变了对应的柱子颜色为红色.
1.下面我将通过报警器功能来实现Age这一列数值颜色的变化。
2.点击报警器选项并新建报警器
3.选择过滤的对象,运算符,操作数。
在我的例子里面我将用红色显示Age小于50的值。
用绿色显示介于50-60的值,用蓝色显示大于60的值。
点击添加子报警器来增加报警条件,点击格式可以改变数值显示的颜色和背景色。
4.创建完毕以后点击确定回到报表页面,点击需要添加报警的数据列(Age)。
5.点击报警器选项,勾选所创建的报警器应用到Age数据列
6.点击确定,Age列的数据值将按照我设定的条件按不同颜色显示