[examples/data-literate][m]: factor our a working markdown+CSV (data literate) example from site (where we already had a demo).

* removed a few extraneous things
* added the README.md with some instructions
This commit is contained in:
Rufus Pollock 2022-02-21 12:25:46 +01:00
parent 99c5e358a1
commit 3a0f4e7b96
22 changed files with 5817 additions and 0 deletions

View File

@ -0,0 +1,57 @@
This example renders markdown + CSV into an elegant web page. These type of data setup we term [data literate][]
[data literate]: https://portaljs.org/data-literate
## How to use
```bash
npx create-next-app -e https://github.com/datopian/portal.js/tree/main/examples/data-literate
# choose a name for your portal when prompted e.g. your-portal or go with default my-app
# then run it
cd your-portal
yarn #install packages
yarn dev # start app in dev mode
```
You should see the demo portal running with the example dataset provided:
TODO
### Use your own dataset
You can try it out with your own data literate setups:
In the directory of your portal do:
```bash
export PORTAL_DATASET_PATH=/path/to/my/dataset
```
Then restart the dev server:
```
yarn dev
```
Check the portal page and it should have updated e.g. like:
TODO
### Static Export
Build the export:
```
yarn build
```
Results will be in `out/` subfolder.
To test you will need to run a local webserver in the folder (just opening the relevant file in your browser won't work):
```
cd out
python3 -m http.server
```

View File

@ -0,0 +1,45 @@
import Layout from '../components/Layout'
import { MDXRemote } from 'next-mdx-remote'
import dynamic from 'next/dynamic'
import Head from 'next/head'
import Link from 'next/link'
import { Vega, VegaLite } from 'react-vega'
// Custom components/renderers to pass to MDX.
// Since the MDX files aren't loaded by webpack, they have no knowledge of how
// to handle import statements. Instead, you must include components in scope
// here.
const components = {
Table: dynamic(() => import('../components/Table')),
Excel: dynamic(() => import('../components/Excel')),
// TODO: try and make these dynamic ...
Vega: Vega,
VegaLite: VegaLite,
LineChart: dynamic(() => import('../components/LineChart')),
Head,
}
export default function DataLiterate({ children, source, frontMatter }) {
return (
<Layout title={frontMatter.title}>
<div className="prose mx-auto">
<header>
<div className="mb-6">
<h1>{frontMatter.title}</h1>
{frontMatter.author && (
<div className="-mt-6"><p className="opacity-60 pl-1">{frontMatter.author}</p></div>
)}
{frontMatter.description && (
<p className="description">{frontMatter.description}</p>
)}
</div>
</header>
<main>
<MDXRemote {...source} components={components} />
</main>
</div>
</Layout>
)
}

View File

@ -0,0 +1,74 @@
import axios from 'axios'
import XLSX from 'xlsx'
import React, { useEffect, useState } from 'react'
import Table from './Table'
export default function Excel ({ src='' }) {
const [data, setData] = React.useState([])
const [cols, setCols] = React.useState([])
const [workbook, setWorkbook] = React.useState(null)
const [error, setError] = React.useState('')
const [hasMounted, setHasMounted] = React.useState(0)
// so this is here so we re-render this in the browser
// and not just when we build the page statically in nextjs
useEffect(() => {
if (hasMounted==0) {
handleUrl(src)
}
setHasMounted(1)
})
function handleUrl(url) {
// 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, {
responseType: 'arraybuffer'
}).then((res) => {
let out = new Uint8Array(res.data)
let workbook = XLSX.read(out, {type: "array"})
// Get first worksheet
const wsname = workbook.SheetNames[0]
const ws = workbook.Sheets[wsname]
// Convert array of arrays
const datatmp = XLSX.utils.sheet_to_json(ws, {header:1})
const colstmp = make_cols(ws['!ref'])
setData(datatmp)
setCols(colstmp)
setWorkbook(workbook)
}).catch((e) => {
setError(e.message)
})
}
return (
<>
{error &&
<div>
There was an error loading the excel file at {src}:
<p>{error}</p>
</div>
}
{workbook &&
<ul>
{workbook.SheetNames.map((value, index) => {
return <li key={index}>{value}</li>
})}
</ul>
}
<Table data={data} cols={cols} />
</>
)
}
/* generate an array of column objects */
const make_cols = refstr => {
let o = [], C = XLSX.utils.decode_range(refstr).e.c + 1
for(var i = 0; i < C; ++i) o[i] = {name:XLSX.utils.encode_col(i), key:i}
return o
}

View File

