From e61a8bd51de13cda8081f422245d8bd12399f5d0 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 3 Mar 2023 14:23:31 +0100 Subject: [PATCH] lives: Can display results as charts on all screens --- direct.go | 74 ++++++++++++++++++- .../routes/surveys/[sid]/admin/+page.svelte | 24 ++++-- ui/src/routes/surveys/[sid]/live/+page.svelte | 20 ++++- 3 files changed, 107 insertions(+), 11 deletions(-) diff --git a/direct.go b/direct.go index d1319d4..e1d6b87 100644 --- a/direct.go +++ b/direct.go @@ -2,8 +2,10 @@ package main import ( "context" + "fmt" "log" "net/http" + "strings" "sync" "time" @@ -280,6 +282,62 @@ func getCorrectionString(qid int64) (ret map[string]int) { return } +func getResponsesStats(qid int64) map[string]interface{} { + q, err := getQuestion(int(qid)) + if err != nil { + return nil + } + + responses, err := q.GetResponses() + if err != nil { + log.Println("Unable to retrieve responses:", err) + return nil + } + + labels := []string{} + values := []uint{} + + if q.Kind == "mcq" || q.Kind == "ucq" { + proposals, err := q.GetProposals() + if err != nil { + return nil + } + + proposal_idx := map[string]int{} + for _, p := range proposals { + proposal_idx[fmt.Sprintf("%d", p.Id)] = len(labels) + labels = append(labels, p.Label) + values = append(values, 0) + } + + for _, r := range responses { + for _, v := range strings.Split(r.Answer, ",") { + values[proposal_idx[v]]++ + } + } + } else { + stats := map[string]uint{} + + for _, r := range responses { + stats[r.Answer]++ + } + + for k, v := range stats { + labels = append(labels, k) + values = append(values, v) + } + } + + return map[string]interface{}{ + "labels": labels, + "datasets": []map[string][]uint{ + map[string][]uint{ + "values": values, + }, + }, + } +} + func SurveyWSAdmin(c *gin.Context) { u := c.MustGet("LoggedUser").(*User) survey := c.MustGet("survey").(*Survey) @@ -342,6 +400,7 @@ func SurveyWSAdmin(c *gin.Context) { // Save corrected state for the callback corrected := v.Corrected + with_stats := v.Stats != nil surveyTimer = time.AfterFunc(time.Duration(OffsetQuestionTimer+v.Timer)*time.Millisecond, func() { surveyTimer = nil @@ -349,7 +408,12 @@ func SurveyWSAdmin(c *gin.Context) { survey.Corrected = v.Corrected survey.Update() - survey.WSWriteAll(WSMessage{Action: "new_question", QuestionId: v.QuestionId, Corrected: true, Corrections: getCorrectionString(*v.QuestionId)}) + var stats map[string]interface{} + if with_stats { + stats = getResponsesStats(*v.QuestionId) + } + + survey.WSWriteAll(WSMessage{Action: "new_question", QuestionId: v.QuestionId, Corrected: true, Stats: stats, Corrections: getCorrectionString(*v.QuestionId)}) } else { var z int64 = 0 survey.Direct = &z @@ -360,10 +424,18 @@ func SurveyWSAdmin(c *gin.Context) { } }) v.Corrected = false + v.Stats = nil } else { survey.Corrected = v.Corrected if v.Corrected { v.Corrections = getCorrectionString(*v.QuestionId) + if v.Stats != nil { + v.Stats = getResponsesStats(*v.QuestionId) + } else { + v.Stats = nil + } + } else { + v.Stats = nil } } _, err = survey.Update() diff --git a/ui/src/routes/surveys/[sid]/admin/+page.svelte b/ui/src/routes/surveys/[sid]/admin/+page.svelte index 25003a7..65cbc89 100644 --- a/ui/src/routes/surveys/[sid]/admin/+page.svelte +++ b/ui/src/routes/surveys/[sid]/admin/+page.svelte @@ -47,6 +47,7 @@ let responses = {}; let corrected = false; let next_corrected = false; + let with_stats = false; let timer = 20; let timer_end = null; let timer_remain = 0; @@ -308,7 +309,6 @@ Réponses - Actions + @@ -374,7 +384,7 @@ class:btn-primary={!next_corrected} class:btn-success={next_corrected} disabled={(question.id === current_question && next_corrected == corrected) || !ws_up} - on:click={() => { ws.send('{"action":"new_question", "corrected": ' + next_corrected + ', "timer": 0, "question":' + question.id + '}')} } + on:click={() => { ws.send('{"action":"new_question", "corrected": ' + next_corrected + (with_stats?', "stats": {}':'') + ', "timer": 0, "question":' + question.id + '}')} } > @@ -382,7 +392,7 @@ type="button" class="btn btn-sm btn-danger" disabled={question.id === current_question || !ws_up} - on:click={() => { ws.send('{"action":"new_question", "corrected": ' + next_corrected + ', "timer": ' + timer * 1000 + ',"question":' + question.id + '}')} } + on:click={() => { ws.send('{"action":"new_question", "corrected": ' + next_corrected + (with_stats?', "stats": {}':'') + ', "timer": ' + timer * 1000 + ',"question":' + question.id + '}')} } > diff --git a/ui/src/routes/surveys/[sid]/live/+page.svelte b/ui/src/routes/surveys/[sid]/live/+page.svelte index 919dff2..ddde42f 100644 --- a/ui/src/routes/surveys/[sid]/live/+page.svelte +++ b/ui/src/routes/surveys/[sid]/live/+page.svelte @@ -3,8 +3,9 @@ import { user } from '$lib/stores/user'; import { ToastsStore } from '$lib/stores/toasts'; - import SurveyBadge from '$lib/components/SurveyBadge.svelte'; + import CorrectionPieChart from '$lib/components/CorrectionPieChart.svelte'; import QuestionForm from '$lib/components/QuestionForm.svelte'; + import SurveyBadge from '$lib/components/SurveyBadge.svelte'; import { getQuestion } from '$lib/questions'; export let data; @@ -88,7 +89,12 @@ if (data.action && data.action == "new_question") { show_question = data.question; survey.corrected = data.corrected; - if (data.corrected) { + if (data.stats) { + stats = data.stats; + } else { + stats = null; + } + if(data.corrected) { corrections = data.corrections; } else { corrections = null; @@ -168,6 +174,7 @@ } let corrections = null; + let stats = null;
Chargement d'une nouvelle question …
{:then question} + {#if stats != null} + + {/if} {/if} - {#if question.kind != 'mcq' && question.kind != 'ucq' && question.kind != 'none'} + {#if !survey.corrected && question.kind != 'mcq' && question.kind != 'ucq' && question.kind != 'none'}