一、Echarts介绍
1.特点:丰富的可视化类型,折线图,柱状图,饼图,K线图
多种数据格式支持,key-value数据格式,二维表,TypedArray格式
流数据的支持,流数据的动态渲染,增量渲染技术
其他,移动端优化,跨平台使用,三维可视化
2.echarts使用过程
1]引入echarts.js文件
2]准备一个呈现图表的盒子
3]初始化echarts实例对象
4]准备配置项
5]将配置项设置给echarts实例对象
引入,准备,设置
3.相关配置讲解
xAxis,yAxis,直角坐标系中的xy轴
series,系列列表,每个系列通过type决定自己的图标类型
x轴type值,类目轴,通过data属性设置数值;y轴type值,数值轴,从series的data属性中读取数值;series的type值,图表类型,如bar柱状图,line折线图,pie饼图
二、Echarts常见图表
柱状图,折线图,散点图,饼图,地图,雷达图,仪表盘图
1.通常配置,option属性
1]标题,title
2]提示,tooltip滑过或点击图表显示的提示框;触发类型trigger(item,axis),触发时机triggerOn(滑过mousemove,点击click),格式化formatter(字符串模板,回调函数)
3]工具栏,toolbox-feature,内置导出图片-saveAsImage,数据视图-dataView,动态类型切换-magicType,数据区域缩放-dataZoom,重置-restore五个工具
4]图例,legend,用于筛选系列,配合series使用,legend内data数组值等于series中的name值
tooltip: {
trigger: 'item',
// trigger: 'axis',
triggerOn: 'click',
// formatter: '{b} 的 {a} : {c}' // 字符串模板
formatter: function(arg) {
// console.info(arg)
return arg.name + '数量: ' + arg.data
}
},
toolbox: {
feature:{
saveAsImage: {},
dataView: {},
restore: {},
dataZoom: {},
magicType: {
type: ['bar','line']
}
}
},
legend: {
data: ['销量', '库存']
}
2.柱状图
常见效果
标记,series属性,最大值,最小值-markPoint(max,min),平均值-makeLine(average)
显示,series属性,数值显示,图形上的文本标签,可用于说明图形的一些数据信息-label(show,rotate旋转,position显示位置-inside内部等),柱宽度-barWidth,横向柱状图-更改xy轴角色
柱状图特点,呈现分类数据
DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>EChartstitle>
<script src="index/echarts.min.js">script>
head>
<body>
<div id="main" style="width: 600px; height:400px">div>
<script>
// 3.初始化echarts实例对象
var mCharts = echarts.init(document.getElementById('main'));
// 4.准备配置项
var option={
title:{
text: '销量分析'
},
xAxis: {
type: 'category',
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {
type: 'value'
},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
markPoint:{
data:[
{
type: 'max',
name: '最大值'
},
{
type: 'min',
name: '最小值'
}
]
},
markLine:{
data:[
{
type: 'average',
name: '平均值'
}
]
},
label:{
show:'true',
rotate:'30',
position:'inside',
},
barWidth: '30',
color: ['#aa6ee5']
}
]
};
// 5.将配置项设置给echarts实例对象
mCharts.setOption(option);
script>
body>
html>
3.折线图
series的type属性值为line
常见效果 series属性
1]标注区间-markarea
2]线条控制,平滑-smooth(true),风格(lineslStyle-color,type-solid、dashed、dotted)
3]填充风格-areaStyle
4]紧挨边缘-boundaryGap: false,X轴属性设置
5]缩放:脱离0值比例-scale: ‘true’,Y轴属性设置
6]堆叠图-stack,series内两个或多个对象stack属性值一致
折线图特点,分析数据随时间的变化趋势
markArea: {
data: [
[
{
xAxis: '裤子'
},
{
xAxis: '高跟鞋'
}
]
]
},
smooth: 'true',
lineStyle: {
color: 'pink',
type: 'dotted'
},
areaStyle: {
color: 'green'
}
4.散点图
series的type属性值为scatter
xAxis,yAxis的type属性值均为value,XY轴数据-二维数组
散点图常见效果 series属性
1]气泡图,series属性,散点的大小不同-symbolSize,散点的颜色不同-itemStyle的color属性
2]涟漪动画效果,series的type值为effectScatter,出现时机-showEffectOn(emphasis滑过,render全部显示),范围大小-rippleEffect的scale属性
散点图特点,推断出不同维度数据之间的相关性
showEffectOn: 'emphasis',
rippleEffect: {
scale: '5'
},
symbolSize: function(arg) {
// console.info(arg)
if(arg[1] > 60) {
return 20
}
return 10
},
itemStyle: {
color: function(arg) {
// console.info(arg)
if(arg.data[1] > 60) {
return 'red'
}
return 'green'
}
}
5.直角坐标系常用配置
直角坐标系图表,柱状图,折线图,散点图
option属性
1]配置1,网格grid,控制直角坐标系的布局和大小,显示grid-show(true)
2]配置2,坐标轴axis,显示位置position,X轴取值top/bottom,Y轴取值left/right
3]配置3,区域缩放dataZoom,数组,可以配置多个区域缩放器
类型type,slider滑块,inside内置,依靠鼠标滚轮或双指缩放
指明产生作用的轴,X轴-xAxisindex,Y轴-yAxisindex,值均为0
指明初始状态的缩放情况,start,end起始终止百分比
grid: {
show: true,
borderWidth: 5,
borderColor: 'pink',
left: 60,
top: 60,
width: 400
},
dataZoom: [
{
type: 'slider',
xAxisIndex: 0
},
{
type: 'slider',
yAxisIndex: 0,
start: 0,
end: 60
}
]
6.饼图
series的type属性值为pie,data值为数组内置对象
饼图常见效果
series属性
1]显示数值,label-formatter
2]圆环,设置两个半径,radius数组,内圆半径,外圆半径
3]南丁格尔图,roseType(radius)
4]选中效果,选中模式selectedMode-single/multiple,单个/全部偏离中心点一段距离
5]选中偏移量selectedOffset
饼图特点,显示不同分类的数据的占比情况
label: {
formatter: function(arg) {
console.info(arg)
return arg.data.name + '销量:' + arg.data.value
}
},
radius: [75, 120],
roseType: 'radius',
// selectedMode: 'single'
selectedMode: 'multiple',
selectedOffset : 30
7.地图
地图图表使用方式,百度地图,申请百度地图AK;矢量地图,准备矢量地图数据
在geo下设置type为map
(1)矢量地图实现步骤
1]ECharts最基本的代码结构
引入js文件,DOM容器,初始化对象,设置option
2]准备中国的矢量地图json文件,json/map目录下
3]导入jquery.min.js文件,通过Ajax加载该区域的矢量地图数据china.json
4]在回调函数中往echarts全局对象注册地图的json数据
<script>
var mCharts = echarts.init(document.getElementById('main'));
// 1. 加载该区域的矢量地图数据
$.get('json/map/china.json', function(ret) {
console.info(ret);
// 2. 通过registerMap注册到echarts全局对象中
echarts.registerMap('chinaMap', ret)
var option = {
// 3. 指明geo配置下的type和map属性
geo: [
{
type: 'map',
map: 'chinaMap'
}
]
};
mCharts.setOption(option);
})
script>
地图常见效果
a.缩放拖动-roam
b.名称显示-label
c.初始缩放比例-zoom
d.地图中心点-center
(2)不同城市颜色不同
1>显示基本的中国地图
2>城市的空气质量数据设置给series
3>将series下的数据和geo关联起来
geoindex-0,type-map
4>配合visualMap配合使用
max,min,inRange-color设置颜色渐变,calculable-true出现滑块
<script>
// 3.初始化echarts实例对象
var mCharts = echarts.init(document.getElementById('main'));
var areaData = [
{name: '北京', value: 180},
{name: '天津', value: 170},
{name: '上海', value: 120},
{name: '重庆', value: 99},
{name: '河北', value: 66},
{name: '山西', value: 110},
{name: '辽宁', value: 33},
{name: '吉林', value: 99},
{name: '黑龙江', value: 56},
{name: '江苏', value: 76},
{name: '浙江', value: 78},
{name: '安徽', value: 120},
{name: '福建', value: 49},
{name: '江西', value: 121},
{name: '山东', value: 34},
{name: '河南', value: 19},
{name: '湖北', value: 72},
{name: '湖南', value: 90},
{name: '广东', value: 56},
{name: '海南', value: 129},
{name: '四川', value: 98},
{name: '贵州', value: 98},
{name: '云南', value: 131},
{name: '陕西', value: 31},
{name: '甘肃', value: 56},
{name: '青海', value: 39},
{name: '台湾', value: 78},
{name: '内蒙古', value: 89},
{name: '广西', value: 132},
{name: '西藏', value: 89},
{name: '宁夏', value: 123},
{name: '新疆', value: 39},
{name: '香港', value: 90},
{name: '澳门', value: 11}
];
$.get('json/map/china.json', function(ret){
// console.info(ret)
echarts.registerMap('chinaMap', ret)
// 4.准备配置项
var option = {
geo: [
{
type: 'map',
map: 'chinaMap',
roam: true,
label: {
show: true
},
zoom: 1
}
],
series: [
{
type: 'map',
geoIndex: 0,
data: areaData
}
],
visualMap: {
min: 0,
max: 300,
inRange: {
color: ['white','red']
},
calculable: true
}
};
// 5.将配置项设置给echarts实例对象
mCharts.setOption(option);
})
script>
(3)地图和散点图结合
1>给series增加新对象
2>准备好散点数据,设置给新对象data
3>配置新对象的type属性值为effectScatter
4>让散点图使用地图坐标系统,设置coordinateSystem属性值为geo
5>让涟漪效果更加明显,ripple。Effect-scale
地图特点,从宏观的角度看出不同地理位置上的数据差异
8.雷达地图
实现步骤
1>最基本的代码结构
2>定义各个纬度的最大值indicator,通过radar属性配置
3>准备数据,设置给series的data属性
4>图表类型type属性值为radar
雷达图常见效果
a.显示数值label
b.区域面积areaStyle
c.绘制类型,最外层形状,shape
雷达图特点,分析多个维度的数据与标准数据的对比情况
<script>
// 3.初始化echarts实例对象
var mCharts = echarts.init(document.getElementById('main'));
// 4.准备配置项
var dataMax = [
{
name: '易用性',
max: 100
},
{
name: '拍照',
max: 100
},
{
name: '功能',
max: 100
},
{
name: '导航',
max: 100
},
{
name: '跑分',
max: 100
},
]
var option = {
radar: {
indicator: dataMax,
shape: 'circle'
},
series: [
{
type: 'radar',
label: {
show: true
},
areaStyle: {},
data: [
{
name: '华为手机',
value: [99, 78, 90, 67, 99]
},
{
name: '苹果手机',
value: [89, 67, 98, 89, 78]
}
]
}
]
};
// 5.将配置项设置给echarts实例对象
mCharts.setOption(option);
script>
9.仪表盘图
实现步骤
1>基本的代码结构
2>准备数据,设置给series的data属性值
3>图表类型,series的type属性为gauge
仪表盘常用效果
a,属猪范围,max,min控制仪表盘范围
b.多个指针,增加data中的数组元素
c.多个指针颜色差异,itemStyle,设置指针样式
仪表盘特点,表现出某个指标的进度或实际情况
10.显示
显示
(1)主题
1]内置主题,light,dark,在初始化对象方法Init中可以指明;Init方法有两个参数,dom节点和内置主题类型(light,dark)
2]自定义主题,步骤;在主题编辑器中编辑主题;下载主题,JS文件;引入主题JS文件
在Init方法中使用主题
3]调色盘,它是一组颜色,图形,系列会自动从其中选择颜色
主题调色盘,全局调色盘(option属性color,数组),局部调色盘(series属性color,数组)
4]样式,调色盘就近原则;颜色渐变-直线渐变,series属性itemStyle-color的属性值,包括type-linear,坐标属性x,y ,x2,y2竖向从上至下,colorStops数组内置对象,属性1-offset值为0(%0)、值为1(%100),属性2-color
径向渐变,与线性渐变不同的是,type-radial,坐标属性x ,y,r(均为0.5)
5]样式
a.直接样式属性
itemStyle,series-data属性,如饼图设置color
textStyle,标题样式属性
lineStyle,areaStyle折线图区域样式属性
label,设置饼图样式,series-data属性,如color
b.高亮样式属性
emphasis属性,内置直接样式属性,鼠标滑过,变成其样式
6]自适应
浏览器大小发生变化,图表随之发生变化
监听窗口大小变化事件window.onresize
在事件处理函数中调用ECharts实例对象的resize
11.动画的使用
(1)加载动画
(2)增量动画
增量动画实现方式,setOption实现
新增修改按钮,添加点击事件,modify数据,调用setOption
var modifyBtn = document.querySelector('#modify');
modifyBtn.onclick = function() {
var newData = [15, 30, 26, 10, 10, 20];
var option = {
series: [
{
data: newData
}
]
};
mCharts.setOption(option);
}
新增修改按钮,添加点击事件,push数据,调用setOption
var addBtn = document.querySelector('#add');
xData.push('小梁')
yData.push(34)
addBtn.onclick = function() {
var option = {
xAxis: {
data: xData
},
series: [
{
data: yData
}
]
};
mCharts.setOption(option);
}
3)动画配置,option属性
a.开启/关闭动画,animation-true/false
b.动画时长,animationDuration(毫秒为单位),固定值或回调函数(arg参数)
c.缓动动画,animationEasing-bounceOut
d.动画阈值,单种形式的元素数量大于这个阈值时动画会关闭,animationThreshold
12.交互API
(1)全局echarts对象,方法包括init(初始化实例对象,使用主题),registerTheme,registerMap,connect
connect,将两个或多个图表关联起来,支持数组,实例对象,保存图片的自动拼接,刷新按钮,重置按钮,提示框联动,图例选择,数据范围修改等
(2)echartsInstance对象,即echarts实例对象,方法包括setOption(设置或修改图表实例的配置项以及数据,多次调用,新旧配置合并),resize(重新计算和绘制图表,一般和window的resize事件结合使用)
1]on/off方法
2]绑定或解绑事件处理函数;
鼠标事件,如’click’、‘dblclick’、'mousedown’等,事件参数arg,和事件相关的数据信息;
echarts事件
3]dispatchAction方法,触发某些行为,使用代码模拟用户的行为
4]clear方法,清空当前实例,会移除实例中所有的组件和图表
5]dispose方法,销毁实例
三、Koa2框架
基于node.js平台的web开发框架;特点,支持asyn\await,洋葱模型的中间件
1.Koa快速上手
a.安装Koa
npm init -y
npm install koa
b.创建并编写app.js文件
创建Koa对象
编写响应函数(中间件)
监听端口
c.启动服务器
node app.js
中间件特点,Koa对象通过use方法加入一个中间件,一个中间件就是一个函数,中间件的执行顺序符合洋葱模型
后台项目目标
1]计算服务器处理请求的总耗时
2]在响应头上加上响应内容的mime类型
3]根据URL读取指定目录下的文件内容
2.后台项目的实现步骤
(1)项目准备
1]安装koa
创建文件和目录结构,app.js,data目录(json文件),middleware文件夹(中间件,包括koa_response_data.js,koa_response_duration.js,koa_response_header.js),utils文件夹(file_utils.js)
const Koa = require('koa')
const app = new Koa()
// 第一个中间件
const durationMiddle = require('./middleware/koa_response_duration')
app.use(durationMiddle)
// 第二个中间件
const headerMiddle = require('./middleware/koa_response_header')
app.use(headerMiddle)
// 第三个中间件
const dataMiddle = require('./middleware/koa_response_data')
app.use(dataMiddle)
app.listen(8084)
2]总耗时中间件
第一层中间件
a.导入中间件-require,导出中间件-module.exports
b.计算执行事件,进入时记录开始时间,其他中间件执行完成后记录结束时间,二者相减
c.设置响应头,调用ctx.set方法,X-Response-Time为主键,ms为单位
koa_response_duration.js文件
module.exports = async (ctx, next) => {
const startTime = Date.now()
await next()
const endStart = Date.now()
// 计算执行事件
const durationTime = endStart - startTime
console.info(durationTime)
// 设置响应头
ctx.set('X-Response-Time', durationTime + 'ms')
}
3]响应中间件
a.第二层中间件
b.获取mime类型,application/json
c.设置响应头,调用ctx.set方法,Content-Type为主键
koa_response_header.js文件
module.exports = async (ctx, next) => {
// 获取mime类型,application/json
const contentType = 'application/json; charset=utf-8'
ctx.set('Content-Type', contentType)
// ctx.response.body = '{"success": true}'
await next()
}
4]业务逻辑中间件
第3层中间件
a.读取文件内容,获取请求的路径,拼接文件路径,读取该路径对应文件的内容
b.设置响应体
koa_response_data.js文件
const path = require('path')
const fileUtils = require('../utils/file_utils')
module.exports = async (ctx, next) => {
// 获取json文件路径
const url = ctx.request.url
let filePath = url.replace('/api', '')
filePath = '../data' + filePath + '.json'
filePath = path.join(__dirname, filePath)
try {
// 读取文件内容
const fileJsonData = await fileUtils.getFileJsonData(filePath)
ctx.response.body = fileJsonData
} catch(error) {
const errorMsg = {
message: '读取文件内容失败,文件不存在!',
status: 404
}
ctx.response.body = JSON.stringify(errorMsg)
}
await next()
}
file_utils.js文件
const fs = require('fs')
module.exports.getFileJsonData = (filePath) => {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf-8', (error, data) => {
if(error) {
reject(error)
} else{
// 读取文件成功
resolve(data)
}
})
})
}
5]允许跨域
a.允许通过Ajax访问服务器
b.同源策略,同协议,同域名,同端口,当前页面的地址和Ajax获取数据的地址
(1)前端项目准备
1]搭建项目(vue create xxx),删除无用代码
2]静态资源引入
3]项目的基本配置vue.config.js(端口号,浏览器自动打开)
4]全局ECharts对象的挂载,main.js
// 挂载,使用this.$echarts
Vue.prototype.$echarts = window.echarts
index.html文件中引入echarts.js文件
5]axios的封装与挂载
安装axios,npm install axios
axios封装和挂载,使用this.$http
// axios封装和挂载,使用this.$http
axios.defaults.baseURL = 'http://127.0.0.1:8084/api/'
Vue.prototype.$http = axios
(2)组件开发
a.组件结构设计
xxPage.vue,测试使用,ShowTest.vue,呈现图表组件
b.布局结构设计
1]在view目录下创建TestPage.vue文件,引入基本模板
2]引入,注册路由,router-index.js
import HotPage from '@/views/TestPage'
{
path: '/testpage',
component: TestPage
}
app.js文件中设置路由占位符
3]在components目录下创建子vue文件ShowTest.vue
在父组件中引入,注册并使用子组件
mport Test from '@/components/ShowTest'
components: {
test: Test
}
<test></test>
c.图标基本功能的实现,柱状图
初始化echarts实例对象initCharts,获取数据getData,更新数据updateCharts
initCharts () {
this.echartsInstance = this.$echarts.init(this.$refs.echarts_ref, 'chalk')
// 移入鼠标停止计时器
this.echartsInstance.on('mouseover', () => {
clearInterval(this.timerId)
})
// 移出鼠标启动计时器
this.echartsInstance.on('mouseout', () => {
this.getIInterval()
})
}
async getData () {
// 获取数据
const { data: ret } = await this.$http.get('data')
this.allData = ret
// 数据排序
this.allData.sort((a, b) => {
return a.value - b.value
})
// 5个元素一页
this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
this.updateCahart()
this.getIInterval()
}
updateCahart () {
const start = (this.currentPage - 1) * 5
const end = this.currentPage * 5
// 截取数据,5个一组
const showData = this.allData.slice(start, end)
const xData = showData.map((item) => {
return item.value
})
const yData = showData.map((item) => {
return item.name
})
const option = {
title: {
text: '商家',
left: 20,
top: 20
},
gird: {
left: '20%',
top: '3%',
right: '6%',
buttom: '3%',
containLabel: true
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: yData
},
series: [
{
type: 'bar',
data: xData,
label: {
show: true,
position: 'right',
textStyle: {
color: 'white'
}
},
itemStyle: {
// 颜色渐变
color: new this.$echarts.graphic.LinearGradient(0, 0, 1, 0, [
{
offset: 0,
color: '#5052EE'
},
{
offset: 1,
color: '#AB6EE5'
}
])
}
}
],
tooltip: {
trigger: 'axis',
// 滑过图表显示背景
axisPointer: {
type: 'line',
z: 0,
lineStyle: {
color: '#2D3443'
}
}
}
}
this.echartsInstance.setOption(option)
}
d.动态刷新的实现
数据处理(数据排序,5个元素显示一页),启动和停止时机,获取数据或鼠标移出图表开启定时器,销毁或移入图表停止定时器
// 启动计时器
getIInterval () {
if (this.timerId) {
clearInterval(this.timerId)
}
this.timerId = setInterval(() => {
this.currentPage++
if (this.currentPage > this.totalPage) {
this.currentPage = 1
}
this.updateCahart()
}, 3000)
}
e.UI的调整
主题的使用,图标的圆角(canvas属性border-radius),图表的标题,坐标轴的位置(包含坐标轴文字,containLabel-true),柱状图条目(宽度,文字,右边圆角,颜色渐变,背景)
f.拆分图表的option,初始化配置,获取数据之后的配置,分辨率适配的配置
g.分配率适配
监听窗口大小变化事件,获取图表容器的宽度,设置新的option,图表实例对象resize
mounted () {
this.initChart()
this.getData()
// 监听浏览器窗口发生变化,图表大小也随之变化
window.addEventListener('resize', this.screenAdapter)
// 在页面加载完成的时候, 主动进行屏幕的适配
this.screenAdapter()
}
screenAdapter () {
const adapterWidth = this.$refs.echarts_ref.offsetWidth / 100 * 3.6
const adapterOption = {
title: {
textStyle: {
fontSize: adapterWidth
}
},
series: [
{
barWidth: adapterWidth,
itemStyle: {
barBorderRadius: [0, adapterWidth / 2, adapterWidth / 2, 0]
}
}
],
tooltip: {
lineStyle: {
width: adapterWidth
}
}
}
this.echartsInstance.setOption(adapterOption)
this.echartsInstance.resize()
}
饼图
a.图例属性
legend: {
data: legnedData,
top: '5%',
// 圆形
icon: 'circle'
}
b. 监听浏览器窗口发生变化,图表大小也随之变化
screebAdapter () {
const adapterWidth = this.$refs.echarts_ref.offsetWidth / 100 * 3.6
console.log(adapterWidth)
const adapterOption = {
title: {
textStyle: {
fontSize: adapterWidth
}
},
label: {
show: 'false'
},
legend: {
itemWidth: adapterWidth / 2,
itemHeight: adapterWidth / 2,
itemGap: adapterWidth / 2,
textStyle: {
fontSize: adapterWidth / 2
}
},
series: [
{
redius: adapterWidth * 4.5,
center: ['50%', '60%']
}
]
}
this.echartsInstance.setOption(adapterOption)
this.echartsInstance.resize()
}