效果图
数据初始化
后端返回的接口数据为
分别对应风速的数据和风向的数据,在同一时间,注意时间不是连续的
数据解析
-
提取风向和风速数据:
const wdiraData = srcData.find(item => item.factorName === 'WDIRA').chartDataList; const wspdaData = srcData.find(item => item.factorName === 'WSPDA').chartDataList;
从原始数据中提取
WDIRA
(风向)和WSPDA
(风速)的分钟数据列表。 -
-
初始化计数数组:
const counts = Array.from({ length: directions }, () => new Array(speedBins).fill(0));
创建一个16(方向)×7(风速区间)的二维数组
counts
,初始值为0,用于统计每个方向-风速组合的数据点数量。
据点:
for (let i = 0; i < totalDataCount; i++) {
const dirValue = parseFloat(wdiraData[i].value);
const speedValue = parseFloat(wspdaData[i].value);
// 分类逻辑...
}
对每个数据点的风向和风速值进行解析。
-
计算风向索引:
javascript
复制
const normalizedAngle = ((dirValue % 360) + 360) % 360; const dirIndex = Math.round(normalizedAngle / 22.5) % 16;
- 将风向规范化为0-359.99度。
- 使用
Math.round
将角度映射到0-15的索引(每22.5度为一个方向)
- 百分比计算:
// 将绝对数量转换为百分比
seriesData = speedBinNames.map((name, bin) => ({
data: counts.map(dir => (dir[bin] / totalDataCount * 100).toFixed(2))
}))
- 可视化渲染:
- 使用极坐标系(polar)和堆叠柱状图(stack)
- 每个扇形区块的总宽度表示该方位出现的总频率
- 不同颜色层表示该方位下不同风速区间所占比例
- 关键配置说明:
radiusAxis: {
max: 100 // 半径轴最大值设为100%
},
series: {
stack: 'a' // 堆叠显示各风速区间
}
这种设计可以同时展示:
- 各风向出现的总频率(通过扇形总宽度)
- 每个风向下不同风速的分布比例(通过颜色堆叠)
- 所有数据的总和为100%(通过百分比计算)
通过这种堆叠式的玫瑰图,可以直观看出:
- 主导风向(最宽的扇形)
- 不同风速在主要风向上的分布情况
- 特殊风速区间(如强风区)的分布模式
var max = 100; // 设置最大占比
const option = {
color: ['#70e7ef', '#3a64e9', '#f34646', '#e43185', '#b53edd', '#cddc39', '#ff9800'],
polar: {
radius: '80%'
},
tooltip: {
formatter: params => {
const direction = params.dataIndex * 22.5;
return `${params.marker}风向=${direction}<br>${params.marker}风速=${params.seriesName}`;
},
borderColor: 'transparent',
backgroundColor: 'rgba(0, 0, 0, 0.1)' // 设置背景颜色为半透明的白色
},
angleAxis: {
type: 'category',
data: ["北","北东北","东北","东东北","东","东东南","东南","南东南",
"南","南西南","西南","西西南","西","西西北","西北","北西北"],
boundaryGap: false,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: { show: false }
},
radiusAxis: {
type: 'value',
min: 0,
max: 100,
axisLine: { show: true },
splitLine: { show: false }
},
radar: {
shape: '',
radius: '80%',
name: {
textStyle: {
color: 'black',
borderRadius: 3,
padding: [3, 5]
}
},
indicator: [
{ name: '北', max: max},
{ name: '北西北', max: max},
{ name: '西北', max: maxSpeed},
{ name: '西西北', max: max},
{ name: '西', max: maxSpeed},
{ name: '西西南', max: max},
{ name: '西南', max: maxSpeed},
{ name: '南西南', max: max},
{ name: '南', max: maxSpeed},
{ name: '南东南', max: max},
{ name: '东南', max: max},
{ name: '东东南', max: max},
{ name: '东', max: maxSpeed},
{ name: '东东北', max: max},
{ name: '东北', max: max},
{ name: '北东北', max: max},
],
zlevel: 10000,
z: 10000
},
legend: {
show: true,
right: 0,
bottom: 0,
type: 'scroll',
orient: 'vertical',
data: props.speedBins.map(bin => bin.label)
},
series: chartData.value.seriesData
}
chartInstance.setOption(option)
}