您现在的位置是:网站首页 > 时间序列数据处理文章详情
时间序列数据处理
陈川
【
ECharts
】
21819人已围观
4717字
时间序列数据的特点
时间序列数据是按时间顺序排列的数据点集合,通常具有以下特点:
- 时间依赖性:当前值与历史值相关
- 趋势性:长期上升或下降的走势
- 季节性:固定周期内的重复模式
- 噪声:随机波动
// 示例时间序列数据
const timeSeriesData = [
['2023-01-01', 156],
['2023-01-02', 178],
['2023-01-03', 192],
// ...更多数据
];
ECharts 中的时间序列处理
ECharts 提供了专门的时间轴(xAxis.type = 'time')来处理时间序列数据。相比普通类别轴,时间轴能自动处理:
- 时间间隔不均匀的情况
- 时间格式化显示
- 动态缩放和平移
- 跨天/月/年的自动刻度计算
option = {
xAxis: {
type: 'time',
axisLabel: {
formatter: '{yyyy}-{MM}-{dd}'
}
},
yAxis: {
type: 'value'
},
series: [{
data: timeSeriesData,
type: 'line'
}]
};
数据预处理技巧
时间格式转换
ECharts 支持多种时间格式,但推荐使用时间戳或ISO格式:
// 将日期字符串转换为时间戳
function processData(rawData) {
return rawData.map(item => {
return [new Date(item[0]).getTime(), item[1]];
});
}
// 或者使用ISO格式
const isoData = [
['2023-01-01T00:00:00', 156],
['2023-01-02T00:00:00', 178]
];
缺失值处理
常见处理方法:
- 线性插值
- 前值填充
- 置零处理
function fillMissingData(data, interval = 86400000 /* 1天 */) {
const result = [];
for (let i = 1; i < data.length; i++) {
const prevTime = new Date(data[i-1][0]).getTime();
const currTime = new Date(data[i][0]).getTime();
const gap = currTime - prevTime;
if (gap > interval) {
const missingCount = Math.round(gap / interval) - 1;
for (let j = 1; j <= missingCount; j++) {
const interpolatedTime = prevTime + j * interval;
const interpolatedValue = data[i-1][1] +
(data[i][1] - data[i-1][1]) * j / (missingCount + 1);
result.push([new Date(interpolatedTime), interpolatedValue]);
}
}
result.push(data[i]);
}
return result;
}
高级时间轴配置
多时间段对比
option = {
xAxis: [{
type: 'time',
gridIndex: 0
}, {
type: 'time',
gridIndex: 1
}],
yAxis: [{
gridIndex: 0
}, {
gridIndex: 1
}],
grid: [{
bottom: '55%'
}, {
top: '55%'
}],
series: [{
data: data2022,
xAxisIndex: 0,
yAxisIndex: 0
}, {
data: data2023,
xAxisIndex: 1,
yAxisIndex: 1
}]
};
动态数据更新
let currentDate = new Date('2023-01-01');
const realTimeData = [];
function updateChart() {
currentDate.setDate(currentDate.getDate() + 1);
const newValue = Math.random() * 200;
realTimeData.push([currentDate.toISOString(), newValue]);
if (realTimeData.length > 30) {
realTimeData.shift();
}
myChart.setOption({
series: [{
data: realTimeData
}]
});
}
setInterval(updateChart, 1000);
性能优化策略
大数据量处理
- 使用采样降频
- 启用渐进渲染
- 使用WebWorker预处理
option = {
series: [{
type: 'line',
progressive: 1000,
progressiveThreshold: 5000,
data: largeTimeSeriesData
}]
};
视觉优化技巧
option = {
dataZoom: [{
type: 'inside',
xAxisIndex: 0,
filterMode: 'filter'
}, {
type: 'slider',
xAxisIndex: 0,
filterMode: 'filter'
}],
visualMap: {
type: 'piecewise',
dimension: 1,
pieces: [{
gt: 200,
color: '#c23531'
}, {
gt: 150,
lte: 200,
color: '#2f4554'
}]
}
};
实际应用案例
股票K线图实现
option = {
xAxis: {
type: 'time',
axisPointer: {
snap: true
}
},
yAxis: {
scale: true
},
series: [{
type: 'candlestick',
data: klineData.map(item => [
item[0], // 时间
item[1], // 开盘价
item[2], // 收盘价
item[3], // 最低价
item[4] // 最高价
]),
itemStyle: {
color: '#ec0000',
color0: '#00da3c',
borderColor: '#8A0000',
borderColor0: '#008F28'
}
}]
};
多周期天气数据
option = {
xAxis: {
type: 'time',
axisLabel: {
formatter: function(value) {
const date = new Date(value);
return `${date.getHours()}时`;
}
}
},
series: [{
data: hourlyTempData,
type: 'line',
smooth: true,
markArea: {
data: [[{
xAxis: '07:00',
itemStyle: { color: 'rgba(255, 173, 177, 0.4)' }
}, {
xAxis: '19:00'
}]]
}
}]
};
交互增强功能
时间范围选择器
option = {
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none'
},
restore: {},
saveAsImage: {}
}
},
dataZoom: [{
type: 'slider',
xAxisIndex: 0,
filterMode: 'filter',
height: 20,
bottom: 10
}]
};
时间点标记
option = {
series: [{
type: 'line',
markPoint: {
data: [{
type: 'max',
name: '最大值'
}, {
type: 'min',
name: '最小值'
}, {
coord: ['2023-06-15', 189],
name: '特殊事件'
}]
}
}]
};