html代码如下:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<title></title>
<!-- CSS only -->
<link href="/static/lib/bootstrap-5.1.3-dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/lib/daterangepicker/daterangepicker.css" rel="stylesheet">
<link rel="stylesheet" href="/static/lib/bootstrap-5.1.3-dist/css/bootstrap-icons.css">
<style>
#tableForecast {
display: grid;
}
#aqiBarLineChart {
height: 400px;
}
#optionsForm label {
float: right;
font-size: 20px;
}
thead {
border-width: 1px 1px;
/* background: #00BC80;*/
background: #BAD3F2;
}
.form-label {
margin-top: 8px;
}
th,
td {
text-align: center;
vertical-align: middle;
}
th {
font-size: 14px;
}
th.group,
td[data-group] {
min-width: 60px;
max-width: 60px;
}
th.site,
td[data-site] {
min-width: 80px;
max-width: 80px;
}
td[data-site] {
color: #0d6efd;
text-decoration: #0d6efd 2px underline;
cursor: pointer;
}
th.min,
td[data-col=min] {
min-width: 50px;
max-width: 50px;
}
th.max,
td[data-col=max] {
min-width: 50px;
max-width: 50px;
}
th.value,
td[data-col=value] {
min-width: 50px;
max-width: 50px;
}
th.primary,
td[data-col=primary] {
min-width: 50px;
max-width: 50px;
}
td[data-col="min"] {
border-left: 3px solid black;
}
#divLegend {
font-size: 16px;
color: black;
}
#divLegend span[data-color="white"] {
color: white;
}
table {
display: block;
}
.tableBody thead {
visibility: collapse;
}
.tableBody {
max-height: 800px;
overflow-y: auto;
}
.tableHead {
margin-bottom: 0px;
}
#title {
text-align: center;
font-size: 28px;
margin: 10px;
}
.table-hover>tbody>tr:hover>* {
color: blue;
}
</style>
<script type="text/templat" id="legendTemplate">
<% var i=0;%>
<span data-color="color" style="background:<%=levelColors[i++]%>;"><<%=first%></span>
<%_.each(between,function(item,index){%>
<span <%if(index==between.length-1)%>data-color="white" <%;%>style="background:<%=levelColors[i++]%>;"><%=item[0]%>~<%=item[1]%></span>
<%});%>
<span data-color="white" style="background:<%=levelColors[i]%>;">><%=last%></span>
<span>单位:<%=dictUnit[factor]%></span>
<span style='color:red;float: right;'>(预报未来7日趋势,点击城市名称可以查看趋势图表)</span>
</script>
<script type="text/template" id="cityForecastAQITableTemplate">
<table class="table table-bordered border-secondary tableHead">
<thead class='thead'>
<tr>
<th class="group region" rowspan="2">
<b>区域</b></th>
<th class="site city" rowspan="2">
<b>城市</b></th>
<% _.each(dates,function(date){ %>
<% if(factor=='AQI') %>
<th class="date" colspan="4">
<b><%=date%></b>
</th>
<% ;%>
<% if(factor!='AQI') %>
<th class="date" colspan="3">
<b><%=date%></b>
</th>
<% ;%>
<% }) %>
</tr>
<tr>
<% _.each(dates,function(date){ %>
<th class="min">
<b>最小</b></th>
<th class="max">
<b>最大</b></th>
<th class="value">
<b><%="平均"||dictFactor[factor]%></b>
</th>
<% if(factor=='AQI') %>
<th class="primary">
<b>首污</b>
</th>
<% ;%>
<% })%>
</tr>
</thead>
</table>
<table class="table table-bordered border-secondary tableBody table-hover">
<thead class='thead'>
<tr>
<th class="group region" rowspan="2">
<b>区域</b></th>
<th class="site city" rowspan="2">
<b>城市</b></th>
<% _.each(dates,function(date){ %>
<% if(factor=='AQI') %>
<th class="date" colspan="4">
<b><%=date%></b>
</th>
<% ;%>
<% if(factor!='AQI') %>
<th class="date" colspan="3">
<b><%=date%></b>
</th>
<% ;%>
<% }) %>
</tr>
<tr>
<% _.each(dates,function(date){ %>
<th class="min">
<b>最小</b></th>
<th class="max">
<b>最大</b></th>
<th class="value">
<b><%="平均"||dictFactor[factor]%></b>
</th>
<% if(factor=='AQI') %>
<th class="primary">
<b>首污</b>
</th>
<% ;%>
<% })%>
</tr>
</thead>
<tbody>
<% _.each(groups,function(group,rIndex){ %>
<% var sites=group['citys'] %>
<% _.each(sites,function(site,cIndex){ %>
<tr data-site="<%=site['code']%>">
<% if(cIndex==0) %>
<td class="td" rowspan="<%=sites.length%>" data-group="<%=group['code']%>"><%=group['name']%></td>
<% ;%>
<td class="td" class="td-site" data-site="<%=site['code']%>"><a onclick="javascript:void(0);"><%=site['name']%></a></td>
<% _.each(dates,function(date,dIndex){ %>
<td class="td" data-col="min" data-date="<%=date%>">0</td>
<td class="td" data-col="max" data-date="<%=date%>">0</td>
<td class="td" data-col="value" data-date="<%=date%>">0</td>
<% if(factor=='AQI') %>
<td class="td" data-col="primary" data-date="<%=date%>">0</td>
<% ;%>
<% }); %>
</tr>
<% }); %>
<% }); %>
</tbody>
</table>
</script>
<script type="text/template" id="stationForecastAQITableTemplate">
<table class="table table-bordered border-secondary tableHead">
<thead class='thead'>
<tr>
<th class="group city" rowspan="2">
<b>城市</b></th>
<th class="site station" rowspan="2">
<b>站点</b></th>
<% _.each(dates,function(date){ %>
<% if(factor=='AQI') %>
<th class="date" colspan="4">
<b><%=date%></b>
</th>
<% ;%>
<% if(factor!='AQI') %>
<th class="date" colspan="3">
<b><%=date%></b>
</th>
<% ;%>
<% }) %>
</tr>
<tr>
<% _.each(dates,function(date){ %>
<th class="min">
<b>最小</b></th>
<th class="max">
<b>最大</b></th>
<th class="value">
<b><%="平均"||dictFactor[factor]%></b>
</th>
<% if(factor=='AQI') %>
<th class="primary">
<b>首污</b>
</th>
<% ;%>
<% })%>
</tr>
</thead>
</table>
<table class="table table-bordered border-secondary tableBody table-hover">
<thead class='thead'>
<tr>
<th class="group city" rowspan="2">
<b>城市</b></th>
<th class="site station" rowspan="2">
<b>站点</b></th>
<% _.each(dates,function(date){ %>
<% if(factor=='AQI') %>
<th class="date" colspan="4">
<b><%=date%></b>
</th>
<% ;%>
<% if(factor!='AQI') %>
<th class="date" colspan="3">
<b><%=date%></b>
</th>
<% ;%>
<% }) %>
</tr>
<tr>
<% _.each(dates,function(date){ %>
<th class="min">
<b>最小</b></th>
<th class="max">
<b>最大</b></th>
<th class="value">
<b><%="平均"||dictFactor[factor]%></b>
</th>
<% if(factor=='AQI') %>
<th class="primary">
<b>首污</b>
</th>
<% ;%>
<% })%>
</tr>
</thead>
<tbody>
<% _.each(groups,function(group,rIndex){ %>
<% var sites=group['stations'] %>
<% _.each(sites,function(site,cIndex){ %>
<tr data-site="<%=site['code']%>">
<% if(cIndex==0) %>
<td class="td" rowspan="<%=sites.length%>" data-group="<%=group['code']%>"><%=group['name']%></td>
<% ;%>
<td class="td" class="td-site" data-site="<%=site['code']%>"><%=site['name']%></td>
<% _.each(dates,function(date,dIndex){ %>
<td class="td" data-col="min" data-date="<%=date%>">0</td>
<td class="td" data-col="max" data-date="<%=date%>">0</td>
<td class="td" data-col="value" data-date="<%=date%>">0</td>
<% if(factor=='AQI') %>
<td class="td" data-col="primary" data-date="<%=date%>">0</td>
<% ;%>
<% }); %>
</tr>
<% }); %>
<% }); %>
</tbody>
</table>
</script>
<script type="text/template" id="cityForecastWeatherTableTemplate">
<table class="table table-bordered border-secondary tableHead">
<thead class='thead'>
<tr>
<th class="group region" rowspan="2">
<b>区域</b></th>
<th class="site city" rowspan="2">
<b>城市</b></th>
<% _.each(dates,function(date){ %>
<th class="date" colspan="3">
<b><%=date%></b>
</th>
<% }) %>
</tr>
<tr>
<% _.each(dates,function(date){ %>
<th class="min">
<b>最小</b></th>
<th class="max">
<b>最大</b></th>
<th class="value">
<b><%="平均"||dictFactor[factor]%></b>
</th>
<% })%>
</tr>
</thead>
</table>
<table class="table table-bordered border-secondary tableBody table-hover">
<thead class='thead'>
<tr>
<th class="group region" rowspan="2">
<b>区域</b></th>
<th class="site city" rowspan="2">
<b>城市</b></th>
<% _.each(dates,function(date){ %>
<th class="date" colspan="3">
<b><%=date%></b>
</th>
<% }) %>
</tr>
<tr>
<% _.each(dates,function(date){ %>
<th class="min">
<b>最小</b></th>
<th class="max">
<b>最大</b></th>
<th class="value">
<b><%="平均"||dictFactor[factor]%></b>
</th>
<% })%>
</tr>
</thead>
<tbody>
<% _.each(groups,function(group,rIndex){ %>
<% var sites=group['citys'] %>
<% _.each(sites,function(site,cIndex){ %>
<tr data-site="<%=site['code']%>">
<% if(cIndex==0) %>
<td class="td" rowspan="<%=sites.length%>" data-group="<%=group['code']%>"><%=group['name']%></td>
<% ;%>
<td class="td" class="td-site" data-site="<%=site['code']%>"><%=site['name']%></td>
<% _.each(dates,function(date,dIndex){ %>
<td class="td" data-col="min" data-date="<%=date%>">0</td>
<td class="td" data-col="max" data-date="<%=date%>">0</td>
<td class="td" data-col="value" data-date="<%=date%>">0</td>
<% }); %>
</tr>
<% }); %>
<% }); %>
</tbody>
</table>
</script>
<script type="text/template" id="optionsTemplate">
<% _.each(rows,function(item){ %>
<option value="<%=item['code']%>"><%=item['name']%></option>
<% }) %>
</script>
</head>
<body>
<div class="container-fluid">
<div class="row" data-role="toolbar" data-menu="forecast" style="display: none;">
<div class="col-10">
<row class="row g-3 justify-content-start" style="display: flex;margin-top: 2px;">
<div class="col-2">
<label for="option_region" class="form-label" style="margin-left: 40px;">选择地区</label>
</div>
<div class="col-2">
<select class="form-select " aria-label="Default select example" id="option_region">
<option value="all" selected>全省</option>
<option value="region_226">2+26城市</option>
<option value="region_fenwei">汾渭平原</option>
<option value="region_boundary">苏皖鲁豫交界</option>
</select>
</div>
<div class="col-1">
<label for="selectCity" class="form-label">起报时间</label>
</div>
<div class="col-2">
<input type="date" class="form-control" id="option_date">
</div>
<div class="col-auto">
<label for="option_factor" class="form-label" style="margin-left: 40px;display: none;">因子</label>
</div>
<div class="col-auto">
<select class="form-select " aria-label="Default select example" id="option_factor" style="display: none;">
<option value="AQI">AQI</option>
<option value="PM10_24h">PM<sub>10</sub></option>
<option value="PM25_24h">PM<sub>2.5</sub></option>
<option value="SO2_24h">SO<sub>2</sub></option>
<option value="NO2_24h">NO<sub>2</sub></option>
<option value="CO_24h">CO</option>
<option value="O3_8h">O<sub>3</sub></option>
</select>
</div>
<div class="col-auto">
<label for="option_factor2" class="form-label" style="margin-left: 40px;display: none;">因子</label>
</div>
<div class="col-auto">
<select class="form-select " aria-label="Default select example" id="option_factor2" style="display: none;">
<option value="temp">温度</option>
<option value="humidity">湿度</option>
<option value="wind">风速</option>
<option value="rain">降水量</option>
<option value="boundary_height">边界层高度</option>
</select>
</div>
<div class="col-1">
<button type="button" class="btn btn-primary" id="option_submit">查 询</button>
</div>
<div class="col-1">
<button type="button" class="btn btn-secondary" id="option_export">导 出</button>
</div>
</row>
</div>
</div>
<div id="title"></div>
<div id="divLegend">
</div>
<div class="row" data-menu="forecast">
<div id="tableForecast" class="table-responsive ">
</div>
</div>
<hr>
<div class="row" data-menu="forecast" id="aqiBarLineDiv" style="display: none;">
<div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" checked name="periodType" id="inlineRadio1" value="hour">
<label class="form-check-label" for="inlineRadio1">小时</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="periodType" id="inlineRadio2" value="day">
<label class="form-check-label" for="inlineRadio2">日均</label>
</div>
</div>
<div id="aqiBarLineChart"></div>
</div>
</div>
<script src="/static/lib/jquery/jquery-1.11.3.js"></script>
<script src="/static/lib/underscore/underscore.js"></script>
<script src="/static/lib/bootstrap-5.1.3-dist/js/bootstrap.min.js"></script>
<script src="/static/lib/chartjs/chart.min.js"></script>
<script src="/static/lib/echarts/echarts.min.js"></script>
<script src="/static/lib/d3/d3.v5.min.js"></script>
<script src="/static/lib/moment/moment.min.js"></script>
<script src="/static/lib/moment/zh-cn.js"></script>
<script src="/static/lib/daterangepicker/daterangepicker.js"></script>
<script src="/static/lib/jquery-cookie/jquery.cookie.js"></script>
<script src="/static/js/base.js"></script>
<script src="/static/js/forecast.js"></script>
</body></html>
js代码如下:
引入JavaScript文件base.js如下:
window.args = _.object(window.location.search.replace('?', '').split('&').map(x => x.split('=')));
try {
if (this.parent.location.pathname == this.location.pathname) {
$('[data-role=toolbar]').show();
}
} catch {
}
//if(moment().hour()<21){
// location.href='www.baidu.com';
//}
function refreshOptions() {
var option = {
toolbox: {
show: true,
feature: {
saveAsImage: {
show: true,
title: '下载'
},
},
}
}
$('[_echarts_instance_]').each(function (i, x) {
var chart = echarts.init(x);
chart.setOption(option);
});
}
window.refreshOptions = refreshOptions;
citysSort = ["郑州", "开封", "洛阳", "平顶山", "安阳", "鹤壁", "新乡", "焦作", "濮阳", "许昌", "漯河", "三门峡", "南阳", "商丘", "信阳", "周口", "驻马店", '济源'];
window.meanItem = function (data) {
var keys = Object.keys(data[0]);
var means = keys.map(x => {
var mean = d3.mean(_.pluck(data, x));
return +mean.toFixed(3);
})
var result = _.object(keys, means);
return result;
}
window.maxItem = function (data) {
var keys = Object.keys(data[0]);
var maxs = keys.map(x => {
var max = d3.max(_.pluck(data, x));
return +max.toFixed(3);
})
var result = _.object(keys, maxs);
return result;
}
window.minItem = function (data) {
var keys = Object.keys(data[0]);
var mins = keys.map(x => {
var min = d3.min(_.pluck(data, x));
return +min.toFixed(3);
})
var result = _.object(keys, mins);
return result;
}
$('#option_date').val(moment().format('YYYY-MM-DD'));
$('#option_date2').val(moment().add(1, 'days').format('YYYY-MM-DD'));
window.sources = ["industry", "fixed", "traffic", "resident", "other"];
window.dictSource = {
traffic: "交通",
resident: "居民",
fixed: "固定燃烧源",
other: "其他",
industry: "工业"
};
window.levelColors = ["#43ce17aa", "#efdc31aa", "#fa0a", "#ff401aaa", "#d20040aa", "#9c0a4eaa"];
window.dictFactor = {
"SO2_24h": 'SO<sub>2</sub>',
"SO2_1h": 'SO<sub>2</sub>',
"NO2_24h": 'NO<sub>2</sub>',
"NO2_1h": 'NO<sub>2</sub>',
"PM10_24h": 'PM<sub>10</sub>',
"CO_24h": 'CO',
"CO_1h": 'CO',
"O3_1h": 'O<sub>3</sub>',
"O3_8h": 'O<sub>3</sub>',
"PM25_24h": 'PM<sub>2.5</sub>',
"AQI": 'AQI',
"temp": '温度',
"humidity": '湿度',
"wind": '风速',
"rain": '降雨量',
"boundary_height": '边界层高度',
}
window.factors = ["SO2_24h", "SO2_1h", "NO2_24h", "NO2_1h", "PM10_24h", "CO_24h", "CO_1h", "O3_1h", "O3_8h", "PM25_24h"];
window.dictRange = {
'SO2_24h': [0, 50, 150, 475, 800, 1600, 2100, 2620],
'SO2_1h': [0, 150, 500, 650, 800],
'NO2_24h': [0, 40, 80, 180, 280, 565, 750, 940],
'NO2_1h': [0, 100, 200, 700, 1200, 2340, 3090, 3840],
'PM10_24h': [0, 50, 150, 250, 350, 420, 500, 600],
'CO_24h': [0, 2, 4, 14, 24, 36, 48, 60],
'CO_1h': [0, 5, 10, 35, 60, 90, 120, 150],
'O3_1h': [0, 160, 200, 300, 400, 800, 1000, 1200],
'O3_8h': [0, 100, 160, 215, 265, 800],
'PM25_24h': [0, 35, 75, 115, 150, 250, 350, 500],
'IAQI': [0, 50, 100, 150, 200, 300, 400, 500],
'AQI': [0, 50, 100, 150, 200, 300, 400],
'temp': [-20, -10, 0, 10, 20, 30, 40],
'humidity': [-1, 30, 50, 60, 70, 80, 90],
'wind': [-1, 0.5, 1.5, 3, 6, 12, 20],
'rain': [-1, 1, 5, 10, 25, 50, 100],
'boundary_height': [-1, 200, 400, 600, 800, 1000, 2000],
};
window.dictUnit = {
'SO2_24h': '微克/立方米',
'SO2_1h': '微克/立方米',
'NO2_24h': '微克/立方米',
'NO2_1h': '微克/立方米',
'PM10_24h': '微克/立方米',
'CO_24h': '毫克/立方米',
'CO_1h': '毫克/立方米',
'O3_1h': '微克/立方米',
'O3_8h': '微克/立方米',
'PM25_24h': '微克/立方米',
'IAQI': '量纲',
'AQI': '量纲',
'temp': '摄氏度',
'humidity': '百分比',
'wind': '米/秒',
'rain': '毫米',
'boundary_height': '米',
};
function getLegend(legendTemplate, factor) {
var between = dictRange[factor].slice(1, 6);
var first = _.first(between);
var last = _.last(between);
bewteen = _.zip(_.initial(between), _.rest(between));
return legendTemplate({
factor: factor,
first: first,
last: last,
between: bewteen
})
}
window.calcIAQI = function (data, type) {
var arrayIAQI = dictRange['IAQI'];
var dictIAQI = _.object(_.map(data, (v, k) => {
var array = dictRange[k];
var index = _.sortedIndex(array, v);
var IAQI =
((arrayIAQI[index] - arrayIAQI[index - 1]) / (array[index] - array[index - 1])) * (v - array[index - 1]) + arrayIAQI[index - 1]
return [k, parseFloat(IAQI.toFixed(0))];
}))
if (data['SO2_1h'] > 800) {
dictIAQI = _.omit(dictIAQI, 'SO2_1h')
}
if (data['O3_8h'] > 800) {
dictIAQI = _.omit(dictIAQI, 'O3_8h')
}
AQI = _.max(dictIAQI, (x, i) => x);
if (type == 'day') {
dictIAQI = _.omit(dictIAQI, 'SO2_1h', 'NO2_1h', 'CO_1h');
}
primarys = []
if (AQI > 50) {
var primaryItem = _.sortBy(_.pairs(dictIAQI), (x, i) => -x[1])[0];
var primaryFactor = primaryItem[0];
var primaryValue = primaryItem[1];
primarys = _.findKey(dictIAQI, (v, k) => (v >= primaryValue));
}
var levelRange = [50, 100, 150, 200, 300]
var levelIndex = _.sortedIndex(levelRange, AQI);
var levels = ["优", "良", "轻度", "中度", "重度", "严重"];
var level = levels[levelIndex]
return {
'dictIAQI': dictIAQI,
'AQI': AQI,
'primarys': primarys,
'level': level
}
}
$(function () {
function getPolygons() {
return new Promise((resolve, reject) => {
$.getJSON('/static/mock/henan_polygon.json', function (geoJson) {
window.henan = geoJson;
echarts.registerMap('henan', geoJson);
resolve(geoJson)
})
})
}
window.getPolygons = getPolygons;
function getRegions() {
return $.getJSON('/static/mock/regions_citys.json', function (data) {
window.regions = data;
window.citys = _.flatten(_.pluck(data, 'citys'));
window.citys = _.sortBy(citys, x => _.indexOf(citysSort, x['name']))
window.stations = _.flatten(_.compact(_.pluck(citys, 'stations')))
return new Promise((resolve, reject) => {
resolve(data);
})
})
}
window.getRegions = getRegions
mockData = function (sites, date) {
var aqis = _.flatten(_.map(hours168, function (x1, i1) {
var aqis = _.map(sites, function (x2, i2) {
var item = {
'SO2_24h': _.random(10, 200),
'SO2_1h': _.random(10, 200),
'NO2_24h': _.random(10, 200),
'NO2_1h': _.random(10, 100),
'PM10_24h': _.random(10, 100),
'CO_24h': _.random(10, 20),
'CO_1h': _.random(10, 20),
'O3_1h': _.random(10, 200),
'O3_8h': _.random(10, 200),
'PM25_24h': _.random(10, 200),
'temp': _.random(-10, 40),
'humidity': _.random(5, 100),
'wind': _.random(0, 21),
'rain': _.random(0, 100),
'boundary_height': _.random(200, 1600),
}
var item0 = _.pick(item, factors)
var aqi = calcIAQI(item0, 'hour');
item['AQI'] = aqi.AQI;
item['site'] = x2['code'];
item['date'] = x1;
return item;
})
return aqis;
}));
var aqis_back = _.flatten(_.map(hours168_back, function (x1, i1) {
var aqis = _.map(sites, function (x2, i2) {
var item = {
'SO2_24h': _.random(10, 200),
'SO2_1h': _.random(10, 200),
'NO2_24h': _.random(10, 200),
'NO2_1h': _.random(10, 100),
'PM10_24h': _.random(10, 100),
'CO_24h': _.random(10, 20),
'CO_1h': _.random(10, 20),
'O3_1h': _.random(10, 200),
'O3_8h': _.random(10, 200),
'PM25_24h': _.random(10, 200),
'temp': _.random(-10, 40),
'humidity': _.random(0, 100),
'wind': _.random(0, 21),
'rain': _.random(0, 100),
'boundary_height': _.random(200, 1600),
}
var item0 = _.pick(item, factors)
var aqi = calcIAQI(item0, 'hour');
item['AQI'] = aqi.AQI;
item['site'] = x2['code'];
item['date'] = x1;
return item;
})
return aqis;
}))
return {
aqis: aqis,
aqis_back: aqis_back
}
}
window.mockData = _.memoize(mockData, function (c, date) {
return date
})
function mockData2(periodType, factor,date) {
if (periodType == 'hour') {
var aqis0 = aqis;
var aqis_back0 = aqis_back;
} else if (periodType == 'day') {
var g = _(aqis).groupBy('site');
var g_back = _(aqis_back).groupBy('site');
var aqis0 = _.mapObject(g, function (item) {
return _.chain(item).groupBy(function (item1) {
return item1['date'].split(' ')[0]
}).mapObject(x3 => {
return d3.mean(_.pluck(x3, factor))
}).value()
});
aqis0 = _.flatten(_(aqis0).map((x, i) => {
return _(x).map((xx, ii) => {
var r = {
'site': i,
'date': ii
};
r[factor] = xx;
return r;
})
}));
var aqis_back0 = _.mapObject(g_back, function (item) {
return _.chain(item).groupBy(function (item1) {
return item1['date'].split(' ')[0]
}).mapObject(x3 => {
return d3.mean(_.pluck(x3, factor))
}).value()
});
aqis_back0 = _.flatten(_(aqis_back0).map((x, i) => {
return _(x).map((xx, ii) => {
var r = {
'site': i,
'date': ii
};
r[factor] = xx;
return r;
})
}));
}
var data = _.where(aqis0.concat(aqis_back0), {
'site': site
})
data = _.sortBy(data, 'date')
var data_back = _.where(aqis_back0, {
'site': site
})
data_back = _.sortBy(data_back, 'date')
return {
data: data,
data_back: data_back
}
}
window.mockData2 = mockData2;
window.initSelectCitys = function ($select) {
getRegions().then(function () {
var optionsTemplate = _.template($('#optionsTemplate').html());
var optionsHtml = optionsTemplate({
rows: citys
});
$select.append($(optionsHtml));
});
}
mockData2 = _.memoize(mockData2, function (type, factor,date) {
return type.toString() +'_'+ factor.toString()+'_'+ date.toString();
})
})
引入javascript文件forecast.js代码如下:
$(function () {
function initAqiBarLineChart(periodType,site, factor, date) {
$.get(`/static/mock/get_${siteType}_hour_forecast.json`, {
site: site,
factor: factor,
periodType: periodType,
date:date,
}, function () {
var result = mockData2(periodType, factor,date);
var data = result['data'];
var data_back = result['data_back'];
var chartDom = document.getElementById('aqiBarLineChart');
var myChart = echarts.init(chartDom);
var last = _.last(dictRange[factor].slice(0, 6));
var array = dictRange[factor].slice(0, 6);
var xdata = _.pluck(data, 'date')
var legendColor;
ydata = data.map(x => {
var value = x[factor];
var value0 = value;
if (value > last) {
value0 = last;
}
var index = _.sortedIndex(array, value0);
legendColor = levelColors[index - 1];
return {
value: parseInt(value),
itemStyle: {
color: levelColors[index - 1]
}
}
});
ydata_back = data_back.map(x => {
var value = x[factor] * (0.8 + _.random(-90, 90) / 300);
return parseInt(value);
});
var factorText = dictFactor[factor].replace('<sub>', '').replace('</sub>', '');
var siteName = $('td[data-site=' + site + ']').text();
var title = `${siteName}${from}至${to}期间${factorText}趋势预报(起报时间:${from})`;
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
dataZoom: [
{
type: 'inside',
xAxisIndex: 0,
minSpan: 5
},
{
type: 'slider',
xAxisIndex: 0,
minSpan: 5,
bottom: 50
}
],
title: {
text: title,
left: 'center'
},
toolbox: {
feature: {
saveAsImage: {
show: true
}
}
},
legend: {
data: ['预报', '实测'],
top: '30px',
},
xAxis: [
{
type: 'category',
data: xdata,
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
name: '',
axisLabel: {
formatter: '{value}'
}
}
],
series: [
{
name: '预报',
type: 'bar',
data: ydata,
barGap: '0%',
color: legendColor,
barCategoryGap: '10%',
},
{
name: '实测',
type: 'line',
color: window['realColor']||'#000',
yAxisIndex: 0,
data: ydata_back,
}
]
};
myChart.setOption(option);
})
}
function initTable_Forecast(factor, groups, dates) {
var type = args['b'].match('city-forecast-.*') ? '城市' : '站点';
var region = $('#option_region option:selected').text() || '全省';
from = moment(_.first(dates)).format('YYYY年M月D日');
to = moment(_.last(dates)).format('YYYY年M月D日');
var run = moment($('#option_date').val()).format('YYYY年M月D日');
$('#title').html(`${from}至${to}期间${region}各${type}${dictFactor[factor]}预报<sub>(起报时间:${run})</sub>`);
var legendTemplate = _.template($('#legendTemplate').html());
var legendHtml = getLegend(legendTemplate, factor);
$('#divLegend').html(legendHtml);
if (args['b'] == 'city-forecast-aqi') {
var forecastAQITableTemplate = _.template($('#cityForecastAQITableTemplate').html());
}
if (args['b'] == 'station-forecast-aqi') {
var forecastAQITableTemplate = _.template($('#stationForecastAQITableTemplate').html());
}
if (args['b'] == 'city-forecast-weather') {
var forecastAQITableTemplate = _.template($('#cityForecastWeatherTableTemplate').html());
}
var html = forecastAQITableTemplate({
'dates': dates,
'factor': factor,
'groups': groups
});
$('#tableForecast').html(html);
$('#divLegend').css('width', $('thead').css('width'));
$('#title').css('width', $('thead').css('width'));
$('#tableForecast thead th.date').each((i, x) => {
$(x).text(dates7[i])
})
var g = _.groupBy(aqis, function (item, index) {
return item['date'].split(' ')[0]
})
window.d = _.mapObject(g, function (x1, i1) {
var aqis1 = _.groupBy(x1, 'site');
var aqis = _.mapObject(aqis1, function (x2, i2) {
var raws = _.map(x2, x3 => _.omit(x3, 'date', 'site'));
var mean = meanItem(raws);
var max = maxItem(raws);
var min = minItem(raws);
var aqi = {
'mean': mean,
'max': max,
'min': min
}
return aqi
})
return aqis;
});
var last = _.last(dictRange[factor].slice(0, 6));
var array = dictRange[factor].slice(0, 6);
$('#tableForecast tr[data-site]').each((i, x) => {
var site = $(x).data('site');
$(x).find('[data-col]').each((j, y) => {
var col = $(y).data('col');
var date = $(y).data('date');
var data_date_site = d[date][site];
if (value > last) {
value = last
}
if (col == 'min') {
var value = data_date_site.min[factor];
} else if (col == 'max') {
var value = data_date_site.max[factor];
} else if (col == 'value') {
var value = data_date_site.mean[factor];
}
if (col != 'primary') {
var index = _.sortedIndex(array, value);
$(y).css('background', levelColors[index - 1]);
$(y).html(value.toFixed(0));
} else if (col == 'primary') {
var mean = data_date_site.mean;
mean = _.pick(mean, factors);
aqi = calcIAQI(mean);
var index = _.sortedIndex(array, aqi.AQI);
$(y).css('background', levelColors[index - 1]);
$(y).html(dictFactor[aqi.primarys]);
}
});
});
}
$('#option_region').change(function () {
getStation();
})
function getStation() {
$.get('/static/mock/get_stations_forecast.json', {
date: $('#option_date').val()
}, function () {
var result = mockData(sites, $('#option_date').val());
aqis = result['aqis'];
aqis_back = result['aqis_back'];
var region = $('#option_region').val();
if (region == 'all') {
citys0 = citys;
} else if (region == 'region_226') {
citys0 = regions[0]['citys'];
} else if (region == 'region_fenwei') {
citys0 = regions[1]['citys'];
} else if (region == 'region_boundary') {
citys0 = regions[2]['citys'];
} else {
citys0 = citys.filter(x => x['name'] == region);
}
var factor = $('#option_factor').val() || $('#option_factor2').val();
initTable_Forecast(factor, citys0, dates7);
})
}
function refreshDate() {
dates7 = _.map(_.range(7), function (item, index) {
var date = moment($('#option_date').val()).add(item, 'days').format('YYYY-MM-DD');
return date;
});
hours168 = _.map(_.range(168), function (item, index) {
var now = moment($('#option_date').val());
var now0 = now.set('second', 0).set('minute', 0).set('hour', 0);
var hour = now0.add(item, 'hour').format('YYYY-MM-DD HH:mm');
return hour;
});
hours168_back = _.map(_.range(-168, 0), function (item, index) {
var now = moment($('#option_date').val());
var now0 = now.set('second', 0).set('minute', 0).set('hour', 0);
var hour = now0.add(item, 'hour').format('YYYY-MM-DD HH:mm');
return hour;
});
}
function getCity() {
$.get('/static/mock/get_citys_forecast.json', {
date: $('#option_date').val()
}, function () {
var result = mockData(sites, $('#option_date').val());
aqis = result['aqis'];
aqis_back = result['aqis_back'];
var factor = $('#option_factor').val() || $('#option_factor2').val();
initTable_Forecast(factor, regions, dates7);
})
}
window.site = null;
$('#tableForecast').delegate('td[data-site]', 'click', function () {
var factor = $('#option_factor').val() || $('#option_factor2').val();
var site = $(this).data('site');
$('#aqiBarLineDiv').css('display', 'flex');
var periodType = $('[name=periodType]:checked').val();
window.site = site;
$('#aqiBarLineDiv').show();
var date=$('#option_date').val();
initAqiBarLineChart(periodType,window.site, factor,date);
$('body')[0].scrollTo(0, 1200);
if (window.location.href != window.parent.location.href) {
window.parent.$('body')[0].scrollTo(0, 800);
}
})
$('[name=periodType]').change(function () {
var factor = $('#option_factor').val() || $('#option_factor2').val();
var periodType = $('[name=periodType]:checked').val();
if (!!window.site) {
var date=$('#option_date').val();
initAqiBarLineChart(periodType,window.site, factor,date);
}
})
$('#option_submit').click(function () {
refreshDate()
var factor = $('#option_factor').val() || $('#option_factor2').val();
var periodType = $('[name=periodType]:checked').val()
if (args['b'] == 'city-forecast-aqi') {
getCity();
}
if (args['b'] == 'station-forecast-aqi') {
getStation();
}
if (args['b'] == 'city-forecast-weather') {
getCity();
}
var date=$('#option_date').val();
if (!!window.site) {
initAqiBarLineChart(periodType,window.site, factor,date);
}
})
if (window.location.href == window.parent.location.href) {
$('[data-role="toolbar"]').show();
}
initSelectCitys($('#option_region'));
refreshDate()
if (args['b'] == 'city-forecast-aqi') {
$('#option_factor').show();
$('[for=option_factor]').show();
$('#option_factor2').parent().remove();
$('[for=option_factor2]').parent().remove();
$('#option_region').parent().remove();
$('[for=option_region]').parent().remove();
window.renderReady = getRegions().then(function () {
siteType='city';
sites = citys;
getCity();
});
}
if (args['b'] == 'station-forecast-aqi') {
$('#option_factor').show();
$('[for=option_factor]').show();
$('#option_factor2').parent().remove();
$('[for=option_factor2]').parent().remove();
window.renderReady = getRegions().then(function () {
siteType='station';
sites = stations;
getStation();
});
}
if (args['b'] == 'city-forecast-weather') {
$('#option_factor2').show();
$('[for=option_factor2]').show();
$('#option_factor').parent().remove();
$('[for=option_factor]').parent().remove();
$('#option_region').parent().remove();
$('[for=option_region]').parent().remove();
window.renderReady = getRegions().then(function () {
siteType='city';
sites = citys;
getCity();
});
}
})
最后再看一下效果:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。