本來一直是使用echarts來畫圖的,結(jié)果畫好了以后,公司又要使用d3來畫,沒有對它進(jìn)行特別的深入,只是了解了一下,能完成需求.
還有就是雖然有d3的官網(wǎng)可以學(xué)習(xí),但是我不翻墻的話網(wǎng)站基本上是沒辦法進(jìn)去的 ,為了以后可以方便的使用d3的一些東西,我覺得自己有必要把它寫下來.
先看效果圖
是不是感覺和echarts畫出來的一毛一樣,我也這么覺得......下次再研究兩者有啥區(qū)別吧.
代碼直接貼過來
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#container{
background-color: #ddd;
width: 500px;
height: 350px;
}
path{
fill: none;
stroke: #4682B4;
stroke-width: 2 ;
}
.domain,.tick line{
stroke: gray;
stroke-width: 1;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="d3.js"></script>
<script>
var width = 500,
height = 300,
margin = {left:50,top:30,right:20,bottom:20},
g_width = width-margin.left-margin.right,
g_height = height-margin.top-margin.bottom;
var svg = d3.select("#container")
.append("svg")
.attr("width",width)
.attr("height",height)
var g = d3.select("svg")
.append("g")
.attr("transform","translate("+margin.left+","+margin.top+")")
var dataset = [
{x: 0, y: 11}, {x: 1, y: 35},
{x: 2, y: 23}, {x: 3, y: 78},
{x: 4, y: 55}, {x: 5, y: 18},
{x: 6, y: 98}, {x: 7, y: 100},
{x: 8, y: 22}, {x: 9, y: 65}
];
var scale_x = d3.scale.linear()
.domain(d3.extent(dataset, function(d) {
return d.x;
}))
.range([0,g_width])
var scale_y = d3.scale.linear()
.domain([0, d3.max(dataset,function(d) {
return d.y;
})])
.range([g_height,0])
var x_axis = d3.svg.axis().scale(scale_x),
y_axis = d3.svg.axis().scale(scale_y).orient("left");
g.append("g")
.call(x_axis)
.attr("transform","translate(0,"+g_height+")")
g.append("g")
.call(y_axis)
.append("text")
.text("Price($)")
.attr("transform","rotate(-90)")
.attr("text-anchor","end")
.attr("dy","1em")
//繪制曲線
var line_generator = d3.svg.line()
.x(function(d){
return scale_x(d.x);
})
.y(function(d){
return scale_y(d.y);
})
.interpolate("cardinal");
d3.select("g")
.append("path")
.attr("d",line_generator(dataset))
</script>
</body>
上面的代碼同樣html css js三部分
HTML部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
css代碼
</head>
<body>
<div id="container"></div>
<script src="d3.js"></script>
<script>
js代碼
</script>
</body>
css部分
<style>
#container{
background-color: #ddd;
width: 500px;
height: 350px;
}
path{
fill: none;//可以對曲線進(jìn)行填充色
stroke: #4682B4;/*曲線的顏色*/
stroke-width: 2 ;/*曲線的寬度*/
}
.domain,.tick line{/*刻度尺的樣式*/
stroke: gray;
stroke-width: 1;
}
</style>
path 是對曲線進(jìn)行的一系列樣式設(shè)置
JS部分
- 0 模擬數(shù)據(jù)
var dataset = [
{x: 0, y: 11}, {x: 1, y: 35},
{x: 2, y: 23}, {x: 3, y: 78},
{x: 4, y: 55}, {x: 5, y: 18},
{x: 6, y: 98}, {x: 7, y: 100},
{x: 8, y: 22}, {x: 9, y: 65}
];
- 1 設(shè)置圖表大小:首先要設(shè)置畫布的大小,然后用margin來存儲(chǔ)圖表的邊距信息,計(jì)算出圖表的寬度和高度
var width = 500,
height = 300,
// SVG畫布邊緣與圖表內(nèi)容的距離
margin = {left:50,top:30,right:20,bottom:20},
g_width = width-margin.left-margin.right,
g_height = height-margin.top-margin.bottom;
- 2 添加畫布
//svg // 創(chuàng)建一個(gè)分組用來組合要畫的圖表元素
var svg = d3.select("#container")
.append("svg")
//屬性:寬二蓝、高
.attr("width",width)
.attr("height",height)
//g元素
var g = d3.select("svg")
.append("g")
// // 設(shè)置該分組的transform屬性
.attr("transform","translate("+margin.left+","+margin.top+")")
d3.select("#container")選擇container元素.往這個(gè)里面添加一個(gè)子元素"svg".,給這個(gè)svg設(shè)定一些屬性峰档,再往“svg”中添加一個(gè)”g”元素并設(shè)定一些屬性。
- 3 設(shè)置橫軸方向和縱軸方向的區(qū)域(Domains)和范圍(Ranges)
畫布添加好了 可是我要怎么畫呢 ?首先要確定定義域和值域
//設(shè)置比例縮放
//創(chuàng)建x軸的比例尺(線性比例尺)
var scale_x = d3.scale.linear()//創(chuàng)建了線性比例尺
.domain(d3.extent(dataset, function(d) {//定義定義域
return d.x;
}))
.range([0,g_width])//定義值域
// 創(chuàng)建y軸的比例尺(線性比例尺)
var scale_y = d3.scale.linear()
.domain([0, d3.max(dataset,function(d) {//定義定義域
return d.y;
})])
.range([g_height,0])//定義值域
這段代碼是為了讓我們導(dǎo)入的數(shù)據(jù)與圖表的大小相適應(yīng)篡悟,range知道是圖表范圍的大小,他是一個(gè)尺寸大小躲雅。這段代碼告訴D3我們要畫些東西在x軸上粮揉,這些東西是時(shí)間/日期的一個(gè)實(shí)體织中。
而domain指的是數(shù)據(jù)的區(qū)域,extent返回的是最小的x或y到最大的x或y這樣一個(gè)跨度病游,所以唇跨,最小的x或y就對應(yīng)于上面range的最小值0
對于y軸的值域,g_height 表示的是當(dāng)數(shù)據(jù)為最大值即“8”的時(shí)候,輸出最高點(diǎn)為g_height衬衬。這里要注意由于瀏覽器從左到右买猖、從上到下的坐標(biāo)系數(shù)值是逐漸增到,因此我們將range的值設(shè)成[g_height佣耐,0]即可實(shí)現(xiàn)整一個(gè)的翻轉(zhuǎn)
//政勃,因?yàn)镾VG畫布的y軸與傳統(tǒng)認(rèn)知上的y軸的方向是反著來的,所以在定義y軸的定義域和值域?qū)?yīng)關(guān)系時(shí)兼砖,也需要反著來
- 4 設(shè)置x,y坐標(biāo)軸
設(shè)置好坐標(biāo)比例問題,就要開始創(chuàng)建坐標(biāo)軸,添加坐標(biāo)軸函數(shù):axis()
//創(chuàng)建x軸 添加坐標(biāo)軸函數(shù):axis()
var x_axis = d3.svg.axis().scale(scale_x),
// 創(chuàng)建y軸
y_axis = d3.svg.axis().scale(scale_y).orient("left").ticks(5);;
坐標(biāo)軸axis初始化方法通過d3.svg.axis()來調(diào)用奸远,然后調(diào)用.scale(scale_x)用前面定義的scale_x來給坐標(biāo)軸設(shè)定刻度既棺, .orient()設(shè)定刻度相對坐標(biāo)軸的位置,.ticks()告訴D3在坐標(biāo)軸上設(shè)定差不多幾個(gè)刻度就夠了懒叛,比方說你要D3給你的Y軸設(shè)定大概20個(gè)刻度 y_axis = d3.svg.axis().scale(scale_y).orient("left").ticks(20);
- 5 添加x,y坐標(biāo)軸
既然比例設(shè)置好了,坐標(biāo)軸也設(shè)置好了,畫布也添加完成了,那么就先把坐標(biāo)軸畫出來
//依次添加X丸冕、Y坐標(biāo)軸,并通過偏移量的設(shè)置使得X坐標(biāo)軸往下移
// 添加SVG元素并與x軸進(jìn)行“綁定”
g.append("g")
.call(x_axis)
.attr("transform","translate(0,"+g_height+")")
// 添加SVG元素并與y軸進(jìn)行“綁定”
g.append("g")
.call(y_axis)
.append("text")
.text("Price($)")
.attr("transform","rotate(-90)")
.attr("text-anchor","end")
.attr("dy","1em")
- 6 繪制曲線
什么都準(zhǔn)備好了,就可以繪制曲線了
//繪制曲線
var line_generator = d3.svg.line()
.x(function(d){
return scale_x(d.x);
})
.y(function(d){
return scale_y(d.y);
})
// 選擇線條的類型
.interpolate("cardinal");
// 添加path元素,并通過line_generator()計(jì)算出值來賦值
d3.select("g")
.append("path")
.attr("d",line_generator(dataset))
這樣,一個(gè)曲線圖就完成啦 !!
如果想在曲線上添加點(diǎn)的話,就加入下面的代碼
d3.select("g").selectAll('circle')
.data(dataset)
.enter()
.append('circle')
.attr('cx', function(d) {
return scale_x(d.x);
})
.attr('cy', function(d) {
return scale_y(d.y);
})
.attr('r', 3)
.attr('fill', function(d) {
return "white";
});
這樣畫出來的曲線圖就有點(diǎn)啦
有曲線圖當(dāng)然也有面積圖 ,如果你想繪制面積圖表,注意需要三個(gè)參數(shù),y0將原來的線型圖變成了封閉的面積圖咯 將上述步驟6中繪制曲線的代碼直接換成一下代碼就可以實(shí)現(xiàn)了
var myArea = d3.svg.area()
.x(function (d) {
return scale_x(d.x)
})
.y0(g_height)
.y1(function(d){
return scale_y(d.y)
})
.interpolate("cardinal")
d3.select("g")
.append("path")
.attr("d",myArea(dataset))
.style("fill","pink")
完成了這些基本上就可以應(yīng)付一些簡單的d3畫圖啦
官網(wǎng):http://www.w3.org
不過我老是訪問不了 汗(⊙﹏⊙)b!!!