feat: 构建泡泡玛特相关图表
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 极简 CSV 解析:首行表头,逗号分隔,自动把数字列转成 number
|
||||
* 不处理引号内的逗号 —— 财报数据用不上,保持简单
|
||||
*/
|
||||
export function parseCSV(text) {
|
||||
const lines = text
|
||||
.trim()
|
||||
.split(/\r?\n/)
|
||||
.filter((l) => l.trim() && !l.trim().startsWith('#'));
|
||||
|
||||
const headers = lines[0].split(',').map((h) => h.trim());
|
||||
|
||||
return lines.slice(1).map((line) => {
|
||||
const cells = line.split(',').map((c) => c.trim());
|
||||
const row = {};
|
||||
headers.forEach((h, i) => {
|
||||
const raw = cells[i];
|
||||
const num = Number(raw);
|
||||
row[h] = raw !== '' && !Number.isNaN(num) ? num : raw;
|
||||
});
|
||||
return row;
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadCSV(path) {
|
||||
const res = await fetch(path);
|
||||
if (!res.ok) throw new Error(`读取 ${path} 失败:${res.status}`);
|
||||
return parseCSV(await res.text());
|
||||
}
|
||||
|
||||
/** 取某一列 */
|
||||
export function col(rows, key) {
|
||||
return rows.map((r) => r[key]);
|
||||
}
|
||||
Reference in New Issue
Block a user