Skip to content

Commit

Permalink
Merge pull request #112 from HE-Arc/sp-110-adding-graph
Browse files Browse the repository at this point in the history
Adding graph
  • Loading branch information
Krucksy authored Apr 12, 2024
2 parents d94e02d + dc128a8 commit 6ab7793
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 11 deletions.
27 changes: 27 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
},
"dependencies": {
"axios": "^1.6.7",
"chart.js": "^4.4.2",
"vue": "^3.4.15",
"vue-chartjs": "^5.3.1",
"vue-router": "^4.2.5"
},
"devDependencies": {
Expand Down
23 changes: 14 additions & 9 deletions frontend/src/api_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,36 @@ export default
}
return btoa(binary);
}

const response = await axios.get(`/api/category/${category_id}/image/`,
{
responseType: 'arraybuffer'
});
return 'data:image/jpeg;base64,' + arrayBufferToBase64(response.data);
}

/**
* Get the current user IQ. It's the best players average IQ in all categories
* @returns {Object} {user_iq: Number}
*/
static async getUserIQ(category_id) {
const response = await axios.get(`/api/category/${category_id}/user_iq`);
return response.data;
}

/**
* Get the global leaderboard. It's the best players average IQ in all categories
* @returns {Array} [{user_id: Number, user_name: String, user_score: Number}]
*/
static async getGlobalLeaderboard()
{
static async getGlobalLeaderboard() {
const response = await axios.get(`/api/rank/global_leaderboard/`);
return response.data;
}
/**
* Get the global leaderboard specific to a category. It's the players with the best IQ in this category id
* @returns {Array} [{user_id: Number, user_name: String, user_score: Number}]
*/
static async getCategoryLeaderboard(category_id)
{
static async getCategoryLeaderboard(category_id) {
const response = await axios.get(`/api/rank/${category_id}/leaderboard/`);
return response.data;
}
Expand All @@ -91,8 +98,7 @@ export default
* Get the global user rank based on average IQ in all categories of the connected player
* @returns {Object} {user_rank: Number, user_score: Number}
*/
static async getGlobalUserRank()
{
static async getGlobalUserRank() {
const response = await axios.get(`/api/rank/global_user/`);
return response.data;
}
Expand All @@ -101,8 +107,7 @@ export default
* Get the user rank specific to a category.
* @returns {Object} {user_rank: Number, user_score: Number}
*/
static async getCategoryUserRank(category_id)
{
static async getCategoryUserRank(category_id) {
const response = await axios.get(`/api/rank/${category_id}/user/`);
return response.data;
}
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/AnswerForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { defineEmits, onMounted, ref, defineProps, watch } from 'vue';
import AnswerMessage from '@/components/AnswerMessage.vue';
// variables specific to this component
const emit = defineEmits(['newQuestion'])
const emit = defineEmits(['newQuestion', 'updateUserIq'])
const answer_sent = ref(false);
const show_text_form = ref(true);
const answer_text = ref("");
Expand All @@ -23,11 +23,13 @@ const props = defineProps({
const submitAnswerText = async () => {
response_to_answer.value = await APIClient.postAnswerText(answer_text.value);
answer_sent.value = true;
emit('updateUserIq');
}
const submitAnswerOption = async (id) => {
response_to_answer.value = await APIClient.postAnswerOption(id);
answer_sent.value = true;
emit('updateUserIq');
}
const fetchOptions = async () => {
Expand Down
68 changes: 68 additions & 0 deletions frontend/src/components/GraphSection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<script setup>
import { ref, computed } from 'vue';
import { Line } from 'vue-chartjs';
import { Chart as ChartJS, Tooltip, PointElement, LineElement, CategoryScale, LinearScale } from 'chart.js';
ChartJS.register(Tooltip, PointElement, LineElement, CategoryScale, LinearScale)
const data = ref([])
const chartData = computed(() => {
let val = {
labels: data.value,
datasets: [
{
backgroundColor: 'rgba(255, 0, 0, 1)',
borderColor: 'rgba(255, 0, 0, 1)',
data: data.value
}
]
};
return val;
});
const addData = (valueToAdd) => {
// pushing the new value to the data array (reactivity is handled by Vue)
data.value = [...data.value, valueToAdd]
}
// expose because addData is called by the parent component
defineExpose({
addData
})
const chartOptions = ref({
scales: {
responsive: true,
maintainAspectRation: false,
x: {
display: false,
},
y: {
display: true,
title: {
display: true,
text: 'IQ Score',
color: 'darkgray'
},
min: 0,
max: 250
}
}
});
</script>

<template>
<h2 class="title">Progression</h2>
<div class="graph-container">
<Line :data="chartData" :options="chartOptions" />
</div>
</template>

<style scoped style="scss">
.graph-container {
margin-bottom: 1.3rem;
padding: 1rem;
border-radius: 20px;
background-color: #F6F6F6;
}
</style>
12 changes: 11 additions & 1 deletion frontend/src/views/QuizView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { onMounted, ref } from 'vue';
import AnswerForm from '@/components/AnswerForm.vue';
import LeaderBoard from '@/components/LeaderBoard.vue';
import CategorieBanner from '@/components/CategorieBanner.vue';
import GraphSection from '@/components/GraphSection.vue';
import APIClient from '@/api_client';
// default variables
Expand All @@ -20,9 +21,16 @@ const fetchNewQuestion = async () => {
// wait for the question before checking if the user has asked for options
hasAskedOptions.value = await APIClient.getIfOptionsAsked();
}
// Fetch user IQ and add it to the graph
const graphComponent = ref(null);
const fetchUserIQ = async () => {
const response = await APIClient.getUserIQ();
graphComponent.value.addData(response.user_iq);
}
onMounted(() => {
fetchNewQuestion();
fetchUserIQ();
});
</script>
Expand All @@ -34,10 +42,12 @@ onMounted(() => {
<div>
<h1 class="title">Question</h1>
<p class="question box">{{ question }}</p>
<AnswerForm @new-question="fetchNewQuestion" :hasAskedOptions="hasAskedOptions" />
<AnswerForm @new-question="fetchNewQuestion" @update-user-iq="fetchUserIQ"
:hasAskedOptions="hasAskedOptions" />
</div>
<div>
<CategorieBanner class="category-banner" :id_category="Number(id_category)" />
<GraphSection ref="graphComponent" />
<LeaderBoard :id_category="Number(id_category)" />
</div>

Expand Down

0 comments on commit 6ab7793

Please sign in to comment.