Last active
May 8, 2022 19:49
-
-
Save FilipIlievski/578e51e08c62c07c1375558cd8a1ca66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Chart as ChartJS, | |
CategoryScale, | |
LinearScale, | |
BarElement, | |
Title, | |
Tooltip, | |
Legend, | |
} from "chart.js"; | |
import { subDays } from "date-fns"; | |
import { useEffect, useState } from "react"; | |
import { Bar } from "react-chartjs-2"; | |
import { DataForChart, getData } from "./chartData"; | |
ChartJS.register( | |
CategoryScale, | |
LinearScale, | |
BarElement, | |
Title, | |
Tooltip, | |
Legend | |
); | |
export const options = { | |
responsive: true, | |
plugins: { | |
legend: { | |
position: "top" as const, | |
}, | |
title: { | |
display: true, | |
text: "Chart.js Bar Chart", | |
}, | |
}, | |
}; | |
export type TimeInterval = { | |
from: Date; | |
to: Date; | |
}; | |
export enum TimeframeLabels { | |
LAST_SEVEN_DAYS = "Last seven days", | |
LAST_14_DAYS = "Last 14 days", | |
LAST_30_DAYS = "Last 30 days", | |
} | |
export const TimeframeDays = { | |
[TimeframeLabels.LAST_SEVEN_DAYS]: 7, | |
[TimeframeLabels.LAST_14_DAYS]: 14, | |
[TimeframeLabels.LAST_30_DAYS]: 30, | |
}; | |
const now = new Date(); | |
const TimeframeVariables: Record<TimeframeLabels, TimeInterval> = { | |
[TimeframeLabels.LAST_SEVEN_DAYS]: { | |
from: subDays(now, 7), | |
to: now, | |
}, | |
[TimeframeLabels.LAST_14_DAYS]: { | |
from: subDays(now, 28), | |
to: now, | |
}, | |
[TimeframeLabels.LAST_30_DAYS]: { | |
from: subDays(now, 90), | |
to: now, | |
}, | |
}; | |
export default function App() { | |
const [timeframe, setTimeframe] = useState<TimeframeLabels>( | |
TimeframeLabels.LAST_30_DAYS | |
); | |
const [data, setData] = useState<DataForChart>( | |
getData({ | |
from: TimeframeVariables[timeframe].from, | |
to: TimeframeVariables[timeframe].to, | |
numberOfDays: TimeframeDays[timeframe], | |
}) | |
); | |
useEffect(() => { | |
const payload = TimeframeVariables[timeframe]; | |
setData( | |
getData({ | |
from: payload.from, | |
to: payload.to, | |
numberOfDays: TimeframeDays[timeframe], | |
}) | |
); | |
}, [timeframe]); | |
return ( | |
<> | |
<div style={{ margin: "40px 0" }}> | |
<label htmlFor="timeframe-dropdown">Select timeframe:</label>{" "} | |
<select | |
name="dropdown" | |
id="timeframe-dropdown" | |
defaultValue={timeframe} | |
onChange={(e) => { | |
setTimeframe(e.target.value as TimeframeLabels); | |
}} | |
> | |
<option value={TimeframeLabels.LAST_SEVEN_DAYS}> | |
{TimeframeLabels.LAST_SEVEN_DAYS} | |
</option> | |
<option value={TimeframeLabels.LAST_14_DAYS}> | |
{TimeframeLabels.LAST_14_DAYS} | |
</option> | |
<option value={TimeframeLabels.LAST_30_DAYS}> | |
{TimeframeLabels.LAST_30_DAYS} | |
</option> | |
</select> | |
</div> | |
<Bar options={options} data={data} /> | |
</> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { addDays, format, isAfter, isBefore } from "date-fns"; | |
type Album = { | |
id: number; | |
title: string; | |
dateCreated: string; | |
dateSold: string; | |
description: string; | |
type: string; | |
image: string; | |
price: number; | |
artist: string; | |
isPublished: boolean; | |
isAuctioning: boolean; | |
priceSold: number; | |
}; | |
export type DataForChart = { | |
labels: string[]; | |
datasets: { | |
label: string; | |
data: number[]; | |
backgroundColor: string; | |
}[]; | |
}; | |
const items: Array<Album> = [ | |
{ | |
id: 1, | |
title: "Meet me where the wild things grow", | |
description: | |
"Lorem ipsum dolor sit amet, consectetur adipiscing elit ut aliquam, purus sit amet luctus venenatis, lectus magna fringilla urna, porttitor rhoncus dolor...", | |
type: "painting", | |
image: | |
"https://images.unsplash.com/photo-1617994422012-baad9c327e20?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=300&ixid=MnwxfDB8MXxyYW5kb218MHx8cGFpbnRpbmcsIGFydCwgY2FudmFzLCBkaWdpdGFsYXJ0LCBhcnRpc3R8fHx8fHwxNjM1NDY5MTI0&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=800", | |
price: 1315, | |
artist: "Leanne Graham", | |
dateCreated: "2021-10-09T02:00:48.989Z", | |
isPublished: false, | |
isAuctioning: false, | |
dateSold: "2022-05-01T02:00:48.989Z", | |
priceSold: 2030, | |
}, | |
{ | |
id: 2, | |
title: "I choose peace", | |
description: | |
"Lorem ipsum dolor sit amet, consectetur adipiscing elit ut aliquam, purus sit amet luctus venenatis, lectus magna fringilla urna, porttitor rhoncus dolor...", | |
type: "sculpture", | |
image: | |
"https://images.unsplash.com/photo-1617994422012-baad9c327e20?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=300&ixid=MnwxfDB8MXxyYW5kb218MHx8cGFpbnRpbmcsIGFydCwgY2FudmFzLCBkaWdpdGFsYXJ0LCBhcnRpc3R8fHx8fHwxNjM1NDY5MTI0&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=800", | |
price: 530, | |
artist: "Ervin Howell", | |
dateCreated: "2021-10-27T02:00:48.989Z", | |
isPublished: false, | |
isAuctioning: false, | |
dateSold: "2022-05-04T02:00:48.989Z", | |
priceSold: 350, | |
}, | |
{ | |
id: 3, | |
title: "Peace Underneath", | |
description: | |
"Lorem ipsum dolor sit amet, consectetur adipiscing elit ut aliquam, purus sit amet luctus venenatis, lectus magna fringilla urna, porttitor rhoncus dolor...", | |
type: "digital", | |
image: | |
"https://images.unsplash.com/photo-1617994422012-baad9c327e20?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=300&ixid=MnwxfDB8MXxyYW5kb218MHx8cGFpbnRpbmcsIGFydCwgY2FudmFzLCBkaWdpdGFsYXJ0LCBhcnRpc3R8fHx8fHwxNjM1NDY5MTI0&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=800", | |
price: 495, | |
artist: "Clementine Bauch", | |
dateCreated: "2021-10-17T02:00:48.989Z", | |
isPublished: true, | |
isAuctioning: false, | |
dateSold: "2022-05-04T02:00:48.989Z", | |
priceSold: 2810, | |
}, | |
{ | |
id: 4, | |
title: "ABC", | |
dateCreated: "2022-04-09T02:00:48.989Z", | |
dateSold: "2022-05-01T02:00:48.989Z", | |
description: "My man", | |
type: "digital", | |
image: "", | |
price: 2222, | |
artist: "Denzel", | |
isPublished: true, | |
isAuctioning: true, | |
priceSold: 200, | |
}, | |
{ | |
id: 5, | |
title: "FFGG", | |
dateCreated: "2022-04-27T02:00:48.989Z", | |
dateSold: "2022-05-04T02:00:48.989Z", | |
description: "Sampanjac", | |
type: "digital", | |
image: "", | |
price: 999, | |
artist: "Mile Kitic", | |
isPublished: true, | |
isAuctioning: true, | |
priceSold: 1100, | |
}, | |
{ | |
id: 6, | |
title: "Test AA", | |
dateCreated: "2022-04-17T02:00:48.989Z", | |
dateSold: "2022-05-04T02:00:48.989Z", | |
description: "My man", | |
type: "digital", | |
image: "", | |
price: 333, | |
artist: "Krume", | |
isPublished: true, | |
isAuctioning: true, | |
priceSold: 200, | |
}, | |
]; | |
export const getData = ({ | |
from, | |
to, | |
numberOfDays, | |
}: { | |
from: Date; | |
to: Date; | |
numberOfDays: number; | |
}): DataForChart => { | |
const labels = Array.from({ length: numberOfDays }).map((_, idx) => | |
format(addDays(from, idx), "dd.MM.yyyy") | |
); | |
const data = items | |
.map((item) => { | |
if ( | |
isBefore(new Date(item.dateCreated), to) && | |
isAfter(new Date(item.dateCreated), from) | |
) { | |
return item.priceSold; | |
} | |
return null; | |
}) | |
.filter((i): i is number => !!i); | |
return { | |
labels, | |
datasets: [ | |
{ | |
label: "Albums", | |
data, | |
backgroundColor: "red", | |
}, | |
], | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "chart_sandbox", | |
"version": "0.1.0", | |
"private": true, | |
"dependencies": { | |
"@testing-library/jest-dom": "^5.16.4", | |
"@testing-library/react": "^13.2.0", | |
"@testing-library/user-event": "^13.5.0", | |
"@types/faker": "5.5.3", | |
"@types/jest": "^27.5.0", | |
"@types/node": "^16.11.33", | |
"@types/react": "^18.0.9", | |
"@types/react-dom": "^18.0.3", | |
"chart.js": "^3.7.1", | |
"date-fns": "^2.28.0", | |
"faker": "5.5.3", | |
"react": "^18.1.0", | |
"react-chartjs-2": "^4.1.0", | |
"react-dom": "^18.1.0", | |
"react-scripts": "5.0.1", | |
"typescript": "^4.6.4", | |
"web-vitals": "^2.1.4" | |
}, | |
"scripts": { | |
"start": "react-scripts start", | |
"build": "react-scripts build", | |
"test": "react-scripts test", | |
"eject": "react-scripts eject" | |
}, | |
"eslintConfig": { | |
"extends": [ | |
"react-app", | |
"react-app/jest" | |
] | |
}, | |
"browserslist": { | |
"production": [ | |
">0.2%", | |
"not dead", | |
"not op_mini all" | |
], | |
"development": [ | |
"last 1 chrome version", | |
"last 1 firefox version", | |
"last 1 safari version" | |
] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment