雷达图是一种基于极坐标系的可视化图表,用于展示多维数据之间的关系。它通过设置不同的角度和半径来表示不同的指标数据,可以直观地展示数据之间的差异和联系。
这个就不多说了,都是前期的准备工作,这里直接看代码吧,有不了解的小伙伴可以看我前面的文章。
npm install echarts --save
import * as echarts from 'echarts';
<div ref="chart" style="width: 50%;height: 400px;"></div>
const chartData = [
{ name: '指标一', value: 80 },
{ name: '指标二', value: 90 },
{ name: '指标三', value: 70 },
{ name: '指标四', value: 60 },
{ name: '指标五', value: 50 }
];
import { ref, onMounted } from 'vue'
const chart = ref(null)
前期的工作准备好了,接下来我们就开始绘制雷达图
首先我们定义了一个 chartOptions对象,用于设置图表的基本配置,包括标题、图例、坐标轴和数据系列等信息;
const chartOptions = {
title: {
text: '雷达图示例'
},
tooltip: {},
legend: {
data: ['数据']
},
radar: {
indicator: chartData.map(item => ({ name: item.name, max: 100 })),
radius: '70%',
center: ['50%', '50%']
},
series: [{
name: '数据',
type: 'radar',
data: [
{
value: chartData.map(item => item.value),
name: '数据'
}
]
}]
};
在这个配置项里,我们配置了标题title,提示框tooltip,图例legend,雷达图的配置项radar和系列配置项series。
其中,在radar配置项中,我们前面定义的chartData数组中的数据通过数组的map函数获取到数组对象中的name,作为指示器配置给radar的indicator属性;radius指定雷达图的半径,center指定雷达图的位置
在series配置项中,我们将前面定义的chartData数组中数据通过map函数获取里面的value值,将其配置给series配置data下的value属性,这样就完成了简单的配置
然后,我们在onMounted函数中,通过echarts的init函数将我们模板中定义的div作为容器传递给Echarts的实例myChart
调用Echarts的setOption函数,将上面定义的配置项传入到myChart实例中
代码如下:
onMounted(() => {
const myChart = echarts.init(chart.value)
myChart.setOption(chartOptions);
})
在实际的项目开发中,我们绘制的雷达图往往比较复杂,这就需要我们先对数据进行一些处理,例如对数据进行归一化处理、设置不同的数据范围等。下面我们对上面实现的雷达图的数据进行归一化处理。
数据归一化处理是将不同数据的取值范围映射到相同的区间内,以便进行比较和分析。在数据处理中,由于不同数据的取值范围可能相差较大,这会导致某些指标的权重过大或过小,从而影响分析结果的准确性。通过数据归一化处理,可以消除这种影响,使得不同指标的权重更加均衡,从而提高分析的准确性。常见的归一化方法包括最小-最大归一化、Z-score 归一化等。
最小-最大归一化(Min-Max Normalization)是一种简单的线性归一化方法,它将原始数据映射到一个指定的值域范围内(通常是 [0,1] 或 [-1,1] 区间内),公式为:
x ′ = x − min ( x ) max ( x ) − min ( x ) × ( m a x − m i n ) + m i n x' = \frac{x - \min(x)}{\max(x) - \min(x)} \times (max - min) + min x′=max(x)−min(x)x−min(x)×(max−min)+min
其中, x x x 是原始数据, x ′ x' x′ 是归一化后的数据, min ( x ) \min(x) min(x) 和 max ( x ) \max(x) max(x) 分别是原始数据的最小值和最大值, m i n min min 和 m a x max max 分别是指定的值域范围的最小值和最大值。
Z-score 归一化(Standardization)是一种基于原始数据的均值和标准差进行归一化的方法,它将原始数据映射到均值为 0,标准差为 1 的分布上,公式为:
x ′ = x − μ σ x' = \frac{x - \mu}{\sigma} x′=σx−μ
其中, x x x 是原始数据, x ′ x' x′ 是归一化后的数据, μ \mu μ 是原始数据的均值, σ \sigma σ 是原始数据的标准差。
最小-最大归一化适用于数据取值范围已知的情况下,可以将数据映射到指定的值域范围内,方便进行比较和分析。而 Z-score 归一化则适用于数据分布未知的情况下,可以将数据映射到均值为 0,标准差为 1 的分布上,方便进行比较和分析。
要对chartData中的数据进行归一化,我们使用上面介绍的最小-最大归一化方法,首先计算出chartData数组中的最大值,并将每个数据项的值除以最大值后乘以 100,从而得到归一化后的数据。然后,我们使用归一化后的数据绘制雷达图。
代码如下:
const maxDataValue = Math.max(...chartData.map(item => item.value));
const normalizedChartData = chartData.map(item => ({
name: item.name,
value: item.value / maxDataValue * 100
}));
将我们上面计算的归一化后的数据normalizedChartData 替换掉我们在Echarts配置项中的chartData数据
const chartOptions = {
title: {
text: '雷达图示例'
},
tooltip: {},
legend: {
data: ['数据']
},
radar: {
indicator: normalizedChartData.map(item => ({ name: item.name, max: 100 })),
radius: '70%',
center: ['50%', '50%']
},
series: [{
name: '数据',
type: 'radar',
data: [
{
value: normalizedChartData.map(item => item.value),
name: '数据'
}
]
}]
};
前面我们已经实现了雷达图,但是这个雷达图看起来效果平平,很难吸引人的眼球,下面我从背景色,填充色、透明度、系列样式、雷达图的填充颜色和边框颜色等方面进行优化
const chartOptions = {
color: ['#000'],
backgroundColor: {
type: 'radial',
x: 0.4,
y: 0.4,
r: 0.35,
colorStops: [{
offset: 0,
color: '#895355' // 0% 处的颜色
}, {
offset: .4,
color: '#593640' // 100% 处的颜色
}, {
offset: 1,
color: '#39273d' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
title: {
text: '雷达图示例',
textStyle:{
color:'#fff'
}
},
tooltip: {},
legend: {
data: ['数据'],
textStyle:{
color:'#fff'
}
},
radar: {
indicator: normalizedChartData.map(item => ({ name: item.name, max: 100 })),
radius: '70%',
center: ['50%', '50%'],
splitArea: {
areaStyle: {
color: [
'rgba(48, 105, 199, .1)',
'rgba(48, 105, 199, .2)',
'rgba(48, 105, 199, .4)',
'rgba(48, 105, 199, .6)',
'rgba(48, 105, 199, .8)',
'rgba(48, 105, 199, 1)',
].reverse(),
},
},
axisLine: {
//指向外圈文本的分隔线样式
lineStyle: {
color: 'rgba(37, 100, 214, 1)',
width: 2,
},
},
splitLine: {
lineStyle: {
width: 2,
color: 'rgba(37, 100, 214, 1)',
},
},
},
series: [{
name: '数据',
type: 'radar',
symbol: 'circle',
symbolSize: 10,
lineStyle: {
color: "#70EDFC",
width: 2,
},
itemStyle: {
color: '#ffffff',
borderColor: "#70EDFC",
borderWidth: 2,
opacity: 1,
},
data: [
{
value: normalizedChartData.map(item => item.value),
name: '数据',
itemStyle: {
lineStyle: {
color: 'rgba(112, 237, 252, .5)',
},
shadowColor: 'rgba(112, 237, 252, .5)',
shadowBlur: 1,
},
areaStyle: {
color: 'rgba(112, 237, 252, .5)',
},
}
]
}]
};
上面代码中,我使用 splitArea 属性设置雷达图的背景,使用 areaStyle属性设置背景的颜色和透明度。然后,使用areaStyle 和 lineStyle属性分别设置雷达图的填充颜色和边框颜色。使用symbol和symbolSize设置雷达图的各个点位圆形。