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部分)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