您的位置:首页 > Web前端 > JavaScript

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