1
1
Fork 0

Styling changes + extra API data

This commit is contained in:
Jordy van Zeeland 2022-10-11 15:33:16 +02:00
parent 1ff04ef771
commit ecbfe6f09a
5 changed files with 144 additions and 91 deletions

View File

@ -4,7 +4,12 @@ from .views import *
urlpatterns = [ urlpatterns = [
path('books/years', getYears), path('books/years', getYears),
path('books/stats', getStats), path('books/stats', getStats),
path('books/pages/stats', getStatsPages),
path('books/pages', pages_per_month),
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/authors', books_per_author),
path('books/countries', books_per_country), path('books/countries', books_per_country),
] ]

View File

@ -92,6 +92,26 @@ def books_per_country(request):
else: else:
return Response("No year header included") return Response("No year header included")
@api_view(['GET'])
def books_per_author(request):
if request.META.get('HTTP_YEAR'):
data = []
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
countries = df.groupby(['author'])['author'].count().reset_index(name="count")
countries = countries.sort_values(by='count', ascending=False)
for index, row in countries.iterrows():
data.append({
"author": row['author'],
"count": int(row['count'])
})
return Response(data)
else:
return Response("No year header included")
@api_view(['GET']) @api_view(['GET'])
def getStats(request): def getStats(request):
if request.META.get('HTTP_YEAR'): if request.META.get('HTTP_YEAR'):
@ -119,6 +139,64 @@ def getStats(request):
else: else:
return Response("No year header included") return Response("No year header included")
@api_view(['GET'])
def getStatsPages(request):
data = []
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
df = df.dropna()
df['pages'] = df['pages'].astype(int)
pages = df.groupby(['pages', 'name', 'author', 'rating'])['pages'].count().reset_index(name="count")
pages = pages.sort_values(by='pages', ascending=True)
shortestbook = pages.iloc[0]
longestbook = pages.iloc[-1]
avgPages = df["pages"].mean().astype(int)
shortestbook = {
"name": shortestbook["name"],
"author": shortestbook['author'],
"pages": shortestbook['pages'],
"rating": shortestbook['rating'].astype(int)
}
longestbook = {
"name": longestbook["name"],
"author": longestbook['author'],
"pages": longestbook['pages'],
"rating": longestbook['rating'].astype(int)
}
data = {
"longestbook": longestbook,
"shortestbook": shortestbook,
"avgbook": avgPages
}
return Response(data)
@api_view(['GET'])
def pages_per_month(request):
if request.META.get('HTTP_YEAR'):
data = []
df = filterData(getBooksData(), request.META.get('HTTP_YEAR'))
# Filter array on genre and date
booksPerMonth = df.groupby(['pages', 'readed'])['pages'].count().reset_index(name="count")
booksPerMonth = booksPerMonth.sort_values(by=['readed', 'count'], ascending=True)
for index, row in booksPerMonth.iterrows():
data.append({
"pages": row['pages'],
"readed": row['readed']
})
return Response(data)
else:
return Response("No year header included")
@api_view(['GET']) @api_view(['GET'])
def getYears(request): def getYears(request):
df = filterData(getBooksData()) df = filterData(getBooksData())

View File

