echarts 用散点图实现象限图
2025.06.06今天我学习了如何使用散点图来做一个象限图,官方文档效果如下:
代码如下:
// 散点数据
let marksData = [{name: '点1',value: [10, 20],},{name: '点2',value: [15, 22],},{name: '点3',value: [34, 51],},{name: '点4',value: [25, 64],},{name: '点5',value: [42, 20],},{name: '点6',value: [32, 15],},{name: '点7',value: [68, 34],},{name: '点8',value: [25, 65],},{name: '点9',value: [45, 56],},{name: '点10',value: [35, 47],}
]
// 中心线
centerLine = [{name: 'y', xAxis: 40},{name: 'x', yAxis: 40}
]
// 中心点
centerMark = [{value: '中心点', coord: [40, 40]}
]option = {tooltip: {axisPointer: {show: true,type: 'cross',lineStyle: {type: 'dashed',width: 1},label: {backgroundColor: '#555'}}},grid: {left: 50,right: 50,bottom: '4%',top: '6%',containLabel: true},xAxis: {scale: true,axisLine: {lineStyle: {color: '#ddd'}},axisLabel: {color: '#666'},splitLine: {lineStyle: {color: '#eee'}}},yAxis: {scale: true,axisLine: {lineStyle: {color: '#ddd'}},axisLabel: {color: '#666'},splitLine: {lineStyle: {color: '#eee'}}},series: [{type: 'scatter',data: marksData,label: {show: true,position: 'bottom',formatter: '{b}'},itemStyle: {shadowBlur: 2,shadowColor: 'rgba(120, 36, 50, 0.5)',shadowOffsetY: 1,color: function (e) {let randomColor = 'rgba(' + Math.floor(Math.random() * 240) + ',' + Math.floor(Math.random() * 240) + ',' + Math.floor(Math.random() * 240) + ',' + '.8' + ')'return randomColor.substring()}},// 各象限区域markArea: {silent: true,data: [// 第一象限[{name: '第一象限',xAxis: 40, // x 轴开始位置yAxis: 70, // y 轴结束位置(直接取最大值)itemStyle: {color: 'rgba(56, 180, 139, .1)'},label: {position: 'inside',color: 'rgba(0, 0, 0, .1)',fontSize: 22}}, {yAxis: 40 // y轴开始位置}],// 第二象限[{name: '第二象限',yAxis: 70, // y 轴结束位置(直接取最大值)itemStyle: {color: 'rgba(68, 97, 123, .1)'},label: {position: 'inside',color: 'rgba(0, 0, 0, .1)',fontSize: 22}}, {xAxis: 40, // x 轴结束位置yAxis: 40 // y轴开始位置}],// 第三象限[{name: '第三象限',yAxis: 40, // y 轴结束位置itemStyle: {color: 'rgba(191, 120, 58, .1)'},label: {position: 'inside',color: 'rgba(0, 0, 0, .1)',fontSize: 22}}, {xAxis: 40, // x 轴结束位置yAxis: 10 // y轴开始位置}],// 第四象限[{name: '第四象限',xAxis: 40, // x 轴开始位置yAxis: 40, // y 轴结束位置itemStyle: {color: 'rgba(116, 83, 153, .1)'},label: {position: 'inside',color: 'rgba(0, 0, 0, .1)',fontSize: 22}}, {yAxis: 10 // y轴开始位置}]]},// 中心点交集象限轴markLine: {silent: true, // 是否不响应鼠标事件precision: 2, // 精度lineStyle: {type: 'solid',color: '#00aca6'},label: {color: '#00aca6',position: 'end',formatter: '{b}'},data: centerLine},// 中心点markPoint: {symbol: 'roundRect',symbolSize: 15,itemStyle: {color: 'rgba(234, 85, 6, .8)'},label: {position: 'top'},data: centerMark}}]
}
然后我自己改装了一下,效果如下:
代码如下:
<template><div style="width:500px;height:500px" ref="scatter"/>
</template><script>
export default{data(){},mounted:{this.get_scatter_charts();//散点图},//散点图get_scatter_charts() {//初始化this.scatter_chart = this.$echarts.init(this.$refs.scatter);//第一个value是x轴的值,第二个value是y轴的值let res_data = [{name:'1',value:[10,20]},{name:'2',value:[11,12]}];let marksData = res_data;const xValues = res_data.map(item => item.value[0]);//获取所有x轴的数据const yValues = res_data.map(item => item.value[1]);//获取所有y轴的数据let xAxis_min = Math.min(...xValues);//获取x轴数据的最小值let xAxis_max = Math.max(...xValues);//获取x轴数据的最大值let yAxis_min = Math.min(...yValues);//获取y轴数据的最小值let yAxis_max = Math.max(...yValues);//获取y轴数据的最大值const avgX = 10.5;//x轴的平均值:累加所有x轴的值/数据的长度const avgY = 16;//y轴的平均值:累加所有y轴的值/数据的长度//marksData = marksData.filter(item => Math.abs(item.value[0]) <= 2 && Math.abs(item.value[1]) <= 3000);//去除异常值(极值)marksData.forEach(item => {item.rate = item.value[0] == 0 ? 0 : Math.round(Math.abs(item.value[1] / item.value[0] / 30));//占比,用于渲染散点的大小item.itemStyle = {color: 'white',}item.label = {show: true,formatter: params => {let label_data = '';if (item.rate >= 25) {//这边是为了防止label太多,占比大于25,才显示labellabel_data = item.name;}return label_data;},textStyle: {color: 'white',fontSize: '1rem',fontWeight: 'bold'},position: item.value[1] >= 0 ? 'top' : 'bottom',//这边根据象限设置展示位置,一、二象限为top,三、四象限为bottom}})marksData.sort((a, b) => {return b.rate - a.rate;})// 中心线let centerLine = [{name: 'y', xAxis: avgX, symbol: 'none'},{name: 'x', yAxis: avgY, symbol: 'none'},]let option = {grid: {left: '5%',right: '5%',bottom: '8%',top: '12%',containLabel: true},xAxis: {name: 'x轴',nameTextStyle: {lineHeight: 490, //标题行高padding: [-30, 0, 0, -440],verticalAlign: "top",color: 'white',fontSize: '1.2rem'},scale: true,axisLine: {lineStyle: {color: 'gray'}},axisLabel: {color: 'white',textStyle: {fontSize: '1rem'}},splitLine: {lineStyle: {color: 'gray'}}},yAxis: {name: 'y轴',nameTextStyle: {lineHeight: 20, //标题行高padding: [100, 0, 0, -170],verticalAlign: "top",color: 'white',fontSize: '1.2rem'},scale: true,axisLine: {lineStyle: {color: 'gray'}},axisLabel: {color: 'white',textStyle: {fontSize: '1rem'}},splitLine: {lineStyle: {color: 'gray'}}},tooltip: {show: true,},series: [{type: 'scatter',data: marksData,symbolSize: params => {//设置散点大小let symbol_size_data = 0;if (params[0] == 0) {symbol_size_data = 5;} else {symbol_size_data = Math.round(Math.abs(params[1] / params[0] / 30));}return symbol_size_data;},// 各象限区域markArea: {silent: true,data: [// 第一象限[{name: '第一象限',xAxis: avgX, // x 轴开始位置yAxis: yAxis_max, // y 轴结束位置(直接取最大值)itemStyle: {color: 'transparent'},label: {position: 'inside',color: 'gray',fontSize: 22}}, {yAxis: avgY // y轴开始位置}],// 第二象限[{name: '第二象限',yAxis: yAxis_max, // y 轴结束位置(直接取最大值)itemStyle: {color: 'transparent'},label: {position: 'inside',color: 'gray',fontSize: 22}}, {xAxis: avgX, // x 轴结束位置yAxis: avgY // y轴开始位置}],// 第三象限[{name: '第三象限',yAxis: yAxis_min, // y 轴结束位置itemStyle: {color: 'transparent'},label: {position: 'inside',color: 'gray',fontSize: 22}}, {xAxis: avgX, // x 轴结束位置yAxis: avgY // y轴开始位置}],// 第四象限[{name: '第四象限',xAxis: avgX, // x 轴开始位置yAxis: yAxis_min, // y 轴结束位置itemStyle: {color: 'transparent'},label: {position: 'inside',color: 'gray',fontSize: 22}}, {yAxis: avgY // y轴开始位置}]]},// 中心点交集象限轴markLine: {silent: true, // 是否不响应鼠标事件precision: 2, // 精度lineStyle: {type: 'solid',color: 'orange',width: 2},label: {show: true,color: 'orange',position: 'start',padding: [0, 0, 0, -40],textStyle: {fontSize: '1rem',fontWeight: 'bold'},formatter: params => {let label = '';if (params.value != 0) {label = params.value;}return label;}},data: centerLine},}]};this.scatter_chart.clear();this.scatter_chart.resize();this.scatter_chart.setOption(option);}
}
</script>