什么是数据可视化?
数据可视化是将数据库中每一个数据项作为单个图元元素表示,大量的数据集构成数据图像,同时将数据的各个属性值以多维数据的形式表示,可以从不同的维度观察数据,从而对数据进行更深入的观察和分析;主要是借助于图形化手段,清晰有效地传达与沟通信息。
ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9 /10/11,chrome,firefox,Safari等),底层依赖轻量级的Canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。
支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)、雷达图(填充雷达 图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等12类图表,同时提供标题,详情气泡、图例、值域、数据区域、时间轴、工具箱等7个可交 互组件,支持多图表、组件的联动和混搭展现。
1.可视化类型丰富,并且提供了吸引眼球的特效
2.多渲染方案,能够跨平台使用,支持以 Canvas、SVG(4.0+)、VML 的形式渲染图表。
3.多维数据的支持以及丰富的视觉编码手段,例如 对于传统的散点图等,传入的数据也可以是多个维度的。
4.多种数据格式无需转换直接使用,内置的 dataset 属性(4.0+)支持直接传入包括二维表,key-value 等多种格式的数据源,此外还支持输入 TypedArray 格式的数据。
5.无障碍访问(4.0+),能够支持自动根据图表配置项智能生成描述,使得盲人可以在朗读设备的帮助下了解图表内容,让图表可以被更多人群访问!
丰富的图表类型
ECharts 提供了常规的折线图、柱状图、散点图、饼图、k线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于数据关系可视化的关系图,treemap,多维数据可视化的平行坐标,还有用于BI的漏斗图,仪表盘,并且支持图与图之间的混搭
动态数据
ECharts由数据驱动,数据的改变驱动图表展现的改变。因此动态数据的实现也变得异常简单,只需获取数据,填入数据,ECharts会找到两组数据之间的差异然后通过合适的动画去表现数据的变化。
移动端的优化
流量珍贵的移动端需要图表库的体积尽量小。ECharts和ZRender代码的重构,带来了核心部分体积的减小。ECharts和ZRender代码的重构带来了核心部分体积的缩小。ECharts提供按需打包的能力,因为ECharts的组件众多,并且会持续增加。
多维数据支持以及丰富的视觉编码手段
ECharts 3开始加强了对多维数据的支持。除了加入平行坐标等常见的多维数据可视化工具外,对于传统的散点图,传入的数据也可以是多个维度的。配合视觉映射组件visualMap 提供丰富的视觉编码,能够将不同维度的数据映射到颜色,大小,透明度,明暗度等不同的视觉通道。
ECharts 底层依赖着轻量级的Canvas类库ZRender。
ZRender(Zlevel Render)是一个轻量级的Canvas类库,MVC封装,数据驱动,提供类DOM事件模型。
MVC核心封装实现图形仓库、视图渲染和交互控制:
特色:
1、数据驱动
利用zrender绘图,你只需做的是定义图形数据,剩下的事情就交给zrender.
2、完整的事件封装
用DOM事件模型去操作canvas里的图形元素。不仅可以响应zrender全局事件,甚至可以为特定的shape添加特定的事件。
3、高效的分层刷新
如css中的z-index一样,你可以定义把不同的shape放在不同的层中,这不仅实现了视觉上的上下覆盖,更重要的是图形元素发生变化后的refresh将局限在发生了变化的图形层中。
4、强大的动画支持
提供promise式的动画接口和常用缓动函数,轻松实现各种动画需求
5、易于扩展
分而治之的图形定义策略允许你扩展自己独有的图形元素,你既可以完整实现三个接口方法(brush,drift,isCover),也可以通过base派生后仅实现需要关心的图形细节。
1.下载地址
https://echarts.apache.org/zh/download.html
2.使用npm安装
npm install echarts
ECharts 的入门使用特别简单, 5分钟就能够上手. 他大体分为这几个步骤
步骤1:引入 echarts.js 文件
echarts是一个 js 的库,当然得先引入这个库文件
<script src="js/echarts.min.js"></script>
步骤2:准备一个呈现图表的盒子
这个盒子通常来说就是我们熟悉的 div ,这个 div 决定了图表显示在哪里
<div id="main" style="width: 600px;height:400px;"></div>
步骤3:初始化 echarts 实例对象
在这个步骤中, 需要指明图表最终显示在哪里的DOM元素
var myChart = echarts.init(document.getElementById('main'))
步骤4:准备配置项
这步很关键,我们最终的效果,到底是显示饼图还是折线图,基本上都是由配置项决定的
var option = {
xAxis: {
type: 'category',
data: ['小明', '小红', '小王']
},
yAxis: {
type: 'value'
},
series: [{
name: '语文',
type: 'bar',
data: [70, 92, 87],
}]
}
步骤5:将配置项设置给 echarts 实例对象
myChart.setOption(option)
通过简单的5个步骤, 就能够把一个简单的柱状图给显示在网页中了.这几个步骤中, 步骤4最重要,一个图表最终呈现什么样子,完全取决于这个配置项.所以对于不同的图表, 除了配置项会发生改变之外,其他的代码 都是固定不变的.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试 ECharts</title>
<!-- 引入 echarts.js -->
<script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
title: {
text: '测试 ECharts'
},
tooltip: {},
legend: {
data:['销量']
},
xAxis: {
data: ["衬衫","短袖","皮鞋","裤子","高跟鞋","袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'line',
data: [9, 10, 36, 19, 14, 20]
}]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
这是要求大家知道以下配置每个模块的主要作用干什么的就可以了
需要了解的主要配置:
series
xAxis
yAxis
grid
tooltip
title
legend
color
series
type
决定自己的图表类型xAxis:直角坐标系 grid 中的 x 轴
yAxis:直角坐标系 grid 中的 y 轴
grid:直角坐标系内绘图网格。
title:标题组件
tooltip:提示框组件
legend:图例组件
color:调色盘颜色列表
数据堆叠,同个类目轴上系列配置相同的stack
值后 后一个系列的值会在前一个系列的值上相加。
option = {
// color设置我们线条的颜色 注意后面是个数组
color: ['pink', 'red', 'green', 'skyblue'],
// 设置图表的标题
title: {
text: '折线图堆叠123'
},
// 图表的提示框组件
tooltip: {
// 触发方式
trigger: 'axis'
},
// 图例组件
legend: {
// series里面有了 name值则 legend里面的data可以删掉
},
// 网格配置 grid可以控制线形图 柱状图 图表大小
grid: {
left: '3%',
right: '4%',
bottom: '3%',
// 是否显示刻度标签 如果是true 就显示 否则反之
containLabel: true
},
// 工具箱组件 可以另存为图片等功能
toolbox: {
feature: {
saveAsImage: {}
}
},
// 设置x轴的相关配置
xAxis: {
type: 'category',
// 是否让我们的线条和坐标轴有缝隙
boundaryGap: false,
data: ['星期一', '周二', '周三', '周四', '周五', '周六', '周日']
},
// 设置y轴的相关配置
yAxis: {
type: 'value'
},
// 系列图表配置 它决定着显示那种类型的图表
series: [
{
name: '邮件营销',
type: 'line',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '联盟广告',
type: 'line',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '视频广告',
type: 'line',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: '直接访问',
type: 'line',
data: [320, 332, 301, 334, 390, 330, 320]
}
]
};
名词 | 描述 |
---|---|
chart | 是指一个完整的图表,如折线图,饼图等“基本”图表类型或由基本图表组合而成的“混搭”图表,可能包括坐标轴、图例等 |
axis | 直角坐标系中的一个坐标轴,坐标轴可分为类目型、数值型或时间型 |
xAxis | 直角坐标系中的横轴,通常并默认为类目型 |
yAxis | 直角坐标系中的纵轴,通常并默认为数值型 |
grid | 直角坐标系中除坐标轴外的绘图网格,用于定义直角系整体布局 |
legend | 图例,表述数据和图形的关联 |
dataRange | 值域选择,常用于展现地域数据时选择值域范围 |
dataZoom | 数据区域缩放,常用于展现大量数据时选择可视范围 |
roamController | 缩放漫游组件,搭配地图使用 |
toolbox | 辅助工具箱,辅助功能,如添加标线,框选缩放等 |
tooltip | 气泡提示框,常用于展现更详细的数据 |
timeline | 时间轴,常用于展现同一系列数据在时间维度上的多份数据 |
series | 数据系列,一个图表可能包含多个系列,每一个系列可能包含多个数据 |
名词 | 描述 |
---|---|
line | 折线图,堆积折线图,区域图,堆积区域图。 |
bar | 柱形图(纵向),堆积柱形图,条形图(横向),堆积条形图。 |
scatter | 散点图,气泡图。散点图至少需要横纵两个数据,更高维度数据加入时可以映射为颜色或大小,当映射到大小时则为气泡图 |
k | K线图,蜡烛图。常用于展现股票交易数据。 |
pie | 饼图,圆环图。饼图支持两种(半径、面积)南丁格尔玫瑰图模式。 |
radar | 雷达图,填充雷达图。高维度数据展现的常用图表。 |
chord | 和弦图。常用于展现关系数据,外层为圆环图,可体现数据占比关系,内层为各个扇形间相互连接的弦,可体现关系数据 |
force | 力导布局图。常用于展现复杂关系网络聚类布局。 |
map | 地图。内置世界地图、中国及中国34个省市自治区地图数据、可通过标准GeoJson扩展地图类型。支持svg扩展类地图应用,如室内地图、运动场、物件构造等。 |
heatmap | 热力图。用于展现密度分布信息,支持与地图、百度地图插件联合使用。 |
gauge | 仪表盘。用于展现关键指标数据,常见于BI类系统。 |
funnel | 漏斗图。用于展现数据经过筛选、过滤等流程处理后发生的数据变化,常见于BI类系统。 |
evnetRiver | 事件河流图。常用于展示具有时间属性的多个事件,以及事件随时间的演化。 |
treemap | 矩形式树状结构图,简称:矩形树图。用于展示树形数据结构,优势是能最大限度展示节点的尺寸特征。 |
venn | 韦恩图。用于展示集合以及它们的交集。 |
tree | 树图。用于展示树形数据结构各节点的层级关系 |
wordCloud | 词云。词云是关键词的视觉化描述,用于汇总用户生成的标签或一个网站的文字内容 |
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var option = {}
mCharts.setOption(option)
</script>
</body>
</html>
此时 option 是一个空空如也的对象
var xDataArr = ['张三', '李四', '王五', '闰土', '小明', '茅台', '二妞', '大强']
var yDataArr = [88, 92, 63, 77, 94, 80, 72, 86]
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value'
},
series: [{
type: 'bar',
data: yDataArr
}]
}
注意: 坐标轴 xAxis 或者 yAxis 中的配置, type 的值主要有两种: category 和 value , 如果 type属性的值为 category ,那么需要配置 data 数据, 代表在 x 轴的呈现. 如果 type 属性配置为 value ,那么无需配置 data , 此时 y 轴会自动去 series 下找数据进行图表的绘制
最终的效果如下图:
标记:
series: [{
......
markPoint: {
data: [{
type: 'max',
name: '最大值'
}, {
type: 'min',
name: '最小值'
}]
}
}]
series: [{
......markLine: {
data: [{
type: 'average',
name: '平均值'
}]
}
}]
series: [{
......
label: {
show: true, // 是否可见
rotate: 60 // 旋转角度
}
} ]
series: [{
......
barWidth: '30%' // 柱的宽度
}]
横向柱状图
所谓的横向柱状图, 只需要让x轴的角色和y轴的角色互换一下即可. 既 xAxis 的 type 设置为value , yAxis 的 type 设置为 category , 并且设置 data 即可
var option = {
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: xDataArr
},
series: [{
type: 'bar',
data: yDataArr
}]
}
柱状图描述的是分类数据,呈现的是每一个分类中『有多少?』, 图表所表达出来的含义在于不同类别数据的排名\对比情况
使用 ECharts 绘制出来的图表, 都天生就自带一些功能, 这些功能是每一个图表都具备的, 我们可以通过配置, 对这些功能进行设置.
var option = {
title: {
text: "成绩", // 标题文字
textStyle: {
color: 'red' // 文字颜色
},
borderWidth: 5, // 标题边框
borderColor: 'green', // 标题边框颜色
borderRadius: 5, // 标题边框圆角
left: 20, // 标题的位置
top: 20 // 标题的位置
}
}
tooltip 指的是当鼠标移入到图表或者点击图表时, 展示出的提示框
触发类型: trigger
可选值有item\axis
触发时机: triggerOn
可选值有 mouseOver\click
格式化显示: formatter
var option = {
tooltip: {
trigger: 'item',
triggerOn: 'click',
formatter: '{b}:{c}'
}
}
这个{b} 和 {c} 所代表的含义不需要去记, 在官方文档中有详细的描述
var option = {
tooltip: {
trigger: 'item',
triggerOn: 'click',
formatter: function (arg) {
return arg.name + ':' + arg.data
}
}
}
toolbox 是 ECharts 提供的工具栏, 内置有 导出图片,数据视图, 重置, 数据区域缩放, 动态类型切换五个工具
工具栏的按钮是配置在 feature 的节点之下
var option = {
toolbox: {
feature: {
saveAsImage: {}, // 将图表保存为图片
dataView: {}, // 是否显示出原始数据
restore: {}, // 还原图表
dataZoom: {}, // 数据缩放
magicType: { // 将图表在不同类型之间切换,图表的转换需要数据的支持
type: ['bar', 'line']
}
}
}
}
legend 是图例,用于筛选类别,需要和 series 配合使用
var option = {
legend: {
data: ['语文', '数学']
},
xAxis: {
type: 'category',
data: ['张三', '李四', '王五', '闰土', '小明', '茅台', '二妞', '大强']
},
yAxis: {
type: 'value'
},
series: [{
name: '语文',
type: 'bar',
data: [88, 92, 63, 77, 94, 80, 72, 86]
}, {
name: '数学',
type: 'bar',
data: [93, 60, 61, 82, 95, 70, 71, 86]
}]
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var option = {}
mCharts.setOption(option)
</script>
</body>
</html>
此时 option 是一个空空如也的对象
var xDataArr = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
var yDataArr = [3000, 2800, 900, 1000, 800, 700, 1400, 1300, 900, 1000, 800, 600]
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value'
},
series: [{
type: 'line',
data: yDataArr
}]
}
标记:
series: [{
......
markPoint: {
data: [{
type: 'max',
name: '最大值'
}, {
type: 'min',
name: '最小值'
}]
}
}]
series: [{
......markLine: {
data: [{
type: 'average',
name: '平均值'
}]
}
}]
series: [{
......
label: {
show: true, // 是否可见
rotate: 60 // 旋转角度
}
} ]
var option = {
series: [{
......
markArea: {
data: [
[{
xAxis: '1月'
}, {
xAxis: '2月'
}],
[{
xAxis: '7月'
}, {
xAxis: '8月'
}]
]
}
}]
}
var option = {
series: [{
......
smooth: true
}]
}
var option = {
series: [{
......
smooth: true,
lineStyle: {
color: 'green',
type: 'dashed' // 可选值还有 dotted solid
}
}]
}
var option = {
series: [{
type: 'line',
data: yDataArr,
areaStyle: {
color: 'pink'
}
}]
}
boundaryGap 是设置给 x 轴的, 让起点从 x 轴的0坐标开始
var option = {
xAxis: {
type: 'category',
data: xDataArr,
boundaryGap: false
}
}
var yDataArr = [3005, 3003, 3001, 3002, 3009, 3007, 3003, 3001, 3005, 3004, 3001, 3009] // 此时y轴的数据都在3000附近, 每个数之间相差不多
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value'
},
series: [{
type: 'line',
data: yDataArr
}]
}
效果如下图:
这显然不是我们想要的效果, 因此可以配置上 scale , 让其摆脱0值比例
scale 配置
scale 应该配置给 y 轴
var option = {
yAxis: {
type: 'value',
scale: true
}
}
堆叠图指的是, 同个类目轴上系列配置相同的 stack 值后,后一个系列的值会在前一个系列的值上相加
如果在一个图表中有两个或者多个折线图, 在没有使用堆叠配置的时候, 效果如下:
var mCharts = echarts.init(document.querySelector("div")) var xDataArr = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
var yDataArr1 = [120, 132, 101, 134, 90, 230, 210]
var yDataArr2 = [20, 82, 191, 94, 290, 330, 310]
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value',
scale: true
},
series: [{
type: 'line',
data: yDataArr1
}, {
type: 'line',
data: yDataArr2
}]
}
mCharts.setOption(option)
var option = {
series: [{
type: 'line',
data: yDataArr1,
stack: 'all' // series中的每一个对象配置相同的stack值, 这个all可以任 意写
}, {
type: 'line',
data: yDataArr2,
stack: 'all' // series中的每一个对象配置相同的stack值, 这个all可以任意 写
}]
}
折线图更多的使用来呈现数据随时间的**『变化趋势』**
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var option = {}
mCharts.setOption(option)
</script>
</body>
</html>
此时 option 是一个空空如也的对象
var data = [{ "gender": "female", "height": 161.2, "weight": 51.6 }, { "gender": "female", "height": 167.5, "weight": 59 }, { "gender": "female", "height": 159.5, "weight": 49.2 }, { "gender": "female", "height": 157, "weight": 63 }, { "gender": "female", "height": 155.8, "weight": 53.6 }, { "gender": "female", "height": 170, "weight": 59 }, { "gender": "female", "height": 159.1, "weight": 47.6 }, { "gender": "female", "height": 166, "weight": 69.8 }, { "gender": "female", "height": 176.2, "weight": 66.8 }, { "gender": "female", "height": 160.2, "weight": 75.2 }, { "gender": "female", "height": 172.5, "weight": 55.2 }, { "gender": "female", "height": 170.9, "weight": 54.2 }, { "gender": "female", "height": 172.9, "weight": 62.5 }, { "gender": "female", "height": 153.4, "weight": 42 }, { "gender": "female", "height": 160, "weight": 50 }, { "gender": "female", "height": 147.2, "weight": 49.8 },...此处省略...]
假设这个数据是从服务器获取到的, 数组中的每一个元素都包含3个维度的数据: 性别,身高,体重, 而散点图需要的数据是一个二维数组, 所以我们需要将从服务器获取到的这部分数据,通过代码生成散点图需要的数据
var axisData = []
for (var i = 0; i < data.length; i++) {
var height = data[i].height
var weight = data[i].weight
var itemArr = [height, weight] axisData.push(itemArr)
}
axisData 就是一个二维数组, 数组中的每一个元素还是一个数组, 最内层数组中有两个元素, 一个代表身高, 一个代表体重
var option = {
xAxis: {
type: 'value'
},
yAxis: {
type: 'value'
},
series: [{
type: 'scatter',
data: axisData
}]
}
步骤4 调整配置项, 脱离0值比例
给 xAxis 和 yAxis 配置 scale 的值为 true
var option = {
xAxis: {
type: 'value',
scale: true
},
yAxis: {
type: 'value',
scale: true
},
series: [{
type: 'scatter',
data: axisData,
}]
}
气泡图效果
要能够达到气泡图的效果, 其实就是让每一个散点的大小不同, 让每一个散点的颜色不同
这两个配置项都支持固定值的写法, 也支持回调函数的写法
固定值的写法如下:
var option = {
series: [{
type: 'scatter',
data: axisData,
symbolSize: 25,
itemStyle: {
color: 'green',
}
}]
}
var option = {
series: [{
type: 'scatter',
data: axisData,
symbolSize: function (arg) {
var weight = arg[1]
var height = arg[0] / 100
// BMI > 28 则代表肥胖, 肥胖的人用大的散点标识, 正常的人用小散点标识
// BMI: 体重/ 身高*身高 kg m
var bmi = weight / (height * height) if (bmi > 28) {
return 20
}
return 5
},
itemStyle: {
color: function (arg) {
var weight = arg.data[1]
var height = arg.data[0] / 100
var bmi = weight / (height * height) if (bmi > 28) {
return 'red'
}
return 'green'
}
}
}]
}
type:effectScatter
将 type 的值从 scatter 设置为 effectScatter 就能够产生涟漪动画的效果
rippleEffect
rippleEffect 可以配置涟漪动画的大小
var option = {
series: [{
type: 'effectScatter',
rippleEffect: {
scale: 3
}
}]
}
showEffectOn 可以控制涟漪动画在什么时候产生, 它的可选值有两个: render 和 emphasis
render 代表界面渲染完成就开始涟漪动画
emphasis 代表鼠标移过某个散点的时候, 该散点开始涟漪动画
var option = {
series: [{
type: 'effectScatter',
showEffectOn: 'emphasis',
rippleEffect: {
scale: 3
}
}]
}
结合地图
散点图也经常结合地图来进行地图区域的标注, 这个效果将在讲解地图时实现
散点图可以帮助我们推断出不同维度数据之间的相关性, 比如上述例子中,看得出身高和体重是正相关, 身高越高, 体重越重
散点图也经常用在地图的标注上
直角坐标系的图表指的是带有x轴和y轴的图表, 常见的直角坐标系的图表有: 柱状图 折线图 散点图
针对于直角坐标系的图表, 有一些通用的配置
配置1: 网格 grid
grid是用来控制直角坐标系的布局和大小, x轴和y轴就是在grid的基础上进行绘制的
显示 grid
show: true
grid 的边框
borderWidth : 10
grid 的位置和大小
left top right bottom width height
var option = {
grid: {
show: true, // 显示grid
borderWidth: 10, // grid的边框宽度
borderColor: 'red', // grid的边框颜色
left: 100, // grid的位置
top: 100,
width: 300, // grid的大小
height: 150
}
}
配置2: 坐标轴 axis
坐标轴分为x轴和y轴, 一个 grid 中最多有两种位置的 x 轴和 y 轴
坐标轴类型 type
value : 数值轴, 自动会从目标数据中读取数据
category : 类目轴, 该类型必须通过 data 设置类目数据
坐标轴位置
xAxis : 可取值为 top 或者 bottom
yAxis : 可取值为 left 或者 right
var option = {
xAxis: {
type: 'category',
data: xDataArr,
position: 'top'
},
yAxis: {
type: 'value',
position: 'right'
}
}
配置3: 区域缩放 dataZoom
dataZoom 用于区域缩放, 对数据范围过滤, x轴和y轴都可以拥有, dataZoom 是一个数组, 意味着可以配置多个区域缩放器
区域缩放类型 type
slider : 滑块
inside : 内置, 依靠鼠标滚轮或者双指缩放
产生作用的轴
xAxisIndex :设置缩放组件控制的是哪个 x 轴, 一般写0即可
yAxisIndex :设置缩放组件控制的是哪个 y 轴, 一般写0即可
指明初始状态的缩放情况
start : 数据窗口范围的起始百分比
end : 数据窗口范围的结束百分比
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value'
},
dataZoom: [{
type: 'slider',
xAxisIndex: 0
}, {
type: 'slider',
yAxisIndex: 0,
start: 0,
end: 80
}]
}
需要注意的是, 针对于非直角坐标系图表, 比如饼图 地图 等, 以上三个配置可能就不会生效了
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var option = {}
mCharts.setOption(option)
</script>
</body>
</html>
此时 option 是一个空空如也的对象
var pieData = [{
value: 11231,
name: "淘宝",
}, {
value: 22673,
name: "京东"
}, {
value: 6123,
name: "唯品会"
}, {
value: 8989,
name: "1号店"
}, {
value: 6700,
name: "聚美优品"
}]
var option = {
series: [{
type: 'pie',
data: pieData
}]
}
饼图的数据是由 name 和 value 组成的字典所形成的数组
饼图无须配置 xAxis 和 yAxis
var option = {
series: [{
type: 'pie',
data: pieData,
label: {
show: true,
formatter: function (arg) {
return arg.data.name + '平台' + arg.data.value + '元\n' + arg.percent + '%'
}
}
}]
}
南丁格尔图
南丁格尔图指的是每一个扇形的半径随着数据的大小而不同, 数值占比越大, 扇形的半径也就越大
var option = {
series: [{
type: 'pie',
data: pieData,
label: {
show: true,
formatter: function (arg) {
return arg.data.name + '平台' + arg.data.value + '元\n' + arg.percent + '%'
}
},
roseType: 'radius'
}]
}
选中效果
选中模式,表示是否支持多个选中,默认关闭,支持布尔值和字符串,字符串取值可选 ‘single’ , ‘multiple’ ,分别表示单选还是多选
选中扇区的偏移距离
var option = {
series: [{
type: 'pie',
data: pieData,
selectedMode: 'multiple', //
selectedOffset: 30
}]
}
饼图的半径。可以为如下类型:
number :直接指定外半径值。 string :例如, ‘20%’ ,表示外半径为可视区尺寸(容器高宽中较小一项)的 20% 长度。 Array. :数组的第一项是内半径,第二项是外半径, 通过 Array , 可以将饼图设置为圆环图
var option = {
series: [{
type: 'pie',
data: pieData,
radius: ['50%', '70%']
}]
}
饼图可以很好地帮助用户快速了解不同分类的数据的占比情况
百度地图API : 使用百度地图的 api , 它能够在线联网展示地图, 百度地图需要申请 ak
矢量地图 : 可以离线展示地图, 需要开发者准备矢量地图数据
接下来的实现是通过矢量图的方式来实现的
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var option = {}
mCharts.setOption(option)
</script>
</body>
</html>
此时 option 是一个空空如也的对象
$.get('json/map/china.json', function (chinaJson) {})
echarts.registerMap('chinaMap', chinaJson)
$.get('json/map/china.json', function (chinaJson) {
echarts.registerMap('chinaMap', chinaJson)
})
步骤5 获取完数据之后, 需要配置 geo 节点, 再次的 setOption
type : ‘map’
map : ‘chinaMap’
var mCharts = echarts.init(document.querySelector("div")) $.get('json/map/china.json', function (chinaJson) {
echarts.registerMap('chinaMap', chinaJson)
var option = {
geo: {
type: 'map', // map是一个固定的值
map: 'chinaMap', //chinaMap需要和registerMap中的第一个参数保持一致
}
};
mCharts.setOption(option)
})
(地图不给放,大家自行尝试)
注意: 需要注意的是, 由于在代码中使用了 Ajax , 所以, 关于此文件的打开, 不能以 file 的协议打开, 应该将其置于 HTTP 的服务之下方可正常展示地图
var option = {
geo: {
type: 'map', // map是一个固定的值
map: 'chinaMap', //chinaMap需要和registerMap中的第一个参数保持一致,
roam: true, // 运行使用鼠标进行拖动和缩放
}
}
var option = {
geo: {
type: 'map', // map是一个固定的值
map: 'chinaMap', //chinaMap需要和registerMap中的第一个参数保持一致,
roam: true,
label: {
show: true
}
}
}
(地图不给放,大家自行尝试)
初始缩放比例: zoom
地图中心点: center
var option = {
geo: {
type: 'map', // map是一个固定的值
map: 'chinaMap', //chinaMap需要和registerMap中的第一个参数保持一致,
roam: true,
label: {
show: true
},
zoom: 0.8, // 地图的缩放比例, 大于1代表放大, 小于1代表缩小
center: [87.617733, 43.792818] // 当前视角的中心点,用经纬度表示
}
}
(地图不给放,大家自行尝试)
显示某个区域
$.get('json/map/anhui.json', function (anhuiJson) { })
在Ajax的回调函数中注册地图矢量数据
echarts.registerMap(‘anhui’, anhuiJson)
配置 geo 的 type:‘map’ , map:‘anhui’
通过 zoom 调整缩放比例
通过 center 调整中心点
<script>
var mCharts = echarts.init(document.querySelector("div")) $.get('json/map/anhui.json', function (anhuiJson) {
console.log(anhuiJson) echarts.registerMap('anhui', anhuiJson) var option = {
geo: {
type: 'map',
map: 'anhui',
label: {
show: true
},
zoom: 1.2,
center: [116.507676, 31.752889]
}
};
mCharts.setOption(option)
})
</script>
不同城市颜色不同
<body>
<div style="width: 600px;height:400px;border:1px solid red"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) $.get('json/map/china.json', function (chinaJson) {
echarts.registerMap('chinaMap', chinaJson) var option = {
geo: {
type: 'map',
map: 'chinaMap',
roam: true,
label: {
show: true
}
}
}
mCharts.setOption(option)
})
</script>
</body>
var airData = [{
name: '北京',
value: 39.92
}, {
name: '天津',
value: 39.13
}, {
name: '上海',
value: 31.22
}, {
name: '重庆',
value: 66
}, {
name: '河北',
value: 147
}, {
name: '河南',
value: 113
}, {
name: '云南',
value: 25.04
}, {
name: '辽宁',
value: 50
}, {
name: '黑龙江',
value: 114
}, {
name: '湖南',
value: 175
}, {
name: '安徽',
value: 117
}, {
name: '山 东',
value: 92
}, {
name: '新疆',
value: 84
}, {
name: '江苏',
value: 67
}, {
name: '浙江',
value: 84
}, {
name: '江西',
value: 96
}, {
name: '湖北',
value: 273
}, {
name: '广西',
value: 59
}, {
name: '甘肃',
value: 99
}, {
name: '山西',
value: 39
}, {
name: '内蒙古',
value: 58
}, {
name: '陕西',
value: 61
}, {
name: '吉林',
value: 51
}, {
name: '福建',
value: 29
}, {
name: '贵州',
value: 71
}, {
name: '广东',
value: 38
}, {
name: '青海',
value: 57
}, {
name: '西藏',
value: 24
}, {
name: '四川',
value: 58
}, {
name: '宁夏',
value: 52
}, {
name: '海南',
value: 54
}, {
name: '台湾',
value: 88
}, {
name: '香港',
value: 66
}, {
name: '澳门',
value: 77
}, {
name: '南海诸岛',
value: 55
}]......
var option = {
......
series: [{
data: airData
}]
}
3.将 series 下的数据和 geo 关联起来
geoIndex: 0
type: ‘map’
var option = {
series: [{
data: airData,
geoIndex: 0,
type: 'map'
}]
}
4.结合 visualMap 配合使用
visualMap 是视觉映射组件, 和之前区域缩放 dataZoom 很类似, 可以做数据的过滤. 只不过dataZoom 主要使用在直角坐标系的图表, 而 visualMap 主要使用在地图或者饼图中
var option = {
geo: {
type: 'map',
map: 'chinaMap',
roam: true,
label: {
show: true
}
},
series: [{
data: airData,
geoIndex: 0,
type: 'map'
}],
visualMap: {
min: 0, // 最小值
max: 300, // 最大值
inRange: {
color: ['white', 'red'] // 颜色的范围
},
calculable: true // 是否显示拖拽用的手柄(手柄能拖拽调整选中范围)
}
}
(地图不给放,大家自行尝试)
地图和散点图结合
var scatterData = [{
value: [117.283042, 31.86119] // 散点的坐标, 使用的是经纬度
}]
3.配置新对象的 type
type:effectScatter
让散点图使用地图坐标系统
coordinateSystem: ‘geo’
让涟漪的效果更加明显
rippleEffect: { scale: 10 }
var option = {
series: [{
data: airData,
geoIndex: 0,
type: 'map'
}, {
data: scatterData,
type: 'effectScatter',
coordinateSystem: 'geo',
rippleEffect: {
scale: 10
}
}]
}
(地图不给放,大家自行尝试)
地图主要可以帮助我们从宏观的角度快速看出不同地理位置上数据的差异
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var option = {}
mCharts.setOption(option)
</script>
</body>
</html>
此时 option 是一个空空如也的对象
var dataMax = [{
name: '易用性',
max: 100
}, {
name: '功能',
max: 100
}, {
name: '拍照',
max: 100
}, {
name: '跑分',
max: 100
}, {
name: '续航',
max: 100
}]
var hwScore = [80, 90, 80, 82, 90]
var zxScore = [70, 82, 75, 70, 78]
var option = {
radar: {
indicator: dataMax
},
series: [{
type: 'radar',
data: [{
name: '华为手机1',
value: hwScore
}, {
name: '中兴手机1',
value: zxScore
}]
}]
}
显示数值 label
var option = {
series: [{
type: 'radar',
label: {
show: true
},
data: [{
name: '华为手机1',
value: hwScore
}, {
name: '中兴手机1',
value: zxScore
}]
}]
}
var option = {
series: [{
type: 'radar',
label: {
show: true
},
areaStyle: {},
data: [{
name: '华为手机1',
value: hwScore
}, {
name: '中兴手机1',
value: zxScore
}]
}]
}
绘制类型 shape
雷达图绘制类型,支持 ‘polygon’ 和 ‘circle’
‘polygon’ : 多边形
‘circle’ 圆形
var option = {
radar: {
indicator: dataMax,
shape: 'circle'
},
series: [{
type: 'radar',
label: {
show: true
},
data: [{
name: '华为手机1',
value: hwScore
}, {
name: '中兴手机1',
value: zxScore
}]
}]
}
雷达图可以用来分析多个维度的数据与标准数据的对比情况
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var option = {}
mCharts.setOption(option)
</script>
</body>
</html>
此时 option 是一个空空如也的对象
步骤2: 准备数据, 设置给 series 下的 data
data:[97]
步骤3: 在 series 下设置 type:gauge
var option = {
series: [{
type: 'gauge',
data: [{
value: 97,
}]
}]
}
var option = {
series: [{
type: 'gauge',
data: [{
value: 97,
itemStyle: {
color: 'pink'
}
}, {
value: 85,
itemStyle: {
color: 'green'
}
}],
min: 50
}]
}
仪表盘可以更直观的表现出某个指标的进度或实际情况
各个图表的英文单词
柱状图:柱状图描述的是分类数据,呈现的是每一个分类中有多少
折线图:折线图常用来分析数据随时间的变化趋势
散点图:散点图可以帮助我们推断出不同维度数据之间的相关性
饼图:饼图可以很好地帮助用户快速了解不同分类的数据的占比情况
地图:地图主要可以帮助我们从宏观的角度快速看出不同地理位置上数据的差异
雷达图:雷达图可以用来分析多个维度的数据与标准数据的对比情况
仪表盘:仪表盘可以更直观的表现出某个指标的进度或实际情况
series[].type | xAxis | yAxis | markPoint | markLine | label | barWidth |
---|---|---|---|---|---|---|
图表类型 | x轴 | y轴 | 最大值\最小 | 平均值 | 显示文 | 柱宽度 |
series[].type | xAxis | yAxis | markPoint | markLine | label | barWidth |
---|---|---|---|---|---|---|
图表类型 | x轴 | y轴 | 最大值\最小 | 平均值 | 显示文 | 柱宽度 |
lineStyle | areaStyle | boundaryGap | scale |
---|---|---|---|
线条风格 | 风格x轴 | 紧挨边缘 | 脱离0值比例 |
series[].type | xAxis | yAxis | symbolSize |
---|---|---|---|
图表类型 | x轴 | y轴 | 散点大小 |
lineStyle | showEffectOn | rippleEffect | scale |
---|---|---|---|
线条风格 | 显示时机 | 涟漪效果 | 脱离0值比例 |
series[].type | label | radius | roseType | selectedMode | selectedOffset |
---|---|---|---|---|---|
图表类型 | 显示文本 | 半径 | 饼图类型 | 是否多选 | 选中扇区偏移量 |
series[].type | geo | map | roam | zoom |
---|---|---|---|---|
图表类型 | 地理坐标系组件 | 指明地图数据 | 开启鼠标拖动和缩放 | 平均值 |
center | label | geoIndex | visualMap | coordinateSystem |
---|---|---|---|---|
图表的中心 | 是否显示地区 | 指明关联的geo组 | 视觉映射组件 | 使用坐标系统 |
series[].type | radar | indicator | label | areaStyle | shape |
---|---|---|---|---|---|
图表类型 | 雷达图组件 | 雷达图的指示器 | 文字 | 区域颜色 | 雷达图形状 |
series[].type | max | min | itemStyle |
---|---|---|---|
图表类型 | 最大值 | 最小值 | 指针样式 |
show | borderWidth | borderColor | left | top | right |
---|---|---|---|---|---|
是否可见 | 边框宽度 | 边框颜色 | 左边 | 顶部 | 右边 |
bottom | width | height |
---|---|---|
底部 | 宽度 | 高度 |
type | data | position |
---|---|---|
底部轴类型 | 数据 | 显示位置 |
type | xAxisIndex | yAxisIndex | start | end |
---|---|---|---|---|
缩放块类型 | x轴索引 | y轴索引 | 初始值 | 结束值 |
textStyle | borderWidth | borderColor | borderRadius |
---|---|---|---|
文字样式 | 边框宽度 | 边框颜色 | 边框圆角 |
left | top | right | bottom |
---|---|---|---|
左边 | 顶部 | 右边 | 底部 |
trigger | triggerOn | formatter |
---|---|---|
触发类型 | 触发时机 | 内容自定义 |
saveAsImage | dataView | restore | dataZoom | magicType |
---|---|---|---|---|
缩放块类型 | x轴索引 | 重置 | 缩放 | 图表转换 |
data |
---|
图例数据, 需要和series数组中某组数据的name值一致 |
默认主题
ECharts 中默认内置了两套主题: light dark
在初始化对象方法 init 中可以指明
var chart = echarts.init(dom, 'light')
var chart = echarts.init(dom, 'dark')
自定义主题
1.在主题编辑器中编辑主题
主题编辑器的地址为: https://echarts.apache.org/zh/theme-builder.html
在该地址中, 你可以定义一个主题的很多方面的内容:
在线编辑完主题之后, 可以点击下载主题按钮, 下载主题的js文件
3.引入主题 js 文件
<script src="js/echarts.min.js"></script>
<script src="js/myTheme.js"></script>
其中, cast.js 就是下载下来的主题文件
4.在 init 方法中使用主题
var mCharts = echarts.init(document.querySelector("div"), 'myTheme')
init方法中的第二个参数myTheme就是主题的名称, 这个名称叫什么我们可以在myTheme.js的代码中
看出
它是一组颜色,图形、系列会自动从其中选择颜色, 不断的循环从头取到尾, 再从头取到尾, 如此往复.
主题调色盘
echarts.registerTheme('myTheme', {
"color": ["#893448", "#d95850", "#eb8146", "#ffb248", "#f2d643", "#ebdba4"],
"backgroundColor": "rgba(242,234,191,0.15)",
......
})
全局调色盘
全局调色盘是在 option 下增加一个 color 的数组
var option = { // 全局调色盘
color: ['red', 'green', 'blue'],
......
}
mCharts.setOption(option)
局部调色盘
局部调色盘就是在 series 下增加一个 color 的数组
var option = { // 全局调色盘
color: ['red', 'green', 'blue'],
series: [{
type: 'pie',
data: pieData, // 局部调色盘
color: ['pink', 'yellow', 'black']
}]
}
mCharts.setOption(option)
需要注意一点的是, 如果全局的调色盘和局部的调色盘都设置了, 局部调色盘会产生效果, 这里面遵循的是就近原则
渐变颜色的实现
在 ECharts 中, 支持线性渐变和径向渐变两种颜色渐变的方式
线性渐变
线性渐变的类型为 linear , 他需要配置线性的方向, 通过 x, y, x2, y2 即可进行配置
x , y , x2 , y2 , 范围从 0 - 1,相当于在图形包围盒中的百分比,如果 global 为 true ,则该四个值是绝对的像素位置
在下述代码中的 0 0 0 1 意味着从上往下进行渐变
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<script>
var mCharts = echarts.init(document.querySelector("div"))
var xDataArr = ['张三', '李四', '王五', '闰土', '小明', '茅台', '二妞',
'大 强'
]
var yDataArr = [88, 92, 63, 77, 94, 80, 72, 86]
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value'
},
series: [{
type: 'bar',
data: yDataArr,
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'red' // 0% 处的颜色
}, {
offset: 1,
color: 'blue' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
}
}
}]
};
mCharts.setOption(option)
</script>
</body>
</html>
线性渐变的类型为 radial , 他需要配置径向的方向, 通过 x , y , r 即可进行配置
前三个参数分别是圆心 x , y 和半径,取值同线性渐变
在下述代码中的 0.5 0.5 0.5 意味着从柱的重点点, 向外径向扩散半径为宽度一半的圆
series: [{
itemStyle: {
color: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.5,
colorStops: [{
offset: 0,
color: 'red' // 0% 处的颜色
}, {
offset: 1,
color: 'blue' // 100% 处的颜色
}],
global: false // 缺省为 false
}
}
}]
直接样式
data: [{
value: 11231,
name: "淘宝",
itemStyle: {
color: 'black'
}
}]
title: {
text: '我是标题',
textStyle: {
color: 'red'
}
}
label: {
color: 'green'
}
这些样式一般都可以设置颜色或者背景或者字体等样式, 他们会覆盖主题中的样式
高亮样式
图表中, 其实有很多元素都是有两种状态的, 一种是默认状态, 另外一种就是鼠标滑过或者点击形成的高亮状态. 而高亮样式是针对于元素的高亮状态设定的样式
那它的使用也非常简单,在 emphasis 中包裹原先的 itemStyle 等等, 我们来试一下
series: [{
type: 'pie',
label: {
color: 'green'
},
emphasis: {
label: {
color: 'red'
},
},
data: [{
value: 11231,
name: "淘宝",
itemStyle: {
color: 'black'
},
emphasis: {
itemStyle: {
color: 'blue'
},
}
}, ]
}]
步骤1: 监听窗口大小变化事件
步骤2: 在事件处理函数中调用 ECharts 实例对象的 resize 即可
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style=" height:400px;border:1px solid red"></div>
<script>
var mCharts = echarts.init(document.querySelector("div")) var xDataArr = ['张三', '李四', '王五', '闰土', '小明', '茅台', '二妞',
'大 强'
]
var yDataArr = [88, 92, 63, 77, 94, 80, 72, 86]
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value'
},
series: [{
type: 'bar',
data: yDataArr
}]
};
mCharts.setOption(option) // 监听window大小变化的事件
window.onresize = function () { // 调用echarts示例对象的resize方法
mCharts.resize()
} // window.onresize = mCharts.resize
</script>
</body>
</html>
ECharts 已经内置好了加载数据的动画, 我们只需要在合适的时机显示或者隐藏即可
mCharts.showLoading()
一般, 我们会在获取图表数据之前 显示加载动画
mCharts.hideLoading()
一般, 我们会在获取图表数据之后 隐藏加载动画, 显示图表
所有数据的更新都通过 setOption 实现, 我们不用考虑数据到底产生了那些变化, ECharts 会找到两组
数据之间的差异然后通过合适的动画去表现数据的变化。
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px"></div>
<button>修改数据</button> <button id="btnAdd">增加数据</button>
<script>
var mCharts = echarts.init(document.querySelector("div"))
var xDataArr = ['张三', '李四', '王五', '闰土', '小明', '茅台', '二妞',
'大强'
]
var yDataArr = [88, 92, 63, 77, 94, 80, 72, 86]
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
yAxis: {
type: 'value'
},
series: [{
type: 'bar',
data: yDataArr
}]
};
mCharts.setOption(option)
var btn = document.querySelector('button');
btn.onclick = function () {
var newArr = [68, 62, 93, 67, 64, 90, 52,
36
]
// setOption的方法可以被调用多次
// 新的option 和旧的option配置
// 新旧option配置项他们之间不是替换的关系,是相互整合的关系
// 我们在设置新的option的时候,只需要考虑到将变化的配置项配置就可以了
var option = {
series: [{
data: newArr,
}]
};
mCharts.setOption(option)
}
var btnAdd = document.querySelector('#btnAdd')
btnAdd.onclick = function () {
setInterval(
function () { //增加数据
xDataArr.push('小明')
yDataArr.push(parseInt(50 + Math.random() * 10))
var option = {
xAxis: {
data: xDataArr
},
series: [{
data: yDataArr
}]
}
mCharts.setOption(option)
}, 1000)
}
</script>
</body>
</html>
开启动画
animation: true
动画时长
animationDuration: 5000
缓动动画
animationEasing : ‘bounceOut’
linear ,线性变化, 这样动画效果会很均匀
bounceOut ,这样动画效果会有一个回弹效果
动画阈值
animationThreshold: 8
单种形式的元素数量大于这个阈值时会关闭动画
全局 echarts 对象是引入 echarts.js 文件之后就可以直接使用的
echarts.init
初始化ECharts实例对象
使用主题
echarts.registerTheme
注册主题
只有注册过的主题,才能在init方法中使用该主题
echarts.registerMap
注册地图数据
$.get('json/map/china.json', function (chinaJson) {
echarts.registerMap('china', chinaJson);
});
geo组件使用地图数据
var option = {
geo: {
type: 'map',
map: 'china',
},
})
echarts.connect
每一个图表对应一个 ECharts 实例对象
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/echarts.min.js"></script>
<script src="js/jquery.min.js"></script>
</head>
<body>
<div style="width: 600px;height:400px;border:1px solid red"></div>
<div style="width: 600px;height:400px;border:1px solid green" id="div1"> </div>
<script>
var mCharts = echarts.init(document.querySelector("div"), 'itcast')
var xDataArr = ['张三', '李四', '王五', '闰土', '小明',
'茅台', '二妞', '大 强'
]
var yDataArr = [88, 92, 63, 77, 94, 80, 72, 86]
var option = {
xAxis: {
type: 'category',
data: xDataArr
},
toolbox: {
feature: {
saveAsImage: {}
}
},
yAxis: {
type: 'value'
},
series: [{
type: 'bar',
data: yDataArr
}]
};
mCharts.setOption(option) $.get('json/map/china.json', function (chinaJson) {
echarts.registerMap('china', chinaJson)
var mCharts2 = echarts.init(document.querySelector('#div1'));
var option2 = {
geo: {
type: 'map',
map: 'china'
}
}
mCharts2.setOption(option2)
echarts.connect([mCharts, mCharts2])
})
</script>
</body>
</html>
这样, 由于我们打开了toolbox中的saveAsImage, 所以会出现下载图片的按钮. 而通过echarts.connect([mCharts, mCharts2]) , 此时点击下载图片按钮, 保存下来的图片就是两个图表的图片了
eChartsInstance 对象是通过 echarts.init 方法调用之后得到的
echartsInstance.setOption
设置或修改图表实例的配置项以及数据
多次调用setOption方法
合并新的配置和旧的配置
增量动画
echartsInstance.resize
重新计算和绘制图表
一般和window对象的resize事件结合使用
window.onresize = function(){
myChart.resize();
}
echartsInstance.on echartsInstance.offff
绑定或者解绑事件处理函数
鼠标事件
常见事件: 'click'、'dblclick'、'mousedown'、'mousemove'、'mouseup'等
事件参数 arg: 和事件相关的数据信息
mCharts.on('click', function (arg) {
// console.log(arg)
console.log('饼图被点击了')
})
解绑事件:
mCharts.off('click')
ECharts 事件
常见事件: legendselectchanged、'datazoom'、'pieselectchanged'、'mapselectchanged' 等
事件参数 arg: 和事件相关的数据信息
mCharts.on('legendselectchanged', function (arg) {
console.log(arg)
console.log('图例选择发生了改变...')
})
echartsInstance.dispatchAction
主动触发某些行为, 使用代码模拟用户的行为
// 触发高亮的行为
mCharts.dispatchAction({
type: "highlight",
seriesIndex: 0,
dataIndex: 1
}) // 触发显示提示框的行为
mCharts.dispatchAction({
type: "showTip",
seriesIndex: 0,
dataIndex: 3
})
echartsInstance.clear
清空当前实例,会移除实例中所有的组件和图表
清空之后可以再次 setOption
echartsInstance.dispose
销毁实例
销毁后实例无法再被使用
在使用echarts绘制图表时, 如果需要使用渐变色, 则应使用echarts内置的渐变色生成器echarts.graphic.LinearGradient
itemStyle: {
normal: {
color: '#00E2FF',
lineStyle: {
// 系列级个性化折线样式
width: 5,
type: 'solid',
// 颜色渐变函数 前四个参数分别表示四个位置依次为
// 右下左上
color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{
offset: 0,
color: '#00E2FF'
},
{
offset: 1,
color: '#0063BF'
}
]) // 线条渐变色
}
},
emphasis: {
color: '#0063BF',
lineStyle: {
// 系列级个性化折线样式
width: 5,
type: 'dotted',
color: '#4fd6d2' // 折线的颜色
}
}
}, // 线条样式
areaStyle: {
normal: {
color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
// 折线图颜色渐变
offset: 0,
color: 'rgba(0, 226, 255, 0.5)'
},
{
offset: 1,
color: 'rgba(0, 99, 191, 0)'
}
])
}
},
入了5个参数:
前4个参数用于配置渐变色的起止位置, 这4个参数依次对应右/下/左/上四个方位. 而0 0 0 1则代表渐变色从正上方开始.
第5个参数则是一个数组, 用于配置颜色的渐变过程. 包含offset和color两个参数. offset的范围是0 ~ 1, 用于表示位置, color表示颜色
https://gitee.com/wu_yuxin/echarts-learning.git
分为三部分代码
原生(jQuery)编写的一个小项目
echarts基础
echarts-online实例
基于 Node.js 平台的Web服务器框架
由 Express 原班人马打造
Express Koa , Koa2 都是 Web 服务器的框架,他们之间的差别和关系可以通过下面这个表格表示出
框架名 | 作用 | 异步处理 |
---|---|---|
Express | web 框架 | 回调函数 |
Koa | web 框架 | Generator+yield |
Koa2 | web 框架 | async/await |
环境依赖 Node v7.6.0 及以上
由于 Koa2 它是支持 async 和 await ,所以它对 Node 的版本是有要求的,它要求 Node 的版本至少是在7.6级以上,因为语法糖 async和await 是在 Node7.6 版本之后出现才支持
洋葱模型的中间件
如下图所示, 对于服务器而言,它其实就是来处理一个又一个的请求, Web 服务器接收由浏览器发过来的一个又一个请求之后,它形成一个又一个的响应返回给浏览器. 而请求到达我们的服务器是需要经过程序处理的,程序处理完之后才会形成响应,返回给浏览器,我们服务器处理请求的这一块程序,在 Koa2 的世界当中就把它称之为中间件
这种中间件可能还不仅仅只有一个,可能会存在多个,比如上图所示, 它就存在三层中间件,这三层中间件在处理请求的过程以及它调用的顺序为:
这个调用顺序就是洋葱模型, 中间件对请求的处理有一种先进后出的感觉,请求最先到达第一层中间件,而最后也是第一层中间件对请求再次处理了一下
如何对 Koa2 进行快速的上手呢?需要有如下几个步骤
检查 Node 的版本
安装 Koa2
npm init -y
这个命令可以快速的创建出 package.json 的文件, 这个文件可以维护项目中第三方包的信息
npm install koa
这个命令可以在线的联网下载最新版本 koa 到当前项目中, 由于线上最新版本的 koa 就是koa2 , 所以我们并不需要执行 npm install koa2
如果下载特别慢的话, 需要将 npm 的下载源换成国内的下载源, 命令如下
npm set registry https://registry.npm.taobao.org/
编写入口文件 app.js
创建 Koa 的实例对象
// 1.创建koa对象
const Koa = require('koa') // 导入构造方法
const app = new Koa() // 通过构造方法, 创建实例对象
编写响应函数(中间件)
响应函数是通过use的方式才能产生效果, 这个函数有两个参数, 一个是 ctx ,一个是 next
上下文, 指的是请求所处于的Web容器,我们可以通过 ctx.request 拿到请求对象, 也可以通过 ctx.response 拿到响应对象
next :
内层中间件执行的入口
// 2.编写响应函数(中间件)
app.use((ctx, next) => {
console.log(ctx.request.url)
ctx.response.body = 'hello world'
})
指明端口号
通过 app.listen 就可以指明一个端口号
// 3.绑定端口号 3000
app.listen(3000)
启动服务器
通过 node app.js 就可以启动服务器了
随即打开浏览器, 在浏览器中输入 127.0.0.1:3000/ 你将会看到浏览器中出现 hello world 的字符串, 并且在服务器的终端中, 也能看到请求的 url
我们已经学习完了 KOA2 的快速上手, 并且对 KOA2 当中的中间件的特点页进行了讲解. 接下来就是利用KOA2 的知识来进行后台项目的开发,后台项目需要达到这以下几个目标:
1.计算服务器处理请求的总耗时
计算出服务器对于这个请求它的所有中间件总耗时时长究竟是,我们需要计算一下
2.在响应头上加上响应内容的 mime 类型
加入mime类型, 可以让浏览器更好的来处理由服务器返回的数据.
如果响应给前端浏览器是 json 格式的数据,这时候就需要在咱们的响应头当中增加 Content- Type 它的值就是 application/json , application/json 就是 json 数据类型的 mime 类型
3.根据URL读取指定目录下的文件内容
为了简化后台服务器的代码,前端图表所要的数据, 并没有存在数据库当中,而是将存在文件当中的,这种操作只是为了简化咱们后台的代码. 所以咱们是需要去读取某一个目录下面的文件内容的。
每一个目标就是一个中间件需要实现的功能, 所以后台项目中需要有三个中间件
创建一个新的文件夹, 叫做 koa_server , 这个文件夹就是后台项目的文件夹
1.项目准备
app.js 是后台服务器的入口文件
data 目录是用来存放所有模块的 json 文件数据
middleware 是用来存放所有的中间件代码
koa_response_data.js 是业务逻辑中间件
koa_response_duration.js 是计算服务器处理时长的中间件
koa_response_header.js 是用来专门设置响应头的中间件
接着将各个模块的 json 数据文件复制到 data 的目录之下, 接着在 app.js 文件中写上代码如下:
// 服务器的入口文件
// 1.创建KOA的实例对象
const Koa = require('koa')
const app = new Koa()
// 2.绑定中间件
// 绑定第一层中间件
// 绑定第二层中间件
// 绑定第三层中间件
// 3.绑定端口号 8888
app.listen(8888)
2.总耗时中间件
1.第1层中间件
总耗时中间件的功能就是计算出服务器所有中间件的总耗时,应该位于第一层,因为第一层的中间件是最先处理请求的中间件,同时也是最后处理请求的中间件
2.计算执行时间
第一次进入咱们中间件的时候,就记录一个开始的时间
当其他所有中间件都执行完之后,再记录下结束时间以后
将两者相减就得出总耗时
3.设置响应头
将计算出来的结果,设置到响应头的 X-Response-Time 中, 单位是毫秒 ms
具体代码如下:
app.js
// 绑定第一层中间件
const respDurationMiddleware = require('./middleware/koa_response_duration')
app.use(respDurationMiddleware)
koa_response_duration.js
// 计算服务器消耗时长的中间件
module.exports = async (ctx, next) => {
// 记录开始时间
const start = Date.now()
// 让内层中间件得到执行
await next()
// 记录结束的时间
const end = Date.now()
// 设置响应头 X-Response-Time
const duration = end - start
// ctx.set 设置响应头
ctx.set('X-Response-Time', duration + 'ms')
}
3.响应头中间件
1.第2层中间件
这个第2层中间件没有特定的要求
2.获取 mime 类型
由于咱们所响应给前端浏览器当中的数据都是 json 格式的字符串,所以 mime 类型可以统一的给它写成 application/json , 当然这一块也是简化的处理了,因为 mime 类型有几十几百种,我们我们没有必要在我们的项目当中考虑那么多,所以这里简化处理一下
3.设置响应头
响应头的key是 Content-Type ,它的值是 application/json , 顺便加上 charset=utf-8
告诉浏览器,我这部分响应的数据,它的类型是 application/json ,同时它的编码是 utf- 8
具体代码如下:
app.js
// 绑定第二层中间件
const respHeaderMiddleware = require('./middleware/koa_response_header')
app.use(respHeaderMiddleware)
koa_response_header.js
// 设置响应头的中间件
module.exports = async (ctx, next) => {
const contentType = 'application/json; charset=utf-8'
ctx.set('Content-Type', contentType)
await next()
}
4.业务逻辑中间件
1.第3层中间件
这个第3层中间件没有特定的要求
2.读取文件内容
获取 URL 请求路径
const url = ctx.request.url
根据URL请求路径,拼接出文件的绝对路径
let filePath = url.replace('/api', '')
filePath = '../data' + filePath + '.json'
filePath = path.join(__dirname, filePath)
这个 filePath 就是需要读取文件的绝对路径
读取这个文件的内容
使用 fs 模块中的 readFile 方法进行实现
3.设置响应体
ctx.response.body
具体代码如下:
app.js
// 绑定第三层中间件
const respDataMiddleware = require('./middleware/koa_response_data')
app.use(respDataMiddleware)
koa_response_data.js
// 处理业务逻辑的中间件,读取某个json文件的数据
const path = require('path')
const fileUtils = require('../utils/file_utils')
module.exports = async (ctx, next) => {
// 根据url
const url = ctx.request.url // /api/seller ../data/seller.json
let filePath = url.replace('/api', '') // /seller
filePath = '../data' + filePath + '.json' // ../data/seller.json
filePath = path.join(__dirname, filePath)
try {
const ret = await fileUtils.getFileJsonData(filePath)
ctx.response.body = ret
} catch (error) {
const errorMsg = {
message: '读取文件内容失败, 文件资源不存在',
status: 404
}
ctx.response.body = JSON.stringify(errorMsg)
}
console.log(filePath)
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.允许跨域
app.use(async (ctx, next) => {
ctx.set("Access-Control-Allow-Origin", "*")
ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE")
await next();
})
1、WebSocket是什么?
WebSocket是一种网络通信协议, 一种由HTML5 开始提供的、在单个 TCP 连接上进行全双工通讯的协议。它和HTTP协议的最大区别在于:HTTP 协议是一种无状态的、无连接的、单向的应用层协议当客户端想要知道服务端的变化时,HTTP协议必须使用“轮询”的方式,效率很低;而WebSocket只需一次连接,便可以让服务端直接向客户端推送信息,从而告别轮询。
其实只要记住几点:
2、WebSocket的优点
很多网站为了实现数据推送,所用的技术都是ajax轮询。轮询是在特定的时间间隔,由浏览器主动发起请求,将服务器的数据拉回来。轮询需要不断的向服务器发送请求,会占用很多带宽和服务器资源。WebSocket建立TCP连接后,服务器可以主动给客户端传递数据,能够更好的节省服务器资源和带宽,实现更实时的数据通讯。
概括地说就是:支持双向通信,更灵活,更高效,可扩展性更好。
属性 | 描述 |
---|---|
Socket.readyState | 只读属性 readyState 表示连接状态,可以是以下值:0 - 表示连接尚未建立。1 - 表示连接已建立,可以进行通信。2 - 表示连接正在进行关闭。3 - 表示连接已经关闭或者连接不能打开。 |
Socket.bufferedAmount | 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。 |
4、WebSocket 事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。
(1)当Browser和WebSocketServer连接成功后,会触发onopen消息;
websocket.onopen = function(evt) {};
(2)如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;
websocket.onerror = function(evt) { };
(3)当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;
websocket.onmessage = function(evt) { };
(4)当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。
websocket.onclose = function(evt) { };
5、WebSocket 方法
以下是 WebSocket 对象的相关方法。假定我们使用了以上代码创建了 Socket 对象:
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
6、通信协议
WebSocket与TCP、HTTP的关系WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。
WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,WebSocket在建立握手连接时,数据是通过http协议传输的,但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。
7、WebSocket通讯解读:
从下图可以明显的看到,分三个阶段:
当Web应用程序调用new WebSocket(url)接口时,Browser就开始了与地址为url的WebServer建立握手连接的过程。
Browser与WebSocket服务器通过TCP三次握手建立连接,如果这个建立连接失败,那么后面的过程就不会执行,Web应用程序将收到错误消息通知。
在TCP建立连接成功后,Browser/UA通过http协议传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。
WebSocket服务器收到Browser/UA发送来的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据回复,同样回复的数据包也是采用http协议传输。
Browser收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,触发onopen消息,此时Web开发者就可以在此时通过send接口想服务器发送数据。否则,握手连接失败,Web应用程序会收到onerror消息,并且能知道连接失败的原因。
这个握手很像HTTP,但是实际上却不是,它允许服务器以HTTP的方式解释一部分handshake的请求,然后切换为websocket
9、数据传输
WebScoket协议中,数据以帧序列的形式传输。
考虑到数据安全性,客户端向服务器传输的数据帧必须进行掩码处理。服务器若接收到未经过掩码处理的数据帧,则必须主动关闭连接。
服务器向客户端传输的数据帧一定不能进行掩码处理。客户端若接收到经过掩码处理的数据帧,则必须主动关闭连接。
针对上情况,发现错误的一方可向对方发送close帧(状态码是1002,表示协议错误),以关闭连接。
关闭WebSocket(握手)
一、js 伪协议的几种调用方法(参考总结的)
1、 这是常用的方法,但是这种方法在传递this等参数的时候很容易出问题,而且javascript:协议作为a的href属性的时候不仅会导致不必要的触发window.onbeforeunload事件,在IE里面更会使gif动画图片停止播放。W3C标准不推荐在href里面执行javascript语句 2、 这种方法是很多网站最常用的方法,也是最周全的方法,onclick方法负责执行js函数,而void是一个操作符,void(0)返回undefined,地址不发生跳转。而且这种方法不会像第一种方法一样直接将js方法暴露在浏览器的状态栏。 3、 这种方法跟跟2种类似,区别只是执行了一条空的js代码。 4、 这种方法也是网上很常见的代码,#是标签内置的一个方法,代表top的作用。所以用这种方法点击后网页后返回到页面的最顶端。 5、 这种方法点击执行了js函数后return false,页面不发生跳转,执行后还是在页面的当前位置。 6、 这种方法在点击 a 标签时,执行一个 js 另外自定义函数 todoFun(void) 。并传参 void。 综合上述,在a中调用js函数最适当的方法推荐使用: 二、href="#"的作用 a中href="#"表示回到最顶部。如果当前页面中需要滚动的话,那么用这种方式就可以直接回到顶部。比如有些网站会在右下角制作一个图标按钮,回到顶部,那么此时可以考虑用这种最简单的方式实现。 三、href="URL"的作用 1、URL为绝对URL 此时指向另一个站点,比如href=“http://write.blog.csdn.NET”,那么点击时就会直接跳转到这个链接的页面。 2、URL为相对URL 此时指向站点内的某个文件,比如href="/test.doc",那么点击时就会直接下载文件。 3、锚 URL 此时指向页面中的锚,比如href="#top",那么点击时就会到当前页面中id="top"的这个锚点,实现当前页面的所谓跳转。用的最多就是在可滚动页面中,添加菜单,可以直接回到页面中的某个部分的内容。 即所有的三种代码样例: 解决方案 1.href ----- 整个URL字符串. 2.protocol ----- 含有URL第一部分的字符串,如https. 3.host ----- 主机名. 4.port ----- 端口号. 5.pathname ----- 路径. 6.search ----- “?” 之后的字符串. 7.hash ----- “#” 之后的字符串. 下面举个例子,有这样一个URL 1.window.location.href 整个URl字符串(浏览器完整的地址栏) 返回值: 2.window.location.protocol URL的协议部分 返回值: 3.window.location.host & window.location.hostname URL的主机部分 返回值: 4.window.location.port URL的端口部分 返回值:" " Note: If the port number is default (80 for http and 443 for https), most browsers will display 0 or nothing. 5.window.location.pathname URL的路径部分 返回值: 6.window.location.search 查询部分 返回值: 7.window.location.hash 锚点 返回值: 说起对数组的排序,大家能想到的应该是冒泡排序,快速排序,sort排序,以及希尔排序吧,但是可能对sort排序只停留再数组层面(每个元素均是数字或者字符串),事实上,它还可以对对象进行排序。 原理是:不管元素是什么类型,sort排序始终是根据元素的unicode编码进行的 下面来分别看下各种情况: 元素为数字或者字符串: 先从简单的开始,大家都知道sort()函数比较的是ASCII码的大小,而且而且而且:Array的sort()方法默认把所有元素先转换为String再排序,所以就有以下问题。 [语法]: arr.sort(compareFunction) [参数]: compareFunction可选。用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的诸个字符的Unicode位点进行排序。 返回排序后的数组。原数组已经被排序后的数组代替。 [描述]: 如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 “Banana” 会被排列到 “cherry” 之前。数字比大小时,2 出现在 10 之前,但这里比较时数字会先被转换为字符串,所以 “10” 比 “2” 要靠前。 如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素: 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前; 所以,比较函数格式如下: 要比较数字而非字符串,比较函数可以简单的以 a 减 b,如下的函数将会将数组升序排列 其中get与set的使用方法: 1、get与set是方法,因为是方法,所以可以进行判断。 2、get是得到 一般是要返回的 set 是设置 不用返回 3、如果调用对象内部的属性约定的命名方式是_age 然后就是几个例子来简单说明一下: 例子2:
删除
<a href="javascript:void(0);" onclick="js_method()"></a>
<a href="javascript:;" onclick="js_method()"></a>
<a href="#" onclick="js_method();return false;"></a>
<span style="font-size:14px;"><a href="#">回到最顶端</a></span>
<a href="http://baidu.com">超链接</a>
<a href="#">回到最顶端</a>
<a href="css/css1.css">文件链接</a>
2、Uncaught TypeError: Object(…) is not a function at resetStoreState
引起这个错误的原因是因为Vuex4.0以上版本依赖于Vue3中的一些属性方法npm uninstall vuex
npm install vuex@3.4.0
// 将版本转换为3.4.0即可完美解决这个问题
3、window.location获取url各项参数详解
https://www.djhero.com:80/dj/post/0805/dongjing.html?ver=1.0&id=1#happy
https://www.djhero.com:80/dj/post/0805/dongjing.html?ver=1.0&id=6#happy
https:
www.djhero.com
/dj/post/0805/dongjing.html
?ver=1.0&id=1
#happy
4、javascript中sort方法的完整解析
var arr1 = [10,1,5,2,3];
arr1.sort();
console.log(arr1);
结果转换成字符串比较,'10’排在了’2’的前面,因为字符’1’比字符’2’的ASCII码小
arr.sort()
[返回值]:
如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。function compare(a, b) {
if (a < b) { // 按某种排序标准进行比较, a 小于 b
return -1;
}
if (a > b) {
return 1;
}
// a must be equal to b
return 0;
}
function compareNumbers(a, b) {
return a - b;
}
5、javascript中set与get方法详解
var person ={
_name : "chen",
age:21,
set name(name) {
this._name = name;
},
get name() {
return this._name;
}
}
console.log(person.name)
输出”chen“
person.name="lunc";
输出"lunc"
person.name
输出"lunc"
var p = {
name:"chen",
work:function() {
console.log("wording...");
},
_age:18,
get age(){
return this._age;
},
set age(val) {
if (val<0 || val> 100) {//如果年龄大于100就抛出错误
throw new Error("invalid value")
}else{
this._age = val;
}
}
};
console.log(p.name);//输出chen
浏览器的直接调试结果:
p.age
"18"
p.age=23
"23"
p.age=200
Uncaught Error: invalid value