@ -199,7 +199,7 @@ export default class App extends Component {
label: '# of Tomatoes', label: '# of Tomatoes',
data: counts, data: counts,
backgroundColor: [ backgroundColor: [
'#7b71ff', '#f9939b', '#3fe7bf', '#9bcafe', '#7c59ff' '#6f52ec', '#ff4c62', '#33d69f', '#fdb700', '#4cb7ff'
], ],
borderWidth: 0, borderWidth: 0,
borderColor: '#1f2940', borderColor: '#1f2940',
@ -235,7 +235,7 @@ export default class App extends Component {
padding: 20, padding: 20,
usePointStyle: true, usePointStyle: true,
// This more specific font property overrides the global property // This more specific font property overrides the global property
color: "white", color: "##101010",
font: { font: {
size: 14, size: 14,
family: 'Source Sans Pro' family: 'Source Sans Pro'
@ -270,7 +270,7 @@ export default class App extends Component {
var colors = [ var colors = [
// '#696ffc', '#7596fa', '#92adfe', '#abc0ff' // '#696ffc', '#7596fa', '#92adfe', '#abc0ff'
'#7b71ff', '#f9939b', '#3fe7bf', '#9bcafe', '#7c59ff' '#6f52ec', '#ff4c62', '#33d69f', '#fdb700', '#4cb7ff'
] ]
var dataSet = []; var dataSet = [];
@ -358,7 +358,7 @@ export default class App extends Component {
x: { x: {
ticks: { ticks: {
beginAtZero: true, beginAtZero: true,
color: "white", color: "#101010",
fontFamily: "Source Sans Pro", fontFamily: "Source Sans Pro",
}, },
stacked: true, stacked: true,
@ -367,7 +367,7 @@ export default class App extends Component {
ticks: { ticks: {
beginAtZero: true, beginAtZero: true,
stepSize: 1, stepSize: 1,
color: "white", color: "#101010",
fontFamily: "Source Sans Pro", fontFamily: "Source Sans Pro",
}, },
stacked: true stacked: true
@ -378,7 +378,7 @@ export default class App extends Component {
position: 'top', position: 'top',
labels: { labels: {
usePointStyle: true, usePointStyle: true,
color: "white", color: "#101010",
padding: 20, padding: 20,
font: { font: {
size: 14, size: 14,
@ -462,6 +462,7 @@ export default class App extends Component {
console.log(this.state); console.log(this.state);
return ( return (
<React.Fragment> <React.Fragment>
<div className="sidebar"></div>
<div className="content"> <div className="content">
<div className="books-stats"> <div className="books-stats">
<div className="container-fluid"> <div className="container-fluid">
@ -527,21 +528,12 @@ export default class App extends Component {
<div className="container-fluid"> <div className="container-fluid">
<div className="row"> <div className="row">
<div className="col-md-12"> <div className="col-md-9">
<div className="books-per-month"><span className="block_name">Boeken per maand per genre</span><canvas id="chart"></canvas></div> <div className="books-per-month"><span className="block_name">Boeken per maand per genre</span><canvas id="chart"></canvas></div>
</div> </div>
</div>
</div>
<div className="container-fluid">
<div className="row">
<div className="col-md-3"> <div className="col-md-3">
<div className="genresPercent"><span className="block_name">Genres</span><canvas id="chartGenres"></canvas></div> <div className="books-per-country">
</div>
<div className="col-md-3">
{/* <div className="books-per-country"><canvas id="countryChart"></canvas></div> */}
<div className="books-per-country">
<span className="block_name">Landen</span> <span className="block_name">Landen</span>
<table id="DataTable" class="showHead table responsive nowrap" width="100%"> <table id="DataTable" class="showHead table responsive nowrap" width="100%">
<thead> <thead>
@ -569,20 +561,13 @@ export default class App extends Component {
</tbody> </tbody>
</table> </table>
</div> </div>
<div className="genresPercent"><span className="block_name">Genres</span><canvas id="chartGenres"></canvas></div>
</div> </div>
<div className="col-md-3">
<div className="books-per-country">
<span className="block_name">Schrijvers</span>
</div>
</div>
<div className="col-md-3">
<div className="books-per-country">
<span className="block_name">Favorieten (5 sterren)</span>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</React.Fragment> </React.Fragment>
) )

File diff suppressed because one or more lines are too long

View File

@ -35,12 +35,16 @@
crossorigin=""></script> crossorigin=""></script>
<style> <style>
html, body{ html, body{
background:#181c3f; background:#f8f8fa;
margin:0; margin:0;
padding:0; padding:0;
font-family: 'Source Sans Pro', sans-serif; font-family: 'Source Sans Pro', sans-serif;
} }
.content{
padding-left: 120px;
}
.filter{ .filter{
width:100%; width:100%;
background:#1f2940; background:#1f2940;
@ -56,46 +60,19 @@
} }
.books-per-month, .genresPercent, .books-per-country{ .books-per-month, .genresPercent, .books-per-country{
background: #2a2e56; background: #ffffff;
padding: 20px; padding: 20px;
box-shadow: 0 1px 4px 0 rgb(0 0 0 / 14%); box-shadow: 0 2px 0px 1px rgb(0 0 0 / 3%);
margin-bottom: 20px;
border-radius: 10px;
} }
.sidebar .menu-item-label-name { .sidebar{
text-align: center; background: #363a53;
font-size: 15px; width: 100px;
font-weight: 100; height: 100vh;
padding-left: 15px; position: fixed;
padding-right: 15px; margin: -20px 0 0 0;
letter-spacing: 1px;
color: #ffffff;
}
.sidebar .menu-item-label-name i{
display: block;
margin-bottom: 10px;
font-size: 20px;
}
.sidebar .sidebar_menu {
padding: 0;
margin: 0;
height: 100%;
}
.sidebar .sidebar_menu li {
list-style-type: none;
color: #555;
padding: 15px 0;
cursor: pointer;
}
.sidebar .sidebar_menu li.submenu-item {
color: #fff;
font-size: 12px;
font-weight: 100;
padding-left: 15px;
padding-right: 15px;
} }
.books-stats{ .books-stats{
@ -103,39 +80,46 @@
} }
.books-stats .stat-block{ .books-stats .stat-block{
background: #2a2e56; background: #ffffff;
box-shadow: 0 1px 4px 0 rgb(0 0 0 / 14%); box-shadow: 0 2px 0px 1px rgb(0 0 0 / 3%);
padding: 10px 5px; padding: 15px 5px;
color:#ffffff; color: #101010;
text-align: center; text-align: center;
border-radius: 10px;
} }
.books-stats .col-md-2:nth-child(1) i{ .books-stats .col-md-2:nth-child(1) i{
background: linear-gradient(60deg,#5848cc,#796eff) !important; background: #f8f5fc;
color: #8066ee;
} }
.books-stats .col-md-2:nth-child(2) i{ .books-stats .col-md-2:nth-child(2) i{
background: linear-gradient(60deg,#c7767c,#fb9a9a) !important; background: #fff5f6;
color: #fe4c62;
} }
.books-stats .col-md-2:nth-child(3) i{ .books-stats .col-md-2:nth-child(3) i{
background: linear-gradient(60deg,#32b69c,#3cedb2) !important; background: #f1fcf8;
color: #58c8d6;
} }
.books-stats .col-md-2:nth-child(4) i{ .books-stats .col-md-2:nth-child(4) i{
background: linear-gradient(60deg,#7c9dcb,#9dd0fe) !important; background: #f2f9ff;
color: #49b8fd;
} }
.books-stats .col-md-2:nth-child(5) i{ .books-stats .col-md-2:nth-child(5) i{
background: linear-gradient(60deg,#663bc3,#9263f9) !important; background: #fffaee;
color: #ffbe0e;
} }
.books-stats .col-md-2:nth-child(6) i{ .books-stats .col-md-2:nth-child(6) i{
background: linear-gradient(60deg,#7b1fa2,#913f9e) !important; background: #f8f5fc;
color: #8066ee;
} }
.books-stats .stat-block i{ .books-stats .stat-block i{
font-weight: 900; font-weight: 900;
font-size: 25px; font-size: 25px;
border-radius: 50%; border-radius: 50%;
padding: 20px; padding: 17px;
width: 70px; width: 65px;
height: 70px; height: 65px;
line-height: 30px; line-height: 30px;
text-align: center; text-align: center;
background: #696ffc; background: #696ffc;
@ -143,26 +127,26 @@
} }
.books-stats .stat-block .stats-number{ .books-stats .stat-block .stats-number{
font-weight: bold; font-weight: 600;
display: inline-block; display: inline-block;
margin-left: 10px; margin-left: 10px;
font-size: 25px; font-size: 20px;
margin-right: 10px; margin-right: 10px;
} }
.books-stats .stat-block .stats-label{ .books-stats .stat-block .stats-label{
color: rgba(255,255,255,0.5); color: #bac0cc;
font-weight: 600; font-weight: 400;
font-size: 25px; font-size: 20px;
} }
.yearselector{ .yearselector{
display: inline-block; display: inline-block;
width: auto; width: auto;
background: #2a2e56; background: #ffffff;
border: none; border: none;
color: #fff; color: #101010;
font-weight: bold; font-weight: 600;
} }
.container-fluid{ .container-fluid{
@ -174,7 +158,7 @@
} }
.table td{ .table td{
color:#ffffff; color: #101010;
border-bottom:none !important; border-bottom:none !important;
padding: 10px 10px !important; padding: 10px 10px !important;
} }
@ -188,9 +172,9 @@
} }
span.block_name{ span.block_name{
color: #ffffff; color: #101010;
font-weight: 600; font-weight: 600;
border-bottom: solid 1px rgba(255,255,255,0.1); border-bottom: solid 1px #f5f6fa;
width: 100%; width: 100%;
display: block; display: block;
padding-bottom: 10px; padding-bottom: 10px;
@ -208,6 +192,7 @@
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8" crossorigin="anonymous"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js" integrity="sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D" crossorigin="anonymous" async></script>
<script src="{% static "js/main.js" %}"></script> <script src="{% static "js/main.js" %}"></script>
</body> </body>
</html> </html>