* Nav bar and layout * Main catch all route that loads material from content * Data Literate: demo plus all associated components * content/data-literate/demo.mdx * components/* (pretty much all are related to demo) * lib/markdown.js, lib/mdxUtils.js * api/proxy.js to proxy remote urls (to handle CORs) * content/data-literate.md (DL home page - old data literate home page converted to markdown) * excel-viewer.js: excel viewer demo from data literate * package.json / yarn.lock * Nav: @headlessui/react @heroicons/react/outline @heroicons/react * CSV support for table: papaparse * Excel support for tables etc: xlsx * Vega: react-vega vega vega-lite * MDX: next-mdx-remote (yarn rm @next/mdx)
84 lines
1.9 KiB
JavaScript
84 lines
1.9 KiB
JavaScript
import axios from 'axios'
|
|
import React, { useEffect, useState } from 'react'
|
|
|
|
const papa = require("papaparse")
|
|
|
|
/*
|
|
Simple HTML Table
|
|
usage: <OutTable data={data} cols={cols} />
|
|
data:Array<Array<any> >;
|
|
cols:Array<{name:string, key:number|string}>;
|
|
*/
|
|
export default function Table({ data=[], cols=[], csv='', url='' }) {
|
|
if (csv) {
|
|
const out = parseCsv(csv)
|
|
data = out.rows
|
|
cols = out.cols
|
|
}
|
|
|
|
const [ourdata, setData] = React.useState(data)
|
|
const [ourcols, setCols] = React.useState(cols)
|
|
const [error, setError] = React.useState('')
|
|
|
|
useEffect(() => {
|
|
if (url) {
|
|
loadUrl(url)
|
|
}
|
|
}, [url])
|
|
|
|
function loadUrl(path) {
|
|
// HACK: duplicate of Excel code - maybe refactor
|
|
// if url is external may have CORS issue so we proxy it ...
|
|
if (url.startsWith('http')) {
|
|
const PROXY_URL = window.location.origin + '/api/proxy'
|
|
url = PROXY_URL + '?url=' + encodeURIComponent(url)
|
|
}
|
|
axios.get(url).then((res) => {
|
|
const { rows, fields } = parseCsv(res.data)
|
|
setData(rows)
|
|
setCols(fields)
|
|
})
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<SimpleTable data={ourdata} cols={ourcols} />
|
|
</>
|
|
)
|
|
}
|
|
|
|
/*
|
|
Simple HTML Table
|
|
usage: <OutTable data={data} cols={cols} />
|
|
data:Array<Array<any> >;
|
|
cols:Array<{name:string, key:number|string}>;
|
|
*/
|
|
function SimpleTable({ data=[], cols=[] }) {
|
|
return (
|
|
<div className="table-responsive">
|
|
<table className="table table-striped">
|
|
<thead>
|
|
<tr>{cols.map((c) => <th key={c.key}>{c.name}</th>)}</tr>
|
|
</thead>
|
|
<tbody>
|
|
{data.map((r,i) => <tr key={i}>
|
|
{cols.map(c => <td key={c.key}>{ r[c.key] }</td>)}
|
|
</tr>)}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function parseCsv(csv) {
|
|
csv = csv.trim()
|
|
const rawdata = papa.parse(csv, {header: true})
|
|
const cols = rawdata.meta.fields.map((r,i) => {
|
|
return { key: r, name: r }
|
|
})
|
|
return {
|
|
rows: rawdata.data,
|
|
fields: cols
|
|
}
|
|
}
|