您现在的位置是:网站首页 > 散点图(Scatter Chart)实现文章详情
散点图(Scatter Chart)实现
陈川
【
ECharts
】
56744人已围观
10745字
散点图是一种常见的数据可视化方式,通过二维坐标系中的点来展示两个变量之间的关系。ECharts 提供了强大的散点图功能,支持多种自定义配置,能够满足复杂的数据展示需求。
基本散点图实现
在 ECharts 中创建一个基本散点图非常简单。以下是一个最简示例:
option = {
xAxis: {},
yAxis: {},
series: [{
symbolSize: 20,
data: [
[10, 5],
[0, 8],
[6, 10],
[2, 12],
[8, 9]
],
type: 'scatter'
}]
};
这段代码会生成一个包含5个数据点的散点图。xAxis
和yAxis
定义了坐标轴,series
中的type: 'scatter'
指定了图表类型为散点图。
数据格式与样式定制
ECharts 散点图支持多种数据格式:
- 二维数组格式:
data: [[1, 2], [3, 4], [5, 6]]
- 对象格式:
data: [
{value: [1, 2], name: '点A'},
{value: [3, 4], name: '点B'}
]
样式定制可以通过itemStyle
实现:
series: [{
type: 'scatter',
itemStyle: {
color: '#c23531',
opacity: 0.8,
borderColor: '#ddd',
borderWidth: 1
},
data: [[10, 5], [0, 8], [6, 10]]
}]
气泡图实现
通过设置symbolSize
为动态值,可以创建气泡图:
option = {
xAxis: {},
yAxis: {},
series: [{
data: [
[10, 5, 8],
[0, 8, 15],
[6, 10, 20]
],
type: 'scatter',
symbolSize: function (data) {
return data[2];
}
}]
};
这里第三个数值决定了点的大小,创建了大小不一的气泡效果。
多系列散点图
可以在一个图表中展示多个系列:
option = {
xAxis: {},
yAxis: {},
series: [
{
name: '系列A',
data: [[1, 2], [3, 4], [5, 6]],
type: 'scatter',
itemStyle: {color: '#c23531'}
},
{
name: '系列B',
data: [[2, 1], [4, 3], [6, 5]],
type: 'scatter',
itemStyle: {color: '#2f4554'}
}
]
};
大型数据集优化
当数据量很大时(如超过1000个点),需要进行性能优化:
series: [{
type: 'scatter',
large: true,
largeThreshold: 1000,
data: [...], // 大数据集
progressive: 400,
progressiveThreshold: 3000
}]
这些配置项会启用渐进式渲染,避免界面卡顿。
交互功能增强
ECharts 散点图支持丰富的交互功能:
option = {
// ...其他配置
tooltip: {
formatter: function (params) {
return `X: ${params.value[0]}<br/>Y: ${params.value[1]}`;
}
},
dataZoom: [
{
type: 'slider',
xAxisIndex: 0
},
{
type: 'slider',
yAxisIndex: 0
}
]
};
这段代码添加了自定义提示框内容和双向数据缩放功能。
散点图与地图结合
可以将散点图叠加在地图上:
option = {
geo: {
map: 'china',
roam: true
},
series: [{
coordinateSystem: 'geo',
data: [
{name: '北京', value: [116.46, 39.92, 100]},
{name: '上海', value: [121.48, 31.22, 80]}
],
type: 'scatter',
symbolSize: function (val) {
return val[2] / 10;
}
}]
};
动画效果配置
ECharts 为散点图提供了多种动画效果:
series: [{
type: 'scatter',
animationDuration: 2000,
animationEasing: 'elasticOut',
animationDelay: function (idx) {
return idx * 100;
},
data: [...]
}]
自定义图形标记
可以替换默认的圆形标记为其他形状或图片:
series: [{
type: 'scatter',
symbol: 'path://M0,0L20,0L10,20Z', // 三角形
// 或者使用图片
// symbol: 'image://http://example.com/icon.png',
data: [...]
}]
响应式设计
使散点图适应不同屏幕尺寸:
window.addEventListener('resize', function() {
myChart.resize();
});
option = {
// ...其他配置
grid: {
left: '10%',
right: '10%',
bottom: '15%',
containLabel: true
}
};
高级视觉映射
使用视觉映射组件实现数据到视觉元素的映射:
option = {
visualMap: {
dimension: 2, // 使用第三个维度
min: 0,
max: 100,
inRange: {
color: ['#50a3ba', '#eac736', '#d94e5d'],
symbolSize: [10, 50]
},
calculable: true
},
series: [{
type: 'scatter',
data: [
[12, 23, 34],
[34, 45, 10],
[56, 67, 89]
]
}]
};
多维度数据展示
ECharts 散点图支持展示超过两个维度的数据:
option = {
dataset: {
source: [
['身高', '体重', '年龄', '性别'],
[170, 65, 25, '男'],
[160, 55, 30, '女'],
[180, 80, 28, '男']
]
},
xAxis: {type: 'value'},
yAxis: {type: 'value'},
visualMap: {
dimension: 3,
categories: ['男', '女'],
inRange: {
color: ['#5470c6', '#ee6666']
}
},
series: [{
type: 'scatter',
encode: {
x: '身高',
y: '体重'
}
}]
};
动态数据更新
实现散点图数据的动态更新:
// 初始数据
let data = [];
for (let i = 0; i < 10; i++) {
data.push([Math.random() * 100, Math.random() * 100]);
}
option = {
// ...其他配置
series: [{
type: 'scatter',
data: data
}]
};
// 定时更新
setInterval(function () {
data.shift();
data.push([Math.random() * 100, Math.random() * 100]);
myChart.setOption({
series: [{
data: data
}]
});
}, 1000);
自定义提示框内容
完全自定义提示框的显示内容和样式:
option = {
// ...其他配置
tooltip: {
trigger: 'item',
formatter: function(params) {
return `
<div style="padding:10px">
<h4>${params.seriesName}</h4>
<p>X值: ${params.value[0]}</p>
<p>Y值: ${params.value[1]}</p>
<p style="color:${params.color}">● 数据点</p>
</div>
`;
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#333',
textStyle: {
color: '#fff'
}
}
};
散点图与折线图组合
将散点图与其他图表类型组合使用:
option = {
xAxis: {type: 'category'},
yAxis: {},
series: [
{
data: [120, 200, 150, 80, 70],
type: 'line'
},
{
data: [
{value: [0, 120], symbolSize: 10},
{value: [1, 200], symbolSize: 20},
{value: [2, 150], symbolSize: 15}
],
type: 'scatter'
}
]
};
极坐标系散点图
在极坐标系中创建散点图:
option = {
angleAxis: {},
radiusAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四'],
z: 10
},
polar: {},
series: [{
type: 'scatter',
coordinateSystem: 'polar',
data: [
[0, 0, 10],
[Math.PI / 2, 1, 20],
[Math.PI, 2, 15],
[3 * Math.PI / 2, 3, 25]
],
symbolSize: function (val) {
return val[2];
}
}]
};
散点图与热力图结合
将散点图与热力图结合展示数据密度:
function generateData() {
let data = [];
for (let i = 0; i < 1000; i++) {
data.push([
Math.random() * 100,
Math.random() * 100
]);
}
return data;
}
option = {
xAxis: {},
yAxis: {},
series: [
{
name: '热力图',
type: 'heatmap',
data: generateData(),
pointSize: 10,
blurSize: 15
},
{
name: '散点',
type: 'scatter',
data: [[50, 50], [30, 70], [80, 20]],
symbolSize: 20,
itemStyle: {
color: '#fff',
borderColor: '#333',
borderWidth: 2
}
}
]
};
自定义渲染逻辑
通过renderItem
函数完全自定义散点渲染:
option = {
xAxis: {},
yAxis: {},
series: [{
type: 'custom',
renderItem: function(params, api) {
const coords = api.coord([api.value(0), api.value(1)]);
return {
type: 'circle',
shape: {
cx: coords[0],
cy: coords[1],
r: api.value(2) / 10
},
style: {
fill: api.visual('color'),
stroke: '#333'
}
};
},
data: [
[10, 20, 50],
[50, 30, 80],
[70, 60, 30]
]
}]
};
散点图与平行坐标系
使用平行坐标系展示高维数据:
option = {
parallelAxis: [
{dim: 0, name: '价格'},
{dim: 1, name: '销量'},
{dim: 2, name: '评分'},
{dim: 3, name: '库存'}
],
parallel: {},
series: {
type: 'scatter',
coordinateSystem: 'parallel',
data: [
[12, 56, 4.5, 120],
[24, 34, 3.8, 90],
[18, 45, 4.2, 110]
],
symbolSize: 12
}
};
散点图与3D坐标系
在3D坐标系中创建散点图:
option = {
grid3D: {},
xAxis3D: {type: 'value'},
yAxis3D: {type: 'value'},
zAxis3D: {type: 'value'},
series: [{
type: 'scatter3D',
data: [
[10, 20, 30],
[30, 40, 50],
[50, 60, 70]
],
symbolSize: 20
}]
};
散点图与时间轴
结合时间轴展示动态变化的散点图:
option = {
baseOption: {
timeline: {
axisType: 'category',
autoPlay: true,
playInterval: 1000,
data: ['2020', '2021', '2022']
},
xAxis: {type: 'value'},
yAxis: {type: 'value'},
series: [{
type: 'scatter',
symbolSize: 20
}]
},
options: [
{
series: [{
data: [[10, 20], [15, 25], [20, 30]]
}]
},
{
series: [{
data: [[12, 22], [18, 28], [25, 35]]
}]
},
{
series: [{
data: [[15, 25], [20, 30], [30, 40]]
}]
}
]
};
散点图与数据标注
为特定数据点添加标注:
option = {
xAxis: {},
yAxis: {},
series: [{
type: 'scatter',
data: [
{value: [10, 20], name: '重要点A'},
[15, 25],
[20, 30]
],
markPoint: {
data: [
{name: '最大值', type: 'max'},
{name: '最小值', type: 'min'},
{coord: [10, 20], name: '自定义标注'}
]
}
}]
};
散点图与数据区域缩放
实现数据区域的选择和缩放:
option = {
toolbox: {
feature: {
dataZoom: {},
brush: {
type: ['rect', 'polygon', 'clear']
}
}
},
brush: {
toolbox: ['rect', 'polygon', 'clear'],
brushLink: 'all'
},
xAxis: {},
yAxis: {},
series: [{
type: 'scatter',
data: [...],
selectedMode: 'multiple'
}]
};
散点图与数据聚类
展示聚类分析的散点图:
option = {
xAxis: {},
yAxis: {},
visualMap: {
dimension: 2,
categories: [0, 1, 2],
inRange: {
color: ['#c23531', '#2f4554', '#61a0a8']
}
},
series: [{
type: 'scatter',
data: [
[1.2, 2.3, 0],
[1.4, 2.1, 0],
[3.5, 4.9, 1],
[3.7, 4.7, 1],
[5.8, 6.2, 2],
[5.6, 6.4, 2]
],
symbolSize: 12
}]
};
散点图与回归线
在散点图上添加回归线:
// 假设已经计算好回归线数据
const scatterData = [[1, 2], [2, 3], [3, 3.5], [4, 5]];
const lineData = [[1, 1.8], [4, 4.8]];
option = {
xAxis: {},
yAxis: {},
series: [
{
type: 'scatter',
data: scatterData
},
{
type: 'line',
data: lineData,
lineStyle: {
color: '#f00',
width: 2
},
symbol: 'none'
}
]
};
散点图与误差线
展示带有误差线的散点图:
option = {
xAxis: {},
yAxis: {},
series: [{
type: 'scatter',
data: [
{
value: [10, 20],
symbolSize: 12,
itemStyle: {color: '#c23531'},
// 误差范围
errorX: {value: 1},
errorY: {value: 2}
},
{
value: [15, 25],
symbolSize: 12,
itemStyle: {color: '#2f4554'},
errorX: {value: 1.5},
errorY: {value: 1}
}
]
}]
};
散点图与数据标签
为散点添加数据标签:
option = {
xAxis: {},
yAxis: {},
series: [{
type: 'scatter',
data: [
{value: [10, 20], name: '点A'},
{value: [15, 25], name: '点B'}
],
label: {
show: true,
formatter: function(params) {
return params.name + '\n(' + params.value[0] + ',' + params.value[1] + ')';
},
position: 'top'
}
}]
};
散点图与数据筛选
实现交互式数据筛选:
option = {
legend: {
data:
上一篇: 饼图(Pie Chart)实现
下一篇: 雷达图(Radar Chart)实现