@ -0,0 +1,29 @@
import Link from 'next/link'
import Head from 'next/head'
export default function Layout({ children, title = 'Home' }) {
return (
<>
<Head>
<title>Portal.JS - {title}</title>
<link rel="icon" href="/favicon.ico" />
<meta charSet="utf-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<div className="mx-auto p-6">
{children}
</div>
<footer className="flex items-center justify-center w-full h-24 border-t">
<a
className="flex items-center justify-center"
href="https://datopian.com/"
target="_blank"
rel="noopener noreferrer"
>
Built by{' '}
<img src="/datopian-logo.png" alt="Datopian Logo" className="h-6 ml-2" />
</a>
</footer>
</>
)
}

View File

@ -0,0 +1,33 @@
import { Vega, VegaLite } from 'react-vega'
export default function LineChart( { data=[] }) {
var tmp = data
if (Array.isArray(data)) {
tmp = data.map((r,i) => {
return { x: r[0], y: r[1] }
})
}
const vegaData = { "table": tmp }
const spec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"mark": "line",
"data": {
"name": "table"
},
"encoding": {
"x": {
"field": "x",
"timeUnit": "year",
"type": "temporal"
},
"y": {
"field": "y",
"type": "quantitative"
}
}
}
return (
<VegaLite data={ vegaData } spec={ spec } />
)
}

View File

@ -0,0 +1,83 @@
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
}
}

View File

@ -0,0 +1,268 @@
---
title: Demo
---
This demos and documents Data Literate features live.
You can see the raw source of this page here: https://raw.githubusercontent.com/datopian/data-literate/main/content/demo.mdx
## Table of Contents
## GFM
We can have github-flavored markdown including markdown tables, auto-linked links and checklists:
```
https://github.com/datopian/portal.js
| a | b |
|---|---|
| 1 | 2 |
* [x] one thing to do
* [ ] a second thing to do
```
https://github.com/datopian/portal.js
| a | b |
|---|---|
| 1 | 2 |
* [x] one thing to do
* [ ] a second thing to do
## Footnotes
```
here is a footnote reference[^1]
[^1]: a very interesting footnote.
```
here is a footnote reference[^1]
[^1]: a very interesting footnote.
## Frontmatter
Posts can have frontmatter like:
```
---
title: Hello World
author: Rufus Pollock
---
```
The title and description are pulled from the MDX file and processed using `gray-matter`. Additionally, links are rendered using a custom component passed to `next-mdx-remote`.
## A Table of Contents
You can create a table of contents by having a markdown heading named `Table of Contents`. You can see an example at the start of this post.
## A Table
You can create tables ...
```
<Table cols={[
{ key: 'id', name: 'ID' },
{ key: 'firstName', name: 'First name' },
{ key: 'lastName', name: 'Last name' },
{ key: 'age', name: 'Age' }
]} data={[
{ id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 },
{ id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 },
{ id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 },
{ id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 },
{ id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 },
{ id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 },
{ id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 },
]}
/>
```
<Table cols={[
{ key: 'id', name: 'ID' },
{ key: 'firstName', name: 'First name' },
{ key: 'lastName', name: 'Last name' },
{ key: 'age', name: 'Age' }
]} data={[
{ id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 },
{ id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 },
{ id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 },
{ id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 },
{ id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 },
{ id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 },
{ id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 },
]}
/>
### Table from Raw CSV
You can also pass raw CSV as the content ...
```
<Table csv={`
Year,Temp Anomaly
1850,-0.418
2020,0.923
`} />
```
<Table csv={`
Year,Temp Anomaly,
1850,-0.418
2020,0.923
`} />
### Table from a URL
<Table url='https://raw.githubusercontent.com/datopian/data-literate/main/public/_files/HadCRUT.5.0.1.0.analysis.summary_series.global.annual.csv' />
```
<Table url='https://raw.githubusercontent.com/datopian/data-literate/main/public/_files/HadCRUT.5.0.1.0.analysis.summary_series.global.annual.csv' />
```
## Charts
You can create charts using a simple syntax.
### Line Chart
<LineChart data={
[
["1850",-0.41765878],
["1851",-0.2333498],
["1852",-0.22939907],
["1853",-0.27035445],
["1854",-0.29163003]
]
}
/>
```
<LineChart data={
[
["1850",-0.41765878],
["1851",-0.2333498],
["1852",-0.22939907],
["1853",-0.27035445],
["1854",-0.29163003]
]
}
/>
```
NB: we have quoted years as otherwise not interpreted as dates but as integers ...
### Vega and Vega Lite
You can using vega or vega-lite. Here's an example using vega-lite:
<VegaLite data={ { "table": [
{
"y": -0.418,
"x": 1850
},
{
"y": 0.923,
"x": 2020
}
]
}
} spec={
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"mark": "bar",
"data": {
"name": "table"
},
"encoding": {
"x": {
"field": "x",
"type": "ordinal"
},
"y": {
"field": "y",
"type": "quantitative"
}
}
}
} />
```jsx
<VegaLite data={ { "table": [
{
"y": -0.418,
"x": 1850
},
{
"y": 0.923,
"x": 2020
}
]
}
} spec={
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"mark": "bar",
"data": {
"name": "table"
},
"encoding": {
"x": {
"field": "x",
"type": "ordinal"
},
"y": {
"field": "y",
"type": "quantitative"
}
}
}
} />
```
#### Line Chart from URL with Tooltip
https://vega.github.io/vega-lite/examples/interactive_multi_line_pivot_tooltip.html
<VegaLite spec={
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "/_files/HadCRUT.5.0.1.0.analysis.summary_series.global.annual.csv"},
"width": 600,
"height": 250,
"mark": "line",
"encoding": {
"x": {"field": "Time", "type": "temporal"},
"y": {"field": "Anomaly (deg C)", "type": "quantitative"},
"tooltip": {"field": "Anomaly (deg C)", "type": "quantitative"}
}
}
} />
## Display Excel Files
Local file ...
```
<Excel src='/_files/eight-centuries-of-global-real-interest-rates-r-g-and-the-suprasecular-decline-1311-2018-data.xlsx' />
```
<Excel src='/_files/eight-centuries-of-global-real-interest-rates-r-g-and-the-suprasecular-decline-1311-2018-data.xlsx' />
Remote files work too (even without CORS) thanks to proxying:
```
<Excel src='https://github.com/datasets/awesome-data/files/6604635/eight-centuries-of-global-real-interest-rates-r-g-and-the-suprasecular-decline-1311-2018-data.xlsx' />
```
<Excel src='https://github.com/datasets/awesome-data/files/6604635/eight-centuries-of-global-real-interest-rates-r-g-and-the-suprasecular-decline-1311-2018-data.xlsx' />

