JavaScript-D3入门五-数据和字符串数组映射到颜色模型
2018-03-08 10:55
603 查看
基于《JavaScript-D3入门四-事件绑定》中的代码。
这里只要soccerviz2.js代替上一篇的soccerviz.js,就可以在Web Server上运行html,一边修改代码一边观察运行效果。
下面是soccerviz2.js源代码//soccerviz2.js
//演示颜色映射的几种方式
function createSoccerViz() {
d3.csv("/data/worldcup.csv", data => {overallTeamViz(data)})
function overallTeamViz(incomingData) {
//根据incomingData的行数添加g.overallG
d3.select("svg")
.append("g")
.attr("id", "teamsG")
.attr("transform", "translate(50,300)")
.selectAll("g")
.data(incomingData)
.enter()
.append("g")//设incomingData中数据的行数为n,添加n个g对象。
.attr("class", "overallG")
.attr("transform", (d, i) =>"translate(" + (i * 50) + ", 0)");//为n个对象设置各自的(x,y)属性
//返回class属性为overallG的所有g节点,即teamG是一个含g节点的数组。
var teamG = d3.selectAll("g.overallG");
//每个g.overallG对象下新建circle,带动画效果
teamG
.append("circle")
.attr("r", 0)
.transition().delay((d, i) => i * 100).duration(500)//多个circle依次变大
.attr("r", 40)
.transition().duration(500)
.attr("r", 20);
//g.overallG下新建text
teamG
.append("text")
.attr("y", 30)
.text(d => d.team);
//改变现有DOM元素在父节点中的先后位置,
//感觉在这里调用没有什么意义,所以把下面两行注释掉了
//d3.select("g.overallG").raise();//往后移动
//d3.select("g.overallG").lower();//往前移动
//使text节点不处理鼠标事件。据说这样的设置可以让鼠标事件穿透当前节点(即当前节点就像不存在一样)。
teamG.select("text").style("pointer-events", "none");
//incomingData第一行数据除了team,region其它column都作为key
//dataKeys=["win","loss","draw","points","gf","ga","cs","yc","rc"]
const dataKeys = Object.keys(incomingData[0])
.filter(d => d !== "team" && d !== "region");
//在body下添加<div id='controls'>节点,在这个节点下再添加button节点
//Hint: 由于button.teams是不存在的,所以会添加button节点.
d3.select("#controls").selectAll("button.teams")
.data(dataKeys).enter()
.append("button")
.on("click", buttonClick)//事件绑定
.html(d => d);
//点击某个button对象更新视图
/*
function buttonClick(datapoint) {
//datapoint的值为["win","loss","draw","points","gf","ga","cs","yc","rc"]数组中的元素!
var maxValue = d3.max(incomingData, d => parseFloat(d[datapoint]))
//color map
//采用RGB颜色模型过度,中间色是灰色的,不符合我们的需求
//var ybRamp = d3.scaleLinear()
// .domain([0, maxValue]).range(["blue", "yellow"]);
//中间色用HSL(hue,saturation,lightness)颜色模型过度
var ybRamp = d3.scaleLinear()
.interpolate(d3.interpolateHsl)//.interpolate(d3.interpolateLab)//D3也支持Lab色彩模型
.domain([0, maxValue]).range(["yellow", "blue"]);
//linear map
var radiusScale = d3.scaleLinear()
.domain([0, maxValue]).range([2, 20])
//更新circle对象的属性,带动画效果
d3.selectAll("g.overallG").select("circle")
.transition().duration(1000)//这行添加了动画效果
.attr("r", d => {
if (radiusScale(d[datapoint]) > 0)
return radiusScale(d[datapoint]);
else
return 0;//r属性不接受negative number.
}).style("fill", d => ybRamp(d[datapoint]));
}//buttonClick
*/
/*
function buttonClick(datapoint) {
var maxValue = d3.max(incomingData, function (el) {
return parseFloat(el[datapoint])
})
//字符串数组到颜色模型的映射.
var tenColorScale = d3.scaleOrdinal()
.domain(["UEFA", "CONMEBOL", "CAF", "AFC"])
.range(d3.schemeCategory10);
//没在domain里的字符串,颜色映射为unknown里指定的颜色.
//var tenColorScale = d3.scaleOrdinal()
// .domain(["UEFA", "CONMEBOL"])
// .range(d3.schemeCategory10)
// .unknown("#c4b9ac");
//radius映射
var radiusScale = d3.scaleLinear().domain([0, maxValue]).range([2, 20]);
d3.selectAll("g.overallG").select("circle").transition().duration(1000)
.style("fill", p => tenColorScale(p.region))
.attr("r", p => radiusScale(p[datapoint]))
}
*/
function buttonClick(datapoint) {
var maxValue = d3.max(incomingData, d => parseFloat(d[datapoint]));
//colorbrewer.Reds[3]为包含多个颜色的一个数组。
var colorQuantize = d3.scaleQuantize()
.domain([0, maxValue]).range(colorbrewer.Reds[3]);
var radiusScale = d3.scaleLinear()
.domain([0, maxValue]).range([2, 20]);
d3.selectAll("g.overallG").select("circle").transition().duration(1000)
.style("fill", d => colorQuantize(d[datapoint]))
.attr("r", d => radiusScale(d[datapoint]))
}
//highlight同一个region的对象。
teamG.on("mouseover", highlightRegion)
function highlightRegion(d) {
//这里的this为teamG数组中的某一个对象。
d3.select(this).select("text").classed("active", true).attr("y", 10);
//修改circle的class属性。
/* 通过修改circle的class属性来改变circle属性
d3.selectAll("g.overallG").select("circle").each(function (p) {
p.region == d.region ?
d3.select(this).classed("active", true) :
d3.select(this).classed("inactive", true);
});
*/
//通过修改circle的fill风格来改变circle的颜色
var teamColor = d3.rgb("#75739F");
d3.selectAll("g.overallG").select("circle").style("fill", p => p.region === d.region ?
teamColor.darker(.75) : teamColor.brighter(.5));
//把this节点,移到parent节点的最后,否则会被同级g节点遮住。
this.parentElement.appendChild(this);
}//highlightRegion
//
teamG.on("mouseout", unHighlight)
function unHighlight() {
d3.selectAll("g.overallG").select("circle").attr("class", "");//修改class属性的另一种方式
d3.selectAll("g.overallG").select("text")
.classed("active", false).attr("y", 30);
}//unHighlight
}//overallTeamViz
}//createSoccerViz
这里只要soccerviz2.js代替上一篇的soccerviz.js,就可以在Web Server上运行html,一边修改代码一边观察运行效果。
下面是soccerviz2.js源代码//soccerviz2.js
//演示颜色映射的几种方式
function createSoccerViz() {
d3.csv("/data/worldcup.csv", data => {overallTeamViz(data)})
function overallTeamViz(incomingData) {
//根据incomingData的行数添加g.overallG
d3.select("svg")
.append("g")
.attr("id", "teamsG")
.attr("transform", "translate(50,300)")
.selectAll("g")
.data(incomingData)
.enter()
.append("g")//设incomingData中数据的行数为n,添加n个g对象。
.attr("class", "overallG")
.attr("transform", (d, i) =>"translate(" + (i * 50) + ", 0)");//为n个对象设置各自的(x,y)属性
//返回class属性为overallG的所有g节点,即teamG是一个含g节点的数组。
var teamG = d3.selectAll("g.overallG");
//每个g.overallG对象下新建circle,带动画效果
teamG
.append("circle")
.attr("r", 0)
.transition().delay((d, i) => i * 100).duration(500)//多个circle依次变大
.attr("r", 40)
.transition().duration(500)
.attr("r", 20);
//g.overallG下新建text
teamG
.append("text")
.attr("y", 30)
.text(d => d.team);
//改变现有DOM元素在父节点中的先后位置,
//感觉在这里调用没有什么意义,所以把下面两行注释掉了
//d3.select("g.overallG").raise();//往后移动
//d3.select("g.overallG").lower();//往前移动
//使text节点不处理鼠标事件。据说这样的设置可以让鼠标事件穿透当前节点(即当前节点就像不存在一样)。
teamG.select("text").style("pointer-events", "none");
//incomingData第一行数据除了team,region其它column都作为key
//dataKeys=["win","loss","draw","points","gf","ga","cs","yc","rc"]
const dataKeys = Object.keys(incomingData[0])
.filter(d => d !== "team" && d !== "region");
//在body下添加<div id='controls'>节点,在这个节点下再添加button节点
//Hint: 由于button.teams是不存在的,所以会添加button节点.
d3.select("#controls").selectAll("button.teams")
.data(dataKeys).enter()
.append("button")
.on("click", buttonClick)//事件绑定
.html(d => d);
//点击某个button对象更新视图
/*
function buttonClick(datapoint) {
//datapoint的值为["win","loss","draw","points","gf","ga","cs","yc","rc"]数组中的元素!
var maxValue = d3.max(incomingData, d => parseFloat(d[datapoint]))
//color map
//采用RGB颜色模型过度,中间色是灰色的,不符合我们的需求
//var ybRamp = d3.scaleLinear()
// .domain([0, maxValue]).range(["blue", "yellow"]);
//中间色用HSL(hue,saturation,lightness)颜色模型过度
var ybRamp = d3.scaleLinear()
.interpolate(d3.interpolateHsl)//.interpolate(d3.interpolateLab)//D3也支持Lab色彩模型
.domain([0, maxValue]).range(["yellow", "blue"]);
//linear map
var radiusScale = d3.scaleLinear()
.domain([0, maxValue]).range([2, 20])
//更新circle对象的属性,带动画效果
d3.selectAll("g.overallG").select("circle")
.transition().duration(1000)//这行添加了动画效果
.attr("r", d => {
if (radiusScale(d[datapoint]) > 0)
return radiusScale(d[datapoint]);
else
return 0;//r属性不接受negative number.
}).style("fill", d => ybRamp(d[datapoint]));
}//buttonClick
*/
/*
function buttonClick(datapoint) {
var maxValue = d3.max(incomingData, function (el) {
return parseFloat(el[datapoint])
})
//字符串数组到颜色模型的映射.
var tenColorScale = d3.scaleOrdinal()
.domain(["UEFA", "CONMEBOL", "CAF", "AFC"])
.range(d3.schemeCategory10);
//没在domain里的字符串,颜色映射为unknown里指定的颜色.
//var tenColorScale = d3.scaleOrdinal()
// .domain(["UEFA", "CONMEBOL"])
// .range(d3.schemeCategory10)
// .unknown("#c4b9ac");
//radius映射
var radiusScale = d3.scaleLinear().domain([0, maxValue]).range([2, 20]);
d3.selectAll("g.overallG").select("circle").transition().duration(1000)
.style("fill", p => tenColorScale(p.region))
.attr("r", p => radiusScale(p[datapoint]))
}
*/
function buttonClick(datapoint) {
var maxValue = d3.max(incomingData, d => parseFloat(d[datapoint]));
//colorbrewer.Reds[3]为包含多个颜色的一个数组。
var colorQuantize = d3.scaleQuantize()
.domain([0, maxValue]).range(colorbrewer.Reds[3]);
var radiusScale = d3.scaleLinear()
.domain([0, maxValue]).range([2, 20]);
d3.selectAll("g.overallG").select("circle").transition().duration(1000)
.style("fill", d => colorQuantize(d[datapoint]))
.attr("r", d => radiusScale(d[datapoint]))
}
//highlight同一个region的对象。
teamG.on("mouseover", highlightRegion)
function highlightRegion(d) {
//这里的this为teamG数组中的某一个对象。
d3.select(this).select("text").classed("active", true).attr("y", 10);
//修改circle的class属性。
/* 通过修改circle的class属性来改变circle属性
d3.selectAll("g.overallG").select("circle").each(function (p) {
p.region == d.region ?
d3.select(this).classed("active", true) :
d3.select(this).classed("inactive", true);
});
*/
//通过修改circle的fill风格来改变circle的颜色
var teamColor = d3.rgb("#75739F");
d3.selectAll("g.overallG").select("circle").style("fill", p => p.region === d.region ?
teamColor.darker(.75) : teamColor.brighter(.5));
//把this节点,移到parent节点的最后,否则会被同级g节点遮住。
this.parentElement.appendChild(this);
}//highlightRegion
//
teamG.on("mouseout", unHighlight)
function unHighlight() {
d3.selectAll("g.overallG").select("circle").attr("class", "");//修改class属性的另一种方式
d3.selectAll("g.overallG").select("text")
.classed("active", false).attr("y", 30);
}//unHighlight
}//overallTeamViz
}//createSoccerViz
相关文章推荐
- javascript入门经典学习三(使用变量,字符串数组)(附js中文手册)
- 将数据模型(数组)转换为json字符串
- JavaScript拆分字符串并将分割的数据放到数组中
- JavaScript中的Date日期、String字符串、Array数组、Math提供对数据的数学计算
- JavaScript 字符串与数组互转,并保持数据去重、排序功能
- JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)
- JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)
- JavaScript fontcolor方法入门实例(按照指定的颜色来显示字符串)
- JavaScript拆分字符串并将分割的数据放到数组中
- JavaScript-D3入门三-数据绑定
- JavaScript fontcolor方法入门实例(按照指定的颜色来显示字符串)
- JavaScript——将字符串转化成数组,并以列表的形式在文档中输出
- JavaScript-快速入门(四)字符串
- 25、使用jQuery操作JavaScript(字符串操作 数组操作 )
- json的作用:按规定格式保存js语言中的一组数据并转换为字符串(json是种特殊的容器,一般保存对象和数组数据(可以嵌套),并把它们装换为字符串在网络中传输?))
- javascript 根据指定字符把字符串拆分为数组
- JavaScript基础 检查字符串中 是否含有 指定的数组中的元素
- JavaScript字符串转数组(升级)
- BZOJ3790 神奇项链 解题报告【字符串】【Manacher】【树状数组】【数据结构优化DP】
- 云星数据---Scala实战系列(精品版)】:Scala入门教程003-Scala数组详解002