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/count', countGenres),
path('books/ratings', avg_ratings_per_month),
path('books/authors', books_per_author),
path('books/countries', books_per_country),

View File

@ -276,3 +276,26 @@ def predictAmountBooks(request):
"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])}")
@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 { getBooksPerYearPerGenres } from "./Data.js";
import { getAvgRatings, getBooksPerYearPerGenres } from "./Data.js";
import { initChart } from "./Charts.js";
export default class Books extends Component {
@ -16,7 +16,11 @@ export default class Books extends Component {
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() {
var challengePercentage = (this.state.totalbooks / this.state.challenge) * 100
var challengePercentage = Math.round((this.state.totalbooks / this.state.challenge) * 100, 0)
return (
<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
@ -137,6 +172,8 @@ export const initChart = (data, year) => {
export const initDoughnut = (data) => {
console.log(data);
var labels = [];
var counts = [];
@ -227,16 +264,6 @@ export const initDoughnut = (data) => {
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;
})
}
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
})
initDoughnut(this.state.genres, this.props.year);
initDoughnut(genres, this.props.year);
})
}

View File

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

View File

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

View File

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