内容概况
非常简洁漂亮的天气效果, echarts中使用到了xAxis.axisLabel. rich, 效果很满意, 只展示了静态代码, 保存为html后就可以直接运行
echarts数据基于易客云天气API返回的json制作, 有需要的可以自己对接, 下一篇文章我会发布一个PHP对接版本
技术点:rich负责定义模板, formatter负责输出格式化后的数据, xAxis赋值是个数组列表, 第一组position为top, 顶部展示日期和天气图标, 另一组position为bottom, 位于底部展示星期
rich 的本质是定义一套 “样式模板”,在 axisLabel.formatter 中通过 {模板名|内容} 的语法调用模板,实现标签内多元素的样式分离。
要添加图标,只需在 rich 模板中通过 backgroundColor 或 textStyle 配置图片(本地 / 在线图片均可),再与文字内容组合即可。
效果预览 点击在线预览HTML
html我已经做好了, 点击上面的链接可预览效果
rich的使用
每个模板是一个独立的样式对象,核心属性:
width/height:控制图标尺寸(必须设置,否则图片可能拉伸异常);
backgroundColor.image:指定图标地址(支持本地路径 ./icon.png 或在线 URL);
padding:控制图标与文字的间距(上右下左,此处仅右间距 5px);
textStyle:控制文字样式(可单独抽成 text 模板复用)。
formatter
通过 {模板名|内容} 语法组合多段内容:
图标模板(如 foodIcon)的 “内容” 为空({foodIcon|}),仅显示背景图片;
文字模板(text)的 “内容” 为 X 轴数据({text|美食}),实现文字样式统一;
用 switch 语句根据不同 value 匹配不同图标,实现差异化显示。
实现代码
代码全部复制,另存为html就可以打开看到效果, 希望对初学者有所帮助
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>ECharts天气预报 - tianqiapi.com</title>
<!-- 引入 ECharts CDN -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<style>
#temperatureChart { width: 1200px; height: 500px; margin: 20px auto; }
</style>
</head>
<body>
<div id="temperatureChart" class="w-full h-full" style="user-select: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); position: relative;"><div style="position: relative; width: 720px; height: 400px; padding: 0px; margin: 0px; border-width: 0px; cursor: default;"><canvas data-zr-dom-id="zr_0" width="1440" height="800" style="position: absolute; left: 0px; top: 0px; width: 720px; height: 400px; user-select: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); padding: 0px; margin: 0px; border-width: 0px;"></canvas></div></div>
<p align="center" style="color:#666; font-size:14px;">数据来源:tianqiapi.com</p>
<script>
// 未来7天的天气数据
const weatherData = {
days: ['星期六', '星期日', '星期一', '星期二', '星期三', '星期四', '星期五'],
dates: ['2025-09-13', '2025-09-14', '2025-09-15', '2025-09-16', '2025-09-17', '2025-09-18', '2025-09-19'],
highTemp: [29, 30, 25, 27, 25, 24, 24],
lowTemp: [19, 18, 19, 17, 16, 16, 17],
weather: ['多云', '晴转多云', '小雨', '晴', '晴', '多云', '多云'],
icons: ['sun-o', 'cloud-sun-o', 'cloud', 'cloud', 'cloud', 'cloud-rain', 'sun-o'],
humidity: [45, 50, 55, 65, 70, 85, 40],
wind: ['3级', '3-4级', '4级', '4-5级', '3级', '3-4级', '2级']
};
// 初始化ECharts图表
function initTemperatureChart() {
// 获取图表容器
const chartDom = document.getElementById('temperatureChart');
const myChart = echarts.init(chartDom);
// 配置图表
const option = {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
borderColor: '#eee',
borderWidth: 1,
textStyle: { color: '#333' },
formatter: function(params) {
let param = params[0];
return `<div class="font-medium">${weatherData.dates[param.dataIndex]}</div>
<div>最高温度: ${weatherData.highTemp[param.dataIndex]}°C</div>
<div>最低温度: ${weatherData.lowTemp[param.dataIndex]}°C</div>
<div>天气: ${weatherData.weather[param.dataIndex]}</div>`;
}
},
legend: {
data: ['最高温度', '最低温度'],
top: 0,
textStyle: { color: '#666' }
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
data: weatherData.days.map((day, i) => `${weatherData.days[i]}`),
axisLine: {
lineStyle: {
color: '#ddd'
}
},
position: 'top',
axisLabel: {
lineHeight: 30,
color: '#666',
rich: {
// 模板1:美食图标(本地/在线图片均可,此处用在线图标)
icon_qing: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/qing.png' // 图标地址
}
},
icon_yun: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/yun.png' // 图标地址
}
},
icon_yin: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/yin.png' // 图标地址
}
},
icon_lei: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/lei.png' // 图标地址
}
},
icon_xue: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/xue.png' // 图标地址
}
},
icon_shachen: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/shachen.png' // 图标地址
}
},
icon_wu: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/wu.png' // 图标地址
}
},
icon_bingbao: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/bingbao.png' // 图标地址
}
},
icon_yu: {
width: 25, // 图标宽度
height: 25, // 图标高度
backgroundColor: {
image: 'http://widget.tianqiapi.com/static/skin/peach/yu.png' // 图标地址
}
}
},
// 2. 调用 rich 模板,组合“图标+文字”
formatter: function(value) {
// 根据 X 轴数据(value)匹配对应的图标模板
switch (value) {
case '星期六':
return '2025-09-13\n{icon_yun|}\n多云\n';
case '星期日':
return '2025-09-14\n{icon_yun|}\n晴转多云\n';
case '星期一':
return '2025-09-15\n{icon_yu|}\n小雨\n';
case '星期二':
return '2025-09-16\n{icon_qing|}\n晴\n';
case '星期三':
return '2025-09-17\n{icon_qing|}\n晴\n';
case '星期四':
return '2025-09-18\n{icon_yun|}\n多云\n';
case '星期五':
return '2025-09-19\n{icon_yun|}\n多云\n';
default:
return value;
}
},
// 标签横向对齐(避免图标偏移)
align: 'center'
}
}, {
type: 'category',
boundaryGap: false,
data: weatherData.days.map((day, i) => `${weatherData.days[i]}`),
axisLine: {
lineStyle: {
color: '#ddd'
}
},
position: 'bottom',
axisLabel: {
lineHeight: 20,
color: '#666'
}
}, ],
yAxis: {
type: 'value',
name: '',
nameTextStyle: { color: '#666' },
axisLine: {
lineStyle: { color: '#ddd' }
},
splitLine: {
lineStyle: { color: '#f0f0f0' }
},
axisLabel: {
formatter: '{value}',
color: '#666'
},
min: function(value) {
return value.min - 2; // 最小值向下调整2度
},
max: function(value) {
return value.max + 2; // 最大值向上调整2度
}
},
series: [
{
name: '最高温度',
type: 'line',
data: weatherData.highTemp,
symbol: 'circle',
symbolSize: 8,
lineStyle: {
width: 3,
color: '#F56C6C' // 暖色调
},
itemStyle: {
color: '#F56C6C',
borderWidth: 2,
borderColor: '#fff',
shadowBlur: 4,
shadowColor: 'rgba(245, 108, 108, 0.5)'
},
emphasis: {
scale: true,
symbolSize: 10
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(245, 108, 108, 0.3)' },
{ offset: 1, color: 'rgba(245, 108, 108, 0)' }
])
}
},
{
name: '最低温度',
type: 'line',
data: weatherData.lowTemp,
symbol: 'circle',
symbolSize: 8,
lineStyle: {
width: 3,
color: '#4E5BA6' // 冷色调
},
itemStyle: {
color: '#4E5BA6',
borderWidth: 2,
borderColor: '#fff',
shadowBlur: 4,
shadowColor: 'rgba(78, 91, 166, 0.5)'
},
emphasis: {
scale: true,
symbolSize: 10
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(78, 91, 166, 0.3)' },
{ offset: 1, color: 'rgba(78, 91, 166, 0)' }
])
}
}
]
};
// 设置图表配置项
myChart.setOption(option);
// 响应窗口大小变化
window.addEventListener('resize', function() {
myChart.resize();
});
}
document.addEventListener('DOMContentLoaded', function() {
initTemperatureChart();
});
</script>
</body>
</html>