今天学习的是SVG的绘制,也是D3的核心内容之一,虽然这章并没有学完,但稍微的浏览了下后面的内容,我觉得D3果然是个神器没跑了~那就好好学着吧。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Page Template</title>
<script src="d3/d3.js"></script>
<style>
div.bar {
display: inline-block;
width: 20px;
height: 75px;/*后面会根据数值定义*/
background-color: teal;
}
</style>
</head>
<body>
<script>
var dataset = [5, 10, 15, 20, 25 ]
<div class="bar"></div>
//attr()用于设定 HTML 元素的属性和值。
/*包含以下5个属性及值
class caption
id country
src logo.png
width 100px
alt Logo
*/
//.attr("class","bar")等同<div class="bar"></div>
//利用class()快速添加或删除元素的类
.classed("bar",true)
.classed("bar",false)
//案例
var dataset = [5, 10, 15, 20, 25 ];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class","bar")
//添加高度,并以5倍乘,添加间隙
.style("height",function(d){
return d*5 +"px";
});
//excise
var dataset = [ 25, 7, 5, 26, 11, 8, 25, 14, 23, 19, 14, 11, 22, 29, 11, 13, 12, 17, 18, 10, 24, 18, 25, 9, 3 ];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class","bar")
.style("height",function(d){
return d*5 + "px";
})
//随机柱状图
var dataset = [];//空数组
//for 循环
for (var i = 0; i<25; i++){
var newNumber = Math.floor(Math.random()*30); //生成介于0到30的随机数
dataset.push(newNumber)//将数值追加到数组中。
}
//math.round()向上舍入最接近的整数
//math.floor()向下舍入最接近的整数
var newNumber = Math.round(Math.random()*30)
//完整
var dataset = [];
for (var i = 0; i<25; i++){
var newNumber = Math.floor(Math.random()*30);
dataset.push(newNumber);
}
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class","bar")
.style("height",function(d){
return d*5 +"px";
})
/*出错点:
d3.select <- da.select
for(var i = 0; i<25; i++) <- (var i = 0, i<25, i++)
.data(dataset) <- .data = dataset
return d*5 +"px" <-return d*5 +px
*/
//绘制SVG
//create cirle
//set width and height
var w = 500;
var h =50;
d3.select("body").append("svg")//create a svg
var svg = d3.select("body")
.append("svg")//create a new variable
.attr("width",w)
.attr("height",h);
var = dataset = [5, 10, 15, 20, 25 ];
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
/*set cx cy and r
cx:圆心x坐标
cy:圆心y坐标
r :半径,此处直接使用数据值。
*/
circle.attr("cx", function(d, i){
return (i * 50 ) + 25;
})
.attr("cy",h/2)
.attr("r",function(d) {
return d;
});
//fill color
.attr("fill","yellow")
.attr("stroke","orange")
.attr("stroke-width",function(d) {
return d/2;
//create rect
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
var w = 500
var h = 100
var svg = d3.select("body")
.append("svg")
.attr("width",w)
.attr("height",h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x",0)
.attr("y",0)
.attr("weight",20)
.attr("height",100);
//解决重叠问题
.attr("x", function(d, i) {
return i * 21;
})//width:20,gap:1
//宽度的动态缩放
var ws = w / dataset.length - barpadding//自己给加的一个函数,我作者也只是忘了放上去吧。
.attr("x", function(d, i) {
return i * (ws + 1);
})//width:20,gap:1
.attr("width", ws)
//坐标轴变换
.attr("y", function(d) {
return h - d * 4;
.attr("height", function(d) {
return d * 4;
})
//fill color
.attr("fill", "teal")
//自己尝试定义了一个条件,终于有次能不看书敲出if的代码了!
.attr("fill", function(d) {
if (d > 15){
return "red"
}else{return "black"};
})
//多值映射的写法
svg.select("rect")
.data(dataset)
.enter()
.append("rect")
.attr({
x:function(d, i) {
return i * (ws + 1);},
y:function(d) { return h - d * 4;},
width: w / dataset.length - barpadding,
height: function(d) { return d *4 ;}
fill: function(d) { return "rgb(255, 0, " + (d * 10) + ")";}
})
//添加数值标签
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d;
})
.attr("x",function(d, i ) {
return i * ( ws + 1);
})
.attr("y",function(d) {
return h - (d * 4) + 14;
})
.attr("fill","white")
作者吐槽:
假如你没有排版强迫症,现在就可以收手了。不过,假如你跟我一样吹毛求疵,会发现值标签与各自的条形没有完美对齐。(比如,第一个条形中的 5。)改这个太容易啦,可以使用 SVG 的 text-anchor 属性来水平居中文本,就像指定 x 值一样:
.attr("text-anchor", "middle")
太懂我好嘛!!!
加上去了以后。
.attr("text-anchor","middle")
但是居然是这样的@_@
发现问题后,才知道x的轴点没算对。果然数学太差,智商捉急。
.attr("x",function(d, i ) {
return i * ( ws + 1) + ws / 2;
})
//添加数值标签全部代码
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d;
})
.attr("x",function(d, i ) {
return i * ( ws + 1) + ws / 2;
})
.attr("y",function(d) {
return h - (d * 4) + 14;
})
.attr("fill","white")
.attr("text-anchor","middle")
//绘制散点图
//散点图需要用到数组。(x,y)轴点
var w = 500
var h = 100
var dataset = [
[ 5, 20 ],
[480, 90 ],
[250, 50 ],
[100, 33 ],
[330, 95 ],
[410, 12 ],
[475, 44 ],
[ 25, 67 ],
[ 85, 21 ],
[220, 88 ]
];
//绘制svg
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx",function(d) {
return d[0];
})
.attr("cy",function(d) {
return d[1];
})
.attr("r", 5);
/*数组中的元素调用
d[0]返回小数组的第一个元素-> 5
d[1]返回小数组的第二个元素-> 20
访问大数组的值
dataset[5] -> [410,12]
*/
/*设置散点大小
几乎所有的绘图都是无法直接指定圆形面积的,都需要依靠自己计算半径,也就是对面积开平方*/
.attr("r", function(d) {
return Math.sqrt(h - d[1])
});
//添加标签
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d){
return d[0] + "," + d[1];
})
.attr({
x: function(d) {return d[0];},
y: function(d) {return d[1];},
fill: "red",
})
.attr("font-size","11px")
.attr("font-family","sans-serif");
</script>
</body>
</html>
This would be a good time to take a break and stretch your legs. Maybe go for a walk, or grab a coffee or a sandwich. I’ll hang out here (if you don’t mind), and when you get back, we’ll jump into D3 scales!
好的呢~看完吃了顿饭回来写这个~