一、安裝D3.js 1.網路連接 2.命令行安裝 cnpm || npm install d3 --save => 我採用的是cnpm install d3 --save 3.創建node 伺服器 a. cnpm || npm install express --save =>前面教程已經說了exp ...
一、安裝D3.js
1.網路連接
<script src="https://d3js.org/d3.v4.min.js"></script>
2.命令行安裝
cnpm || npm install d3 --save => 我採用的是cnpm install d3 --save
3.創建node 伺服器
a. cnpm || npm install express --save =>前面教程已經說了express 搭建伺服器了。後面的教程的都是採用 node 搭建本地伺服器。
b. 安裝watch文件資源改變的時候自動啟動node cnpm install -g supervisor
以前啟動服務的時候 是 node server.js 以後 就是 supervisor server.js
//server.js
var express = require('express'); var app = express(); var d3 = require('d3'); app.get('/demo1.js',function(req,res){ res.sendFile(__dirname + '/' + 'demo1.js'); }) app.get('/',function(req,res){ res.sendFile(__dirname + '/' + 'demo.html'); }) app.get('/demo.html',function(req,res){ res.sendFile(__dirname + '/' + 'demo.html'); }) app.get('/d3.js',function(req,res){ res.sendFile(__dirname + '/' + 'node_modules/d3/build/d3.js'); }) var server = app.listen('3000',function(){ console.log('server start 127.0.0.1'); })
c.demo.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>D3 Demo1</title> <script src="d3.js"></script> </head> <body> </body> <script src="demo1.js"></script> </html>
準備工作完畢,還是寫Hello World!
二、hello world
var body = d3.select('body'); //選擇body元素 body.append('h1') //向 body元素中插入 h1標簽 .text('Hello world') // 給h1標簽填充文字為hello world .style('color','red'); //修改樣式 字體顏色 為紅色 /* 這裡涉及一個概念:選擇集 使用 d3.select() 或 d3.selectAll() 選擇元素後返回的對象,就是選擇集。 另外,有人會發現,D3 能夠連續不斷地調用函數,形如: d3.select().selectAll().text() 這稱為鏈式語法,和 JQuery 的語法很像,常用 JQuery 的朋友一定會感到很親切。 因為封裝每個方法的時候都會返回當前對象 return this; */
三、元素的操作
1. 選擇元素和元素的綁定
/* 在D3中如何選擇元素 d3.select():是選擇所有指定元素的第一個 d3.selectAll():是選擇指定元素的全部 d3.select('p') 選擇頁面中第一個P標簽 d3.selectAll('p'); //選擇頁面中的所有P標簽 */ /* 如何綁定數據 datum():綁定一個數據到選擇集上 data():綁定一個數組到選擇集上,數組的各項值分別與選擇集的各元素綁定 */ // datum var data = 'hello world'; var p = d3.selectAll('p'); p.datum(data).text(function (d,i) { return '第' + i + '個P標簽的數據是' + d; }) //data 綁定一個數組 var dataArr = [1,2,3,4]; p.data(dataArr).text(function(d,i){ return '第' + i + '個P標簽的數據是' + d; });
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>D3 Demo1</title> <script src="d3.js"></script> </head> <body> <p></p> <p></p> <p></p> </body> <script src="demo1.js"></script> </html>
2.選擇、插入和刪除元素
//選擇器的方法 <h1 id='app' class='demo'></h1> var h1 = d3.select('h1');// select('#app'),select("h1"); var h1 = d3.selectAll('h1'); // => 跟上面的方法一樣,跟jQuery 的元素選擇器一樣 // 插入元素 var body = d3.select('body'); body.append('h2').text('我是插在body 末尾的元素'); body.insert('h2','#app').text('我是插在id為APP的元素前面的 h2標簽') //跟jQuery中的方法一樣 //刪除元素 var app = d3.select('#app'); app.remove(); //刪除 id為app的元素
三、柱狀圖
var w = 400,h = 400; var body = d3.select('body'); //選擇 body元素 var data = [50,100,200,150]; var svg = body.append('svg'); //在body中插入svg 元素 畫布 /* SVG 是什麼 SVG,指可縮放矢量圖形(Scalable Vector Graphics),是用於描述二維矢量圖形的一種圖形格式,是由萬維網聯盟制定的開放標準。 SVG 使用 XML 格式來定義圖形,除了 IE8 之前的版本外,絕大部分瀏覽器都支持 SVG, 可將 SVG 文本直接嵌入 HTML 中顯示。 SVG 有如下特點: SVG 繪製的是矢量圖,因此對圖像進行放大不會失真。 基於 XML,可以為每個元素添加 JavaScript 事件處理器。 每個圖形均視為對象,更改對象的屬性,圖形也會改變。 不適合游戲應用。 要註意,在 SVG 中,x 軸的正方向是水平向右,y 軸的正方向是垂直向下的。 Canvas 是什麼 Canvas 是通過 JavaScript 來繪製 2D 圖形,是 HTML 5 中新增的元素。 Canvas 有如下特點: 繪製的是點陣圖,圖像放大後會失真。 不支持事件處理器。 能夠以 .png 或 .jpg 格式保存圖像 適合游戲應用 */ svg.selectAll('rect') //選擇svg 中的rect(svg 中提供的矩形標簽) 元素 .data(data) //綁定數據 .enter() // 當 data.length > rect 的元素個時候用enter()。 update,exit()以後再說 .append('rect') //補充data.length - rect.length 剩餘的rect元素 .attr('x',20) //上面說了SVG畫布的坐標問題 x就是橫向坐標的距離 .attr('y',function(d,i){ //Y 也一樣 都是相對 (0,0)點 return 25 * i; }) .attr('width',function(d,i){ // 設置矩形的寬度 return d; }) .attr('height',function(d,i){ //設置柱子的高度 return 20; }) .attr('fill','green'); //給柱子填充顏色 // 其實跟canvas 中的fillrect 繪製矩形一樣
四、比例尺
//比例尺 /* 在數學中,x 的範圍被稱為定義域,y 的範圍被稱為值域。 D3 中的比例尺,也有定義域和值域,分別被稱為 domain 和 range。 開發者需要指定 domain 和 range 的範圍,如此即可得到一個計算關係。 */ //線型比例尺 /* 線性比例尺,能將一個連續的區間,映射到另一區間。要解決柱形圖寬度的問題,就需要線性比例尺。 */ var dataset = [0.3,0.9,1,2,2.5]; //要把這個區間映射到0-300的範圍 var max = d3.max(dataset); var linear = d3.scaleLinear() .domain([0,max]) .range([0,300]); /* v3: d3.scale.linear() (v3第三版) 返回一個線性比例尺。domain() 和 range() 分別設定比例尺的定義域和值域。在這裡還用到了兩個函數,它們經常與比例尺一起出現: d3.max() d3.min() v4: 最新版 scaleLinear(); */ console.log(linear(1)); // 120 //序數比例尺 有時候,定義域和值域不一定是連續的。例如,有兩個數組: var index = [0, 1, 2, 3, 4]; var color = ["red", "blue", "green", "yellow", "black"]; var ordinal = d3.scaleOrdinal() .domain(index) .range(color); console.log(ordinal(1)) // blue 這樣兩個數組就有對應關係 /* v3: d3.scale.ordinal() .domain() .range(); v4: d3.scaleOrdinal() .domain() .range() */ //用比列尺轉換為柱狀圖 就以上面那個線型比例尺為列 畫布用上一點的畫布 svg svg.selectAll('rect') .data(dataset) .enter() .append('rect') .attr('x',20) .attr('y',function(d,i){ return i * 25; }) .attr('width',function(d,i){ return linear(d); }) .attr('height',function(d,i){ return 20; }) .attr('fill','blue');
五、創建帶坐標軸的柱形圖
//創建已經帶坐標軸的柱形圖 var w = 600,h = 400; var body = d3.select('body'); //選擇 body元素 var svg = body.append('svg').attr('width',w).attr('height',h); //在body中插入svg 元素 畫布 var dataset = [0.3,0.9,1,2,2.5]; //要把這個區間映射到0-300的範圍 var max = d3.max(dataset); var linear = d3.scaleLinear() .domain([0,max]) .range([0,300]); //用比列尺轉換為柱狀圖 就以上面那個線型比例尺為列 畫布用上一點的畫布 svg svg.selectAll('rect') .data(dataset) .enter() .append('rect') .attr('x',20) .attr('y',function(d,i){ return i * 25; }) .attr('width',function(d,i){ return linear(d); }) .attr('height',function(d,i){ return 20; }) .attr('fill','blue'); //添加坐標軸 var axis = d3.axisBottom() //v4: axisBottom 表示向下的比例尺 v3: d3.svg.axis().scale(linear).orient('bottom').ticks(5) v4 和v3差別真大 .scale(linear) //指定比例尺 .ticks(5); //指定刻度數量 svg.append('g') // svg 提供的標簽,不知道的可以去熟悉下svg .attr('transform',function(d,i){ return 'translate('+ 20 +','+ 25*5 +')'; //把坐標軸移到對應的位置 }) .call(axis);
六、一個完整的柱狀圖(矩形,坐標軸,對前面幾條的一個綜合應用)
var w = 500,h=500; var body = d3.select('body'); //選擇body元素 //創建SVG 畫布並把大小設置為 500*500 var svg = body.append('svg').attr('width',w).attr('height',h); //定義一個數組 var dataset = [10, 20, 30, 40, 33, 24, 12, 5]; //y軸 的比例尺 range[0-400] var linearY = d3.scaleLinear().domain([0,d3.max(dataset)]).range([400,0]); //X軸的比例尺 [0,400] [0,8]; var linearX = d3.scaleLinear().domain([0,8]).range([0,400]); var axisY = d3.axisLeft().scale(linearY).ticks(8); var axisX = d3.axisBottom().scale(linearX).ticks(8); svg.append('g') .attr('transform','translate(30,80)') //Y軸 的坐標 .call(axisY); svg.append('g') .attr('transform','translate(30,480)') //X坐標 .call(axisX); svg.selectAll('rect') .data(dataset) .enter() .append('rect') .attr('x',function(d,i){ return linearX(i) + 70; }) .attr('y',function(d,i){ return linearY(d)+ 80; }) .attr('height',function(d,i){ return 400 - linearY(d); }) .attr('width',20) .attr('fill',function(d,i){ return d3.color("hsl("+i * 17+", 80%, 50%)") });
七、第一部分完了
主要是瞭解下怎麼綁定數據,怎麼選擇元素。以前看的時候v3版本的。後來用NPM下來的包是V4發現很多API都改了。還要摸索一段時間。
暫時就說到這兒吧。