1
1
Fork 0

Changes to the UI + Ratings data

This commit is contained in:
Jordy van Zeeland 2023-03-07 17:07:53 +01:00
parent aeaa8cb3b5
commit e7551b0599
23 changed files with 1544 additions and 3083 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -18,6 +18,7 @@ urlpatterns = [
path('books/genres', books_per_genre_per_month), path('books/genres', books_per_genre_per_month),
path('books/genres/count', countGenres), path('books/genres/count', countGenres),
path('books/ratings', avg_ratings_per_month),
path('books/authors', books_per_author), path('books/authors', books_per_author),
path('books/countries', books_per_country), path('books/countries', books_per_country),

View File

@ -276,3 +276,26 @@ def predictAmountBooks(request):
"amount": math.floor(predict_books[0]) "amount": math.floor(predict_books[0])
}) })
# return Response(f"The amount of books i'm gonna read in {current_year} is {math.floor(predict_books[0])}") # return Response(f"The amount of books i'm gonna read in {current_year} is {math.floor(predict_books[0])}")
@api_view(['GET'])
def avg_ratings_per_month(request):
datayear = request.META.get('HTTP_YEAR')
if datayear:
data = []
# Get CSV file with book data
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
avgratingspermonth = df.groupby('readed')['rating'].mean().reset_index(name="rating")
for index, row in avgratingspermonth.iterrows():
data.append({
"date": row['readed'],
"rating": int(row['rating'])
})
return Response(data)
else:
return Response("No year header included")

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { getBooksPerYearPerGenres } from "./Data.js"; import { getAvgRatings, getBooksPerYearPerGenres } from "./Data.js";
import { initChart } from "./Charts.js"; import { initChart } from "./Charts.js";
export default class Books extends Component { export default class Books extends Component {
@ -16,7 +16,11 @@ export default class Books extends Component {
books: books books: books
}) })
initChart(books, this.props.year); getAvgRatings(this.props.year).then(ratings => {
initChart(books, ratings, this.props.year);
})
}) })
} }

View File

