AQI预测 - 空气质量预报 - 最近12个月空气质量分布
配置项如下
// 数据源
const dataOrigin = {
xAxisData: [
'01',
'02',
'03',
'04',
'05',
'06',
'07',
'08',
'09',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25',
'26',
'27',
'28',
'29',
'30',
'31',
],
yAxisData: [
'2020-10',
'2020-11',
'2020-12',
'2021-01',
'2021-02',
'2021-03',
'2021-04',
'2021-05',
'2021-06',
'2021-07',
'2021-08',
],
seriesDatas: [
{
name: '优',
data: [
[2, 0, 31],
[3, 0, 36],
[4, 0, 34],
[5, 0, 36],
[6, 0, 25],
[7, 0, 35],
[8, 0, 34],
[9, 0, 34],
[10, 0, 41],
[11, 0, 44],
[12, 0, 48],
[13, 0, 37],
[14, 0, 31],
[15, 0, 28],
[16, 0, 46],
[17, 0, 39],
[18, 0, 36],
[19, 0, 49],
[24, 0, 50],
[25, 0, 47],
[26, 0, 44],
[27, 0, 45],
[28, 0, 38],
[29, 0, 41],
[30, 0, 43],
[2, 1, 45],
[3, 1, 39],
[10, 1, 42],
[11, 1, 41],
[15, 1, 43],
[16, 1, 44],
[18, 1, 40],
[19, 1, 33],
[20, 1, 23],
[21, 1, 47],
[22, 1, 44],
[23, 1, 35],
[24, 1, 18],
[25, 1, 38],
[0, 2, 48],
[7, 2, 43],
[12, 2, 33],
[13, 2, 44],
[27, 2, 29],
[28, 2, 46],
[18, 3, 46],
[23, 3, 42],
[6, 4, 35],
[7, 4, 29],
[8, 4, 41],
[9, 4, 39],
[11, 4, 50],
[15, 4, 38],
[16, 4, 39],
[18, 4, 47],
[19, 4, 44],
[21, 4, 39],
[22, 4, 38],
[23, 4, 37],
[24, 4, 40],
[25, 4, 36],
[26, 4, 28],
[27, 4, 33],
[1, 5, 48],
[4, 5, 42],
[5, 5, 42],
[6, 5, 49],
[7, 5, 40],
[10, 5, 47],
[17, 5, 43],
[25, 5, 41],
[30, 5, 33],
[1, 6, 42],
[3, 6, 45],
[4, 6, 45],
[5, 6, 43],
[7, 6, 46],
[8, 6, 50],
[9, 6, 37],
[10, 6, 48],
[12, 6, 39],
[13, 6, 44],
[20, 6, 47],
[23, 6, 50],
[24, 6, 48],
[25, 6, 47],
[29, 6, 47],
[0, 7, 40],
[1, 7, 50],
[2, 7, 36],
[10, 7, 46],
[11, 7, 39],
[12, 7, 46],
[13, 7, 49],
[14, 7, 31],
[15, 7, 41],
[17, 7, 36],
[18, 7, 31],
[21, 7, 32],
[24, 7, 49],
[25, 7, 49],
[30, 7, 30],
[0, 8, 30],
[6, 8, 30],
[7, 8, 45],
[8, 8, 33],
[10, 8, 40],
[11, 8, 43],
[12, 8, 46],
[13, 8, 42],
[14, 8, 22],
[15, 8, 27],
[16, 8, 42],
[24, 8, 30],
[25, 8, 32],
[26, 8, 28],
[27, 8, 39],
[28, 8, 33],
[29, 8, 32],
[0, 9, 27],
[1, 9, 30],
[2, 9, 30],
[4, 9, 49],
[5, 9, 43],
[6, 9, 31],
[7, 9, 30],
[8, 9, 30],
[14, 9, 32],
[15, 9, 30],
[16, 9, 37],
[17, 9, 32],
[18, 9, 27],
[19, 9, 26],
[20, 9, 35],
[21, 9, 29],
[22, 9, 26],
[23, 9, 18],
[24, 9, 18],
[25, 9, 18],
[26, 9, 27],
[27, 9, 34],
[29, 9, 45],
[30, 9, 47],
[0, 10, 31],
[1, 10, 22],
[2, 10, 28],
[3, 10, 28],
[4, 10, 28],
[5, 10, 26],
[6, 10, 27],
[7, 10, 50],
[8, 10, 46],
[9, 10, 33],
[10, 10, 27],
[11, 10, 29],
[12, 10, 28],
[13, 10, 25],
[14, 10, 22],
[15, 10, 32],
[16, 10, 43],
[19, 10, 40],
[20, 10, 49],
[21, 10, 34],
[22, 10, 42],
[23, 10, 46],
[25, 10, 45],
[29, 10, 50],
],
color: '#8DB25D',
},
{
name: '良',
data: [
[0, 0, 54],
[1, 0, 54],
[20, 0, 60],
[21, 0, 80],
[22, 0, 69],
[23, 0, 53],
[31, 0, 66],
[0, 1, 98],
[1, 1, 56],
[4, 1, 62],
[7, 1, 71],
[8, 1, 67],
[9, 1, 56],
[12, 1, 57],
[13, 1, 56],
[14, 1, 51],
[17, 1, 55],
[26, 1, 51],
[27, 1, 57],
[28, 1, 95],
[29, 1, 59],
[1, 2, 93],
[2, 2, 57],
[3, 2, 66],
[4, 2, 52],
[5, 2, 71],
[6, 2, 77],
[8, 2, 93],
[14, 2, 82],
[15, 2, 71],
[16, 2, 92],
[17, 2, 80],
[18, 2, 58],
[23, 2, 74],
[24, 2, 55],
[25, 2, 100],
[29, 2, 63],
[30, 2, 68],
[1, 3, 76],
[2, 3, 55],
[3, 3, 59],
[4, 3, 64],
[5, 3, 74],
[6, 3, 55],
[7, 3, 69],
[8, 3, 91],
[10, 3, 93],
[11, 3, 79],
[14, 3, 63],
[15, 3, 72],
[16, 3, 93],
[17, 3, 94],
[19, 3, 72],
[20, 3, 73],
[21, 3, 79],
[24, 3, 52],
[27, 3, 69],
[28, 3, 68],
[29, 3, 80],
[30, 3, 89],
[0, 4, 77],
[1, 4, 70],
[2, 4, 95],
[3, 4, 64],
[4, 4, 87],
[5, 4, 88],
[10, 4, 55],
[12, 4, 54],
[13, 4, 60],
[14, 4, 62],
[17, 4, 58],
[20, 4, 74],
[0, 5, 51],
[2, 5, 54],
[3, 5, 70],
[8, 5, 55],
[9, 5, 54],
[11, 5, 83],
[12, 5, 88],
[13, 5, 72],
[14, 5, 81],
[15, 5, 65],
[16, 5, 58],
[18, 5, 53],
[19, 5, 99],
[20, 5, 56],
[21, 5, 73],
[22, 5, 78],
[23, 5, 96],
[24, 5, 64],
[26, 5, 81],
[27, 5, 99],
[0, 6, 53],
[2, 6, 51],
[6, 6, 51],
[11, 6, 60],
[14, 6, 78],
[16, 6, 59],
[17, 6, 63],
[18, 6, 54],
[19, 6, 52],
[21, 6, 58],
[22, 6, 53],
[26, 6, 84],
[27, 6, 81],
[28, 6, 67],
[3, 7, 75],
[4, 7, 60],
[7, 7, 92],
[8, 7, 73],
[9, 7, 53],
[16, 7, 57],
[19, 7, 54],
[20, 7, 54],
[22, 7, 60],
[23, 7, 89],
[26, 7, 62],
[27, 7, 53],
[28, 7, 77],
[29, 7, 58],
[1, 8, 54],
[2, 8, 56],
[3, 8, 69],
[4, 8, 88],
[5, 8, 53],
[9, 8, 67],
[17, 8, 52],
[18, 8, 61],
[19, 8, 55],
[20, 8, 54],
[21, 8, 53],
[22, 8, 60],
[23, 8, 51],
[3, 9, 64],
[9, 9, 51],
[10, 9, 51],
[11, 9, 53],
[12, 9, 54],
[13, 9, 56],
[28, 9, 59],
[17, 10, 58],
[18, 10, 54],
[24, 10, 81],
[26, 10, 67],
[27, 10, 58],
[28, 10, 53],
],
color: '#DBCE66',
},
{
name: '轻度',
data: [
[5, 1, 112],
[6, 1, 118],
[9, 2, 146],
[19, 2, 101],
[20, 2, 125],
[21, 2, 131],
[0, 3, 101],
[9, 3, 101],
[12, 3, 109],
[13, 3, 120],
[22, 3, 109],
[25, 3, 101],
[26, 3, 113],
[29, 5, 116],
[15, 6, 103],
[5, 7, 127],
[6, 7, 137],
],
color: '#F49028',
},
{
name: '中度',
data: [
[11, 2, 171],
[22, 2, 163],
[26, 2, 152],
],
color: '#F35654',
},
{
name: '重度',
data: [
[10, 2, 223],
[28, 5, 204],
],
color: '#B255C5',
},
{ name: '严重', data: [], color: '#F53362' },
],
};
// AQI 等级
const AQI_LEVELS = [
{
icon: 'k1',
label: '优',
otherName: '一级',
value: 1,
min: 0,
max: 50,
proposal: '空气质量令人满意,基本无空气污染',
influence: '各类人群可正常活动',
color: '#8DB25D',
lightColor: '#D2F5A5',
},
{
icon: 'k2',
label: '良',
otherName: '二级',
value: 2,
min: 51,
max: 100,
proposal: '空气质量可接受,但某些污染物可能对极少数异常敏感人群健康有较弱影响',
influence: '极少数异常敏感人群应减少户外活动',
color: '#DBCE66',
lightColor: '#EBEBD8',
},
{
icon: 'k3',
label: '轻度',
otherName: '三级',
value: 3,
min: 101,
max: 150,
proposal: '易感人群症状有轻度加剧,健康人群出现刺激症状',
influence: '儿童、老年人及心脏病、呼吸系统疾病患者应减少长时间、高强度的户外锻炼',
color: '#F49028',
lightColor: '#F2E1C7',
},
{
icon: 'k4',
label: '中度',
otherName: '四级',
value: 4,
min: 151,
max: 200,
proposal: '进一步加剧易感人群症状,可能对健康人群心脏、呼吸系统有影响',
influence: '儿童、老年人及心脏病、呼吸系统疾病患者避免长时间、高强度的户外锻炼,一般人群适量减少户外运动',
color: '#F35654',
lightColor: '#F3D3D3',
},
{
icon: 'k5',
label: '重度',
otherName: '五级',
value: 5,
min: 201,
max: 300,
proposal: '心脏病和肺病患者症状显著加剧,运动耐受力降低,健康人群普遍出现症状',
influence: '儿童、老年人及心脏病、肺病患者应停留在室内,停止户外运动,一般人群减少户外运动',
color: '#B255C5',
lightColor: '#E5D2ED',
},
{
icon: 'k6',
label: '严重',
otherName: '六级',
value: 6,
min: 301,
max: '+',
proposal: '健康人群运动耐受力降低,有明显强烈症状,提前出现某些疾病',
influence: '儿童、老年人和病人应停留在室内,避免体力消耗,一般人群避免户外活动',
color: '#F53362',
lightColor: '#F3CBD7',
},
];
/**
* @description 获取AQI等级
* @params {number} value
*/
const getLevel = (value) => {
let index = 0;
if (!value || value <= 50) index = 0;
if (value > 50 && value <= 100) index = 1;
if (value > 100 && value <= 150) index = 2;
if (value > 150 && value <= 200) index = 3;
if (value > 200 && value <= 300) index = 4;
if (value > 300) index = 5;
return { index, ...AQI_LEVELS[index] };
};
// 获取悬浮提示元素
const getTooltipRow = (params, isHideEmpty = false) => {
if (isHideEmpty && !params.value) return '';
return `
<div style="display: flex; justify-content: space-between; min-width: 80px; padding-top: 3px;">
<span style="${params.marker ? '' : 'padding-left: 18px'}">${params.marker || ''} ${params.seriesName}</span>
<span style="padding-left: 10px; font-weight: bold;">${params.value || '-'}</span>
</div>`;
};
const visualMapPieces = AQI_LEVELS.map(({ min, max, color }) => ({ min, max, color }));
option = {
title: {
text: '最近12个月空气质量分布',
left: 'center',
textStyle: {
fontWeight: 'bold',
fontFamily: 'Microsoft YaHei',
fontSize: 18,
},
},
tooltip: {
position: 'top',
formatter: (params) => {
const dateStr = `${dataOrigin.yAxisData[params.data[1]]}-${params.name}`;
const value = {
marker: params.marker,
seriesName: getLevel(params.data[2]).label,
value: params.data[2] || '-',
};
return `${dateStr}<br />${getTooltipRow(value)}`;
},
},
grid: {
top: 40,
left: 65,
right: 15,
bottom: 65,
},
visualMap: {
show: false,
pieces: visualMapPieces,
},
legend: {
show: true,
icon: 'circle',
bottom: 10,
},
xAxis: {
type: 'category',
data: dataOrigin.xAxisData,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
splitArea: {
show: true,
},
},
yAxis: {
type: 'category',
data: dataOrigin.yAxisData,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
splitArea: {
show: true,
},
},
series: dataOrigin.seriesDatas.map(({ name, data, color }) => ({
name,
data,
type: 'heatmap',
label: {
show: true,
},
itemStyle: {
color,
borderColor: '#fff',
borderWitdh: 5,
borderCap: 'round',
},
})),
};