#reactjs #fetch #papaparse #react-highcharts
Вопрос:
Я пытаюсь извлечь и проанализировать CSV-файл в своем проекте ReactJS. Я читаю из потока фрагмент за фрагментом, а затем разбираю его на пары значений [Дата,данные]. Намерение состоит в том, чтобы затем использовать массив значений для загрузки графика Highcharts/Highstock.
import React, { useEffect, useState } from 'react';
import HighchartsReact from 'highcharts-react-official';
import HighStock from "highcharts/highstock";
import Papa from 'papaparse';
async function readAndParseData() {
const response = await fetch(dataURI)
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8')
let values = []
//Keep reading in chunks until finished
let value, done;
while (!done) {
({ value, done } = await reader.read());
if (done) {
break
}
const csv = decoder.decode(value) // the csv text
const results = await Papa.parse(csv, { header: false }) // object with { data, errors, meta }
const rows = results.data // array of objects
//Put data into [[x1,y2], [x2,y2], ...] format
rows.slice(1).forEach(ele => {
values.push([Date.parse(ele[0]), parseFloat(ele[2])])
});
return values
}
}
useEffect(() => {
//Gets and sets graph data
async function getGraphData() {
let graphData = await readAndParseData()
console.log(graphData)
setDataSource(graphData)
}
getGraphData()
}, []);
Проблема, с которой я сталкиваюсь, заключается в том, что я не всегда получаю полные данные CSV, а иногда это просто первый фрагмент или несколько фрагментов. Я попробовал asyncs и ожидает, чтобы он возвращался только после завершения всего потока и всех данных в массиве значений. Что я здесь упускаю?
Ваше здоровье!
Ответ №1:
Для всех, кто застрял на этом, вот что я сделал:
import React, { useEffect, useState } from 'react';
import HighchartsReact from 'highcharts-react-official';
import HighStock from "highcharts/highstock";
import Papa from 'papaparse';
async function readAndParseData() {
const response = await fetch(dataURI)
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8')
//Keep reading in chunks until finished
let csvText = ""
let value, done;
while (!done) {
({ value, done } = await reader.read());
if (done) {
break
}
const csv = decoder.decode(value) // the csv text
csvText = csvText.concat(csv) //concat new csv chunk
}
const results = await Papa.parse(csvText, { header: false }) // object with { data, errors, meta }
const rows = results.data // array of objects
//Put data into [[x1,y2], [x2,y2], ...] format
let values = []
rows.slice(1).forEach(ele => {
values.push([Date.parse(ele[0]), parseFloat(ele[2])])
});
return values
}
useEffect(() => {
//Gets and sets graph data
async function getGraphData() {
let graphData = await readAndParseData()
setDataSource(graphData)
}
getGraphData()
}, []);
Просто продолжайте считывать все данные и декодировать их в одну строку кусок за куском. Затем, после того как все данные будут прочитаны, преобразуйте и установите их.