一、数据可视化
1.概念
数据可视化Data Visualization:就是指将结构或非结构数据转换成适当的可视化图表,然后将隐藏在数据中的信息直接展现于人们面前。
2.常见使用场景
(1)媒体大屏
适合展会、媒体访问等公众场合,是企业形象、品牌展示的窗口;
(2)接待大屏
适用企业内部宣传专区,用于接待来访领导、客户或投资。
(3)监控大屏
针对企业运营或运维监控需求,比较适用内部指挥监控等;
(4)科技大屏
滴滴出行大数据、天猫双十一交易数据、茅台数博会大屏等;
3.数据可视化工具
3.1绘图容器
canvas svg
3.2绘图工具
d3.js echarts
二.Canvas绘图容器
1.什么是Canvas?
Canvas标签用于绘制图形的 HTML 元素,canvas元素本身并没有绘制能力,它仅仅是图形的容器,通常通过JavaScript脚本进行绘制。canvas最早由Apple引入WebKit,用于MacOSX的Dashboard,随后被各个浏览器实现。如今,所有主流的浏览器都支持它。
Internet Explorer 9、Firefox、Opera、Chrome 以及 Safari 支持 及其属性和方法。
注释:Internet Explorer 8 以及更早的版本不支持 元素。
2.应用场景
绘制图形,小游戏
3.Canvas和SVG的区别
Canvas
(1)依赖分辨率
(2)不支持事件处理器
(3)弱的文本渲染能力
(4)能够以 .png 或 .jpg 格式保存结果图像
SVG
(1)不依赖分辨率
(2)支持事件处理器
(3)最适合带有大型渲染区域的应用程序(比如谷歌地图)
(4)不适合游戏应用
4.初识Canvas标签和Canvas对象
4.1canvas标签
<!-- 默认300*150px -->
<canvas id="canvas" width="400" height="400">
您的浏览器不支持,请升级您的浏览器
</canvas>
4.2canvas 上下文对象
getConText()
绘制图形的方法和属性
<script type="text/javascript">
// 1.获取canvas对象
let canvas = document.getElementById('canvas')
// 2.获取上下文对象
if(canvas.getContext('2d')){
let ctx = canvas.getContext('2d')
//绘制图形代码
}else{
alert('请升级您的浏览器')
}
</script>
5.认识线条
5.1画布栅格及坐标空间
(1)canvas元素默认被网格所覆盖。通常来说网格中的一个单元相当于canvas元素中的一像素。
(2)栅格的起点为左上角[坐标为(0,0)]所有元素的位置都相对于原点定位。
5.2线条相关属性及方法
moveTo(x,y)把路径移动到画布中的指定点,不创建线条
lineTo(x,y)添加一个新点,绘制一条从当前位置到指定新点(x,y)位置的直线。
strokeStyle设置或返回描边颜色
fillStyle设置或返回填充颜色
lineWidth设置或返回当前的线条宽度
lineJoin设置或返回两条线相交时,所创建的拐角类型
lineCap设置或返回线条的结束端点样式
5.3描边与填充
stroke()
描边已定义绘图(路径)
fill()
填充当前绘图(路径)
代码案例
// 3.绘制线条
// 1)绘制路径
ctx.moveTo(50,50)
ctx.lineTo(150,50)
ctx.lineTo(150,150)
// 1)修改线条颜色 宽度等样式
// 描边颜色
ctx.strokeStyle = "#007AFF"
// 线宽
ctx.lineWidth = "10"
// 填充颜色
ctx.fillStyle = "#00BB00"
// 相交拐角样式 默认值 尖角
ctx.lineJoin = "miter"
// 圆角
ctx.lineJoin = "round"
// 斜角
ctx.lineJoin = "bevel"
// 2)绘制
// 描边
ctx.stroke()
// 填充
ctx.fill()
5.4绘制路径
beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。生成路径的第一步叫做beginPath()。
closePath()
闭合路径之后图形绘制命令又重新指向到上下文中。不是必需的。
代码案例
// beginPath 开启新的路径
ctx.beginPath()
ctx.moveTo(50,50)
ctx.lineTo(150,50)
ctx.lineWidth = "20"
ctx.stroke()
// 开辟了新的空间
ctx.beginPath()
ctx.moveTo(50,150)
ctx.lineTo(150,150)
ctx.lineWidth = "20"
// 线条两端的样式 默认值
ctx.lineCap="butt"
// 矩形--长度变长了
ctx.lineCap="square"
// 圆角--长度变长了
ctx.lineCap="round"
ctx.stroke()
// 2)绘制三角形
ctx.moveTo(50,50) //起点
ctx.lineTo(150,50)//过程
// ....
ctx.lineTo(150,150)//当前点
// ctx.lineTo(50,50)
// 当前点回到起点
ctx.closePath()
ctx.lineWidth="10"
// 绘制
ctx.stroke()
6.绘制矩形
1.rect(x, y, width, height)
将一个矩形路径增加到当前路径上,绘制一个左上角坐标为(x,y),宽高为width以及height的矩形。需要配合 fill()或者stroke()使用
2.fillRect(x, y, width, height)
绘制一个填充的矩形
3.strokeRect(x, y, width, height)
绘制一个矩形的边框
4.clearRect(x, y, width, height)
清除指定矩形区域,让清除部分完全透明。
代码案例
// 绘制矩形 rect(x, y, width, height)
// ctx.rect(50,50,200,100)
// ctx.stroke()
ctx.strokeStyle="#006699"
ctx.strokeRect(50,50,200,100)
setTimeout(()=>{
// 清除指定区域内的图形
ctx.clearRect(0,0,300,300)
ctx.strokeRect(70,70,200,100)
},1000)
// ctx.fillStyle="#00BB00"
// ctx.fillRect(50,200,200,100)
7.绘制文本
font 文本内容的当前字体属性
textAlign 文本内容的当前对齐方式
fillText()在画布上绘制“被填充的”文本
strokeText()在画布上绘制文本(无填充)
代码案例
// 绘制文字
//指定坐标的下边界坐标 文字绘制在指定坐标上边绘制
ctx.font = "40px 黑体"
ctx.textAlign="right"
ctx.fillText("hello world",100,100)
ctx.strokeText("hello world",100,200)
8、绘制圆形、弧形、扇形
arc(x,y,r,sAngle,eAngle,counterclockwise);
画一个以(x,y)为圆心的以r为半径的圆弧(圆),从sAngle开始到eAngle结束,按照counterclockwise给定的方向(默认为顺时针)生成,true代表逆时针,false代表顺时针。
代码案例
// 1.圆 arc(x,y,r,sAngle,eAngle,counterclockwise);
/*
1.弧度计算公式 弧度=角度/180*Math.PI
2. 0度 三点钟方向
3.默认值 false 顺时针
*/
// ctx.arc(200,200,100,0/180*Math.PI,360/180*Math.PI,false)
// ctx.stroke()
// 绘制弧度
// ctx.arc(200,200,100,0/180*Math.PI,90/180*Math.PI,true)
// ctx.stroke()
// 绘制扇形
ctx.moveTo(200,200)
ctx.arc(200,200,100,0/180*Math.PI,90/180*Math.PI,false)
ctx.closePath()
ctx.stroke()
ctx.fill()
9.太极图案例
代码案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>绘制线条</title>
<style>
#canvas{
/* border:1px solid red;
background-color: pink; */
/* 2.调用动画 */
animation: rotate 3s linear infinite;
}
/* 1.定义帧动画 */
@keyframes rotate{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<!-- 默认300*150px -->
<canvas id="canvas" width="400" height="400">
您的浏览器不支持,请升级您的浏览器
</canvas>
<script type="text/javascript">
// 1.获取canvas对象
let canvas = document.getElementById('canvas')
// 2.获取上下文对象
if(canvas.getContext('2d')){
let ctx = canvas.getContext('2d')
var PI = Math.PI
// 1.绘制大圆
ctx.beginPath()
ctx.arc(200,200,200,0,2*PI,false)
ctx.stroke()
ctx.fillStyle="#fff"
ctx.fill()
// 2.右边的大半圆
ctx.beginPath()
ctx.fillStyle="#000"
ctx.arc(200,200,200,-90/180*PI,90/180*PI,false)
ctx.fill()
//3.上边大黑圆
ctx.beginPath()
ctx.arc(200,100,100,0,2*PI,false)
ctx.fill()
ctx.beginPath()
ctx.fillStyle="#fff"
ctx.arc(200,100,25,0,2*PI,false)
ctx.fill()
// 4.下边的大白圆
ctx.beginPath()
ctx.fillStyle="#fff"
ctx.arc(200,300,100,0,2*PI,false)
ctx.fill()
ctx.beginPath()
ctx.fillStyle="#000"
ctx.arc(200,300,25,0,2*PI,false)
ctx.fill()
}else{
alert('请升级您的浏览器')
}
</script>
</body>
</html>
11.绘制阴影
shadowColor 阴影颜色
shadowOffsetX X轴偏移
shadowBlur 模糊度
shadowOffsetY Y轴偏移
代码案例
ctx.fillStyle="pink"
ctx.shadowColor="#007AFF"
ctx.shadowOffsetX="-20"
ctx.shadowOffsetY="20"
ctx.shadowBlur="3"
ctx.fillRect(50,50,200,100)
12.绘制图像
drawImage() 方法在画布上绘制图像
三个参数:context.drawImage(img,x,y);
五个参数:context.drawImage(img,x,y,width,height);
九个参数:context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
人物代码案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>绘制图像</title>
<style>
#canvas{
border:1px solid red;
/* background-color: pink; */
}
</style>
</head>
<body>
<!-- 默认300*150px -->
<canvas id="canvas" width="400" height="400">
您的浏览器不支持,请升级您的浏览器
</canvas>
<script type="text/javascript">
// 1.获取canvas对象
let canvas = document.getElementById('canvas')
// 2.获取上下文对象
if(canvas.getContext('2d')){
let ctx = canvas.getContext('2d')
let img = new Image()
img.src = "./人物走动.jpg"
img.onload = function(){
// 三个参数:context.drawImage(img,x,y);
图像资源 img 图像在画布上放置的位置的左上角
// ctx.drawImage(img,0,0)
// 五个参数:context.drawImage(img,x,y,width,height);
图像资源 在画布上位置 x y 图片在画布上的宽高
// ctx.drawImage(img,100,100,100,100)
// 九个参数:context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
/*
sx,sy,swidth,sheight 裁剪图片 起始位置x,y 裁剪的宽高
x,y,width,height 图片在画布上的起始位置 和在画布上的宽高
*/
// ctx.drawImage(img,0,0,184,325,0,0,185,325)
// ctx.drawImage(img,184,0,184,325,0,0,185,325)
// ctx.drawImage(img,368,0,184,325,0,0,185,325)
let num = 0;
setInterval(()=>{
ctx.clearRect(0,0,400,400)
ctx.drawImage(img,num*184,0,184,325,0,0,185,325)
num++
if(num > 7){
num = 0
}
},300)
}
}else{
alert('请升级您的浏览器')
}
</script>
</body>
</html>
13.canvas渐变(了解)
13.1什么是渐变?
渐变是一种有规律性的变化,渐变色是指某个物体的颜色从明到暗,或由深转浅,或是从一个色彩缓慢过渡到另一个色彩
13.2渐变的使用场景
处理图表、处理文字、处理图片、用做背景
13.3createLinearGradient 线性渐变
代码案例
// 1,创建渐变 createLinearGradient(起始位置的x,y 结束位置x,y)
// 坐标 相对于画布左上角进行定位
// let lg = ctx.createLinearGradient(50,50,200,50) //x轴发生变化 水平的渐变
// let lg = ctx.createLinearGradient(50,50,50,150) //y轴发生变化 垂直的渐变
let lg = ctx.createLinearGradient(0,0,200,150) // x y轴发生变化 倾斜的渐变
// 2.渐变添加颜色节点 至少两种颜色
lg.addColorStop(0,"#f00")
lg.addColorStop(0.5,"#00f")
lg.addColorStop(1,"#5f2")
// 3.使用渐变颜色
ctx.fillStyle = lg
ctx.fillRect(50,50,150,100)
13.4 createRadialGradient 放射性渐变
代码案例
// 1,创建渐变
// 坐标 相对于画布左上角进行定位
// let rg = ctx.createRadialGradient(200,200,50,200,200,150)
// let rg = ctx.createRadialGradient(180,180,50,200,200,150)
let rg = ctx.createRadialGradient(200,200,50,180,180,150)
// 2.渐变添加颜色节点 至少两种颜色
rg.addColorStop(0,"#f00")
// lg.addColorStop(0.5,"#00f")
rg.addColorStop(1,"#5f2")
// 3.使用渐变颜色
ctx.fillStyle = rg
ctx.arc(200,200,150,0,2*Math.PI,false)
ctx.fill()
14.canvas 变形
参考css
1.旋转 rotate(弧度)
2.缩放 scale(x, y)
3.移动 translate(x, y) 坐标原点
4.Canvas状态
save()
保存画布(canvas)的所有状态
restore()
恢复 canvas 状态
代码案例
// 旋转
// ctx.rotate(30/180*Math.PI)
// 缩放
// ctx.scale(0.5,0.5)
// 平移 坐标原点的位置 左上角 0,0
//ctx.translate(100,100)
// 保存之前的环境
ctx.save()
ctx.translate(100,100)
ctx.fillStyle="coral"
ctx.fillRect(50,50,200,100)
// ctx.strokeRect(-100,-100,100,50)
//恢复之前保存的环境--坐标轴
ctx.restore()
ctx.strokeRect(0,0,100,50)
15.钟表案例
代码案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>绘制钟表</title>
<style>
#canvas{
border:1px solid red;
/* background-color: pink; */
}
</style>
</head>
<body>
<!-- 默认300*150px -->
<canvas id="canvas" width="500" height="500">
您的浏览器不支持,请升级您的浏览器
</canvas>
<script type="text/javascript">
// 1.获取canvas对象
let canvas = document.getElementById('canvas')
// 2.获取上下文对象
if(canvas.getContext('2d')){
let ctx = canvas.getContext('2d');
let PI = Math.PI;
setInterval(fun,1000)
function fun(){
// 获取现在的时间
let t = new Date()
let h = t.getHours()
let m = t.getMinutes()
let s = t.getSeconds()
let sAngle = (-90+s*6)/180*PI
let mAngle = (-90+m*6)/180*PI
let hAngle = (-90+h*30 +m/2)/180*PI
// 1.绘制分针,秒针,刻度
for(var i= 0;i<60;i++){
ctx.beginPath()
ctx.moveTo(250,250)
ctx.arc(250,250,200,i*6/180*PI,(i+1)*6/180*PI,false)
ctx.closePath()
ctx.lineWidth="2"
ctx.strokeStyle="#000"
ctx.stroke()
}
// ctx.beginPath()
// ctx.moveTo(250,250)
// ctx.arc(250,250,200,0,6/180*PI,false)
// ctx.closePath()
// ctx.stroke()
// ctx.beginPath()
// ctx.moveTo(250,250)
// ctx.arc(250,250,200,6/180*PI,12/180*PI,false)
// ctx.closePath()
// ctx.stroke()
// 画一个白圆 覆盖扇形中间的区域
ctx.beginPath()
ctx.arc(250,250,190,0,2*PI,false)
ctx.fillStyle="#fff"
ctx.fill()
// 2.时针 刻度
for(var i= 0;i<12;i++){
ctx.beginPath()
ctx.moveTo(250,250)
ctx.arc(250,250,200,i*30/180*PI,(i+1)*30/180*PI,false)
ctx.closePath()
ctx.lineWidth="3"
ctx.stroke()
}
// 画一个白圆 覆盖扇形中间的区域
ctx.beginPath()
ctx.arc(250,250,180,0,2*PI,false)
ctx.fillStyle="#fff"
ctx.fill()
// 3.绘制时间文本
ctx.save()
ctx.translate(241,258)
var str= ['Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'X', 'Ⅺ', 'Ⅻ', 'Ⅰ', 'Ⅱ'];
for(var i = 0;i<12;i++){
ctx.beginPath()
ctx.font="20px 黑体";
var x = 160*Math.cos(i*30/180*PI)
var y = 160*Math.sin(i*30/180*PI)
ctx.fillStyle="#000"
ctx.fillText(str[i],x,y)
}
ctx.restore()
// 4.绘制时针--扇形(开始弧度和结束弧度一致)
ctx.beginPath()
ctx.moveTo(250,250)
ctx.arc(250,250,130,hAngle,hAngle,false)
ctx.lineWidth="4"
ctx.stroke()
// 4.绘制分针--扇形(开始弧度和结束弧度一致)
ctx.beginPath()
ctx.moveTo(250,250)
ctx.arc(250,250,165,mAngle,mAngle,false)
ctx.lineWidth="2"
ctx.stroke()
// 4.绘制秒针--扇形(开始弧度和结束弧度一致)
ctx.beginPath()
ctx.moveTo(250,250)
ctx.arc(250,250,185,sAngle,sAngle,false)
ctx.lineWidth="1"
ctx.stroke()
// 6.中心点
ctx.beginPath()
ctx.arc(250,250,5,0,2*PI,false)
ctx.fill()
ctx.strokeStyle="#f00"
ctx.lineWidth="3"
ctx.stroke()
}
}else{
alert('请升级您的浏览器')
}
</script>
</body>
</html>