基础阶段
canvas
canvas 是 HTML5 的新特性,它允许我们使用 canvas 元素在网页上通过 JavaScript 绘制图像。
入门案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="800" height="800"></canvas>
<script>
const canvas = document.getElementById('canvas');
// 获取 canvas 对象
const ctx = canvas.getContext('2d')
// 修改填充色
ctx.fillStyle = 'red'
// 横坐标,纵坐标,宽,高
// 绘制矩形
ctx.fillRect(0, 0, 50, 100)
// 绘制线段
ctx.beginPath()
ctx.lineWidth = 1 // 线条宽度
ctx.strokeStyle = 'blue' // 线条颜色
ctx.moveTo(100, 100) // 起点坐标
ctx.lineTo(250, 75) // 中间点坐标
ctx.lineTo(300, 100) // 终点坐标
ctx.stroke() // 绘制线段
ctx.beginPath()
// 绘制一个圆
ctx.lineWidth = 2
ctx.strokeStyle = 'green'
ctx.fillStyle = 'red'
// 圆心坐标, 半径, 起始角度, 最终角度
ctx.arc(200, 200, 50, 0, 1 * Math.PI)
ctx.stroke() // 绘制圆形的边框
ctx.fill() // 绘制圆形的填充色
</script>
</body>
</html>
结果:
进阶案例:图片压缩
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="file" id="upload">
<script>
const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg'] // 限定图片文件类型
const MAXSIZE = 3 * 1024 * 1024 // 限定图片最大容量
const MAXSIZE_STR = '1MB'
function convertImageToBase64(file, callback) {
let reader = new FileReader()
// load 事件监听
reader.addEventListener('load', (e) => {
const base64Image = e.target.result // 获取文件内容,等同于 reader.result
// console.log(base64Image);
callback && callback(base64Image)
reader = null
})
// readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,触发 load 事件
// 将文件格式转成 base64
reader.readAsDataURL(file)
}
// 核心
function compress(base64Image, callback) {
// console.log(base64Image);
let maxW = 1024
let maxH = 1024
const image = new Image();
image.addEventListener('load', e => {
// 图片的压缩比
let ratio
// 是否需要压缩
let needCompress = false
console.log(image.naturalWidth, image.naturalHeight);
if(maxW < image.naturalWidth) {
needCompress = true
ratio = image.naturalWidth / maxW
// 这样做是保持一致的宽高比
maxH = image.naturalHeight / ratio
} // 经过处理后,实际图片的尺寸为 300 * 211
if(maxH < image.naturalHeight) {
needCompress = true
ratio = image.naturalHeight / maxH
maxW = image.naturalWidth / ratio
} // 经过处理后,实际图片的尺寸为 300 * 211
if(!needCompress) {
maxH = image.naturalHeight
maxW = image.naturalWidth
} // 如果不需要压缩,需要获取图片的实际尺寸
// 使用canvas 进行绘制
const canvas = document.createElement('canvas')
canvas.setAttribute('id', '__compress__')
canvas.width = maxW
canvas.height = maxH
canvas.style.visibility = 'hidden'
document.body.appendChild(canvas)
const ctx = canvas.getContext('2d')
// 这个方法通过把像素设置为透明以达到擦除一个矩形区域的目的。
ctx.clearRect(0, 0, maxW, maxH)
// 第一次压缩
ctx.drawImage(image, 0, 0, maxW, maxH)
// 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。
// 第二次压缩
const compressImage = canvas.toDataURL('image/jpeg', 0.1)
callback && callback(compressImage)
// 用来展示压缩后的图片
const _image = new Image()
_image.src = compressImage
document.body.append(_image)
canvas.remove()
})
image.src = base64Image;
document.body.appendChild(image)
}
function uploadToServer(compressImage) {
console.log('upload image to server...', compressImage);
}
const upload = document.getElementById('upload')
upload.addEventListener('change', e => {
const [file] = e.target.files;
if(!file) {
return;
}
const {
type: fileType, size: fileSize } = file
// 图片类型检查
if(!ACCEPT.includes(fileType)) {
alert(`不支持[${
fileType}]文件类型`);
upload.value = ''
return;
}
// 图片大小检查
if(fileSize > MAXSIZE) {
alert(`文件超出${
MAXSIZE_STR}!`)
upload.value = ''
return;
}
// 压缩图片
convertImageToBase64(file, (base64Image) => compress(base64Image, uploadToServer))
})
</script>
</body>
</html>
svg
SVG是一种基于 XML 的图像文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形
入门案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<svg width="800" height="800">
<rect
width="50"
height="50"
style="fill: red; stroke-width: 1; stroke: rgb(0, 0, 0)"
></rect>
<line
x1="100"
y1="100"
x2="250"
y2="75"
style="stroke: blue; stroke-width: 1"
/>
<line
x1="250"
y1="75"
x2="300"
y2="100"
style="stroke: blue; stroke-width: 1"
/>
<circle
cx="200"
cy="200"
r="50"
stroke="green"
stroke-width="2"
fill="red"
/>
<line
x1="300"
y1="300"
x2="301"
y2="301"
style="stroke: red; stroke-width: 1"
/>
</svg>
</body>
</html>
结果:
zrender
zrender 是二维绘图引擎,它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器。
使用流程
- 引入 zrender 库
- 编写 div 容器
- 初始化 zrender 对象
- 初始化 zrender 绘图对象
- 调用 zrender add 方法绘图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/zrender/4.3.0/zrender.js"
></script>
</head>
<body>
<div id="container" style="width: 800px; height: 800px"></div>
<script>
var zr = zrender.init(document.getElementById("container"));
var rect = new zrender.Rect({
shape: {
x: 0,
y: 0,
width: 50,
height: 50,
},
style: {
fill: "red",
lineWidth: 0,
},
});
var line = new zrender.Polyline({
shape: {
points: [
[100, 100],
[250, 75],
[300, 100],
],
},
style: {
stroke: "blue",
lineWidth: 1,
},
});
var circle = new zrender.Circle({
shape: {
cx: 200,
cy: 200,
r: 50,
},
style: {
fill: "red",
stroke: "green",
lineWidth: 2,
},
});
var point = new zrender.Polyline({
shape: {
points: [
[300, 300],
[301, 301],
],
},
style: {
stroke: "red",
lineWidth: 1,
},
});
zr.add(rect);
zr.add(line);
zr.add(circle);
zr.add(point);
</script>
</body>
</html>
echarts
入门案例:
- 引入 js 库
- 编写渲染容器 DOM,添加 width 和 height 样式属性
- 获取渲染 DOM 对象
- 初始化 ECharts 对象
- 编写 option 参数
- 调用 setOption 完成渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#chart {
width: 800px;
height: 400px;
}
</style>
</head>
<body>
<div id="chart"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.7.0/echarts.min.js"></script>
<script>
const chartDom = document.getElementById('chart')
const chart = echarts.init(chartDom)
chart.setOption({
title: {
text: '快速入门echarts开发'
},
xAxis: {
data: ['食品', '数码', '服饰', '箱包']
},
yAxis: {
},
series: {
type: 'bar',
data: [100, 120, 90, 150]
}
})
</script>
</body>
</html>
Echarts基本概念
ECharts 基本概念: 系列
系列(series)是指:一组数值映射成对应的图
案例:
const option = {
xAxis: {
data: ["一季度", "二季度", "三季度", "四季度"],
},
yAxis: {
},
series: [
{
type: "pie",
center: ["65%", 60],
radius: 35,
data: [
{
name: "分类1",
value: 50,
},
{
name: "分类2",
value: 60,
},
{
name: "分类3",
value: 55,
},
{
name: "分类4",
value: 70,
},
],
},
{
type: "line",
data: [100, 112, 96, 123],
},
{
type: "bar",
data: [79, 81, 88, 72],
},
],
};
chart.setOption(option);
Echarts 4.0 新特性:dataset
ECharts 4 开始支持了 数据集(dataset)组件用于单独的数据集声明,从而数据可以单独管理,被多个组件复用,并且可以自由指定数据到视觉的映射。这一特性能将逻辑和数据分离,带来更好的复用,并易于理解。
案例:
const option = {
xAxis: {
type: 'category'
},
yAxis: {
},
dataset: {
source: [
['一季度', 79, 100, '分类1', 50],
['二季度', 81, 112, '分类2', 60],
['三季度', 88, 96, '分类3', 55],
['四季度', 72, 123, '分类4', 70],
]
},
series: [
{
type: 'pie',
center: ['65%', 60],
radius: 35,
encode: {
itemName: 3, value: 4 }
},
{
type: 'line',
encode: {
x: 0, y: 2 }
},
{
type: 'bar',
encode: {
x: 0, y: 1 }
}
]
};
chart.setOption(option);
ECharts 基本概念: 组件
ECharts 中除了绘图之外其他部分,都可抽象为 「组件」。例如,ECharts 中至少有这些组件:xAxis(直角坐标系 X 轴)、yAxis(直角坐标系 Y 轴)、grid(直角坐标系底板)、angleAxis(极坐标系角度轴)
案例:
const option = {
title: {
text: '数据可视化'
},
xAxis: {
type: 'category'
},
yAxis: {
},
// legend 要显示,在 series 中name必须要对应
legend: {
data: [{
name: '分类',
// 强制设置图形为圆。
icon: 'circle',
// 设置文本为红色
textStyle: {
color: 'red'
}
}, '折线图', '柱状图'],
left: 100
},
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none'
},
restore: {
},
saveAsImage: {
}
}
},
dataZoom: [{
show: true,
start: 30,
end: 70
}],
dataset: {
source: [
['一季度', 79, 100, '分类1', 50],
['二季度', 81, 112, '分类2', 60],
['三季度', 88, 96, '分类3', 55],
['四季度', 72, 123, '分类4', 70],
]
},
series: [
{
name: '分类',
type: 'pie',
center: ['65%', 60],
radius: 35,
encode: {
itemName: 3, value: 4 }
},
{
name: '折线图',
type: 'line',
encode: {
x: 0, y: 2 }
},
{
name: '柱状图',
type: 'bar',
encode: {
x: 0, y: 1 }
}
]
};
Echarts基本概念:定位
大多数组件都提供了定位属性,我们可以采用类似 CSS absolute 的定位属性来控制组件的位置,下面这个案例可以通过修改 grid 组件定位来控制图表的位置
在option 中加上 grid 这个组件就行
Echarts基本概念:坐标系
很多系列,例如 line(折线图)、bar(柱状图)、scatter(散点图)、heatmap(热力图)等等,需要运行在 “坐标系” 上。坐标系用于布局这些图,以及显示数据的刻度等等。例如 ECharts 中至少支持这些坐标系:直角坐标系、极坐标系、地理坐标系(GEO)、单轴坐标系、日历坐标系 等。其他一些系列,例如 pie(饼图)、tree(树图)等等,并不依赖坐标系,能独立存在。还有一些图,例如 graph(关系图)等,既能独立存在,也能布局在坐标系中,依据用户的设定而来。
一个坐标系,可能由多个组件协作而成。我们以最常见的直角坐标系来举例。直角坐标系中,包括有 xAxis(直角坐标系 X 轴)、yAxis(直角坐标系 Y 轴)、grid(直角坐标系底板)三种组件。xAxis、yAxis 被 grid 自动引用并组织起来,共同工作。
案例:散点图
我们来看下图,这是最简单的使用直角坐标系的方式:只声明了 xAxis、yAxis 和一个 scatter(散点图系列),ECharts 会为它们创建 grid 并进行关联:
案例:双坐标系
再来看下图,两个 yAxis,共享了一个 xAxis。两个 series,也共享了这个 xAxis,但是分别使用不同的 yAxis,使用 yAxisIndex 来指定它自己使用的是哪个 yAxis:
案例:
const option = {
legend: {
},
tooltip: {
},
xAxis: {
type: "category",
},
// 双 Y 轴坐标系要专门这么写
yAxis: [
{
min: 0,
max: 100,
},
{
min: 0,
max: 100,
},
],
dataset: {
source: [
["product", "2012", "2013", "2014", "2015"],
// 第 0 行
["Matcha Latte", 41.1, 30.4, 65.1, 53.3],
// 第 1 行
["Milk Tea", 86.5, 92.1, 85.7, 83.1],
],
},
series: [
{
type: "bar", seriesLayoutBy: "row", yAxisIndex: 0 },
{
type: "line", seriesLayoutBy: "row", yAxisIndex: 1 }
],
};