View File

@ -0,0 +1,33 @@
import matter from 'gray-matter'
import toc from 'remark-toc'
import slug from 'remark-slug'
import gfm from 'remark-gfm'
import footnotes from 'remark-footnotes'
import { serialize } from 'next-mdx-remote/serialize'
/**
* Parse a markdown or MDX file to an MDX source form + front matter data
*
* @source: the contents of a markdown or mdx file
* @returns: { mdxSource: mdxSource, frontMatter: ...}
*/
const parse = async function(source) {
const { content, data } = matter(source)
const mdxSource = await serialize(content, {
// Optionally pass remark/rehype plugins
mdxOptions: {
remarkPlugins: [gfm, toc, slug, footnotes],
rehypePlugins: [],
},
scope: data,
})
return {
mdxSource: mdxSource,
frontMatter: data
}
}
export default parse

View File

@ -0,0 +1,23 @@
import fs from 'fs'
import glob from 'glob'
import path from 'path'
// POSTS_PATH is useful when you want to get the path to a specific file
export const POSTS_PATH = path.join(process.cwd(), 'content')
const walkSync = (dir, filelist = []) => {
fs.readdirSync(dir).forEach(file => {
filelist = fs.statSync(path.join(dir, file)).isDirectory()
? walkSync(path.join(dir, file), filelist)
: filelist.concat(path.join(dir, file))
})
return filelist
}
// postFilePaths is the list of all mdx files inside the POSTS_PATH directory
export const postFilePaths = walkSync(POSTS_PATH)
.map((file) => { return file.slice(POSTS_PATH.length) })
// Only include md(x) files
.filter((path) => /\.mdx?$/.test(path))

View File

@ -0,0 +1,38 @@
{
"name": "docs",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"build": "next build && next export",
"start": "next start"
},
"dependencies": {
"@headlessui/react": "^1.3.0",
"@heroicons/react": "^1.0.3",
"@mdx-js/loader": "^1.6.22",
"@tailwindcss/typography": "^0.4.0",
"autoprefixer": "^10.0.4",
"frictionless.js": "^0.13.4",
"gray-matter": "^4.0.3",
"next": "11.1.3",
"next-mdx-remote": "^3.0.4",
"papaparse": "^5.3.1",
"postcss": "^8.2.10",
"prop-types": "^15.7.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-vega": "^7.4.4",
"remark": "^13.0.0",
"remark-footnotes": "^3.0.0",
"remark-gfm": "^1.0.0",
"remark-html": "^13.0.2",
"remark-slug": "^6.1.0",
"remark-toc": "^7.2.0",
"tailwindcss": "^2.2.16",
"vega": "^5.20.2",
"vega-lite": "^5.1.0",
"xlsx": "^0.17.0"
}
}

View File

