news 2026/6/30 13:30:21

风向可视化实战:从十六方位定义到ECharts动态风向箭头绘制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
风向可视化实战:从十六方位定义到ECharts动态风向箭头绘制

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 }]

这里有几个关键点需要注意:

  1. rotation属性控制箭头的旋转角度。由于SVG箭头的默认方向是向右,我们需要先旋转90度(Math.PI/2)使其向上,再加上风向角度。
  2. 风向角度需要从度数转换为弧度(乘以Math.PI/180)。
  3. api.coord方法将数据值转换为画布坐标。
  4. 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(); });

对于大数据量的优化策略:

  1. 使用数据采样(sampling)减少数据点数量
  2. 启用渐进渲染(progressive rendering)
  3. 使用更轻量级的图形元素
series: [{ // 风向箭头系列 progressive: 200, progressiveThreshold: 1000 }, { // 风速曲线系列 progressive: 200, progressiveThreshold: 1000 }]

7. 完整实现与调试技巧

将以上所有部分组合起来,就得到了一个完整的风向风速可视化图表。在实际开发中,可能会遇到一些常见问题:

  1. 箭头方向不正确:

    • 检查角度转换公式是否正确
    • 确认SVG箭头的初始方向
    • 验证数据中的角度值范围
  2. 性能问题:

    • 减少同时显示的箭头数量
    • 简化SVG路径
    • 考虑使用精灵图(sprite)替代单个SVG
  3. 视觉映射不生效:

    • 确认dimension设置正确
    • 检查数据格式是否符合预期
    • 验证visualMap的pieces配置

一个实用的调试技巧是先在少量数据上测试,确认基本功能正常后再扩展到完整数据集。可以使用console.log输出中间计算结果,验证角度转换等关键步骤是否正确。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/30 13:29:38

原神帧率解锁终极指南:如何轻松突破60帧限制获得流畅体验

原神帧率解锁终极指南&#xff1a;如何轻松突破60帧限制获得流畅体验 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock 想要在原神中享受超越60帧的极致流畅游戏体验吗&#xff1f;genshin…

作者头像 李华
网站建设 2026/6/30 13:27:07

如何彻底解锁原神60帧限制:3步实现120帧极致流畅体验

如何彻底解锁原神60帧限制&#xff1a;3步实现120帧极致流畅体验 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock 你是否厌倦了原神游戏中的60帧限制&#xff0c;想要在高刷新率显示器上体…

作者头像 李华
网站建设 2026/6/30 13:27:00

Agent 入门实战(上篇):宏观篇——从概念到市场

2023 年被称作“大模型元年”&#xff0c;2024 年“AI 应用”井喷&#xff0c;而 2025、2026 年的行业关键词几乎毫无悬念地锁定在了一个词上——Agent&#xff08;智能体&#xff09;。随便打开一个技术论坛或招聘网站&#xff0c;你会发现“Agent 工程师”“智能体开发”“Mu…

作者头像 李华
网站建设 2026/6/30 13:26:35

鸿蒙ArkTS布局之constraintSize完整指南

鸿蒙原生 ArkTS 布局方式之 constraintSize 完整指南&#xff1a;minWidth / maxWidth / minHeight / maxHeightHarmonyOS NEXT API Version 24 ArkTS 声明式 UI 一次搞懂尺寸约束 API 的所有细节&#xff0c;从此告别布局溢出和自适应难题。一、引言 在鸿蒙原生应用开发中&a…

作者头像 李华
网站建设 2026/6/30 13:22:17

鸿蒙 DFX 新工具能力合集

本原创文章帖发布在华为开发者联盟社区&#xff0c;欢迎开发者前往访问评论交流&#xff0c;更多与该内容相关讨论&#xff0c;请点击原帖查看&#xff1a; 鸿蒙 DFX 新工具&能力合集-华为开发者话题 | 华为开发者联盟 备受期待的 HarmonyOS 7.0.0(26) Beta 版本已正式发布…

作者头像 李华