I currently have
- Amplify to authenticate into my s3 bucket
- storage to get the data
- js to clean the data
- apex-charts-react to visualize my data
I want to start by saying: I am not a front end web developer, but I am working on a project where I have had to write this page in aws-amplify, react.js, apex charts and aws-storage. I have some ideas of what I want to do and want to see if I can get help accomplishing that.
I have this page with 4 charts - two that pull back a single number from a .csv each and 2 that I will pull arrays and then build barcharts with. I currently am creating useState() variables that I put into my useEffect() calls for the first 2, and I was wondering : can this be rewritten so I only have the one UseEffect that can take filename as an infput, and then output the value I have in my current call?
This will allow me pass multiple files from my s3 bucket to the storage call - allow js to clean it accordinlgy and then create a useState variable all in one go. This is well beyond my level of experience. I have searched online, but get lost and have not found a proper solution to this.
I have attached my existing view and the code that generates it for your reference.
import { Alert, Button } from '@aws-amplify/ui-react'
import Chart from "react-apexcharts";
import {Storage} from 'aws-amplify';
///aws-amplify configuration
Storage.configure({
AWSS3: {
bucket: 'this-is-placeholder-text',
region: 'us-east-1',
},
level:'public',
customPrefix: {public:'test/'}
})
const bar1 = {
options: {
title: {
text: 'example chart #1',
align: 'center',
margin: 10,
offsetX: 0,
offsetY: 0,
floating: false,
style: {
fontSize: '10',
fontWeight: 'bold',
fontFamily: undefined,
color: '#263233'
}
},
chart: {
id: "basic-bar",
redrawOnWindowResize: true,
colors: '#e22925'
},
xaxis: {
categories: [2000,1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998].sort()
},
fill: {
colors: ['#e22925']
}
},
series: [
{
name: "crap",
data: [30, 40, 45, 50, 49, 60, 70, 91,12].sort()
}
]
};
const bar2 = {
options: {
chart: {
type: 'bar',
},
plotOptions: {
bar: {
horizontal: true,
}
},
dataLabels: {
enabled: false
},
title: {
text: 'example chart #2',
align: 'center',
margin: 10,
offsetX: 0,
offsetY: 0,
floating: false,
style: {
fontSize: '10',
fontWeight: 'bold',
fontFamily: undefined,
color: '#263233'
}
}, fill: {
colors: ['#e22925']
},
chart: {
id: "basic-bar",
redrawOnWindowResize: true
},
xaxis: {
categories: [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008]
}
},
series: [
{
name: "series1",
data: [50, 60, 70, 80, 90, 100, 105, 110]
}
]
};
const [someData, setSomeData] = React.useState(undefined)
React.useEffect(() => {
// declare the data fetching function
const fetchData = async () => {
const response1 = await Storage.get('NOfAssets.csv',{ download : true });
const response2 = await response1.Body.text()
const resp3 = await response2.split('\n')[1]
setSomeData(resp3)
console.log(resp3);
}
// call the function
fetchData()
// make sure to catch any error
.catch(console.error);
}, [])
const [someData1, setSomeData1] = React.useState(undefined)
React.useEffect(() => {
// declare the data fetching function
const fetchData = async () => {
const response1 = await Storage.get('NOfConnections.csv',{ download : true });
const response2 = await response1.Body.text()
const resp3 = await response2.split('\n')[1]
setSomeData1(resp3)
console.log(resp3);
}
// call the function
fetchData()
// make sure to catch any error
.catch(console.error);
}, [])
return (
<html lang="en">
<head>
<link href=https://fonts.googleapis.com/icon?family=Material+Icons+Outlined rel="stylesheet" />
<script defer src=https://d3js.org/d3.v6.min.js></script>
<script defer src=https://cdn.jsdelivr.net/npm/apexcharts></script>
</head>
<div className="container">
<div id="flex1">
<div className="block block1">
<div className="block-inner">
<p className="text-primary">TOTAL ASSETS</p>
<span className="material-icons-outlined text-sf">inventory_2</span>
</div>
<span className="text-primary font-weight-bold">
<div id="number_of_assets">
{someData}
</div>
</span>
</div>
<div className="block block2">
<div className="block-inner">
<p className="text-primary">DATA CONNECTIONS</p>
<span className="material-icons-outlined text-sf">handshake</span>
</div>
<span className="text-primary font-weight-bold">
<div id="number_of_connections" className="text-primary font-weight-bold">
{someData1}
</div>
</span>
</div>
<div className="block block3"> <Chart options={bar1.options} series={bar1.series} type="bar" width="100%"
height="100%"
/>
</div>
<div className="block block4">
<Chart
options={bar2.options}
series={bar2.series}
type="bar"
width="100%"
height='100%'
/>
</div>
</div>
</div>
)
}
}
export default DataSetsPage

If I understand your task right, you have two async data sources, which you want to use to draw your four charts.
Normally, in React, you separate the state and the visual part using a state manager. It's a very powerful and clean pattern, but it can require some getting used to.
For a quick and dirty component which manages its own state, I would use something like this:
The obvious downside is that every time the component renders from scratch, it will query the backend for data which could be reused had you used a state manager. But this will get you started.