# echartsMap
**Repository Path**: jsnoob/echartsMap
## Basic Information
- **Project Name**: echartsMap
- **Description**: 直播讲解echarts制作疫情地图
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 5
- **Forks**: 1
- **Created**: 2020-05-04
- **Last Updated**: 2022-09-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 一、项目介绍
应对现在数据可视化的趋势,越来越多企业需要在很多场景(营销数据,生产数据,用户数据)下使用,可视化图表来展示体现数据,让数据更加直观,数据特点更加突出。该项目除了使用了基础的页面布局,应用了echarts技术,快速构建各类图表。主要功能有:柱状图、折线图、地图。
工具:echarts、jQuery
课程目标:
- echarts基本使用
- flex 布局
- 原生js + jquery 使用
- rem适配
代码统计:
- css 160行 (有效)
- html 40行 (有效)
- js 500行 (有效)
## 二、echarts介绍
ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 [ZRender](https://github.com/ecomfe/zrender),提供直观,交互丰富,可高度个性化定制的数据可视化图表。
- JS插件
- 在PC与移动设备性流畅运行
- 兼容主流浏览器
- 提供常用图表(折线图、柱状图、散点图、饼状图、热力图、地图....),且可**定制**
## 三、echarts的使用
### (1)、基本用法演示
1. 引入echarts
2. 准备图表容器
3. 初始化echarts实例
4. 设置图表的配置项
### (2)、部分配置项介绍
- series:系列列表。每个系列通过 `type` 决定自己的图表类型(指定什么类型的图标)
- xAxis:直角坐标系x 轴
- yAxis:直角坐标系y 轴
- grid:直角坐标系内绘图网格
- title:标题组件
- tooltip:提示框组件
- legend:图例组件
- visualMap:视觉映射组件
- 
### (3)、rem适配
- 引入flexible.js,此文件把HTML标签字体大小为屏幕宽度的十分之一来,如此页面宽为10rem
- 设计稿对应10rem宽,则以rem为单位的样式值参考的基础字体大小为设计稿宽度的十分之一
## 四、书写项目页面布局
### (1)、创建项目结构
- 创建项目目录
- 在页面中引入js、css资源
引入CSS资源
```html
```
引入JS资源
```html
```
### (2)、页面基础布局
HTML结构
```html
```
CSS样式 —— 设置部分默认样式
```css
* {
margin: 0;
padding: 0;
}
body{
background-color: #10aeb5;
}
li {
list-style: none;
}
i{
font-style: normal;
}
span {
cursor: pointer;
}
```
CSS样式 —— 设置布局容器
```css
.container {
width: 10rem;
margin: 20px auto;
padding: 0.15625rem 0;
text-align: center;
background-color: #fff;
border-radius: 15px;
}
```
### (3)、海外疫情地图
HTML结构
```html
-
3577405
累计确诊
昨日+71180
-
2204402
现有确诊
昨日+28919
-
248216
死亡人数
昨日+3752
-
1124787
治愈人数
昨日+38509
```
CSS代码
```css
.brief_header {
width: 9.375rem;
margin: 0 auto;
overflow: hidden;
}
.brief_header h2 {
float: left;
height: 0.46875rem;
font-size: 0.375rem;
line-height: 0.46875rem;
margin-left: 0.078125rem;
}
.brief_header p {
float: left;
height: 0.46875rem;
font-size: 0.25rem;
color: #acacac;
line-height: 0.46875rem;
margin-left: 0.15625rem;
}
.brief_body {
display: flex;
justify-content: space-evenly;
margin-top: 0.3125rem;
}
.brief_body .number {
font-size: 0.34375rem;
}
.brief_body .item {
width: 1.5625rem;
height: 0.421875rem;
background-color: #ccc;
border-radius: 0.078125rem;
line-height: 0.421875rem;
color: #000;
margin: 0.078125rem 0;
}
.brief_body .change span {
color: #000;
}
.allConfirm {
color: #d73a30;
}
.nowConfirm {
color: #ee5b00;
}
.deadNum {
color: #003146;
}
.cureNum {
color: #00c7c7;
}
.map_header {
font-size: 0.375rem;
width: 9.21875rem;
margin: 0.3125rem auto;
text-align-last: left;
}
.brief .map_info {
width: 9.375rem;
height: 4.921875rem;
margin: 0.3125rem auto;
}
.brief .map_tab {
display: flex;
justify-content: center;
align-items: center;
}
.brief .map_tab span {
width: 1.59375rem;
height: 0.578125rem;
font-size: 0.25rem;
line-height: 0.578125rem;
background-color: #f4f5f6;
margin: 0 0.046875rem;
}
.brief .map_tab span.cur {
color: #ffb1b2;
border: 0.015625rem solid #ffb1b2;
background-color: #fff;
}
```
### (4)、海外疫情趋势
HTML结构
```html
新增确诊
累计确诊/
现有确诊
死亡数/
治愈数
病死率/
治愈率
```
CSS代码
```css
.tendency .map_info {
width: 9.21875rem;
height: 6rem;
margin: 0.15625rem auto;
}
.tendency .map_tab {
display: flex;
justify-content: space-around;
align-items: center;
}
.tendency .map_tab span {
display: flex;
justify-content: center;
align-items: center;
width: 1.59375rem;
height: .6875rem;
font-size: 0.25rem;
line-height: 0.6875rem;
background-color: #f4f5f6;
margin: 0 0.046875rem;
}
.tendency .map_tab span.cur {
color: #ffb1b2;
border: 0.015625rem solid #ffb1b2;
background-color: #fff;
}
.tendency .map_tab span:nth-child(n + 2) {
font-size: .1875rem;
line-height: 0.35rem;
}
.tendency .map_tab span:nth-child(n + 2) i {
transform: scale(0.9);
}
```
### (5)、昨日新增确诊国家Top10
HTML结构
```html
```
CSS代码
```css
.addTop10 .map_info {
width: 9.21875rem;
height: 6rem;
margin: 0.15625rem auto;
}
```
### (6)、海外多国新增确诊趋势
HTML结构
```html
```
CSS代码
```css
.importantNation .map_info {
width: 9.21875rem;
height: 6rem;
margin: 0.15625rem auto;
}
.importantNation .map_tab {
display: flex;
justify-content: center;
align-items: center;
}
.importantNation .map_tab span {
width: 1.265625rem;
height: 0.578125rem;
font-size: 0.25rem;
line-height: 0.578125rem;
background-color: #f4f5f6;
margin: 0 0.046875rem;
}
.importantNation .map_tab span.cur {
color: #ffb1b2;
border: 0.015625rem solid #ffb1b2;
background-color: #fff;
}
```
## 六、获取、插入数据
### (1)、获取数据
#### 请求地址
```js
// 国外数据
https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign
// 国内数据
https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5
```
#### 请求、保存数据
```js
var foreignData = null;
var chinaData = null;
$.ajax({
url: "https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign",
dataType: "jsonp",
success: function (data) {
foreignData = JSON.parse(data.data);
console.log("国外数据");
}
})
$.ajax({
url: "https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5",
dataType: "jsonp",
success: function (data) {
chinaData = JSON.parse(data.data);
console.log("国内数据");
}
})
```
#### 在请求完成后注入数据
```js
$.when($.ajax({
// 请求1
}), $.ajax({
// 请求2
})).then(function () {
// 注入数据
});
```
### (2)、注入标题数据
#### 声明title函数
```js
// 标题
function title(){
$(".brief .brief_header p").text("更新时间 - "+foreignData.globalStatis.lastUpdateTime)
}
```
#### 在请求完成后执行
```js
$.when($.ajax({
// 请求1
}), $.ajax({
// 请求2
})).then(function () {
// 标题
title();
});
```
### (3)、注入总览数据
#### 声明brief函数
```js
function brief() {
var globalStatis = foreignData.globalStatis;
var htmlStr = `
${globalStatis.confirm}
累计确诊
昨日${globalStatis.confirmAdd > 0 ? "+" + globalStatis.confirmAdd : "-" + globalStatis.confirmAdd}
${globalStatis.nowConfirm}
现有确诊
昨日${globalStatis.nowConfirmAdd > 0 ? "+" + globalStatis.nowConfirmAdd : "-" + globalStatis.nowConfirmAdd}
${globalStatis.dead}
死亡人数
昨日${globalStatis.deadAdd > 0 ? "+" + globalStatis.deadAdd : "-" + globalStatis.deadAdd}
${globalStatis.heal}
治愈人数
昨日${globalStatis.healAdd > 0 ? "+" + globalStatis.healAdd : "-" + globalStatis.healAdd}
`
$(".brief .brief_body").html(htmlStr);
}
```
#### 在请求完成后执行
```js
$.when($.ajax({
// 请求1
}), $.ajax({
// 请求2
})).then(function () {
// 标题
title();
// 海外疫情总览
brief();
});
```
## 七、世界疫情地图
### (1)、世界疫情地图 - 基本设置
#### 声明map函数
```js
function map() {}
```
#### 初始化echarts实例
```js
var myChart = echarts.init(document.querySelector(".brief .map_info"));
```
#### 设置option配置项
```js
var option = {
title: {
text: '默认标题',
},
series: [{
name: '',
type: 'map',
mapType: 'world'
}]
};
```
#### 绘制图表
```js
myChart.setOption(option);
```
#### 注意:如果要绘制地图、必须要先注册地图,地图注册的方式有两种
- 通过json文件注册地图
```js
echarts.registerMap(地图名称, 地图json数据,特殊配置项);
```
- 通过js文件注册地图
引入js文件即可
### (2)、世界疫情地图 - 修改配置项
#### 设置标题
```js
// 删除title、或者设置text项为空
title: {
text: '',
}
```
#### 设置缩放、地区名称映射、鼠标经过高亮
```js
series: [{
name: '',
type: 'map',
mapType: 'world',
roam: true,
nameMap:nameMap,
itemStyle: {
normal: {
label: {
show: false
}
},
emphasis: {
areaColor: '#c9ffff',
label: {
show: false
}
}
}
}]
```
#### 设置数据
##### a、目标数据
```js
[
0: {name: "美国", value: 1212955},
1: {name: "西班牙", value: 248301},
2: {name: "俄罗斯", value: 134687},
3: {name: "英国", value: 104145},
4: {name: "意大利", value: 97689}...
]
```
##### b、处理原始数据
```js
var virusDatas = [];
// 遍历数据,获取目标信息
$.each(foreignData.foreignList, function (i, v) {
virusDatas[i] = {};
virusDatas[i].name = v.name;
virusDatas[i].value = v.confirm;
})
// 加入中国数据
virusDatas.push({
name: "中国",
value: chinaData.chinaTotal.confirm
});
```
##### c、设置地图数据映射
```js
// option下设置visualMap
visualMap: {
type: 'piecewise',
pieces: [
{ max: 0, label: '0', color: '#fff' },
{ min: 1, max: 499, label: '1-499', color: '#fff7ba' },
{ min: 500, max: 4999, label: '500-4999', color: '#ffc24b' },
{ min: 5000, max: 9999, label: '5000-9999', color: '#ff7c20' },
{ min: 10000, max: 100000, label: '1万-10万', color: '#fe5e3b' },
{ min: 100000, max: 500000, label: '10万-50万', color: '#e2482b' },
{ min: 500000, label: '50万以上', color: '#b93e26' },
]
}
```
#### 设置提示信息
```js
// option下设置tooltip
tooltip: {
trigger: 'item',
formatter: function (params) {
return params.name + " : " + (params.value ? params.value : 0)
}
}
```
#### 设置组件杂项
```js
// visualMap下添加以下配置
visualMap: {
itemHeight: 10,
itemWidth: 10,
itemSymbol: "arrow",
inverse: true
}
// series下添加以下配置
series: [{
top: "center",
left: "center",
scaleLimit: {
min: 1,
max: 10
},
layoutCenter: ['center', 'center'],
layoutSize: "180%",
}]
```
### (3)、世界疫情地图 - 切换地图
```js
// 绑定事件、切换数据
$(".brief .map_tab span").eq(0).click(function () { fn("confirm") });
$(".brief .map_tab span").eq(1).click(function () { fn("nowConfirm") });
function fn(valueName) {
// 重新过滤数据
var virusDatas = [];
$.each(foreignData.foreignList, function (i, v) {
virusDatas[i] = {};
virusDatas[i].name = v.name;
virusDatas[i].value = v[valueName];
})
virusDatas.push({
name: "中国",
value: chinaData.chinaTotal[valueName]
});
// 利用过滤后的数据重新设置配置项
option.series[0].data = virusDatas;
// 重新绘制图表
myChart.setOption(option);
}
// 鼠标点击高亮
$(".map_tab span").click(function () {
$(this).addClass("cur").siblings().removeClass("cur");
})
```
## 八、海外疫情趋势
### (1)、海外疫情趋势 - 基本设置
#### 声明tendency函数
```js
function tendency(){ }
```
#### 初始化echarts实例
```js
var myChart = echarts.init(document.querySelector("#box"));
```
#### 设置配置项
```js
// 设置基本配置项:只有title和series
var option = {
title: {
text: "默认标题"
},
xAxis: {
type: 'category',
},
yAxis: {
type: 'value',
},
series: [{
name: "",
type: 'line'
}]
};
```
#### 绘制图表
```js
myChart.setOption(option);
```
### (2)、设置图表数据
#### 过滤数据
```js
// 获取历史数据
var globalDailyHistory = foreignData.globalDailyHistory;
// 设置容器分别保存数据
var num = [], date = [];
globalDailyHistory.reverse();
globalDailyHistory.shift()
$.each(globalDailyHistory, function (i, v) {
if (num.length < 27 && i % 3 == 0) {
num.push(v.all.newAddConfirm);
date.push(v.date);
}
})
```
#### 设置数据
```js
// 在series中设置data项
series: [{
data: num.reverse()
}]
```
#### 设置Y轴
```js
// 在yAxis中添加以下设置
yAxis: {
// 最小刻度
min: 0,
// 最大刻度
max: 120000,
// 设置坐标轴线样式
axisLine: {
show: false
},
// 设置坐标轴刻度样式
axisTick: {
length: 0,
},
// 设置坐标轴文字格式
axisLabel: {
formatter: function (value, index) {
return value.toString();
}
},
// 设置竖直方向的分割线
splitLine: {
lineStyle: {
color: "#ccc"
}
}
},
```
#### 设置X轴
```js
// 在xAxis中添加以下设置
xAxis: {
length: 7,
data: date.reverse(),
axisTick: {
length: 0,
rotate: 45
},
axisLabel: {
interval: 0,
rotate: 45,
color: "#ccc",
fontSize: 10
}
}
```
#### 设置连线样式
```js
// 在series中添加以下项
series: [{
smooth: true,
lineStyle: {
color: "#ff3d18"
}
}]
```
### (3)、切换图表
#### 图标重绘步骤
```js
1、修改原配置项
2、实例调用setOption方法,根据修改过的配置项重新绘制图表
```
#### 清除原图表
```js
myCharts.clear();
```
#### 绑定事件
```js
$(".tendency .map_tab span").eq(0).click(function () { })
$(".tendency .map_tab span").eq(1).click(function () { })
$(".tendency .map_tab span").eq(2).click(function () { })
$(".tendency .map_tab span").eq(3).click(function () { })
```
#### 切换图表1
```js
// 重新过滤数据
var num = [];
var date = [];
$.each(globalDailyHistory, function (i, v) {
if (num.length < 27 && i % 3 == 0) {
num.push(v.all.newAddConfirm);
date.push(v.date);
}
})
// 根据新数据修改option配置项
option.series = [{
name: "新增确诊",
data: num.reverse(),
type: 'line',
smooth: true,
lineStyle: {
color: "#ff3d18"
}
}]
option.xAxis.data = date.reverse();
option.yAxis.max = 120000;
option.yAxis.splitNumber = 7;
option.yAxis.axisLabel.formatter = function (value, index) {
return value.toString();
}
// 重新绘制图表
myChart.clear();
myChart.setOption(option, true);
```
#### 切换图表2
```js
// 重新过滤数据
// 两个数据系列,使用两个数组容器保存数据
var num1 = [];
var num2 = [];
var date = [];
$.each(globalDailyHistory, function (i, v) {
if (num1.length < 27 && i % 3 == 0) {
num1.push(v.all.confirm);
num2.push(parseFloat(v.all.confirm) - parseFloat(v.all.heal) - parseFloat(v.all.dead));
date.push(v.date);
}
})
option.series = [{
name: "累计确诊",
data: num1.reverse(),
type: 'line',
smooth: true,
lineStyle: {
color: "#c1021b"
}
}, {
name: "现有确诊",
data: num2.reverse(),
type: 'line',
smooth: true,
lineStyle: {
color: "#ed5b00"
}
}]
option.xAxis.data = date.reverse();
option.yAxis.max = 3500000;
option.yAxis.splitNumber = 8;
option.yAxis.axisLabel.formatter = function (value, index) {
return value.toString();
}
myChart.clear();
myChart.setOption(option);
```
#### 切换图表3
```js
// 重新过滤数据
// 两个数据系列,使用两个数组容器保存数据
var num1 = [];
var num2 = [];
var date = [];
$.each(globalDailyHistory, function (i, v) {
if (num1.length < 27 && i % 3 == 0) {
num1.push(v.all.dead);
num2.push(v.all.heal);
date.push(v.date);
}
})
// 根据新数据修改option配置项
option.series = [{
name: "死亡数",
data: num1.reverse(),
type: 'line',
smooth: true,
lineStyle: {
color: "#ff3d18"
}
}, {
name: "治愈数",
data: num2.reverse(),
type: 'line',
smooth: true,
lineStyle: {
color: "#ff3d18"
}
}]
option.xAxis.data = date.reverse();
option.yAxis.max = 1200000;
option.yAxis.splitNumber = 7;
option.yAxis.axisLabel.formatter = function (value, index) {
return value.toString();
}
// 重新绘制图表
myChart.clear();
myChart.setOption(option);
```
#### 切换图表4
```js
// 重新过滤数据
// 两个数据系列,使用两个数组容器保存数据
var num1 = [];
var num2 = [];
var date = [];
$.each(globalDailyHistory, function (i, v) {
if (num1.length < 27 && i % 3 == 0) {
num1.push(parseFloat(v.all.deadRate));
num2.push(parseFloat(v.all.healRate));
date.push(v.date);
}
})
// 根据新数据设置option配置项
option.series = [{
name: "病死率",
data: num1.reverse(),
type: 'line',
smooth: true,
lineStyle: {
color: "#ff3d18"
}
}, {
name: "治愈率",
data: num2.reverse(),
type: 'line',
smooth: true,
lineStyle: {
color: "#ff3d18"
}
}]
option.xAxis.data = date.reverse();
option.yAxis.max = 35;
option.yAxis.splitNumber = 8;
option.yAxis.axisLabel.formatter = function (value, index) {
return value + "%";
}
// 重新绘制图表
myChart.clear();
myChart.setOption(option);
```
## 九、昨日新增确诊国家Top10
### (1)、昨日新增确诊国家Top10 - 基本设置
#### 声明top10函数
```js
function top10(){ }
```
#### 初始化echarts实例
```js
var myChart = echarts.init(document.querySelector(".addTop10 .map_info"));
```
#### 设置配置项
```js
var option = {
title: {
text: "默认文本"
},
xAxis: {
type: 'category'
},
yAxis: {
type: 'value'
},
series: [{
type: 'bar'
}],
};
```
#### 绘制图表
```js
myChart.setOption(option);
```
### (2)、昨日新增确诊国家Top10 - 修改配置
#### 过滤数据
```js
var countryAddConfirmRankList = foreignData.countryAddConfirmRankList;
var num = [];
var nation = [];
$.each(countryAddConfirmRankList, function (i, v) {
num.push(v.addConfirm);
nation.push(v.nation);
})
```
#### 设置数据
```js
// 在series中添加以下项
series: [{
data: num
}]
```
#### 设置Y轴
```js
// 在yAxis中添加以下项
yAxis: {
type: 'value',
axisLabel: {
fontSize: 10,
}
}
```
#### 设置X轴
```js
// 在xAxis中添加以下项
xAxis: {
type: 'category',
data: nation,
axisTick: {
length: 0,
},
axisLabel: {
interval: 0,
fontSize: 10,
rotate: 45,
}
}
```
## 十、海外多国新增确诊趋势
### (1)、海外多国新增确诊趋势 - 基本设置
#### 声明top10函数
```js
function importantNation(){ }
```
#### 初始化echarts实例
```js
var myChart = echarts.init(document.querySelector(".importantNation .map_info"));
```
#### 设置配置项
```js
var option = {
title: {
text: "默认文本"
},
xAxis: {
type: 'category'
},
yAxis: {
type: 'value'
},
series: [{
type: 'line'
}],
};
```
#### 绘制图表
```js
myChart.setOption(option);
```
### (2)、海外多国新增确诊趋势 - 修改设置
#### 过滤数据
```js
// 存储数据
var stateData = {};
// 记录不同类别数据
var nationName = ["欧洲", "北美洲", "亚洲", "南美洲", "非洲"];
var continentStatis = foreignData.continentStatis;
$.each(nationName, function (i1, v1) {
stateData[v1] = {
date: [],
num: []
};
$.each(continentStatis, function (i2, v2) {
stateData[v1].date.push(v2.date);
stateData[v1].num.push(v2.statis[v1] || 0);
})
})
```
#### 设置数据
```js
// 在series中设置数据项
series: [{
data: stateData["欧洲"].num
}]
```
#### 设置标题
```js
// 在中设置添加项
title: {
text: '',
}
```
#### 设置X轴
```js
// 在xAxis中添加以下项
xAxis: {
length: 0,
data: stateData["欧洲"].date,
axisTick: {
length: 0,
rotate: 45
},
axisLabel: {
interval: 0,
rotate: 45,
color: "#ccc",
fontSize: 10
}
}
```
#### 设置Y轴
```js
// 在yAxis中添加以下项
yAxis: {
axisLine: {
show: false
},
axisTick: {
length: 0,
},
splitLine: {
lineStyle: {
color: "#ccc"
}
},
axisLabel: {
formatter: function (value, index) {
return value.toString();
}
}
}
```
#### 设置图例组件
```js
// 在option中添加legend项
legend: {
show: true,
verticalAlign: "middle",
icon: "rect",
itemWidth: 12,
itemHeight: 12,
right: 20,
top: 20,
orient: 'horizontal'
}
```
#### 设置其他杂项
```js
// 修改title
title: {
text: "海外新增确诊趋势",
// 设置文本样式
textStyle: {
fontSize: 14
},
// 设置标题位置
top: 20
},
// 设置网格线框颜色
grid: {
borderColor: "#ccc"
},
// 在series中添加以下设置项
series: [{
smooth: true,
lineStyle: {
color: "#ff3d18"
}
}]
```
### (3)、切换图表
#### 绑定事件
```js
$(".importantNation .map_tab span").click(function () { })
```
#### 事件处理程序
```js
// 通过点击的元素的文本内容获取对应数据,并更新option配置项
option.series[0].data = stateData[this.innerText].num;
myChart.setOption(option);
```