1. 风向十六方位的基础知识
在气象学中,风向是指风的来向,通常用十六个方位来表示。这种表示方法源自航海时代,至今仍是气象观测的标准。十六方位将360度圆周等分为16个22.5度的扇形区域,每个区域用一个特定的缩写表示。
十六方位的英文缩写和对应的角度范围如下:
- 北(N):348.75°-11.25°
- 北东北(NNE):11.25°-33.75°
- 东北(NE):33.75°-56.25°
- 东东北(ENE):56.25°-78.75°
- 东(E):78.75°-101.25°
- 东东南(ESE):101.25°-123.75°
- 东南(SE):123.75°-146.25°
- 南东南(SSE):146.25°-168.75°
- 南(S):168.75°-191.25°
- 南西南(SSW):191.25°-213.75°
- 西南(SW):213.75°-236.25°
- 西西南(WSW):236.25°-258.75°
- 西(W):258.75°-281.25°
- 西西北(WNW):281.25°-303.75°
- 西北(NW):303.75°-326.25°
- 北西北(NNW):326.25°-348.75°
理解这些方位定义是进行风向可视化的基础。在实际应用中,我们经常需要将具体的角度值转换为对应的方位缩写,或者反过来,将方位缩写转换为具体的角度范围。
2. ECharts基础配置
ECharts是一个强大的JavaScript可视化库,特别适合用来展示气象数据。在开始绘制风向图之前,我们需要先配置一个基础的ECharts实例。
首先,创建一个简单的HTML容器:
<div id="windChart" style="width: 800px;height:400px;"></div>然后初始化ECharts实例:
// 初始化图表 let chartDom = document.getElementById('windChart'); let myChart = echarts.init(chartDom); // 基础配置 let option = { backgroundColor: "rgba(48, 65, 90, 1)", grid: { top: 40, bottom: 80 }, tooltip: { trigger: 'axis' }, xAxis: { type: 'time', splitLine: { lineStyle: { color: '#ddd' } }, axisLine: { lineStyle: { color: "#ffffff" } } }, yAxis: { name: '风速(m/s)', splitLine: { lineStyle: { color: '#ddd' } }, axisLine: { lineStyle: { color: "#ffffff" } } } }; myChart.setOption(option);这个基础配置包含了图表的基本元素:背景色、网格、坐标轴和提示框。xAxis设置为时间类型,适合展示时间序列数据;yAxis用于显示风速值。
3. 自定义风向箭头绘制
ECharts的custom系列允许我们自定义图形元素。对于风向箭头,我们需要根据风向角度动态旋转箭头图标。
首先定义箭头的大小和形状:
let arrowSize = 12; let arrowPath = 'M31 16l-15-15v9h-26v12h26v9z'; // 箭头SVG路径然后创建custom系列来绘制风向箭头:
series: [{ type: 'custom', name: "风向(°)", renderItem: function (param, api) { var point = api.coord([api.value(0), api.value(1)]); return { type: 'path', shape: { pathData: arrowPath, x: -arrowSize / 2, y: -arrowSize / 2, width: arrowSize, height: arrowSize }, rotation: -((Math.PI / 2) + (api.value(2) * Math.PI / 180)), position: point, style: api.style({ stroke: '#555', lineWidth: 1 }) }; }, encode: { x: 0, y: 1 }, itemStyle: { color: "#F4E9A3" }, data: windDirectionData }]这里有几个关键点需要注意:
rotation属性控制箭头的旋转角度。由于SVG箭头的默认方向是向右,我们需要先旋转90度(Math.PI/2)使其向上,再加上风向角度。- 风向角度需要从度数转换为弧度(乘以Math.PI/180)。
api.coord方法将数据值转换为画布坐标。data数组中的每个元素应该包含时间、风速和风向角度三个值。
4. 风速曲线与视觉映射
为了完整展示气象数据,我们还需要绘制风速曲线。同时,可以通过视觉映射(visualMap)组件来根据风速大小改变箭头颜色。
添加风速曲线系列:
series: [{ type: 'line', name: "风速(m/s)", symbol: 'none', encode: { x: 0, y: 1 }, lineStyle: { color: '#FFAA44' }, itemStyle: { color: "#FFAA44" }, data: windSpeedData }]配置视觉映射组件:
visualMap: { show: false, type: "piecewise", pieces: [ { "lt": 11, "color": "#18BF12", "label": "微风(<11节)" }, { "gte": 11, "lt": 17, "color": "#f4e9a3", "label": "中风(11~17节)" }, { "gte": 17, "color": "#D33C3E", "label": "大风(>=17节)" } ], dimension: 1 }视觉映射会根据风速值(维度1)自动改变箭头颜色。这样用户一眼就能看出哪些时段风速较大。
5. 数据格式处理与工具提示
实际项目中,数据可能来自API接口,格式可能不完全符合ECharts的要求。我们需要对数据进行适当的处理。
假设原始数据格式如下:
let rawData = [ ['2023-11-27 01:00:00', 11.6, '东北'], ['2023-11-27 02:00:00', 11.6, '东北'], // 更多数据... ];我们需要将方位文字转换为角度值:
function directionToDegree(direction) { const map = { 'N': 0, 'NNE': 22.5, 'NE': 45, 'ENE': 67.5, 'E': 90, 'ESE': 112.5, 'SE': 135, 'SSE': 157.5, 'S': 180, 'SSW': 202.5, 'SW': 225, 'WSW': 247.5, 'W': 270, 'WNW': 292.5, 'NW': 315, 'NNW': 337.5 }; return map[direction] || 0; } let processedData = rawData.map(item => { return [new Date(item[0]), item[1], directionToDegree(item[2])]; });工具提示(tooltip)也需要定制,以显示更友好的信息:
tooltip: { trigger: 'axis', formatter: function (params) { let time = params[0].value[0]; let speed = params[0].value[1] || "无数据"; let degree = params[0].value[2]; let direction = "无数据"; if (degree != null) { let index = Math.floor((degree + 11.25) / 22.5) % 16; let directions = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']; direction = directions[index] + " (" + degree + "°)"; } return ` 时间: ${echarts.format.formatTime('yyyy-MM-dd hh:mm', time)}<br> 风速: ${speed} m/s<br> 风向: ${direction} `; } }6. 响应式设计与性能优化
在实际应用中,图表需要适应不同尺寸的屏幕,并且要处理可能的大量数据。
实现响应式设计:
window.addEventListener('resize', function() { myChart.resize(); });对于大数据量的优化策略:
- 使用数据采样(sampling)减少数据点数量
- 启用渐进渲染(progressive rendering)
- 使用更轻量级的图形元素
series: [{ // 风向箭头系列 progressive: 200, progressiveThreshold: 1000 }, { // 风速曲线系列 progressive: 200, progressiveThreshold: 1000 }]7. 完整实现与调试技巧
将以上所有部分组合起来,就得到了一个完整的风向风速可视化图表。在实际开发中,可能会遇到一些常见问题:
箭头方向不正确:
- 检查角度转换公式是否正确
- 确认SVG箭头的初始方向
- 验证数据中的角度值范围
性能问题:
- 减少同时显示的箭头数量
- 简化SVG路径
- 考虑使用精灵图(sprite)替代单个SVG
视觉映射不生效:
- 确认dimension设置正确
- 检查数据格式是否符合预期
- 验证visualMap的pieces配置
一个实用的调试技巧是先在少量数据上测试,确认基本功能正常后再扩展到完整数据集。可以使用console.log输出中间计算结果,验证角度转换等关键步骤是否正确。