Echarts
静态地图布局设计
这一节的教程是基于b站pink老师的教程进行记录的,感兴趣的可以点过去学习一波
案例——ECharts
前期准备工作,搭建项目文件夹存储对应文件
所需技术
css布局
flex布局
引用flex文件,下载地址:https://github.com/amfe/lib-flexible,之后在页面引用index.js文件(修改名字更佳)
设置分配大小
1
2
3
4
5// set 1rem = viewWidth / 10
function setRemUnit() {
var rem = docEl.clientWidth / 24; //设置平均分24等分
docEl.style.fontSize = rem + "px";
}设置样式,浏览器控制台验证是否生效
原生js+JQuery
rem适配(px转rem)
sublime安装插件,下载地址https://gitee.com/selience/Sublime-cssrem-plugin.git
打开sublime插件目录
将下载的插件包复制进该文件夹
打开sublime,首选项→package Settions→cssrem→设置,本来打算在这两个文件设置相应配置,但失败了(懒得研究)
在插件文件夹打开Sublime-cssrem-plugin,路径→Sublime Text 3\Packages\Sublime-cssrem-plugin,修改设置
1
2
3
4
5{
"px_to_rem": 80, //设置80px转1rem
"max_rem_fraction_length": 6,
"available_file_types": [".css", ".less", ".sass"]
}
页面布局
页面HTML文件
1 |
|
页面初始化
1 | * { |
页面底部以及背景图设置
- 引入背景图(覆盖整个页面)
1 | body { |
页面顶部导航条设置
- 高度为100px
- 背景图,在容器内显示
- 缩放比例为 100%
- h1 标题部分 白色 38像素 居中显示 行高为 80像素
- 时间模块 showTime 定位右侧 right 为 30px 行高为 75px 文字颜色为:rgba(255, 255, 255, 0.7) 而文字大小为 20像素
1 | header { |
- 这里的时间实时更新函数引用之前的js案例并相应修改,同时添加定时器(setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式)用来每隔指定时间调用该函数
1 | var formaDate = function() { |
mainbox主体模块
- 需要一个上左右的10px 的内边距
- column 列容器,分三列,占比 3:5:3
1 | .mainbox { |
公共面板模块 panel
设置放置图表的容器公共样式
- 高度为 310px
- 1像素的 1px solid rgba(25, 186, 139, 0.17) 边框
- 有line.jpg 背景图片
- padding为 上为 0 左右 15px 下为 40px
- 下外边距是 15px
- 利用panel 盒子 before 和after 制作上面两个角 大小为 10px 线条为 2px solid #02a6b5
- 新加一个盒子before 和after 制作下侧两个角 宽度高度为 10px
1 | .panel { |
图表标题及图表布局
- 标题模块 h2 高度为 48px 文字颜色为白色 文字大小为 20px
- 图标内容模块 chart 高度 240px
- 以上可以作为panel公共样式部分
1 | .panel h2 { |
中间布局
上面是no 数字模块
下面是map 地图模块
字体声明
1
2
3
4
5/* 声明字体*/
@font-face {
font-family: electronicFont;
src: url(../font/DS-DIGIT.TTF);
}
- 数字模块 no 有个背景颜色 rgba(101, 132, 226, 0.1); 有个15像素的内边距
- 注意中间列 column 有个 左右 10px 下 15px 的外边距
- no 模块里面上下划分 上面是数字(no-hd) 下面 是 相关文字说明(no-bd)
- no-hd 数字模块 有一个边框 1px solid rgba(25, 186, 139, 0.17)
- no-hd 数字模块 里面分为两个小li 每个小li高度为 80px 文字大小为 70px 颜色为 #ffeb7b 字体是图标字体 electronicFont
- no-hd 利用 after 和 before制作2个小角, 边框 2px solid #02a6b5 宽度为 30px 高度为 10px
- 小竖线 给 第一个小li after 就可以 1px宽 背景颜色为 rgba(255, 255, 255, 0.2); 高度 50% top 25% 即可
- no-bd 里面也有两个小li 高度为 40px 文字颜色为 rgba(255, 255, 255, 0.7) 文字大小为 18px 上内边距为 10px
1 | .no { |
地图模块(css动画)
- 地图模块高度为 810px 里面包含4个盒子 chart、 放图表模块、球体盒子、旋转1、旋转2
- 球体图片模块 map1 大小为 518px 要加背景图片 因为要缩放100% 定位到最中央 透明度 .3
- 旋转1 map 2 大小为 643px 要加背景图片 因为要缩放100% 定位到中央 透明度 .6 做旋转动画
- 旋转2 map3 大小为 566px 要加背景图片 因为要缩放100% 定位到中央 旋转动画 注意是逆时针
1 | .map { |
ECharts
这一节的教程也是基于b站pink老师的教程进行记录的,感兴趣的可以点过去学习一波
常见的数据可视化库:
- D3.js 目前 Web 端评价最高的 Javascript 可视化工具库(入手难)
- ECharts.js 百度出品的一个开源 Javascript 数据可视化库
- Highcharts.js 国外的前端数据可视化库,非商用免费,被许多国外大公司所使用
- AntV 蚂蚁金服全新一代数据可视化解决方案 等等
- Highcharts 和 Echarts 就像是 Office 和 WPS 的关系
ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。
简单理解
使用步骤
下载地址:https://www.echartsjs.com/zh/index.html
- 引入echarts 插件文件到html页面中(🔺注意:引入的Echarts的js文件必须在arcgis前面)
1 | <script src="js/echarts.min.js"> </script> |
- 准备一个具备宽度和高度的DOM容器
1 | <div id="main" style="width: 600px;height:400px;"></div> |
- 初始化echarts实例对象
1 | var myChart = echarts.init(document.getElementById('main')); |
- 指定配置项和数据(option)
1 | var option = { |
- 将配置项设置给echarts实例对象
1 | myChart.setOption(option); |
常用对象
series
xAxis
yAxis
grid
tooltip
title
legend
color
series
- 系列列表。每个系列通过
type
决定自己的图表类型 - 图标数据,指定什么类型的图表,可以多个图表重叠。
- 系列列表。每个系列通过
xAxis:直角坐标系 grid 中的 x 轴
- boundaryGap: 坐标轴两边留白策略 true,这时候刻度只是作为分隔线,标签和数据点都会在两个刻度之间的带(band)中间。
yAxis:直角坐标系 grid 中的 y 轴
grid:直角坐标系内绘图网格。
title:标题组件
tooltip:提示框组件
legend:图例组件
color:调色盘颜色列表
数据堆叠,同个类目轴上系列配置相同的
stack
值后 后一个系列的值会在前一个系列的值上相加。
1 | option = { |
项目正式使用
使用立即执行函数制作各个表格模块
立即执行函数优点:
- 不必为函数命名,避免了污染全局变量
- 立即执行函数内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量
- 封装变量
每个要制作图表的dom容器必须指定长宽
左上柱状图
官网找到类似实例, 适当分析,并且引入到HTML页面中
根据需求定制图表
修改图表柱形颜色
修改图表大小 top 为 10px bottom 为 4% grid决定我们的柱状图的大小
1
2
3
4
5
6
7
8color: ["#2f89cf"],
grid: {
left: "0%",
top: "10px",
right: "0%",
bottom: "4%",
containLabel: true //是否将文字标注也算进去
},X轴相关设置 xAxis
- 文本颜色设置为 rgba(255,255,255,.6) 字体大小为 12px
- X轴线的样式 不显示
- 修改data为自己的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28// X轴
xAxis: [{
type: "category", //X轴类型
data: [
"湖北",
"广东",
"江西",
"北京",
"上海",
"河北",
"浙江"
],
//刻度
axisTick: {
alignWithLabel: true
},
//刻度标签
axisLabel: {
textStyle: {
color: "rgba(255,255,255,.6)",
fontSize: '12'
}
},
//刻度线
axisLine: {
show: false
}
}],Y 轴相关定制
- 文本颜色设置为 rgba(255,255,255,.6) 字体大小为 12px
- Y 轴线条样式 更改为 1像素的 rgba(255,255,255,.1) 边框
- 分隔线的颜色修饰为 1像素的 rgba(255,255,255,.1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21yAxis: [{
type: "value",
axisLabel: {
textStyle: {
color: "rgba(255,255,255,.6)",
fontSize: '12'
}
},
axisLine: {
lineStyle: {
color: "rgba(255,255,255,.1)"
// width: 1,
// type: "solid"
}
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,.1)"
}
}
}],- 修改柱形为圆角以及柱子宽度 series 里面设置 添加数据
1
2
3
4
5
6
7
8
9
10
11//图表中心内容
series: [{
name: "直接访问",
type: "bar",
barWidth: "35%",
// fontSize: '8',
data: [200, 300, 300, 900, 1500, 1200, 600],
itemStyle: {
barBorderRadius: 5
}
}]- 让图表跟随屏幕自适应
1
2
3
4
5//图表跟随屏幕自适应
window.addEventListener('resize', function() {
myChart.resize();
})
})();- 完整代码
1 | //左上模块 |
柱状图2定制
- 官网找到类似实例, 适当分析,并且引入到HTML页面中
- 根据需求定制图表
需求1: 修改图形大小 grid
1 | // 图标位置 |
需求2: 不显示x轴
1 | xAxis: { |
需求3: y轴相关定制
不显示y轴轴线和相关刻度
y轴文字的颜色设置为白色
1 | //y轴 |
需求4:
修改第一组柱子相关样式(条状)
设置第一组柱子内百分比显示数据
设置第一组柱子不同颜色
1 | { |
需求5: 修改第二组柱子的相关配置(框状)
1 | { |
需求6: 给y轴添加第二组数据
1 | //定义右侧y坐标轴 |
需求7: 设置两组柱子层叠以及更换数据
1 | // 给series 第一个对象里面的 添加 |
完整代码:
1 | // 学习进度柱状图模块 |
折线图1 模块
- 官网找到类似实例, 适当分析,并且引入到HTML页面中
- 根据需求定制图表
需求1: 修改折线图大小,显示边框设置颜色:#012f4a,并且显示刻度标签。
1 | grid: { |
需求2: 修改图例组件中的文字颜色 #4c9bfd, 距离右侧 right 为 10%
1 | //图例模块 |
需求3: x轴相关配置
- 刻度去除
- x轴刻度标签字体颜色:#4c9bfd
- 剔除x坐标轴线颜色(将来使用Y轴分割线)
- 轴两端是不需要内间距 boundaryGap
1 | xAxis: { |
需求4: y轴的定制
- 刻度去除
- 字体颜色:#4c9bfd
- 分割线颜色:#012f4a
1 | yAxis: { |
需求5: 两条线形图定制
- 颜色分别:#00f2f1 #ed3f35
- 把折线修饰为圆滑 series 数据中添加 smooth 为 true
1 | series: [{ |
需求6: 配置数据
1 | // x轴的文字 |
1 | // 图表数据 |
需求7: 新增需求 点击 2020年 2021年 数据发生变化
以下是后台送过来数据(ajax请求过来的)
1 | var yearData = [ |
- tab栏切换事件
- 点击2020按钮 需要把 series 第一个对象里面的data 换成 2020年对象里面data[0]
- 点击2020按钮 需要把 series 第二个对象里面的data 换成 2020年对象里面data[1]
- 2021 按钮同样道理
1 | // 5.点击切换效果 |
完整代码(这里去掉年份需求):
1 | //折线图模块 |
折线图2模块
- 引入类似的官方示例
- 进行样式定制
更换图例组件文字颜色 rgba(255,255,255,.5) 文字大小为12
1 | legend: { |
修改图表大小
1 | grid: { |
修改x轴相关配置
- 修改文本颜色为rgba(255,255,255,.6) 文字大小为 12
- x轴线的颜色为 rgba(255,255,255,.2)
1 | // 文本颜色为rgba(255,255,255,.6) 文字大小为 12 |
修改y轴的相关配置
1 | yAxis: [{ |
修改两个线模块配置(注意在series 里面定制)
1 | series: [{ |
更换数据
1 | 没有 |
饼形图1模块
- 官网找到类似实例, 适当分析,并且引入到HTML页面中
- 根据需求定制图表
定制图表需求1:
- 修改图例组件在底部并且居中显示。
- 每个小图标的宽度和高度修改为 10px
- 文字大小为12 颜色 rgba(255,255,255,.5)
1 | legend: { |
定制需求2:
- 修改水平居中 垂直居中
- 修改内圆半径和外圆半径为 [“40%”, “60%”] pink老师友情提示,带有直角坐标系的比如折线图柱状图是 grid修改图形大小,而我们饼形图是通过 radius 修改大小
1 | series: [{ |
更换颜色
1 | color: [ |
完整代码
1 | (function() { |
饼形图(南丁格尔玫瑰图)
- 官网找到类似实例, 适当分析,并且引入到HTML页面中
- 根据需求定制图表
完整代码
1 | (function() { |
载入arcgis server 的地图服务
详细的教程可去官网: ArcGIS API for JavaScript
require
请求将所需模块加载进去,这里因为想调用arcgis online 中的某个地图,经查阅资料得出,通过调用该id号获取其底图(在调用arcgis online的底图时需要登录才能查看该id,详情可以看该教程),所以需要用到WebMap
模块。require以及底图加载代码如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27require([
//require写什么,后面参数必须按require的顺序写
"esri/WebMap",
"esri/views/MapView", //地图查看器模块
"esri/layers/FeatureLayer", //要素图层
"esri/layers/TileLayer"
], function(WebMap, MapView, FeatureLayer, TileLayer) {
//基础底图
// var map = new Map({
// basemap: "streets-night-vector" //底图样式
// });
//id号获取底图
var map = new WebMap({
portalItem: {
id: "bf024b8d0b4b48f5a486070214e87c5f" //ArcGIS Online
}
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [116.26, 24.2], // longitude, latitude 地理坐标
zoom: 3 //缩放程度s
});
})通过调用在arcgis server发布的地图服务url,将要显示的要素图层加载进去,然后在本地就可以浏览echarts和arcgis server结合的简单案例啦,调用url代码在回调函数中,如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14//添加Traiheads要素图层
var china = new FeatureLayer({
url: "http://localhost:6080/arcgis/rest/services/Text/text/MapServer", //url:....../1:行政区图层索引号
//数组存放标题和内容
outFields: ["Name", "性别比"],
//显示路径名称和弹出窗口的字段
popupTemplate: { // 启动弹出模板
"title": "{Name}", // 标题名
"content": "<p>该省性别比为</p> <p>{性别比}。</p>" // 弹出框文本内容
},
opacity: .4 //透明程度
});
map.add(china);成果
后台搭建服务器
整理好相关文件
创建整理文件夹
- public(存放js、css、图片文件)
- views(存放html页面)
下载所需基础模块(下载模块前记得初始化package文件)
- jQuery
- Bootstrap(可能用不到)
- body-parser(最后发现用不到)
- express
- mongoose(本来打算连接芒果数据库的数据,最后发现本地有一个json格式的疫情数据,就用不上这个模块了)
- art-template(模板引擎)
设计路由,因为这里简单只需用到渲染页面以及返回数据的路由,所以偷个懒
初始化app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33var express = require('express')
var app = express()
//引入fs模块,用来读取疫情数据
var fs = require('fs')
//body-parse中间件配置
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//模板引擎 engine后面没有r谢谢
app.engine('html', require('express-art-template'))
//开放静态资源
app.use('/public', express.static('./public/'))
app.use('/node_modules', express.static("./node_modules/"))
//首页渲染
app.get('/', (req, res) => {
})
//post请求返回疫情数据
app.post('/', (req, res) => {
})
//开放端口
app.listen(3000, () => {
console.log("server is running...")
})渲染页面(get路由)
1
2
3app.get('/', (req, res) => {
res.render('index.html')
})分析json文件
这里因为只需要中国地区城市的疫情数据,所以需要进行筛选
从数据可以看出,数组内第一个对象即为中国的疫情状况,所以这里直接读取第一个对象即可,用fs模块读取整个json文件,因为读取后的数据是json格式,使用json.parse将其转化为对象格式,再从里面的cities获取中国城市的疫情数据,记得读取文件时加上
utf8
参数,否则会出现乱码,下面放出代码1
2
3
4
5
6
7
8
9
10
11
12
13app.post('/', (req, res) => {
fs.readFile('./public/DXYArea.json', 'utf8', (err, data) => {
if (err) {
console.log('error')
}
// console.log(data)
var virus = JSON.parse(data).results
console.log(virus)
var cn = virus[0].cities
res.send(cn)
})
})到这里,后台搭建就准完毕,可以浏览器访问
localhost:3000
查看基础页面
ajax配合echarts使用
这里,其实思考过几种方法,一种是通过后台获取数据然后利用模板引擎将数据转到前端隐藏控件中去读取然后进行数据渲染,详情可参考这篇文章https://blog.csdn.net/tksnail/article/details/88096072,但是里面的数据较为简单,而这边是一整个对象数组,转到前端去就全部变成字符串类型,除非先在后台对数据进行处理,转成一个一个数组后传递到前端,但我想尝试在前端的Ajax中处理。所以自己摸索研究了一下
在放有echarts的js文件中,在想要引用数据的图表中,建立Ajax,代码如下
1
2
3
4
5
6
7
8$.ajax({
url: '/',
type: 'post',
data: {},
dataType: 'json',
success: function(data) {
console.log(data)
})分析数据,依旧是对象格式,这很棒,然后就想着怎么拿里面数据,这里要拿到城市名和疫情状况,字段名分别是
cityName
和confirmedCount
,这里在ajax外定义两个数组用来存放数据,,接着在通过for循环将数据存入数组1
2
3
4for (var i = 0; i < data.length; i++) {
city.push(data[i].cityName)
num.push(data[i].confirmedCount)
}最后需要重新配置图表用以更新数据
1
2
3
4
5
6
7
8
9
10//必须在这里在设置一遍,这里涉及到的问题不太懂,只知道如不再设置,而在ajax外赋值是没有作用的
myChart.setOption({ //加载数据图表
xAxis: {
data: city
},
series: [{
// 根据名字对应到相应的系列
data: num
}]
})完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26var city = []
var num = []
$.ajax({
url: '/',
type: 'post',
data: {},
dataType: 'json',
success: function(data) {
console.log(data)
for (var i = 0; i < data.length; i++) {
city.push(data[i].cityName)
num.push(data[i].confirmedCount)
}
// myChart.hideLoading()
//必须在这里在设置一遍,这里涉及到的问题不太懂(可能是同步异步的问题,后面再去补齐这一部分理论),只知道如不再设置,而在ajax外赋值是没有作用的
myChart.setOption({ //加载数据图表
xAxis: {
data: city
},
series: [{
// 根据名字对应到相应的系列
data: num
}]
})
}
})这里,echarts搭配node以及ajax的学习过程就完成啦,后面会将整个疫情地图的小项目完成放在自己的博客上。