Commit 373e97a9 authored by alain's avatar alain 🐙
Browse files

add optional graph pages

parent ed799c1c
//const path = require('path');
const { editWebpackPlugin, appendWebpackPlugin } = require('@rescripts/utilities')
const CopyWebpackPlugin = require('copy-webpack-plugin');
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
......@@ -10,17 +11,19 @@ module.exports = config => {
)
config.resolve.plugins.splice(scopePluginIndex, 1)
config = appendWebpackPlugin(
new CopyWebpackPlugin({
patterns: [
{ from: '../public', to: '../build' }
{
from: '../public',
to: '../build'
}
]
}),
config,
config
)
// config = appendWebpackPlugin(
// new BundleAnalyzerPlugin(),
// config,
......@@ -40,7 +43,7 @@ module.exports = config => {
config,
)
// set js filename
// set js filename
config.output.filename = 'bundle.js'
// disable sourcemap
......@@ -56,7 +59,6 @@ module.exports = config => {
}
return config
}
import React from 'react'
export const appSettingsDefault = {
language: "nl",
header: false,
panelBreakpoint: 600,
yAxisWidth: 30,
defaultGranularity: "hourly"
defaultGranularity: "hourly",
mapRoute: "/"
}
......@@ -1094,9 +1094,9 @@
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
"@deck.gl/aggregation-layers": {
"version": "8.1.6",
"resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.1.6.tgz",
"integrity": "sha512-6XzBoK5TltzoJyobQuEJUbFJBRV9tl9VwlJqT1MWVgRtgSZzebSemOOU+dRqwoDHndBtPXUtt46mKO84jLlUcA==",
"version": "8.1.7",
"resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.1.7.tgz",
"integrity": "sha512-onWic+Am/K8oHdquu4wZF5HWlhMQFeDNv0DHaEiz5zIGr5o1TjIn5Aku9QGQ1kB45Rwy7aYlmDkRHnJqp3oW4A==",
"requires": {
"@luma.gl/shadertools": "^8.1.2",
"@math.gl/web-mercator": "^3.1.3",
......@@ -1104,12 +1104,12 @@
}
},
"@deck.gl/core": {
"version": "8.1.6",
"resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.1.6.tgz",
"integrity": "sha512-KI7nzqz3Ostn+hF4vT5uZOCQ3pLigAbkDjBfzo23ZeD5RJcyl7OYhtHtF1KvQnvWbyw3/qneLsUijGbJc/ZMiQ==",
"version": "8.1.7",
"resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.1.7.tgz",
"integrity": "sha512-o7t6/UmFTxywACJHQ/335seZkZBwloaAFvoWM5qCyytaf3UxV69EuMU2+Ry5Q1Uve26qf8mHdAZbtbuyu9MOqw==",
"requires": {
"@loaders.gl/core": "^2.1.1",
"@loaders.gl/images": "^2.1.1",
"@loaders.gl/core": "^2.1.6",
"@loaders.gl/images": "^2.1.6",
"@luma.gl/core": "^8.1.2",
"@math.gl/web-mercator": "^3.1.3",
"gl-matrix": "^3.0.0",
......@@ -1119,25 +1119,25 @@
}
},
"@deck.gl/layers": {
"version": "8.1.6",
"resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.1.6.tgz",
"integrity": "sha512-b0H9xAsxeQxiFe4iUZEs4SqPlgp9kQ1Q3q38Y2n5IHV9ssxtUWRM1nRxvmaF3EgMe9k/JuC1g0T9sVbtuTKP6A==",
"version": "8.1.7",
"resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.1.7.tgz",
"integrity": "sha512-beZCM04ooL13Rh0WqMrlnt6SkD+0Ut96VC5+s8Vl1lwb+tbFvRXCmY5ldQ3/uBx5m2qSzuHg2s6dec6vl02gXw==",
"requires": {
"@loaders.gl/core": "^2.1.1",
"@loaders.gl/images": "^2.1.1",
"@loaders.gl/core": "^2.1.6",
"@loaders.gl/images": "^2.1.6",
"@mapbox/tiny-sdf": "^1.1.0",
"earcut": "^2.0.6"
}
},
"@deck.gl/mapbox": {
"version": "8.1.6",
"resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.1.6.tgz",
"integrity": "sha512-AuvkxvsB8IZ2OE0qZhKgGwDN9Kr+Hp3LdveTjKZ1ZQWSQL4BY5dFDyfNCLW4vPmtRf2YbdS+nil5SMKg4+f9YA=="
"version": "8.1.7",
"resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.1.7.tgz",
"integrity": "sha512-xhYEcUVzGtMhmo+VewwhsCkjcN3SN6RPT7B6W+AQ5Qz5x61mwJd+cQ6R9WErODmMTiZWkAZGl7mkA2o8G8AVEQ=="
},
"@deck.gl/react": {
"version": "8.1.6",
"resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.1.6.tgz",
"integrity": "sha512-kc/MSfgPec0DtU2z7tT3hztBhj2+08WtxB9s+ODtGlHJh8tEJawVm8Wmkgmt2OP52bBgsalMIomF7u1Xkke7VA==",
"version": "8.1.7",
"resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.1.7.tgz",
"integrity": "sha512-KsbaIy6ykeKf+vSGEba+6sQarhQeSk5PzH6/UlVMDnONV1yxxU5SFr1uOJECGG7FMEKXF6PYh2Xcf7JHIq6w5g==",
"requires": {
"prop-types": "^15.6.0"
}
......@@ -3999,12 +3999,13 @@
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
},
"copy-webpack-plugin": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.0.0.tgz",
"integrity": "sha512-tM6DhoJm8jvkHLjH62r5NHKSxmtyHYWOwWTkLWEZYHbxEH0Aele2pGRZ2HSDJb8Rdb/BcYWYFiJXTzHt377fPg==",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.0.1.tgz",
"integrity": "sha512-tcbZnGtQ70b4vtYGUNg8uUYri/80H1On3AC+wPsVOKSj7xbDinYuxAZPAeI3/3hxjjuwoGTHN5BeSksQ4kGUTw==",
"dev": true,
"requires": {
"cacache": "^15.0.3",
"fast-glob": "^3.2.2",
"find-cache-dir": "^3.3.1",
"glob-parent": "^5.1.1",
"globby": "^11.0.0",
......@@ -4623,9 +4624,9 @@
}
},
"css-unit-converter": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz",
"integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY="
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz",
"integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA=="
},
"css-what": {
"version": "3.2.1",
......@@ -5922,9 +5923,9 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"eventemitter3": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz",
"integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg=="
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
"integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ=="
},
"events": {
"version": "3.1.0",
......@@ -6897,6 +6898,19 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
},
"history": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
"requires": {
"@babel/runtime": "^7.1.2",
"loose-envify": "^1.2.0",
"resolve-pathname": "^3.0.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0",
"value-equal": "^1.0.1"
}
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
......@@ -7073,9 +7087,9 @@
"integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q="
},
"http-proxy": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
"integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"requires": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
......@@ -9540,6 +9554,30 @@
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
"dev": true
},
"mini-create-react-context": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
"integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
"requires": {
"@babel/runtime": "^7.5.5",
"tiny-warning": "^1.0.3"
},
"dependencies": {
"@babel/runtime": {
"version": "7.9.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
"integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"regenerator-runtime": {
"version": "0.13.5",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
"integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
}
}
},
"mini-css-extract-plugin": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
......@@ -9713,9 +9751,9 @@
}
},
"moment": {
"version": "2.25.3",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.25.3.tgz",
"integrity": "sha512-PuYv0PHxZvzc15Sp8ybUCoQ+xpyPWvjOuK72a5ovzp2LI32rJXOiIfyoFoYvG3s6EwwrdkMyWuRiEHSZRLJNdg=="
"version": "2.26.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
},
"moment-range": {
"version": "4.0.2",
......@@ -12370,6 +12408,52 @@
}
}
},
"react-router": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
"hoist-non-react-statics": "^3.1.0",
"loose-envify": "^1.3.1",
"mini-create-react-context": "^0.4.0",
"path-to-regexp": "^1.7.0",
"prop-types": "^15.6.2",
"react-is": "^16.6.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"path-to-regexp": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
"requires": {
"isarray": "0.0.1"
}
}
}
},
"react-router-dom": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
"loose-envify": "^1.3.1",
"prop-types": "^15.6.2",
"react-router": "5.2.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
}
},
"react-scripts": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
......@@ -12552,13 +12636,6 @@
"react-smooth": "^1.0.5",
"recharts-scale": "^0.4.2",
"reduce-css-calc": "^2.1.7"
},
"dependencies": {
"eventemitter3": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
"integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ=="
}
}
},
"recharts-scale": {
......@@ -12926,6 +13003,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
},
"resolve-pathname": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
},
"resolve-protobuf-schema": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
......@@ -14488,6 +14570,16 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
},
"tiny-invariant": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
"integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
},
"tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
"tinyqueue": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz",
......@@ -14908,6 +15000,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
"value-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
......@@ -15702,9 +15799,9 @@
}
},
"webpack-bundle-analyzer": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.7.0.tgz",
"integrity": "sha512-mETdjZ30a3Yf+NTB/wqTgACK7rAYQl5uxKK0WVTNmF0sM3Uv8s3R58YZMW7Rhu0Lk2Rmuhdj5dcH5Q76zCDVdA==",
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz",
"integrity": "sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw==",
"dev": true,
"requires": {
"acorn": "^7.1.1",
......
......@@ -31,11 +31,11 @@ class Modal extends React.Component {
return (
<div className="modal" onClick={event => {
// Prevent closing on double click / touch devices (it's registering a click event for some reason..)
if(+ new Date() - this.mountTime > 300) closeModal(event)
if(closeModal && + new Date() - this.mountTime > 300) closeModal(event)
}}>
<div className="content" onClick={event => { event.stopPropagation() }}>
<button className="button-close" onClick={event => closeModal(event)}>×</button>
{this.props.children}
{ closeModal && <button className="button-close" onClick={event => closeModal(event)}>×</button>}
{ this.props.children }
</div>
</div>
)
......
......@@ -256,7 +256,7 @@ class StationInfo extends React.Component {
</span> }
</header>
{ downloadJSX }
<div id="chart-body">
<div id="chart-body" className="station-chart">
<ResponsiveContainer width="100%" height={chartHeight}>
<ComposedChart data={data} margin={{ top: 0, right: 30, left: 0, bottom: 10 }}>
{ gradients }
......
import React from 'react'
import { Link } from 'react-router-dom'
import { appSettings } from "../../../config/app"
const Header = (props) => {
return (
<header id="site-header">
<Link id="site-titles" to="/">
<h1>{ appSettings.header.title }</h1>
<h2>{ appSettings.header.subtitle }</h2>
</Link>
<ul id="site-navigation">
{ Object.keys(appSettings.header.navigation).map(i => {
const iValue = appSettings.header.navigation[i]
if(typeof iValue === 'string' || iValue instanceof String) {
return <li key={i}>
<Link to={iValue}>{i}</Link>
</li>
} else {
return <li key={i}>
<span>{i}</span>
<div className="sub">
<ul>
{ Object.keys(iValue).map(j => <li key={j}><Link to={iValue[j]}>{ j }</Link></li>) }
</ul>
</div>
</li>
}
})}
</ul>
</header>
)
}
export default Header
\ No newline at end of file
import React from 'react'
import ReScatterChart from './ReScatterChart'
import ReLineChart from './ReLineChart'
import ReAreaChart from './ReAreaChart'
import ReBarChart from './ReBarChart'
const Page = (props) => {
return (
<div className="page">
<h1>{props.title}</h1>
<div dangerouslySetInnerHTML={{__html: props.intro}} />
{ props.content.map(item => {
switch (item.type) {
case 'scatter-chart':
return <ReScatterChart key={item.title} title={item.title} data={item.data} settings={item.settings} />
case 'line-chart':
return <ReLineChart key={item.title} title={item.title} data={item.data} settings={item.settings} />
case 'area-chart':
return <ReAreaChart key={item.title} title={item.title} data={item.data} settings={item.settings} />
case 'bar-chart':
return <ReBarChart key={item.title} title={item.title} data={item.data} settings={item.settings} />
default:
return <div>...</div>
}
}
)}
</div>
)
}
export default Page
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { ResponsiveContainer, AreaChart, Area, XAxis, YAxis, Tooltip, Legend } from "recharts"
import { appSettings } from "../../../config/app"
const ReLineChart = (props) => {
const settings = props.settings
const [data, setData] = useState(null)
useEffect(() => {
async function fetchData() {
const response = await fetch(props.settings.data)
const json = await response.json()
setData(json)
}
fetchData();
}, [props.settings.data]);
return (
<div>
<h2>{props.title}</h2>
<ResponsiveContainer width="100%" height={320}>
<AreaChart data={data} margin={{ top: 5, right: 15, bottom: 20, left: 0 }}>
<XAxis { ...settings.x } />
<YAxis label={{ value: settings.y.name, angle: -90, position: 'insideBottomLeft', offset:10, style: {textAnchor: 'start'}}} { ...settings.y } />
<Tooltip cursor={{ strokeDasharray: '3 3' }} animationDuration={0} { ...settings.tooltip } />
<Legend align="right" { ...settings.legend } />
{ settings.categories.map((category, i) => {
return <Area type="linear" stackId="1" key={category} dataKey={category} fill={appSettings.colors[i]} fillOpacity="1" stroke={appSettings.colors[i]} />
}) }
</AreaChart>
</ResponsiveContainer>
</div>
)
}
export default ReLineChart
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, Tooltip, Legend } from "recharts"
import { appSettings } from "../../../config/app"
const CustomizedAxisTick = (props) => {
const { x, y, payload } = props
const words = payload.value ? payload.value.replace('_answer','').split('_') : []
return (
<g transform={`translate(${x},${y})`}>
{ words.map((word, i) => <text key={i} x={0} y={0} dy={14*(i+1)} textAnchor="middle">{word}</text>) }
</g>
)
}
const ReLineChart = (props) => {
const settings = props.settings
const [data, setData] = useState(null)
useEffect(() => {
async function fetchData() {
const response = await fetch(props.settings.data)
const json = await response.json()
setData(json)
}
fetchData();
}, [props.settings.data]);
return (
<div>
<h2>{props.title}</h2>
<ResponsiveContainer width="100%" height={320}>
<BarChart data={data} margin={{ top: 5, right: 15, bottom: 20, left: 0 }}>
<XAxis { ...settings.x } tick={CustomizedAxisTick} minTickGap={0} interval={0} />
<YAxis label={{ value: settings.y.name, angle: -90, position: 'insideBottomLeft', offset:10, style: {textAnchor: 'start'}}} { ...settings.y } />
<Tooltip cursor={{ strokeDasharray: '3 3' }} animationDuration={0} />
<Legend align="right" wrapperStyle={{bottom: 0}} { ...settings.legend } />
{ settings.categories.map((category, i) => {
return <Bar type="linear" key={category} dataKey={category} fill={appSettings.colorsBinary[i]} />
}) }
</BarChart>
</ResponsiveContainer>
</div>
)
}
export default ReLineChart
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, Tooltip, Legend } from "recharts"
import { appSettings } from "../../../config/app"
const ReLineChart = (props) => {
const settings = props.settings
const [data, setData] = useState(null)
useEffect(() => {
async function fetchData() {
const response = await fetch(props.settings.data)
const json = await response.json()
setData(json)
}