如何基于数据条件在dygraph中映射数据并绘制时序图
解决Dygraph适配多序列CSV数据的两种方案
Dygraph默认要求数据为宽表格式(每列对应一个序列),你的原始数据是长表格式(每行是单个序列的一个数据点),下面提供两种可行方案:
方案一:转换数据为宽表格式
通过JavaScript将原始长表数据转换为Dygraph需要的宽表结构,示例代码如下:
// 原始CSV字符串(假设已读取到该变量) const rawCsv = `_time,value,Id,provider 2022-09-20T10:43:00Z,1,1,x 2022-09-20T10:43:15Z,2,1,x 2022-09-20T10:43:30Z,3.2,1,x 2022-09-20T10:43:45Z,4,1,x 2022-09-20T10:44:00Z,4.1,1,x 2022-09-20T10:44:15Z,5,1,x 2022-09-20T10:43:00Z,2,2,y 2022-09-20T10:43:15Z,4,2,y 2022-09-20T10:43:30Z,4.5,2,y 2022-09-20T10:43:45Z,4,2,y 2022-09-20T10:44:00Z,5,2,y 2022-09-20T10:44:15Z,6,2,y`; // 解析CSV为数组 const rows = rawCsv.split('\n').slice(1).map(row => row.split(',')); // 按时间分组,整理每个provider的值 const grouped = {}; rows.forEach(row => { const time = row[0]; const value = parseFloat(row[1]); const provider = row[3]; if (!grouped[time]) { grouped[time] = { time }; } grouped[time][provider] = value; }); // 转换为宽表CSV字符串 const headers = ['time', ...new Set(rows.map(row => row[3]))]; const wideRows = [headers.join(','), ...Object.values(grouped).map(item => { return headers.map(col => item[col] || '').join(','); })].join('\n'); // 初始化Dygraph new Dygraph(document.getElementById('graph'), wideRows, { xlabel: '时间', ylabel: '数值', legend: 'always' });
方案二:直接适配原始数据(无需转换)
通过Dygraph的自定义数据访问器和series配置,直接处理长表数据,无需转换格式,示例代码如下:
// 原始CSV字符串 const rawCsv = `_time,value,Id,provider 2022-09-20T10:43:00Z,1,1,x 2022-09-20T10:43:15Z,2,1,x 2022-09-20T10:43:30Z,3.2,1,x 2022-09-20T10:43:45Z,4,1,x 2022-09-20T10:44:00Z,4.1,1,x 2022-09-20T10:44:15Z,5,1,x 2022-09-20T10:43:00Z,2,2,y 2022-09-20T10:43:15Z,4,2,y 2022-09-20T10:43:30Z,4.5,2,y 2022-09-20T10:43:45Z,4,2,y 2022-09-20T10:44:00Z,5,2,y 2022-09-20T10:44:15Z,6,2,y`; // 解析CSV为结构化数组 const data = rawCsv.split('\n').slice(1).map(row => { const cols = row.split(','); return { time: new Date(cols[0]), value: parseFloat(cols[1]), provider: cols[3] }; }); // 获取所有唯一的provider const providers = [...new Set(data.map(item => item.provider))]; // 初始化Dygraph new Dygraph(document.getElementById('graph'), data, { // 自定义数据访问器 xValue: (item) => item.time.getTime(), yValue: (item, seriesName) => item.provider === seriesName ? item.value : null, // 配置每个序列 series: providers.reduce((acc, provider) => { acc[provider] = { label: provider, axis: 'y' }; return acc; }, {}), xlabel: '时间', ylabel: '数值', legend: 'always', connectSeparatedPoints: true });
内容的提问来源于stack exchange,提问作者redfox
相关产品推荐
相关产品推荐

