Changes to the UI + Ratings data
This commit is contained in:
parent
aeaa8cb3b5
commit
e7551b0599
|
@ -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),
|
||||
|
||||
|
|
|
@ -275,4 +275,27 @@ def predictAmountBooks(request):
|
|||
"year": current_year,
|
||||
"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
|
@ -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);
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -94,4 +94,17 @@ export const getGenresCount = (year) => {
|
|||
.then(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;
|
||||
})
|
||||
}
|
|
@ -16,7 +16,7 @@ export default class Genres extends Component {
|
|||
genres: genres
|
||||
})
|
||||
|
||||
initDoughnut(this.state.genres, this.props.year);
|
||||
initDoughnut(genres, this.props.year);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ function Booklist(){
|
|||
<React.Fragment>
|
||||
<Sidebar />
|
||||
<div className="content">
|
||||
<h1>Boekenlijst</h1>
|
||||
|
||||
<Filters />
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
Loading…
Reference in New Issue