Moltes dades que necessitem estan en format CSV
Introducció
En aquest enllaç tens el projecte de suport d’aquesta activitat: https://gitlab.com/xtec/ts/csv
Entorn de treball
Crea un projecte react:
$ bun create vite csv --template react-swc-tsPapaParse
PapaParse és un parser de dades CSV.
Afegeix una dependència amb papaparse
$ bun add papaparse$ bun add --dev @types/papaparseAfegeix aquest import al fitxer index.ts:
import Papa from 'papaparse'Imagina’t que tenim aquestes dades CSV:
const csv = `name,age,emailJohn,32,jonn@gmail.comRuth,51,ruth@gmail.com`Defineix el tipus Person per les nostres dades CSV:
import Papa from "papaparse"
interface Person { name: string age: number email: string}Amb aquesta interfície pots llegir les dades CSV:
const persons = Papa.parse<Person>(csv, { header: true, dynamicTyping: true}).dataAl indicar que la primera fila és una capçalera (“header”), cada fila s’organitza pel nom del camp enlloc d’utilitzar un index.
Per defecte tot es converteix al tipus string.
Amb dynamicTyping: true fas que els números es converteixin en number i els booleans en boolean.
I ja pots mostrar tots els noms en una llista:
import Papa from 'papaparse'
interface Person { name: string age: number email: string}
export default function App() {
const csv = `name,age,emailJohn,32,jonn@gmail.comRuth,51,ruth@gmail.com`
const persons = Papa.parse<Person>(csv, { header: true, dynamicTyping: true }).data
return ( <ul> {persons.map(person => <li>{person.name}</li>)} </ul> )
}Enlloc de mostrar una llista, mostra tots els resultats en una taula:
{% sol %}
return ( <div className='container m-5'> <div className='row align-items-center'> <div className='col-6'> <h3 className='text-center'>Data</h3> <table className='table table-striped mt-5 text-center'> <tr><th>Name</th><th>Age</th><th>Email</th></tr> {persons.map(person => <tr><td>{person.name}</td><td>{person.age}</td><td>{person.email}</td></tr>)} </table> </div> </div> </div> ){% endsol %}
Mou tot el codi a un fitxer FromString.tsx.
Modificar el fitxer App.tsx amb aquest codi:
import FromString from "./FromString"
export default function App() {
return <FromString/>
}Fitxer remot
Pots treballar amb fitxer remots has de passar una URL i un funció “callback”:
import { useEffect, useState } from "react"import Papa from 'papaparse'
export default function App() {
const [data, setData] = useState<any[]>([])
useEffect(() => {
// https://datos.gob.es/es/catalogo/ea0010587-numero-de-estudiantes-de-educacion-superior-que-han-recibido-becas-o-ayudas-segun-el-tipo-de-beca-o-ayuda-recibida-identificador-api-t13-p460-2019-l0-02014-px1
const url = "https://www.ine.es/jaxi/files/tpx/csv_bdsc/43494.csv" Papa.parse(url, { // El fitxer utilitza ; com a delimitador enlloc de , delimiter: ";", download: true, complete: function (results) { setData(results.data); } } ) }, [])
return (<><h3>Data</h3><ViewCSV csv={data} /></> )}
// Funció que crea una taula amb el contingut del fitxer CSVfunction ViewCSV({ csv }: { csv: any[][] }) {
return <table className='table table-striped'> {csv.map(row => <tr> {row.map( item => <td>{item}</td> )} </tr>)} </table>
}Gestiona l’error amb un missatge:
{% sol %}
import { useEffect, useState } from "react"import Papa from 'papaparse'
export default function App() {
const [result, setResult] = useState<{ message: string, data: any[] }>({ message: "Descargando", data: [] })
useEffect(() => {
// https://datos.gob.es/es/catalogo/ea0010587-numero-de-estudiantes-de-educacion-superior-que-han-recibido-becas-o-ayudas-segun-el-tipo-de-beca-o-ayuda-recibida-identificador-api-t13-p460-2019-l0-02014-px1
const url = "https://www.ine.es/jaxi/files/tpx/csv_bdsc/43494.csvXXX" Papa.parse(url, { // El fitxer utilitza ; com a delimitador enlloc de , delimiter: ";", download: true, complete: function (results) {
if (results.errors.length != 0) { setResult({ message: "Error", data: [] });
} else { setResult({ message: "Descargado", data: results.data }); } } } ) }, [])
return ( <div className="container"> <h3 className="text-center">Data</h3> <p className="border border-2 border-info rounded p-2 text-secondary">{result.message}</p> <ViewCSV csv={result.data} /> </div> )}
// Funció que crea una taula amb el contingut del fitxer CSVfunction ViewCSV({ csv }: { csv: any[][] }) {
return <table className='table table-striped'> {csv.map(row => <tr> {row.map(item => <td>{item}</td>)} </tr>)} </table>
}{% endsol %}
Seguir explicat: https://www.papaparse.com/
Plot
https://github.com/javascriptdata/danfojs
import Plot from 'react-plotly.js';import Papa from 'papaparse';import { useEffect, useState } from "react";
export default function App() {
const [result, setResult] = useState({message:"Descargando", data:[]})
useEffect(() => {
// https://datos.gob.es/es/catalogo/ea0010587-numero-de-estudiantes-de-educacion-superior-que-han-recibido-becas-o-ayudas-segun-el-tipo-de-beca-o-ayuda-recibida-identificador-api-t13-p460-2019-l0-02014-px1
const url = "https://www.ine.es/jaxi/files/tpx/csv_bdsc/43494.csv"; Papa.parse(url, { // El fitxer utilitza ; com a delimitador enlloc de , delimiter: ";", download: true, complete: function (results) {
if(results.errors.length > 0){ setResult({message:"Error", data: []}); }else{ setResult({message:"Listo", data: results.data}); } } } ) }, [])
console.log(result.data)
const graphData = [{ x: result.data.slice(1, result.data.length - 1).map(row => row[0]), y: (result.data.slice(1, result.data.length - 1)) .map(row => row[1]) .map(str => str.replace(/\./gi, '')) .map(num => Number(num)), text: result.data.slice(1, result.data.length - 1).map(row => row[1]), type: 'bar' }] // debugger
const layout = { title: "Num of students that have recived a scholarship", }
return <Plot data={graphData} layout={layout} />;}