一、前言
近来参与的一个电力大数据项目,用户数据达到 50+G
在该项目编程中,笔者参与后台业务,也参与前端 JS 交互。
开发过程,经历众多问题,但最后都解决了,下面简单前后端各列举一个难点,并给出具体可行的解决方案。
1.后台最大的难度,在于如何快速提取数据
,传递给前端。
快速:
① 数据库表拆分(提高范式…)
② 使用缓存(Redis…)
③ 使用分布式架构(Dubbo、SpringCloud…)
④ MySQL 数据库拆分(阿里云 RDS…)
⑤ SQL优化(使用存储过程、减少循环层数…)
⑥ …
2.前端最大的难度,在于如何将后台传来的数据可视化
。
可视化:
① hightchart:http://www.hcharts.cn/
② echart:http://echarts.baidu.com/
③ elelmentUI:https://github.com/ElemeFE/element
④ 优化后台传来的 JSON 数据格式,减少前端业务逻辑
⑤ 使用 MVC、MVVM 框架处理数据(AngularJS、Vue…)
⑥ …
二、代码
由于隐私的问题
下面提取项目中一小部分的代码,作为示例(原项目使用来 layui 辅助做界面,笔者尽量删除无关的代码了)
1.前端:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>全局用电类别分析</title>
<link rel="stylesheet" href="../../layui/css/layui.css">
<link rel="stylesheet" href="../../bootstrap/dist/css/bootstrap.css">
</head>
<body class="layui-layout-body" ng-app="news" ng-controller="contro">
<div class="layui-layout layui-layout-admin">
<div class="layui-body">
<!--2、主体内容-->
<div>
<fieldset class="layui-elem-field layui-field-title" >
<legend style="font-weight: bold">全局用电类别分析</legend>
</fieldset>
<div style="padding: 20px; background-color: #F2F2F2;">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-header" style="text-align: center;font-weight: bold;font-size: 15px">总用电量时间序列变化图</div>
<div class="layui-card-body">
<div style="min-height: 360px" id="plot01"></div>
<hr class="layui-bg-blue">
<i class="layui-icon layui-icon-read"><strong style="font-size: 15px"> 分析:</strong></i>
<p style="padding-left: 36px">无</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="../../layui/layui.js"></script>
<script>
//JavaScript代码区域
layui.use('element', function(){
var element = layui.element;
});
</script>
<!--绘图-->
<script type="text/javascript" src="../../Echarts/js/echarts.js"></script>
<script type="text/javascript" src="../../Echarts/theme/shine.js"></script>
<script type="text/javascript" src="../../Echarts/theme/dark.js"></script>
<script type="text/javascript" src="../../Echarts/theme/infographic.js"></script>
<script type="text/javascript" src="../../Echarts/theme/macarons.js"></script>
<script type="text/javascript" src="../../Echarts/theme/roma.js"></script>
<script type="text/javascript" src="../../Echarts/theme/vintage.js"></script>
<script src="../../js/angular.js" type="text/javascript"></script>
<!-- 绘制图plot01 -->
<script type="text/javascript">
var app2 = angular.module('news',[]);
app2.controller('contro',function($scope,$http){
$http.get('/analysis1/getZYDLofYSYCLX').then(function(res1){
var dom = document.getElementById("plot01");
var myChart = echarts.init(dom,'macarons');
var app = {};
option = null;
app.title = '多 X 轴示例';
var colors = ['#5793f3', '#d14a61', '#675bba']
option = {
color: colors,
tooltip: {
trigger: 'none',
axisPointer: {
type: 'cross'
}
},
legend: {
//data:['A局', 'B局','C局', 'D局','E局', 'F局','G局'],
data:res1.data.data.allGDJName,
selected: {
//'D局': false, 'E局': false, 'F局': false, 'G局': false
}
},
grid: {
top: 70,
bottom: 50
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLine: {
onZero: false,
lineStyle: {
color: colors[1]
}
},
axisPointer: {
label: {
formatter: function (params) {
return '用电量 ' + params.value
+ (params.seriesData.length ? ':' + params.seriesData[0].data : '');
}
}
},
//data: ["2016-1", "2016-2", "2016-3", "2016-4", "2016-5", "2016-6", "2016-7", "2016-8", "2016-9", "2016-10", "2016-11", "2016-12"]
data: res1.data.data.month
},
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLine: {
onZero: false,
lineStyle: {
color: colors[0]
}
},
axisPointer: {
label: {
formatter: function (params) {
return '用电量 ' + params.value
+ (params.seriesData.length ? ':' + params.seriesData[0].data : '');
}
}
},
data: []//["2015-1", "2015-2", "2015-3", "2015-4", "2015-5", "2015-6", "2015-7", "2015-8", "2015-9", "2015-10", "2015-11", "2015-12"]
}
],
yAxis: [
{
type: 'value'
}
],
series: res1.data.data.partMonthCountVOs
};
;
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
});
});
</script>
</body>
</html>
2.后台
http://localhost:8080/analysis1/getZYDLofYSYCLX
后台使用 springboot + mybatisplus
代码逻辑本来可以很简单的,为了使前端 0 逻辑,不得不搞得逻辑相当混乱,就不分享了,直接分享接口数据
{
"code": "200",
"msg": "操作成功",
"data": {
"month": [
"2017-07",
"2017-08",
"2017-09",
"2017-10",
"2017-11",
"2017-12",
"2018-01",
"2018-02",
"2018-03",
"2018-04",
"2018-05",
"2018-06"
],
"partMonthCountVOs": [
{
"name": "类别0",
"type": "line",
"smooth": true,
"data": [
53571,
25591,
97527,
22906,
53045,
15177,
47385,
15530,
70228,
7603,
96184,
13639
]
},
{
"name": "类别1",
"type": "line",
"smooth": true,
"data": [
4971,
29001,
6897,
6812,
52943,
2246,
1734,
15418,
169,
472,
15508,
1706
]
},
{
"name": "类别2",
"type": "line",
"smooth": true,
"data": [
1951,
9209,
17120,
1310,
30731,
2058,
7549,
157,
1398,
1691,
1736,
24915
]
},
{
"name": "类别3",
"type": "line",
"smooth": true,
"data": [
532,
14383,
10,
5037,
66,
1102,
458,
25286,
1526,
10651,
677,
2237
]
},
{
"name": "类别4",
"type": "line",
"smooth": true,
"data": [
969,
895,
17139,
63,
56257,
66,
54376,
728,
332,
24705,
374,
990
]
},
{
"name": "类别5",
"type": "line",
"smooth": true,
"data": [
885,
12002,
737,
66297,
193,
8518,
18674,
4182,
4415,
28546,
24706,
4246
]
}
],
"allGDJName": [
"类别0",
"类别1",
"类别2",
"类别3",
"类别4",
"类别5"
]
}
}