最近遇到線條處理的問題,所以將之前使用過的Canvas,SVG(從實(shí)現(xiàn)畫線的角度進(jìn)行出發(fā)),進(jìn)行總結(jié);順便將ECharts和D3兩大庫引入進(jìn)來,進(jìn)行闡述,這兒我從單一層面闡述ECharts和D3簡單使用,至于它們更強(qiáng)大的光芒,期待自己后面內(nèi)容不斷更新~
關(guān)鍵點(diǎn):
- 1.Canvas,SVG實(shí)現(xiàn)線條繪制
- 2.Canvas,SVG對(duì)比
- 3.Canvas,SVG實(shí)現(xiàn)常見效果畫餅圖
- 4.ECharts和D3庫的簡單使用
一.Canvas
1.canvas介紹
canvas標(biāo)簽定義圖形渐溶,比如圖表和其他圖像。標(biāo)記由 Apple 在 Safari 1.3 Web 瀏覽器中引入蕉汪。對(duì) HTML 的這一根本擴(kuò)展的原因在于钧舌,HTML 在 Safari 中的繪圖能力也為 Mac OS X 桌面的 Dashboard 組件所使用巡蘸,并且 Apple 希望有一種方式在 Dashboard 中支持腳本化的圖形叨咖。歷史這兒就簡單了解即可,知道Canvas是如何誕生的;
2.canvas使用
使用Canvas(重要點(diǎn)),大多數(shù) Canvas 繪圖 API 都沒有定義在canvas元素本身上,而是定義在通過畫布的 getContext() 方法獲得的一個(gè)“繪圖環(huán)境”對(duì)象上惋戏。直白的說,通過豐富的Canvas API,在畫布上畫出我們想要的美眉(哈哈,你懂的~)
??直接上DEMO,使用我們的強(qiáng)大的Canvas畫起屬于我們的線條;
//1>.畫線
HTML:
/*注意:此處width,height寫成屬性賦值,不使用css,立flag,不是我們的重點(diǎn)*/
<canvas id="c1" width="800" height="600"></canvas>;
JS:
var oC=document.getElementById('c1');
var gd=oC.getContext('2d');
gd.beginPath(); //beginPath() 方法開始一條路徑邀杏,或重置當(dāng)前的路徑贫奠。(注意:當(dāng)通過定時(shí)器不斷重新繪制,讓元素動(dòng)起來,beginPath()能夠清除之前的路徑)
gd.moveTo(100,100); //起始點(diǎn)
gd.lineTo(300,300); //從起始點(diǎn)到某點(diǎn)畫線
gd.closePath(); //封閉空間
gd.strokeStyle = 'red'; //設(shè)置邊框樣式
gd.lineWidth=20; //設(shè)置線條寬度
gd.stroke(); //繪制路徑
gd.fillStyle = 'green'; //設(shè)置填充樣式
gd.fill(); //進(jìn)行填充
//2>.畫矩形
var gd = document.getElementById('c1').getContext('2d');
gd.fillStyle='red'; //設(shè)置填充顏色(注意順序:先設(shè)置樣式,然后根據(jù)樣式進(jìn)行填充;順序錯(cuò)了沒有效果)
gd.fillRect(100, 100, 400, 300); //繪制矩形
//3>.繪制圓
//為了方便(弧度與角度的轉(zhuǎn)換)計(jì)算和使用,可以將其封裝成JavaScript函數(shù)(后面有推薦內(nèi)容可看)
function getRads (degrees) { return (Math.PI * degrees) / 180; } //角度轉(zhuǎn)弧度
function getDegrees (rads) { return (rads * 180) / Math.PI; } //弧度轉(zhuǎn)角度
var gd = document.getElementById('c1').getContext('2d');
//語法:arc(圓心x, 圓心y, 半徑, 起點(diǎn)角度(弧度), 終點(diǎn)角度(角度), 是否逆時(shí)針)
gd.arc(300,300,100,getRads(0),getRads(360),false); //繪圓
gd.stroke(); //描邊
二.SVG
1.SVG介紹
可縮放矢量圖形(Scalable Vector Graphics望蜡,SVG)是基于可擴(kuò)展標(biāo)記語言(XML)唤崭,用于描述二維矢量圖形的一種圖形格式。SVG由W3C制定脖律,是一個(gè)開放標(biāo)準(zhǔn)谢肾。
2.SVG畫線
//1>.畫直線(注意點(diǎn):1.svg能夠直接響應(yīng)事件 2.x1,y1起點(diǎn) , x2,y2終點(diǎn))
<svg id="svg1" width="800" height="600">
<line x1="100" y1="100" x2="300" y2="300" style="stroke:red; stroke-width:20;" onmouseover="this.style.stroke='green'" onmouseout="this.style.stroke='red'" />
</svg>
//2>.畫矩形[style="stroke:red(外部線條) ; fill:green(填充)"]
<svg id="svg1" width="800" height="600">
<rect x="100" y="100" width="300" height="200" style="stroke:red;fill:green" />
</svg>
//3>.畫圓(cx,cy:圓心 , r:半徑)
<svg id="svg1" width="800" height="600">
<circle cx="300" cy="300" r="200" />
</svg>
//4>.畫橢圓(cx,cy:圓心 ; rx:水平半徑,ry:垂直半徑)
<svg id="svg1" width="800" height="600">
<ellipse cx="300" cy="200" rx="200" ry="100" />
</svg>
//5>.使用path能夠?qū)崿F(xiàn)上面的所有效果(line,rect,circle,ellipse)
*1.實(shí)現(xiàn)line效果(M 起點(diǎn)坐標(biāo) ; L 畫線路徑,可以多點(diǎn)路徑) //注意點(diǎn):數(shù)值之間也可以使用,連接.
<svg id="svg1" width="800" height="600">
<path d="M 100 100 L 300 300" style="stroke:black;fill:none;" />
</svg>
*2.實(shí)現(xiàn)rect效果(Z封閉空間)
<svg id="svg1" width="800" height="600">
<path d="M 100,100 L 400,100 400,300 100,300 Z" style="stroke:black;fill:none;" />
</svg>
*3.實(shí)現(xiàn)circle,ellipse效果
/*
path中d屬性的解析:
M(x,y) 起始點(diǎn)
L(x,y) 線條位置,可以有很多線條
Z 封閉空間
A rx ry(半徑) x-axis-rotation(旋轉(zhuǎn)角度) large-arc-flag(大小弧標(biāo)志0,1) sweep-flag(鏡像標(biāo)志:弧顯示的位置 0左 1右) x y(終點(diǎn))
*/
<svg id="svg1" width="800" height="600">
<path d="
M 100,100
L 200,100
A 150,50,0,1,0,300,100
L 400,100
" style="stroke:black;fill:none;" />
</svg>
三.Canvas和SVG比美
沒有完美的人,自然也沒有完美的代碼,有時(shí)候缺點(diǎn)可能是優(yōu)點(diǎn)的觸發(fā)點(diǎn)(又毒雞湯了,不過確實(shí)如此)
Canvas | SVG|
----|------|----
位圖(像素,放大失真) |矢量圖(沒單位,放大不失真)
依賴js | 脫離js
圖形不能修改 | 圖形可以修改
沒有事件| 有事件
性能很高| 性能一般
適合:大型圖表,游戲|適合:地圖,交互頻繁的圖表
四.常用案例通過Canvas和SVG分別實(shí)現(xiàn)餅圖
1.Canvas畫餅
function getRads (degrees) { return (Math.PI * degrees) / 180; } //角度轉(zhuǎn)弧度
function getDegrees (rads) { return (rads * 180) / Math.PI; } //弧度轉(zhuǎn)角度
window.onload = function (){
var oC = document.getElementById('c1');
var oBtn = document.getElementById('btn1');
var gd = oC.getContext('2d');
function pie(startAng, endAng, color) {
//#1.根據(jù)角度,畫出線條
var x = Math.cos(getRads(startAng))*150+300;
var y = Math.sin(getRads(startAng))*150+300;
gd.beginPath();
gd.moveTo(300,300);
gd.lineTo(x,y);
gd.strokeStyle = 'cyan';
gd.stroke();
//#2.畫弧
gd.arc(300,300,150,getRads(startAng),getRads(endAng),false);
//#3.閉合
gd.closePath();
gd.fillStyle = color;
gd.fill();
}
//原始數(shù)據(jù)
var arr = [1,1,1,1,1,1]; //每部分的值隨便給
var aColor = ['red', 'blue', 'green', 'yellow', 'pink', 'purple']; //顏色隨便給
//1.求和:(目的算出每個(gè)部分所占的等分,求得對(duì)應(yīng)角度)
var sum = 0;
for(var i = 0;i<arr.length;i++){
sum += arr[i];
}
//2.比例、角度(算出每份所占角度)
var arrAng = [];
for(var i = 0;i<arr.length;i++){
arrAng[i] = 360*arr[i]/sum;
}
//3.畫角
//第n個(gè)pie 前一次~前一次+arrAng[n]
var now = 0;
for(var i = 0;i<arrAng.length;i++){
pie(now, now+arrAng[i], aColor[i]);
now += arrAng[i];
}
};
2.SVG畫餅
<svg id="svg1" width="800" height="600">
<path d=
"
M 300,300
L 441,158
A 200,200,0,0,1,400,473
Z
"
style="stroke:black;fill:red;" />
</svg>
五.ECharts
1.ECharts介紹
ECharts小泉,縮寫來自Enterprise Charts芦疏,商業(yè)級(jí)數(shù)據(jù)圖表,一個(gè)純Javascript的圖表庫微姊,可以流暢的運(yùn)行在PC和移動(dòng)設(shè)備上酸茴,兼容當(dāng)前絕大部分瀏覽器(IE6/7/8/9 /10/11,chrome兢交,firefox薪捍,Safari等),底層依賴輕量級(jí)的Canvas類庫ZRender,提供直觀酪穿,生動(dòng)与倡,可交互,可高度個(gè)性化定制的數(shù)據(jù)可視化圖表昆稿。創(chuàng)新的拖拽重計(jì)算、數(shù)據(jù)視圖息拜、值域漫游等特性大大增強(qiáng)了用戶體驗(yàn)溉潭,賦予了用戶對(duì)數(shù)據(jù)進(jìn)行挖掘、整合的能力少欺。
支持折線圖(區(qū)域圖)喳瓣、柱狀圖(條狀圖)、散點(diǎn)圖(氣泡圖)赞别、K線圖畏陕、餅圖(環(huán)形圖)、雷達(dá)圖(填充雷達(dá) 圖)仿滔、和弦圖惠毁、力導(dǎo)向布局圖、地圖崎页、儀表盤鞠绰、漏斗圖、事件河流圖等12類圖表飒焦,同時(shí)提供標(biāo)題蜈膨,詳情氣泡、圖例牺荠、值域翁巍、數(shù)據(jù)區(qū)域、時(shí)間軸休雌、工具箱等7個(gè)可交 互組件灶壶,支持多圖表、組件的聯(lián)動(dòng)和混搭展現(xiàn)杈曲。
2.ECharts使用
1>.餅圖
<html>
<head>
<meta charset="utf-8">
<title></title>
<style media="screen">
#div1 {width:500px;height:400px;border:1px solid black;}
</style>
<script src="echarts.js" charset="utf-8"></script>
<script>
window.onload=function (){
//1.初始化
var charts=echarts.init(document.getElementById('div1'));
//2.數(shù)據(jù)
var data={
title: { //標(biāo)題
text: '性別比例'
},
legend: { //圖例(按鈕可點(diǎn)擊,進(jìn)行禁用)
data: ['男', '女', '其他']
},
series: [ //系列,可以實(shí)現(xiàn)嵌套餅圖
{
name: '性別',
type: 'pie', //圖標(biāo)類型
radius: ['60%', '70%'], //內(nèi)圓,外圓的半徑大小
data: [ //name顯示部分名字 ; value每部分對(duì)應(yīng)值
{name: '男', value: 57.3},
{name: '女', value: 41.6},
{name: '其他', value: 1.1}
]
}
]
};
//3.放進(jìn)去
charts.setOption(data);
};
</script>
</head>
<body>
<div id="div1"></div>
</body>
</html>
1>.柱狀圖
var oDiv=document.getElementById('div1');
//1.初始化echarts對(duì)象
var charts=echarts.init(oDiv);
//2.數(shù)據(jù)寫好
var data={
//1>.標(biāo)題
title: {
text: '2016年產(chǎn)量'
},
//2>.x軸
xAxis: {
data: ['第1季度', '第2季度', '第3季度', '第4季度']
},
//3>.y軸
yAxis: {},
//4>.圖例
legend: {},
//5>.數(shù)據(jù)
series: [
{
name: '產(chǎn)量',
type: 'bar',
data: [454334, 554433, 133221, 55666]
}
]
};
//3.數(shù)據(jù)扔進(jìn)去
charts.setOption(data);
};
六.D3
雖然D3是強(qiáng)大的繪圖庫,用來做圖表,貌似不能突出他的強(qiáng)悍,但是這兒講解依然使用D3進(jìn)行圖表繪制,就忽略逼格的問題了~
1.D3介紹
D3可以將任意數(shù)據(jù)綁定到一個(gè)文檔對(duì)象模型(DOM),然后應(yīng)用數(shù)據(jù)驅(qū)動(dòng)轉(zhuǎn)換的文檔例朱。例如,您可以使用D3來生成一個(gè)HTML表從一個(gè)數(shù)字?jǐn)?shù)組∮悴酰或者,使用相同的數(shù)據(jù)創(chuàng)建一個(gè)交互式SVG條形圖平滑過渡和交互洒嗤。D3不是一個(gè)整體框架,旨在提供所有可能的功能。相反,D3解決了問題的癥結(jié)所在:文檔基于數(shù)據(jù)的有效處理魁亦。這避免了專有的表示和提供非凡的靈活性,暴露web標(biāo)準(zhǔn)的全部功能,如HTML渔隶、SVG和CSS。以最小的開銷,D3非常快,支持大型數(shù)據(jù)集和動(dòng)態(tài)行為交互和動(dòng)畫间唉。D3的功能性風(fēng)格允許代碼重用通過收集不同的組件和插件绞灼。(牛逼吹得可以)
2.D3畫餅
//D3使用過程中抓住:生成器 -> 數(shù)據(jù) -> 結(jié)果,形成整體脈絡(luò)即可,一步一步完成;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="d3.js" charset="utf-8"></script>
<style media="screen">
#svg1 {border:1px solid black;}
</style>
<script>
window.onload=function (){
/*
注意點(diǎn):提出g標(biāo)簽概念:在svg中提供了如g元素這樣的將多個(gè)元素組織在一起的元素。由g元素編組在一起的可以設(shè)置相同的顏色呈野,可以進(jìn)行坐標(biāo)變換;
完成之后結(jié)構(gòu)<svg><g><path></path></g></svg>,如果直接使用path位置默認(rèn)為左上角,使用g標(biāo)簽更好控制圖形位置
*/
//1.準(zhǔn)備工作
var svg = d3.select('#svg1');
var g = svg.append('g')
.attr('transform', 'translate(400,300)'); //添加g節(jié)點(diǎn),移動(dòng)位置
var colors = ['#A0C', '#0AC', '#AC0', '#00C'];
//2.餅圖生成器
var pieGen = d3.pie();
//3.生成一堆a(bǔ)rc數(shù)據(jù)
var arrArc = pieGen([3000, 48000, 69000, 12000]);
//4.arc生成器
var arcGen = d3.arc();
//5.arc生成器+arc數(shù)據(jù) => 一堆字符串(生成的字符串即path標(biāo)簽d屬性需要的屬性值)
for(var i=0;i<arrArc.length;i++){
var strArc=arcGen({
innerRadius: 0,
outerRadius: 150,
startAngle: arrArc[i].startAngle,
endAngle: arrArc[i].endAngle
});
//6.生成path元素
g.append('path')
.attr('d', strArc)
.attr('fill', colors[i]);
}
};
</script>
</head>
<body>
<svg id="svg1" width="800" height="600"></svg>
</body>
</html>