数据可视化、Canvas绘图容器

一、数据可视化

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>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值