@ -0,0 +1,48 @@
import fs from 'fs'
import path from 'path'
import parse from '../lib/markdown.js'
import DataLiterate from '../components/DataLiterate'
import { postFilePaths, POSTS_PATH } from '../lib/mdxUtils'
export default function PostPage({ source, frontMatter }) {
return (
<DataLiterate source={source} frontMatter={frontMatter} />
)
}
export const getStaticProps = async ({ params }) => {
const mdxPath = path.join(POSTS_PATH, `${params.slug.join('/')}.mdx`)
const postFilePath = fs.existsSync(mdxPath) ? mdxPath : mdxPath.slice(0, -1)
const source = fs.readFileSync(postFilePath)
const { mdxSource, frontMatter } = await parse(source)
return {
props: {
source: mdxSource,
frontMatter: frontMatter,
},
}
}
export const getStaticPaths = async () => {
var paths = postFilePaths
// Remove file extensions for page paths
.map((path) => path.replace(/\.mdx?$/, ''))
// Map the path into the static paths object required by Next.js
paths = paths.map((slug) => {
// /demo => [demo]
const parts = slug.slice(1).split('/')
return { params: { slug: parts } }
})
return {
paths,
fallback: false,
}
}

View File

@ -0,0 +1,8 @@
import '../styles/globals.css'
import '../styles/tailwind.css'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp

View File

@ -0,0 +1,26 @@
import axios from 'axios'
export default function handler(req, res) {
if (!req.query.url) {
res.status(200).send({
error: true,
info: 'No url to proxy in query string i.e. ?url=...'
})
return
}
axios({
method: 'get',
url: req.query.url,
responseType:'stream'
})
.then(resp => {
resp.data.pipe(res)
})
.catch(err => {
res.status(400).send({
error: true,
info: err.message,
detailed: err
})
})
}

View File

