数据同比的效果如下
下面介绍其前端代码,先看html页面,使用boostrap作为样式和布局,引入了bootstrap-daterangepicker插件作为日期范围选择面板,引入select2插件作为下拉选择列表,引入moment作为时间格式化工具,引入echarts作为图表库:
代码语言:html复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>传感器异常分析</title>
<!-- Bootstrap core CSS -->
<link href="dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="dist/lib/font-awesome/css/font-awesome.min.css">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
<!-- daterange picker -->
<link rel="stylesheet" href="dist/lib/bootstrap-daterangepicker/daterangepicker.css">
<!-- Select2 -->
<link rel="stylesheet" href="dist/lib/select2/dist/css/select2.min.css">
<!-- Custom styles for this template -->
<link href="css/index.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="assets/js/ie-emulation-modes-warning.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script type="text/template" id="selectDevNamesTemplate">
<%_.each(items,function(item){ %>
<option value='<%=item["name"]%>' ><%=item["text"]%></option>
<%})%>
</script>
<script type="text/template" id="selectDevUnitsTemplate">
<%_.each(items,function(item){ %>
<option value='<%=item["name"]%>' ><%=item["text"]%></option>
<%})%>
</script>
<script type="text/template" id="alertTemplate">
<div class="alert alert-danger alert-dismissible fade in" role="alert" id="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<strong><%=devName%>没有<%=devUnit%>数据!</strong>
</div>
</script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label>因子</label>
<select class="form-control select2" style="width: 100%;" id="devUnits">
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label>站点</label>
<select class="form-control select2" style="width: 100%;" id="devNames">
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label>选择时间范围:</label>
<div class="input-group">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right" id="daterange">
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>查询数据:</label>
<button type="submit" id="submit" class="btn btn-default">查询数据</button>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>开启图例:</label>
<button class="btn btn-success" type="button" aria-expanded="false" id="legend">
图例开关
</button>
</div>
</div>
</div>
<div class="row" id="alert">
</div>
<div class="row">
<table class="table table-bordered table-striped responsive-utilities" id="weekTable">
<thead>
<tr>
<th>
星期过滤
</th>
<th>
<button type="button" class="btn btn-success" aria-haspopup="true" aria-expanded="false" data-day=0>周日</button>
</th>
<th>
<button type="button" class="btn btn-success" aria-haspopup="true" aria-expanded="false" data-day=1>周一</button>
</th>
<th>
<button type="button" class="btn btn-success" aria-haspopup="true" aria-expanded="false" data-day=2>周二</button>
</th>
<th>
<button type="button" class="btn btn-success" aria-haspopup="true" aria-expanded="false" data-day=3>周三</button>
</th>
<th>
<button type="button" class="btn btn-success" aria-haspopup="true" aria-expanded="false" data-day=4>周四</button>
</th>
<th>
<button type="button" class="btn btn-success" aria-haspopup="true" aria-expanded="false" data-day=5>周五</button>
</th>
<th>
<button type="button" class="btn btn-success" aria-haspopup="true" aria-expanded="false" data-day=6>周六</button>
</th>
</tr>
</thead>
</table>
</div>
<div class="row">
<div class="jumbotron" id="chart">
</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="dist/lib/jquery/dist/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="assets/js/vendor/jquery.min.js"></script>')
</script>
<script src="dist/lib/underscore.js"></script>
<script src="dist/lib/backbone.js"></script>
<script src="dist/js/bootstrap.min.js"></script>
<!-- Select2 -->
<script src="dist/lib/select2/dist/js/select2.full.min.js"></script>
<!-- date-range-picker -->
<script src="dist/lib/moment/min/moment.min.js"></script>
<script src="dist/lib/bootstrap-daterangepicker/daterangepicker.js"></script>
<!-- bootstrap datepicker -->
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="assets/js/ie10-viewport-bug-workaround.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.2.1/echarts.min.js"></script>-->
<script src="https://echarts.baidu.com/examples/vendors/echarts/echarts.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>
再看一下js代码:
代码语言:javascript复制 $(function () {
$('#chart').css('height', parseInt($('.container').css('height').substring(0, $('.container').css('height').length - 2) * 0.78) "px")
var myChart = echarts.init(document.getElementById('chart'));
// 指定图表的配置项和数据
var data = [[15, 0], [-50, 10], [-56.5, 20], [-46.5, 30], [-22.1, 40]];
var option = {
title: {
text: ''
},
legend: {
orient: 'horizontal',
align: 'left',
data: [],
x: 'left',
show: true,
},
tooltip: {
formatter: function (params) {
var data = params.data || [0, 0];
var value = data[0];
var name = params.seriesName;
return name " 时间:" parseInt(value / 60) ":" parseInt(value % 60) " 数据:" data[1];
}
},
dataZoom: [
{
show: true,
realtime: true,
labelFormatter: function (value) {
return parseInt(value / 60) "点" parseInt(value % 60);
}
},
{
type: 'inside',
realtime: true,
labelFormatter: function (value) {
return parseInt(value / 60) "点" parseInt(value % 60);
}
}
],
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value',
axisLine: {
onZero: false
},
axisLabel: {
formatter: function (value, index) {
return parseInt(value / 60) "点" parseInt(value % 60);
}
},
max: 24 * 60 - 1
},
yAxis: {
type: 'value',
axisLine: {
onZero: false
}
},
series: [
]
};
var series = {
id: '',
name: '',
type: 'line',
smooth: true,
symbolSize: 5,
data: []
};
window.devs = null;
//取得设备信息
$.getJSON('http://..../devs', function (data) {
data = $.parseJSON(data.result);
//返回数据格式处理
//提取传感器信息
devs = _.map(_.zip(_.values(data.devId), _.values(data.devName), _.values(data.devUnit)), function (item) {
return {
'devId': item[0],
'devName': item[1],
'devUnit': item[2]
}
});
//提取传感器单位,根据数据生成单位下拉列表
var devUnits = _.unique(_.values(data.devUnit));
$('#devUnits').html(_.template($('#selectDevUnitsTemplate').html())({
items: devUnits.map(function (item) {
return {
'name': item,
'text': item
}
})
}));
//提取设备名称,根据数据生成名称下拉列表
var devNames = _.unique(_.values(data.devName));
$('#devNames').html(_.template($('#selectDevNamesTemplate').html())({
items: devNames.map(function (item) {
return {
'name': item,
'text': item
}
})
}));
console.log(data);
$('.select2').select2();
});
//生成日期范围选择控件
$('#daterange').daterangepicker({
locale: {
format: "YYYY-MM-DD",
separator: ' - ',
applyLabel: '应用',
cancelLabel: '取消',
monthNames: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
daysOfWeek: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
}
});
//控制图例显示与否
$("#legend").click(function () {
$(this).toggleClass('btn-success').toggleClass('btn-default');
if ($(this).hasClass("btn-success")) {
option.legend.show = true;
} else {
option.legend.show = false;
}
myChart.setOption(option);
});
//查询数据,处理数据格式,生成图表
//因为要将每一天的数据作为一条曲线,所以要将返回的日期范围内的数据根据日期汇总
//又因为每一天的数据时间列不对齐,没有选择date类型的X轴,而使用value类型的X轴
//需要用moment将时间格式转换为时间戳数字类型,这里数据基于分钟的,所以最后转换为一天内的分钟总数。
//然后自定义axisLabel,dataZoom 和tooltip的格式来将时间戳显示为时间。
$('#submit').click(function () {
var dev = _.find(devs, {
devName: $('#devNames').val(),
devUnit: $('#devUnits').val()
});
if (!dev) {
$('#alert').prepend(_.template($('#alertTemplate').html())({
devName: $('#devNames').val(),
devUnit: $('#devUnits').val()
}));
return;
}
$('#weekTable').find('button').addClass("btn-success").removeClass("btn-default");
myChart.showLoading();
$.getJSON('http://..../data', {
dev: dev['devId'],
startDate: $('#daterange').val().split(' - ')[0],
endDate: $('#daterange').val().split(' - ')[1]
}, function (data) {
data = $.parseJSON(data.result);
data = _.map(_.zip(_.values(data.recDateTime), _.values(data.DevData)), function (item) {
return {
'time': item[0],
'value': item[1]
}
});
window.data2 = _.groupBy(data, function (item) {
return item['time'].split(' ')[0]
});
var serieses = _.map(data2, function (item1, index1) {
var seriesData = _.map(item1, function (item2) {
var time = moment(item2['time']);
return [time.hour() * 60 time.minute(), item2['value']]
});
var series0 = _.clone(series);
series0.id = index1;
series0.name = index1;
series0.data = seriesData;
return series0;
});
option.yAxis.min = _.min(_.pluck(_.flatten(_.values(data2)), 'value')) * 0.8;
option.series = serieses;
option.legend.data = _.keys(data2);
option.legend.show = $("#legend").hasClass('btn-success');
myChart.hideLoading();
myChart.clear();
myChart.setOption(option);
})
});
//根据星期过滤echarts的图例,然后触发它们的选择和取消选择事件
$('#weekTable').delegate('button', 'click', function (item) {
var day = $(this).data('day');
$(this).toggleClass("btn-success").toggleClass("btn-default");
var dates = _.filter(_.keys(data2), function (item) {
return moment(item).day() == day;
});
if ($(this).hasClass("btn-success")) {
_.each(dates, function (item) {
myChart.dispatchAction({
type: 'legendSelect',
name: item
});
});
} else {
_.each(dates, function (item) {
myChart.dispatchAction({
type: 'legendUnSelect',
name: item
});
});
}
});
window.onresize = function () {
myChart.resize();
}
})
最后附上样式文件
代码语言:css复制html,
body {
height: 100%;
padding: 0;
margin: 0;
}
#chartRow {
height: 100%;
width: 100%;
}
#chart {
position: relative;
overflow: hidden;
width: 100%;
height: 600px;
padding-bottom: 10px;
padding: 0px;
margin: 0px;
border-width: 0px;
cursor: default;
}
#weekTable th {
text-align: center;
}
.daterangepicker.ltr .calendar.right {
margin-left: 25px;
}