JavaScript+ECharts实现大屏数据可视化
JavaSctipt+ECharts实现大屏数据可视化
本文利用纯JS语言+ECharts实现对数据的可视化(目前数据是静态的,后期如果有时间,会增加和数据库的交互)
最终结果如下图所示:
实现过程
1 项目适配
对屏幕的不同尺寸实现适配,文件放在js/flexible.js下(这里用到了立即执行函数) 代码片
.
(function flexible(window, document) {
// 获取的html 的根元素
var docEl = document.documentElement
// dpr 物理像素比,可以在浏览器控制台查看对应的dpr
var dpr = window.devicePixelRatio || 1
// 设置我们body 的字体大小
function setBodyFontSize() {
// 如果页面中有body 这个元素 就设置body的字体大小
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
} else {
// 如果页面中没有body 这个元素,则等着 我们页面主要的DOM元素加载完毕再去设置body的字体大小
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 24 设置我们html 元素的文字大小 将整个页面划分成多少等份
function setRemUnit() {
var rem = docEl.clientWidth / 24
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize 当我们页面尺寸大小发生变化的时候,要重新设置下rem 的大小
window.addEventListener('resize', setRemUnit)
// pageshow 是我们重新加载页面触发的事件
window.addEventListener('pageshow', function(e) {
// e.persisted 返回的是true 就是说如果这个页面是从缓存取过来的页面,也需要从新计算一下rem 的大小
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports 有些移动端的浏览器不支持0.5像素的写法
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
2 搭建页面初始结构
将页面划分为3大部分,左,中,右(有很多冗余的代码,可以使用JS进行动态节点生成,减少代码量)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts数据可视化</title>
<script src="/js/07-flexible.js"></script>
<!-- <script src="./js//china.js"></script> -->
<link rel="stylesheet" href="./fonts/icomoon.css">
<link rel="stylesheet" href="/css/base.css">
<link rel="stylesheet" href="./css/index.less">
<link rel="stylesheet" href="./css/index.css">
<link rel="stylesheet" href="./fonts/style.css">
<script src="/js/echarts.min.js"></script>
<script src="/js/07-flexible.js"></script>
<script src="/js/jquery.min.js"></script>
<script src="/js/china.js"></script>
<script src="/js/bar.js"></script>
<!-- tab切换的js文件 -->
<style>
</style>
</head>
<body>
<div class="viewport">
<div class="column">
<div class="panel overview">
<div class="inner">
<ul>
<li>
<h4>2,190</h4>
<span>
<i class="iconfont icon-dot"></i>
设备总数
</span>
</li>
<li>
<h4>190</h4>
<span>
<i class="iconfont icon-dot" style="color: #6acca3;"></i>
季度新增
</span>
</li>
<li>
<h4>3,001</h4>
<span>
<i class="iconfont icon-dot"></i>
运营设备
</span>
</li>
<li>
<h4>108</h4>
<span>
<i class="iconfont icon-dot" style="color: #ed3f35;"></i>
异常设备
</span>
</li>
</ul>
</div>
</div>
<div class="panel monitor">
<div class="inner">
<div class="tabs">
<a href="javascript:;" class="active" index="0">故障设备监控</a>
<a href="javascript:;" index="1" >异常设备监控</a>
</div>
<div class="content" style="display: block;">
<div class="header">
<span class="col">故障时间</span>
<span class="col">设备地址</span>
<span class="col">异常代码</span>
</div>
<div class="marquee-view">
<div class="marquee">
<div class="row">
<span class="col">20180701</span>
<span class="col">11北京市昌平西路金燕龙写字楼</span>
<span class="col">1000001</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190601</span>
<span class="col">北京市昌平区城西路金燕龙写字楼</span>
<span class="col">1000002</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190704</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000003</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20180701</span>
<span class="col">北京市昌平区建路金燕龙写字楼</span>
<span class="col">1000004</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000005</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000006</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建西路金燕龙写字楼</span>
<span class="col">1000007</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000008</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000009</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190710</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000010</span>
<span class="icon-dot"></span>
</div>
</div>
</div>
</div>
<div class="content">
<div class="header">
<span class="col">异常时间</span>
<span class="col">设备地址</span>
<span class="col">异常代码</span>
</div>
<div class="marquee-view">
<div class="marquee">
<div class="row">
<span class="col">20180701</span>
<span class="col">11北京市昌平西路金燕龙写字楼</span>
<span class="col">1000001</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190601</span>
<span class="col">北京市昌平区城西路金燕龙写字楼</span>
<span class="col">1000002</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190704</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000003</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20180701</span>
<span class="col">北京市昌平区建路金燕龙写字楼</span>
<span class="col">1000004</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000005</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000006</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建西路金燕龙写字楼</span>
<span class="col">1000007</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000008</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190701</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000009</span>
<span class="icon-dot"></span>
</div>
<div class="row">
<span class="col">20190710</span>
<span class="col">北京市昌平区建材城西路金燕龙写字楼</span>
<span class="col">1000010</span>
<span class="icon-dot"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="panel point">
<div class="inner">
<h3>点位分布统计</h3>
<div class="chart">
<div class="pie"></div>
<div class="data">
<div class="item">
<h4>320,11</h4>
<span><i class="icon-dot" style="color: #ed3f35;"></i>点位总数</span>
</div>
<div class="item">
<h4>418</h4>
<span><i class="icon-dot" style="color: #eacf19;"></i>本月新增</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="column">
<div class="map">
<div class="map1"></div>
<div class="map2"></div>
<div class="map3"></div>
<div class="chart"></div>
</div>
<div class="total panel">
<div class="inner">
<h3>全国用户总量统计</h3>
<div class="chart">
<div class="bar"></div>
<div class="data">
<div class="item">
<h4>120,899</h4>
<span><i class="icon-dot" style="color: #ed3f35;"></i>用户总量</span>
</div>
<div class="item">
<h4>248</h4>
<span><i class="icon-dot" style="color: #eacf19;"></i>本月新增</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="column">
<div class="order panel">
<div class="inner">
<div class="tabs">
<a href="javascript:;" class="active">365天</a>
<a href="javascript:;">90天</a>
<a href="javascript:;">30天</a>
<a href="javascript:;">24小时</a>
</div>
<div class="content" style="display:block">
<ul>
<li>
<h4>20,301,987</h4>
<span><i class="icon-dot" style="color: #ed3f35;" ></i>订单量</span>
</li>
<li>
<h4>99,834</h4>
<span><i class="icon-dot" style="color: #eacf19;"></i>销售额(万元)</span>
</li>
</ul>
</div>
<div class="content" >
<ul>
<li>
<h4>2,301,987</h4>
<span><i class="icon-dot" style="color: #ed3f35;" ></i>订单量</span>
</li>
<li>
<h4>9,834</h4>
<span><i class="icon-dot" style="color: #eacf19;"></i>销售额(万元)</span>
</li>
</ul>
</div>
<div class="content" >
<ul>
<li>
<h4>301,987</h4>
<span><i class="icon-dot" style="color: #ed3f35;" ></i>订单量</span>
</li>
<li>
<h4>834</h4>
<span><i class="icon-dot" style="color: #eacf19;"></i>销售额(万元)</span>
</li>
</ul>
</div>
<div class="content" >
<ul>
<li>
<h4>987</h4>
<span><i class="icon-dot" style="color: #ed3f35;" ></i>订单量</span>
</li>
<li>
<h4>34</h4>
<span><i class="icon-dot" style="color: #eacf19;"></i>销售额(万元)</span>
</li>
</ul>
</div>
</div>
</div>
<div class="sales panel">
<div class="inner">
<div class="header">
<h3>销售额统计</h3>
<ul>
<li class="active" type="year">年</li>
<li type="quarter">季</li>
<li type="month">月</li>
<li type="week">周</li>
</ul>
</div>
<div class="chart">
<div class="line"></div>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="./js/monitor.js"></script>
<script src="./js/point.js"></script>
<script src="./js/map.js"></script>
<script src="./js/order.js"></script>
<script src="./js/sale.js"></script>
</html>
3 对页面进行CSS初始化
写前端页面,第一步都会将页面上初始的样式去除,然后在添加自己的样式,存放在css/base.css中。可以看到最终的实现效果,每个小部分的边框都是一样的,所以这里用到了一个很重要的知识是–边框图片。通过给边框设置图片,来实现这个样式。
/*清楚元素默认的内外边距*/
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
/*让所有斜体不倾斜*/
em,i{
font-style: normal;
}
/*去掉列表前面的小点*/
li{
list-style: none;
}
/*图片没有边框 去掉图片底侧的空白间隙*/
img{
border: 0;
vertical-align: middle;
}
/*让button按钮变成小手*/
button{
cursor: pointer;
}
/*去掉a链接的下划线 以及设置颜色*/
a{
text-decoration: none;
color:#666;
}
a:hover{
color: red;
}
h4{
font-weight: normal;
}
/* 控制屏幕的缩放 实现rem适配 */
@media screen and (max-width:1024px) {
html{
font-size: 42.66px !important;
}
}
@media screen and (min-width:1920px) {
html{
font-size: 80px !important;
}
}
/* 给body设置背景图片 */
body{
background: url("/img/bg.jpg") no-repeat;
background-size: cover;
}
/* 公共面板样式 */
.panel{
/* 父元素定位是相对定位,子元素绝对定位才能修改 */
position: relative;
/* 必须指定边框,不然边框图片不生效 */
border: 15px solid transparent;
border-image-source: url("../img/border.png");
/* 边框切割 */
border-image-slice: 51 38 20 132;
border-image-repeat: stretch;
/* 给了边框的宽度,就不需要给边框图片的宽度了 */
border-width: .6375rem .475rem .25rem 1.65rem;
margin-bottom: .25rem;
}
.panel h3{
font-size: .25rem;
color: white;
}
/* 内侧的盒子 */
.inner{
position: absolute;
top: -0.6375rem;
right: -0.475rem;
bottom: -0.25rem;
left: -1.65rem;
padding: .3rem .45rem;
}
对项目的初始化到此结束,剩下的部分在后面的进行展示。(这个项目的实现难点,其实是在JS部分)