@ -0,0 +1,8 @@
// If you want to use other PostCSS plugins, see the following:
// https://tailwindcss.com/docs/using-with-preprocessors
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@ -0,0 +1,173 @@
Time,Anomaly (deg C),Lower confidence limit (2.5%),Upper confidence limit (97.5%)
1850,-0.41765878,-0.589203,-0.24611452
1851,-0.2333498,-0.41186792,-0.054831687
1852,-0.22939907,-0.40938243,-0.04941572
1853,-0.27035445,-0.43000934,-0.110699534
1854,-0.29163003,-0.43282393,-0.15043613
1855,-0.2969512,-0.43935776,-0.15454465
1856,-0.32035372,-0.46809322,-0.1726142
1857,-0.46723005,-0.61632216,-0.31813794
1858,-0.3887657,-0.53688604,-0.24064532
1859,-0.28119546,-0.42384982,-0.13854107
1860,-0.39016518,-0.5389766,-0.24135375
1861,-0.42927712,-0.5972301,-0.26132414
1862,-0.53639776,-0.7037096,-0.36908585
1863,-0.3443432,-0.5341645,-0.1545219
1864,-0.4654367,-0.6480974,-0.282776
1865,-0.33258784,-0.5246526,-0.14052312
1866,-0.34126064,-0.52183825,-0.16068307
1867,-0.35696334,-0.55306214,-0.16086453
1868,-0.35196072,-0.52965826,-0.17426313
1869,-0.31657043,-0.47642276,-0.15671812
1870,-0.32789087,-0.46867347,-0.18710826
1871,-0.3685807,-0.5141493,-0.22301209
1872,-0.32804197,-0.4630833,-0.19300064
1873,-0.34133235,-0.4725396,-0.21012507
1874,-0.3732512,-0.5071426,-0.2393598
1875,-0.37562594,-0.514041,-0.23721085
1876,-0.42410994,-0.56287116,-0.28534868
1877,-0.101108834,-0.22982001,0.027602348
1878,-0.011315193,-0.13121258,0.10858219
1879,-0.30363432,-0.43406433,-0.1732043
1880,-0.31583208,-0.44015095,-0.19151321
1881,-0.23224552,-0.35793498,-0.10655605
1882,-0.29553008,-0.4201501,-0.17091006
1883,-0.3464744,-0.4608177,-0.23213111
1884,-0.49232006,-0.6026686,-0.38197154
1885,-0.47112358,-0.5830682,-0.35917896
1886,-0.42090362,-0.5225382,-0.31926903
1887,-0.49878576,-0.61655986,-0.3810117
1888,-0.37937889,-0.49332377,-0.265434
1889,-0.24989556,-0.37222093,-0.12757017
1890,-0.50685817,-0.6324095,-0.3813068
1891,-0.40131494,-0.5373699,-0.26525995
1892,-0.5075585,-0.64432853,-0.3707885
1893,-0.49461925,-0.6315314,-0.35770702
1894,-0.48376393,-0.6255681,-0.34195974
1895,-0.4487516,-0.58202064,-0.3154826
1896,-0.28400728,-0.4174015,-0.15061308
1897,-0.25980017,-0.39852425,-0.12107607
1898,-0.48579213,-0.6176492,-0.35393503
1899,-0.35543364,-0.48639694,-0.22447036
1900,-0.23447904,-0.3669676,-0.10199049
1901,-0.29342857,-0.42967388,-0.15718324
1902,-0.43898427,-0.5754281,-0.30254042
1903,-0.5333264,-0.66081935,-0.40583345
1904,-0.5975614,-0.7288325,-0.46629035
1905,-0.40775132,-0.5350291,-0.28047356
1906,-0.3191393,-0.45052385,-0.18775477
1907,-0.5041577,-0.6262818,-0.38203365
1908,-0.5138707,-0.63748026,-0.3902612
1909,-0.5357649,-0.6526296,-0.41890016
1910,-0.5310242,-0.6556868,-0.40636164
1911,-0.5392051,-0.66223973,-0.4161705
1912,-0.47567302,-0.5893311,-0.36201498
1913,-0.46715254,-0.5893755,-0.34492958
1914,-0.2625924,-0.38276345,-0.1424214
1915,-0.19184391,-0.32196194,-0.06172589
1916,-0.42020997,-0.5588941,-0.28152588
1917,-0.54301953,-0.6921192,-0.3939199
1918,-0.42458433,-0.58198184,-0.26718682
1919,-0.32551822,-0.48145813,-0.1695783
1920,-0.2985808,-0.44860035,-0.14856121
1921,-0.24067703,-0.38175339,-0.09960067
1922,-0.33922812,-0.46610323,-0.21235302
1923,-0.31793055,-0.444173,-0.1916881
1924,-0.3120622,-0.4388317,-0.18529275
1925,-0.28242525,-0.4147755,-0.15007503
1926,-0.12283547,-0.25264767,0.006976739
1927,-0.22940508,-0.35135695,-0.10745319
1928,-0.20676155,-0.33881804,-0.074705064
1929,-0.39275664,-0.52656746,-0.25894582
1930,-0.1768054,-0.29041144,-0.06319936
1931,-0.10339768,-0.2126916,0.0058962475
1932,-0.14546166,-0.25195515,-0.0389682
1933,-0.32234442,-0.4271004,-0.21758842
1934,-0.17433685,-0.27400395,-0.07466974
1935,-0.20605922,-0.30349734,-0.10862111
1936,-0.16952093,-0.26351926,-0.07552261
1937,-0.01919893,-0.11975875,0.08136089
1938,-0.012200732,-0.11030374,0.08590227
1939,-0.040797167,-0.14670466,0.065110326
1940,0.07593584,-0.04194966,0.19382134
1941,0.038129337,-0.16225387,0.23851255
1942,0.0014060909,-0.1952124,0.19802457
1943,0.0064140745,-0.19959097,0.21241911
1944,0.14410514,-0.054494828,0.3427051
1945,0.043088365,-0.15728289,0.24345961
1946,-0.1188128,-0.2659574,0.028331792
1947,-0.091205545,-0.23179041,0.04937931
1948,-0.12466127,-0.25913337,0.009810844
1949,-0.14380224,-0.2540775,-0.033526987
1950,-0.22662179,-0.33265698,-0.12058662
1951,-0.06115397,-0.15035024,0.028042298
1952,0.015354565,-0.08293597,0.11364509
1953,0.07763074,-0.020529618,0.1757911
1954,-0.11675021,-0.20850271,-0.024997713
1955,-0.19730993,-0.28442997,-0.1101899
1956,-0.2631656,-0.33912563,-0.18720557
1957,-0.035334926,-0.10056862,0.029898768
1958,-0.017632553,-0.083074555,0.04780945
1959,-0.048004825,-0.11036375,0.0143540995
1960,-0.115487024,-0.17416587,-0.056808177
1961,-0.019997388,-0.07078052,0.030785747
1962,-0.06405444,-0.11731443,-0.010794453
1963,-0.03680589,-0.09057008,0.016958294
1964,-0.30586675,-0.34949213,-0.26224136
1965,-0.2043879,-0.25357357,-0.15520222
1966,-0.14888458,-0.19839221,-0.09937696
1967,-0.11751631,-0.16062479,-0.07440783
1968,-0.1686323,-0.21325313,-0.124011464
1969,-0.031366713,-0.07186544,0.009132013
1970,-0.08510657,-0.12608096,-0.04413217
1971,-0.20593274,-0.24450706,-0.16735843
1972,-0.0938271,-0.13171694,-0.05593726
1973,0.04993336,0.013468528,0.086398184
1974,-0.17253734,-0.21022376,-0.1348509
1975,-0.11075424,-0.15130512,-0.07020335
1976,-0.21586166,-0.25588378,-0.17583954
1977,0.10308852,0.060056705,0.14612034
1978,0.0052557723,-0.034576867,0.04508841
1979,0.09085813,0.062358618,0.119357646
1980,0.19607207,0.162804,0.22934014
1981,0.25001204,0.21939126,0.28063282
1982,0.034263328,-0.005104665,0.07363132
1983,0.22383861,0.18807402,0.2596032
1984,0.04800471,0.011560736,0.08444869
1985,0.04972978,0.015663471,0.08379609
1986,0.09568697,0.064408,0.12696595
1987,0.2430264,0.21218552,0.27386728
1988,0.28215173,0.2470353,0.31726816
1989,0.17925027,0.14449838,0.21400215
1990,0.36056247,0.32455227,0.39657268
1991,0.33889654,0.30403617,0.3737569
1992,0.124896795,0.09088206,0.15891153
1993,0.16565846,0.12817313,0.2031438
1994,0.23354977,0.19841294,0.2686866
1995,0.37686616,0.34365577,0.41007656
1996,0.2766894,0.24318004,0.31019878
1997,0.4223085,0.39009082,0.4545262
1998,0.57731646,0.54304415,0.6115888
1999,0.32448497,0.29283476,0.35613516
2000,0.3310848,0.29822788,0.36394167
2001,0.48928034,0.4580683,0.5204924
2002,0.5434665,0.51278186,0.57415116
2003,0.5441702,0.5112426,0.5770977
2004,0.46737072,0.43433833,0.5004031
2005,0.60686255,0.5757053,0.6380198
2006,0.5725527,0.541973,0.60313237
2007,0.5917013,0.56135315,0.6220495
2008,0.46564984,0.43265733,0.49864236
2009,0.5967817,0.56525564,0.6283077
2010,0.68037146,0.649076,0.7116669
2011,0.53769773,0.5060012,0.5693943
2012,0.5776071,0.5448553,0.6103589
2013,0.6235754,0.5884838,0.6586669
2014,0.67287165,0.63890487,0.7068384
2015,0.82511437,0.79128706,0.8589417
2016,0.93292713,0.90176356,0.96409065
2017,0.84517425,0.81477475,0.87557375
2018,0.762654,0.731052,0.79425603
2019,0.8910726,0.85678726,0.92535794
2020,0.9227938,0.8882121,0.9573755
2021,0.6640137,0.5372486,0.79077876
1 Time Anomaly (deg C) Lower confidence limit (2.5%) Upper confidence limit (97.5%)
2 1850 -0.41765878 -0.589203 -0.24611452
3 1851 -0.2333498 -0.41186792 -0.054831687
4 1852 -0.22939907 -0.40938243 -0.04941572
5 1853 -0.27035445 -0.43000934 -0.110699534
6 1854 -0.29163003 -0.43282393 -0.15043613
7 1855 -0.2969512 -0.43935776 -0.15454465
8 1856 -0.32035372 -0.46809322 -0.1726142
9 1857 -0.46723005 -0.61632216 -0.31813794
10 1858 -0.3887657 -0.53688604 -0.24064532
11 1859 -0.28119546 -0.42384982 -0.13854107
12 1860 -0.39016518 -0.5389766 -0.24135375
13 1861 -0.42927712 -0.5972301 -0.26132414
14 1862 -0.53639776 -0.7037096 -0.36908585
15 1863 -0.3443432 -0.5341645 -0.1545219
16 1864 -0.4654367 -0.6480974 -0.282776
17 1865 -0.33258784 -0.5246526 -0.14052312
18 1866 -0.34126064 -0.52183825 -0.16068307
19 1867 -0.35696334 -0.55306214 -0.16086453
20 1868 -0.35196072 -0.52965826 -0.17426313
21 1869 -0.31657043 -0.47642276 -0.15671812
22 1870 -0.32789087 -0.46867347 -0.18710826
23 1871 -0.3685807 -0.5141493 -0.22301209
24 1872 -0.32804197 -0.4630833 -0.19300064
25 1873 -0.34133235 -0.4725396 -0.21012507
26 1874 -0.3732512 -0.5071426 -0.2393598
27 1875 -0.37562594 -0.514041 -0.23721085
28 1876 -0.42410994 -0.56287116 -0.28534868
29 1877 -0.101108834 -0.22982001 0.027602348
30 1878 -0.011315193 -0.13121258 0.10858219
31 1879 -0.30363432 -0.43406433 -0.1732043
32 1880 -0.31583208 -0.44015095 -0.19151321
33 1881 -0.23224552 -0.35793498 -0.10655605
34 1882 -0.29553008 -0.4201501 -0.17091006
35 1883 -0.3464744 -0.4608177 -0.23213111
36 1884 -0.49232006 -0.6026686 -0.38197154
37 1885 -0.47112358 -0.5830682 -0.35917896
38 1886 -0.42090362 -0.5225382 -0.31926903
39 1887 -0.49878576 -0.61655986 -0.3810117
40 1888 -0.37937889 -0.49332377 -0.265434
41 1889 -0.24989556 -0.37222093 -0.12757017
42 1890 -0.50685817 -0.6324095 -0.3813068
43 1891 -0.40131494 -0.5373699 -0.26525995
44 1892 -0.5075585 -0.64432853 -0.3707885
45 1893 -0.49461925 -0.6315314 -0.35770702
46 1894 -0.48376393 -0.6255681 -0.34195974
47 1895 -0.4487516 -0.58202064 -0.3154826
48 1896 -0.28400728 -0.4174015 -0.15061308
49 1897 -0.25980017 -0.39852425 -0.12107607
50 1898 -0.48579213 -0.6176492 -0.35393503
51 1899 -0.35543364 -0.48639694 -0.22447036
52 1900 -0.23447904 -0.3669676 -0.10199049
53 1901 -0.29342857 -0.42967388 -0.15718324
54 1902 -0.43898427 -0.5754281 -0.30254042
55 1903 -0.5333264 -0.66081935 -0.40583345
56 1904 -0.5975614 -0.7288325 -0.46629035
57 1905 -0.40775132 -0.5350291 -0.28047356
58 1906 -0.3191393 -0.45052385 -0.18775477
59 1907 -0.5041577 -0.6262818 -0.38203365
60 1908 -0.5138707 -0.63748026 -0.3902612
61 1909 -0.5357649 -0.6526296 -0.41890016
62 1910 -0.5310242 -0.6556868 -0.40636164
63 1911 -0.5392051 -0.66223973 -0.4161705
64 1912 -0.47567302 -0.5893311 -0.36201498
65 1913 -0.46715254 -0.5893755 -0.34492958
66 1914 -0.2625924 -0.38276345 -0.1424214
67 1915 -0.19184391 -0.32196194 -0.06172589
68 1916 -0.42020997 -0.5588941 -0.28152588
69 1917 -0.54301953 -0.6921192 -0.3939199
70 1918 -0.42458433 -0.58198184 -0.26718682
71 1919 -0.32551822 -0.48145813 -0.1695783
72 1920 -0.2985808 -0.44860035 -0.14856121
73 1921 -0.24067703 -0.38175339 -0.09960067
74 1922 -0.33922812 -0.46610323 -0.21235302
75 1923 -0.31793055 -0.444173 -0.1916881
76 1924 -0.3120622 -0.4388317 -0.18529275
77 1925 -0.28242525 -0.4147755 -0.15007503
78 1926 -0.12283547 -0.25264767 0.006976739
79 1927 -0.22940508 -0.35135695 -0.10745319
80 1928 -0.20676155 -0.33881804 -0.074705064
81 1929 -0.39275664 -0.52656746 -0.25894582
82 1930 -0.1768054 -0.29041144 -0.06319936
83 1931 -0.10339768 -0.2126916 0.0058962475
84 1932 -0.14546166 -0.25195515 -0.0389682
85 1933 -0.32234442 -0.4271004 -0.21758842
86 1934 -0.17433685 -0.27400395 -0.07466974
87 1935 -0.20605922 -0.30349734 -0.10862111
88 1936 -0.16952093 -0.26351926 -0.07552261
89 1937 -0.01919893 -0.11975875 0.08136089
90 1938 -0.012200732 -0.11030374 0.08590227
91 1939 -0.040797167 -0.14670466 0.065110326
92 1940 0.07593584 -0.04194966 0.19382134
93 1941 0.038129337 -0.16225387 0.23851255
94 1942 0.0014060909 -0.1952124 0.19802457
95 1943 0.0064140745 -0.19959097 0.21241911
96 1944 0.14410514 -0.054494828 0.3427051
97 1945 0.043088365 -0.15728289 0.24345961
98 1946 -0.1188128 -0.2659574 0.028331792
99 1947 -0.091205545 -0.23179041 0.04937931
100 1948 -0.12466127 -0.25913337 0.009810844
101 1949 -0.14380224 -0.2540775 -0.033526987
102 1950 -0.22662179 -0.33265698 -0.12058662
103 1951 -0.06115397 -0.15035024 0.028042298
104 1952 0.015354565 -0.08293597 0.11364509
105 1953 0.07763074 -0.020529618 0.1757911
106 1954 -0.11675021 -0.20850271 -0.024997713
107 1955 -0.19730993 -0.28442997 -0.1101899
108 1956 -0.2631656 -0.33912563 -0.18720557
109 1957 -0.035334926 -0.10056862 0.029898768
110 1958 -0.017632553 -0.083074555 0.04780945
111 1959 -0.048004825 -0.11036375 0.0143540995
112 1960 -0.115487024 -0.17416587 -0.056808177
113 1961 -0.019997388 -0.07078052 0.030785747
114 1962 -0.06405444 -0.11731443 -0.010794453
115 1963 -0.03680589 -0.09057008 0.016958294
116 1964 -0.30586675 -0.34949213 -0.26224136
117 1965 -0.2043879 -0.25357357 -0.15520222
118 1966 -0.14888458 -0.19839221 -0.09937696
119 1967 -0.11751631 -0.16062479 -0.07440783
120 1968 -0.1686323 -0.21325313 -0.124011464
121 1969 -0.031366713 -0.07186544 0.009132013
122 1970 -0.08510657 -0.12608096 -0.04413217
123 1971 -0.20593274 -0.24450706 -0.16735843
124 1972 -0.0938271 -0.13171694 -0.05593726
125 1973 0.04993336 0.013468528 0.086398184
126 1974 -0.17253734 -0.21022376 -0.1348509
127 1975 -0.11075424 -0.15130512 -0.07020335
128 1976 -0.21586166 -0.25588378 -0.17583954
129 1977 0.10308852 0.060056705 0.14612034
130 1978 0.0052557723 -0.034576867 0.04508841
131 1979 0.09085813 0.062358618 0.119357646
132 1980 0.19607207 0.162804 0.22934014
133 1981 0.25001204 0.21939126 0.28063282
134 1982 0.034263328 -0.005104665 0.07363132
135 1983 0.22383861 0.18807402 0.2596032
136 1984 0.04800471 0.011560736 0.08444869
137 1985 0.04972978 0.015663471 0.08379609
138 1986 0.09568697 0.064408 0.12696595
139 1987 0.2430264 0.21218552 0.27386728
140 1988 0.28215173 0.2470353 0.31726816
141 1989 0.17925027 0.14449838 0.21400215
142 1990 0.36056247 0.32455227 0.39657268
143 1991 0.33889654 0.30403617 0.3737569
144 1992 0.124896795 0.09088206 0.15891153
145 1993 0.16565846 0.12817313 0.2031438
146 1994 0.23354977 0.19841294 0.2686866
147 1995 0.37686616 0.34365577 0.41007656
148 1996 0.2766894 0.24318004 0.31019878
149 1997 0.4223085 0.39009082 0.4545262
150 1998 0.57731646 0.54304415 0.6115888
151 1999 0.32448497 0.29283476 0.35613516
152 2000 0.3310848 0.29822788 0.36394167
153 2001 0.48928034 0.4580683 0.5204924
154 2002 0.5434665 0.51278186 0.57415116
155 2003 0.5441702 0.5112426 0.5770977
156 2004 0.46737072 0.43433833 0.5004031
157 2005 0.60686255 0.5757053 0.6380198
158 2006 0.5725527 0.541973 0.60313237
159 2007 0.5917013 0.56135315 0.6220495
160 2008 0.46564984 0.43265733 0.49864236
161 2009 0.5967817 0.56525564 0.6283077
162 2010 0.68037146 0.649076 0.7116669
163 2011 0.53769773 0.5060012 0.5693943
164 2012 0.5776071 0.5448553 0.6103589
165 2013 0.6235754 0.5884838 0.6586669
166 2014 0.67287165 0.63890487 0.7068384
167 2015 0.82511437 0.79128706 0.8589417
168 2016 0.93292713 0.90176356 0.96409065
169 2017 0.84517425 0.81477475 0.87557375
170 2018 0.762654 0.731052 0.79425603
171 2019 0.8910726 0.85678726 0.92535794
172 2020 0.9227938 0.8882121 0.9573755
173 2021 0.6640137 0.5372486 0.79077876

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,16 @@
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}

View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -0,0 +1,33 @@
const defaultTheme = require("tailwindcss/defaultTheme");
module.exports = {
mode: 'jit',
// purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
purge: [
"./pages/**/*.js",
"./pages/**/*.ts",
"./pages/**/*.jsx",
"./pages/**/*.tsx",
"./components/**/*.js",
"./components/**/*.ts",
"./components/**/*.jsx",
"./components/**/*.tsx"
],
darkMode: false, // or 'media' or 'class'
theme: {
container: {
center: true,
},
extend: {
fontFamily: {
mono: ["Inconsolata", ...defaultTheme.fontFamily.mono]
}
},
},
variants: {
extend: {},
},
plugins: [
require('@tailwindcss/typography'),
],
}

File diff suppressed because it is too large Load Diff