@ -37,7 +37,7 @@ export default class Challenge extends Component {
} }
render() { render() {
var challengePercentage = (this.state.totalbooks / this.state.challenge) * 100 var challengePercentage = Math.round((this.state.totalbooks / this.state.challenge) * 100, 0)
return ( return (
<React.Fragment> <React.Fragment>

View File

@ -1,4 +1,4 @@
export const initChart = (data, year) => { export const initChart = (data, ratings, year) => {
/* /*
---------------------------------- ----------------------------------
@ -54,6 +54,41 @@ export const initChart = (data, year) => {
}) })
} }
/*
----------------------------------
Avarage ratings per month
----------------------------------
*/
var avgRatings = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (var j = 0; j < 12; j++) {
if (j < 9) {
var month = "0" + (j + 1)
} else {
month = (j + 1)
}
for (var i = 0; i < ratings.length; i++) {
if (ratings[i].date == month + '-' + year) {
avgRatings[j] = ratings[i].rating;
}
}
}
dataSet.push({
label: 'Gemiddelde beoordeling',
data: avgRatings,
backgroundColor: '#ffa500',
borderColor: '#ffa500',
tension: 0.4,
type: 'line',
order: 1
})
console.log(dataSet);
/* /*
---------------------------------- ----------------------------------
Stacked bar chart Stacked bar chart
@ -137,6 +172,8 @@ export const initChart = (data, year) => {
export const initDoughnut = (data) => { export const initDoughnut = (data) => {
console.log(data);
var labels = []; var labels = [];
var counts = []; var counts = [];
@ -227,16 +264,6 @@ export const initDoughnut = (data) => {
return this.height += 30; return this.height += 30;
} }
} }
}, {
afterDraw: chart => {
var ctx = chart.ctx;
ctx.save();
var image = new Image();
image.src = 'https://www.iconsdb.com/icons/preview/gray/book-xxl.png';
var imageSize = 80;
ctx.drawImage(image, chart.width / 2 - imageSize / 2, chart.height / 2 - imageSize / 6, imageSize, imageSize);
ctx.restore();
}
}], }],
}); });
} }

View File

@ -95,3 +95,16 @@ export const getGenresCount = (year) => {
return data; return data;
}) })
} }
export const getAvgRatings = (year) => {
return fetch('/api/books/ratings', {
"method": "GET",
"headers": {
"year": year
}
})
.then(response => response.json())
.then(data => {
return data;
})
}

View File

@ -16,7 +16,7 @@ export default class Genres extends Component {
genres: genres genres: genres
}) })
initDoughnut(this.state.genres, this.props.year); initDoughnut(genres, this.props.year);
}) })
} }

View File

@ -51,7 +51,6 @@ function Booklist(){
<React.Fragment> <React.Fragment>
<Sidebar /> <Sidebar />
<div className="content"> <div className="content">
<h1>Boekenlijst</h1>
<Filters /> <Filters />

View File

@ -26,17 +26,11 @@ export default class Dashboard extends Component {
} }
componentDidMount() { componentDidMount() {
setTimeout(() =>{
document.getElementById("loading-overlay").style.display = "none";
}, 1000);
getReadingYears().then(data => { getReadingYears().then(data => {
this.setState({ this.setState({
readingYears: data readingYears: data
}) })
}) })
} }
render() { render() {
@ -46,9 +40,6 @@ export default class Dashboard extends Component {
<React.Fragment> <React.Fragment>
<Sidebar /> <Sidebar />
<div className="content"> <div className="content">
<h1>Dashboard</h1>
<div className="books-stats"> <div className="books-stats">
<div className="container-fluid"> <div className="container-fluid">
<div className="row"> <div className="row">

View File

@ -30,7 +30,7 @@ html, body{
.content{ .content{
padding: 50px 50px 50px 240px; padding: 30px;
} }
.filter{ .filter{
@ -84,9 +84,8 @@ html, body{
.sidebar{ .sidebar{
background: #363a53; background: #363a53;
width: 200px; width: 100%;
height: 100vh; height: 54px;
position: fixed;
} }
.sidebar .menu-item{ .sidebar .menu-item{
@ -115,6 +114,7 @@ html, body{
list-style-type: none; list-style-type: none;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
display: inline-block;
} }
.sidebar ul li a { .sidebar ul li a {
@ -129,13 +129,12 @@ html, body{
.sidebar ul li:has(> a.active) { .sidebar ul li:has(> a.active) {
background: #333f54 !important; background: #333f54 !important;
border-left: solid 3px #8066ee; border-bottom: solid 3px #8066ee;
} }
.sidebar ul li a.active { .sidebar ul li a.active {
color: #ffffff; color: #ffffff;
background: rgba(0,0,0,0.2) !important; background: rgba(0,0,0,0.2) !important;
border-left: solid 3px #8066ee;
} }
.sidebar ul li a.active i { .sidebar ul li a.active i {
@ -197,11 +196,11 @@ html, body{
.books-stats .stat-block i{ .books-stats .stat-block i{
font-weight: 900; font-weight: 900;
font-size: 25px; font-size: 22px;
border-radius: 50%; border-radius: 50%;
padding: 17px; padding: 11px;
width: 65px; width: 50px;
height: 65px; height: 50px;
line-height: 30px; line-height: 30px;
text-align: center; text-align: center;
background: #696ffc; background: #696ffc;
@ -212,14 +211,14 @@ html, body{
font-weight: 600; font-weight: 600;
display: inline-block; display: inline-block;
margin-left: 10px; margin-left: 10px;
font-size: 20px; font-size: 18px;
margin-right: 10px; margin-right: 10px;
} }
.books-stats .stat-block .stats-label, .stats-label{ .books-stats .stat-block .stats-label, .stats-label{
color: #a7adbd; color: #a7adbd;
font-weight: 400; font-weight: 400;
font-size: 20px; font-size: 18px;
} }
.yearselector{ .yearselector{

View File

@ -0,0 +1 @@
"use strict";(self.webpackChunkfrontend=self.webpackChunkfrontend||[]).push([[225],{3225:(e,t,o)=>{o.r(t),o.d(t,{getAllBooks:()=>s,getBooksPerYearPerGenres:()=>c,getChallenge:()=>n,getCountries:()=>r,getGenresCount:()=>g,getReadingYears:()=>a,getShortestLongestBook:()=>d,getStats:()=>h});const s=()=>fetch("/api/books",{method:"GET"}).then((e=>e.json())).then((e=>e)),h=e=>fetch("/api/books/stats",{method:"GET",headers:{year:e}}).then((e=>e.json())).then((e=>e)),n=e=>fetch("/api/books/challenge",{method:"GET",headers:{year:e}}).then((e=>e.json())).then((e=>e)),a=()=>fetch("/api/books/years",{method:"GET"}).then((e=>e.json())).then((e=>e)),r=e=>fetch("/api/books/countries",{method:"GET",headers:{year:e}}).then((e=>e.json())).then((e=>e)),d=e=>fetch("/api/books/pages/stats",{method:"GET",headers:{year:e}}).then((e=>e.json())).then((e=>e)),c=e=>fetch("/api/books/genres",{method:"GET",headers:{year:e}}).then((e=>e.json())).then((e=>e)),g=e=>fetch("/api/books/genres/count",{method:"GET",headers:{year:e}}).then((e=>e.json())).then((e=>e))}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,32 @@
/*!
* Sizzle CSS Selector Engine v2.3.9
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2022-12-19
*/
/*!
* jQuery JavaScript Library v3.6.3
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2022-12-20T21:28Z
*/
/*! DataTables 1.13.3
* ©2008-2023 SpryMedia Ltd - datatables.net/license
*/
//! moment.js
//! moment.js locale configuration

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! For license information please see src_components_Data_js.js.LICENSE.txt */ /*! For license information please see src_components_Data_js.js.LICENSE.txt */
"use strict";(self.webpackChunkfrontend=self.webpackChunkfrontend||[]).push([["src_components_Data_js"],{"./src/components/Data.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "getAllBooks": () => (/* binding */ getAllBooks),\n/* harmony export */ "getBooksPerYearPerGenres": () => (/* binding */ getBooksPerYearPerGenres),\n/* harmony export */ "getChallenge": () => (/* binding */ getChallenge),\n/* harmony export */ "getCountries": () => (/* binding */ getCountries),\n/* harmony export */ "getGenresCount": () => (/* binding */ getGenresCount),\n/* harmony export */ "getReadingYears": () => (/* binding */ getReadingYears),\n/* harmony export */ "getShortestLongestBook": () => (/* binding */ getShortestLongestBook),\n/* harmony export */ "getStats": () => (/* binding */ getStats)\n/* harmony export */ });\nconst getAllBooks = () => {\n return fetch(\'/api/books\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getStats = year => {\n return fetch(\'/api/books/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getChallenge = year => {\n return fetch(\'/api/books/challenge\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getReadingYears = () => {\n return fetch(\'/api/books/years\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getCountries = year => {\n return fetch(\'/api/books/countries\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getShortestLongestBook = year => {\n return fetch(\'/api/books/pages/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getBooksPerYearPerGenres = year => {\n return fetch(\'/api/books/genres\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getGenresCount = year => {\n return fetch(\'/api/books/genres/count\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n//# sourceURL=webpack://frontend/./src/components/Data.js?')}}]); "use strict";(self.webpackChunkfrontend=self.webpackChunkfrontend||[]).push([["src_components_Data_js"],{"./src/components/Data.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "getAllBooks": () => (/* binding */ getAllBooks),\n/* harmony export */ "getAvgRatings": () => (/* binding */ getAvgRatings),\n/* harmony export */ "getBooksPerYearPerGenres": () => (/* binding */ getBooksPerYearPerGenres),\n/* harmony export */ "getChallenge": () => (/* binding */ getChallenge),\n/* harmony export */ "getCountries": () => (/* binding */ getCountries),\n/* harmony export */ "getGenresCount": () => (/* binding */ getGenresCount),\n/* harmony export */ "getReadingYears": () => (/* binding */ getReadingYears),\n/* harmony export */ "getShortestLongestBook": () => (/* binding */ getShortestLongestBook),\n/* harmony export */ "getStats": () => (/* binding */ getStats)\n/* harmony export */ });\nconst getAllBooks = () => {\n return fetch(\'/api/books\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getStats = year => {\n return fetch(\'/api/books/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getChallenge = year => {\n return fetch(\'/api/books/challenge\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getReadingYears = () => {\n return fetch(\'/api/books/years\', {\n "method": "GET"\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getCountries = year => {\n return fetch(\'/api/books/countries\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getShortestLongestBook = year => {\n return fetch(\'/api/books/pages/stats\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getBooksPerYearPerGenres = year => {\n return fetch(\'/api/books/genres\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getGenresCount = year => {\n return fetch(\'/api/books/genres/count\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\nconst getAvgRatings = year => {\n return fetch(\'/api/books/ratings\', {\n "method": "GET",\n "headers": {\n "year": year\n }\n }).then(response => response.json()).then(data => {\n return data;\n });\n};\n\n//# sourceURL=webpack://frontend/./src/components/Data.js?')}}]);

File diff suppressed because one or more lines are too long

Binary file not shown.