Fixes export bugs

parent 0d2864c8
{"export":{"page_header":"&LQuiz-Statistik und Ranglisten generiert in einer Live-Session mit arsnova.click&R__createdAt__","page_footer":"&L&A&Carsnova.click ist Open Source Software, siehe arsnova.io&R &P/&N","summary":"Zusammenfassung","exported_at_date":"Exportiert am","session_content":"Archivierte Quizfragen (Um das Quiz zu importieren, kopiere den vollständigen Zellinhalt in eine leere .json-Datei. Importiere dann die Datei mit dem entsprechenden Icon in der Fußzeile der App.)","cas_account_id":"CAS Account-ID","cas_account_email":"CAS E-Mail","quiz_name":"Quizname","question":"Quizfrage","question_type":"Typ der Quizfrage","number_of_answers":"Anzahl der Antworten","percent_correct":"Korrekte Antworten (in %)","answer":"Antwort","attendee":"Teilnehmer/in","attendee_complete_correct":"Teilnehmer/innen mit vollständig richtig beantworteten Fragen","attendee_complete_correct_none_available":"Keine Einträge vorhanden","correct_questions_none_available":"Keine","attendee_all_entries":"Alle Teilnehmer/innen","time":"Antwortzeit (in ms)","confidence_level":"Antwortsicherheit","correct_value":"Richtiger Wert","min_range":"Mindestwert","max_range":"Maximalwert","correct_questions":"Richtig beantwortete Fragen","overall_response_time":"Kumulierte Antwortzeit (in ms)","average_response_time":"Durchschnittliche Antwortzeit (in ms)","number_attendees":"Anzahl der Teilnehmer/innen","average_number_attendees_participated":"Durchschnittliche Teilnahmen am Quiz (in %)","average_correct_answered_questions":"Durchschnittlich richtig beantwortete Fragen","average_confidence":"Durchschnittliche Antwortsicherheit (in %)","exported_at":"um","exported_at_time":"Uhr","type":{"SurveyQuestion":"Umfragen","TrueFalseSingleChoiceQuestion":"Wahr-Falsch Frage","YesNoSingleChoiceQuestion":"Ja-Nein Frage","ABCDSingleChoiceQuestion":"ABCD Single-Choice Frage","SingleChoiceQuestion":"Single-Choice Frage","RangedQuestion":"Schätzfrage","FreeTextQuestion":"Freitext Frage","MultipleChoiceQuestion":"Multiple-Choice Frage"}},"view":{"answeroptions":{"free_text_question":{"config_case_sensitive":"Groß- und Kleinschreibung beachten","config_trim_whitespaces":"Leerzeichen entfernen","config_use_keywords":"Reihenfolge der Wörter beachten","config_use_punctuation":"Interpunktion beachten"}}},"global":{"no":"Nein","yes":"Ja"}}
\ No newline at end of file
{
"export": {
"page_header": "&LQuiz-Statistik und Ranglisten generiert in einer Live-Session mit arsnova.click&R__createdAt__",
"page_footer": "&L&A&Carsnova.click ist Open Source Software, siehe arsnova.io&R &P/&N",
"summary": "Zusammenfassung",
"exported_at_date": "Exportiert am",
"session_content": "Archivierte Quizfragen (Um das Quiz zu importieren, kopiere den vollständigen Zellinhalt in eine leere .json-Datei. Importiere dann die Datei mit dem entsprechenden Icon in der Fußzeile der App.)",
"cas_account_id": "CAS Account-ID",
"cas_account_email": "CAS E-Mail",
"quiz_name": "Quizname",
"question": "Quizfrage",
"question_type": "Typ der Quizfrage",
"number_of_answers": "Anzahl der Antworten",
"percent_correct": "Korrekte Antworten (in %)",
"answer": "Antwort",
"attendee": "Teilnehmer/in",
"attendee_complete_correct": "Teilnehmer/innen mit vollständig richtig beantworteten Fragen",
"attendee_complete_correct_none_available": "Keine Einträge vorhanden",
"correct_questions_none_available": "Keine",
"attendee_all_entries": "Alle Teilnehmer/innen",
"time": "Antwortzeit (in ms)",
"confidence_level": "Antwortsicherheit",
"correct_value": "Richtiger Wert",
"min_range": "Mindestwert",
"max_range": "Maximalwert",
"correct_questions": "Richtig beantwortete Fragen",
"overall_response_time": "Kumulierte Antwortzeit (in ms)",
"average_response_time": "Durchschnittliche Antwortzeit (in ms)",
"number_attendees": "Anzahl der Teilnehmer/innen",
"average_number_attendees_participated": "Durchschnittliche Teilnahmen am Quiz (in %)",
"average_correct_answered_questions": "Durchschnittlich richtig beantwortete Fragen",
"average_confidence": "Durchschnittliche Antwortsicherheit (in %)",
"exported_at": "um",
"exported_at_time": "Uhr",
"type": {
"SurveyQuestion": "Umfrage",
"TrueFalseSingleChoiceQuestion": "Wahr-Falsch Frage",
"YesNoSingleChoiceQuestion": "Ja-Nein Frage",
"ABCDSingleChoiceQuestion": "ABCD Single-Choice Frage",
"SingleChoiceQuestion": "Single-Choice Frage",
"RangedQuestion": "Schätzfrage",
"FreeTextQuestion": "Freitext Frage",
"MultipleChoiceQuestion": "Multiple-Choice Frage"
}
},
"view": {
"answeroptions": {
"free_text_question": {
"config_case_sensitive": "Groß- und Kleinschreibung beachten",
"config_trim_whitespaces": "Leerzeichen entfernen",
"config_use_keywords": "Reihenfolge der Wörter beachten",
"config_use_punctuation": "Interpunktion beachten"
}
}
},
"global": {
"no": "Nein",
"yes": "Ja"
}
}
\ No newline at end of file
......@@ -183,7 +183,7 @@ export class MemberEntity extends AbstractEntity implements IMemberEntity {
responses[i] = {
value: [],
responseTime: -1,
confidence: 0,
confidence: -1,
readingConfirmation: false,
};
}
......
import * as xlsx from 'excel4node';
import * as MessageFormat from 'messageformat';
import MemberDAO from '../db/MemberDAO';
import { AbstractQuestionEntity } from '../entities/question/AbstractQuestionEntity';
import { IMemberEntity } from '../interfaces/entities/Member/IMemberEntity';
import { ILeaderBoardItemBase } from '../interfaces/leaderboard/ILeaderBoardItemBase';
import { IQuizEntity } from '../interfaces/quizzes/IQuizEntity';
......@@ -78,7 +77,7 @@ export abstract class ExcelWorksheet {
});
} else {
this._responsesWithConfidenceValue = MemberDAO.getMembersOfQuiz(this._quiz.name).filter(nickname => {
return nickname.responses.filter(responseItem => responseItem.confidence > -1);
return nickname.responses.some(responseItem => responseItem.confidence > -1);
});
}
if (this._responsesWithConfidenceValue.length > 0) {
......@@ -100,27 +99,8 @@ export abstract class ExcelWorksheet {
protected getLeaderboardData(questionIndex: number): Array<ILeaderBoardItemBase> {
const leaderBoard = new Leaderboard();
const correctResponses: any = {};
const question: AbstractQuestionEntity = this.quiz.questionList[questionIndex];
MemberDAO.getMembersOfQuiz(this._quiz.name).forEach(attendee => {
if (leaderBoard.isCorrectResponse(attendee.responses[questionIndex], question) === 1) {
if (!correctResponses[attendee.name]) {
correctResponses[attendee.name] = {
responseTime: 0,
correctQuestions: [],
confidenceValue: 0,
};
}
correctResponses[attendee.name].responseTime += <number>attendee.responses[questionIndex].responseTime;
correctResponses[attendee.name].correctQuestions.push(questionIndex);
correctResponses[attendee.name].confidenceValue += <number>attendee.responses[questionIndex].confidence;
} else {
delete correctResponses[attendee.name];
}
});
return leaderBoard.objectToArray(correctResponses);
const { correctResponses } = leaderBoard.buildLeaderboard(this.quiz);
return leaderBoard.sortBy(correctResponses, 'score');
}
private prefixNumberWithZero(num: number): string {
......
......@@ -44,7 +44,7 @@ export class FreeTextExcelWorksheet extends ExcelWorksheet implements IExcelWork
this.ws.row(1).setHeight(20);
this.ws.column(1).setWidth(this.responsesWithConfidenceValue.length > 0 ? 40 : 30);
this.ws.column(2).setWidth(30);
this.ws.column(3).setWidth(35);
this.ws.column(3).setWidth(45);
this.ws.column(4).setWidth(35);
this.ws.cell(1, 1, 1, columnsToFormat).style(defaultStyles.quizNameRowStyle);
......@@ -156,7 +156,9 @@ export class FreeTextExcelWorksheet extends ExcelWorksheet implements IExcelWork
${this.mf(answerOption.configTrimWhitespaces ? 'global.yes' : 'global.no')}`);
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.length / MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
this.ws.cell(7, 3).string(`
......
......@@ -150,8 +150,12 @@ export class MultipleChoiceExcelWorksheet extends ExcelWorksheet implements IExc
this.ws.cell(2, 1).string(this.mf('export.question'));
this.ws.cell(6, 1).string(this.mf('export.number_of_answers') + ':');
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.length / MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
if (this.responsesWithConfidenceValue.length > 0) {
this.ws.cell(8, 1).string(this.mf('export.average_confidence') + ':');
let confidenceSummary = 0;
......@@ -160,22 +164,30 @@ export class MultipleChoiceExcelWorksheet extends ExcelWorksheet implements IExc
});
this.ws.cell(8, 2).number(Math.round(confidenceSummary / this.responsesWithConfidenceValue.length));
}
this.ws.cell(4, 1).string(this._question.questionText.replace(/[#]*[*]*/g, ''));
for (let j = 0; j < answerList.length; j++) {
this.ws.cell(2, (j + 2)).string(this.mf('export.answer') + ' ' + (j + 1));
this.ws.cell(4, (j + 2)).string(answerList[j].answerText);
this.ws.cell(6, (j + 2)).number(calculateNumberOfAnswers(this.quiz, this._questionIndex, j));
}
let nextColumnIndex = 1;
this.ws.cell(10, nextColumnIndex++).string(this.mf('export.attendee'));
if (this._isCasRequired) {
this.ws.cell(10, nextColumnIndex++).string(this.mf('export.cas_account_id'));
this.ws.cell(10, nextColumnIndex++).string(this.mf('export.cas_account_email'));
}
this.ws.cell(10, nextColumnIndex++).string(this.mf('export.answer'));
if (this.responsesWithConfidenceValue.length > 0) {
this.ws.cell(10, nextColumnIndex++).string(this.mf('export.confidence_level'));
}
this.ws.cell(10, nextColumnIndex++).string(this.mf('export.time'));
let nextStartRow = 10;
......
......@@ -211,7 +211,9 @@ export class RangedExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
this.ws.cell(6, 4).number(numberOfInputValuesPerGroup.maxRange);
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.length / MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
if (this.responsesWithConfidenceValue.length > 0) {
......
......@@ -167,7 +167,9 @@ export class SingleChoiceExcelWorksheet extends ExcelWorksheet implements IExcel
this.ws.cell(6, 1).string(this.mf('export.number_of_answers') + ':');
this.ws.cell(7, 1).string(this.mf('export.percent_correct') + ':');
const correctResponsesPercentage: number = this.leaderBoardData.length / MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
const correctResponsesPercentage: number = this.leaderBoardData.map(leaderboard => leaderboard.correctQuestions)
.filter(correctQuestions => correctQuestions.includes(this._questionIndex)).length
/ MemberDAO.getMembersOfQuiz(this.quiz.name).length * 100;
this.ws.cell(7, 2).number((isNaN(correctResponsesPercentage) ? 0 : Math.round(correctResponsesPercentage)));
if (this.responsesWithConfidenceValue.length > 0) {
......
......@@ -3,8 +3,6 @@ import MemberDAO from '../db/MemberDAO';
import { QuestionType } from '../enums/QuestionType';
import { IMemberEntity } from '../interfaces/entities/Member/IMemberEntity';
import { IExcelWorksheet } from '../interfaces/iExcel';
import { ILeaderBoardItemBase } from '../interfaces/leaderboard/ILeaderBoardItemBase';
import { Leaderboard } from '../lib/leaderboard/leaderboard';
import { staticStatistics } from '../statistics';
import { ExcelWorksheet } from './ExcelWorksheet';
......@@ -73,43 +71,52 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
this.ws.cell(1, 1, 2, 1).style({
alignment: {
indent: 7,
indent: 5,
},
});
this.ws.cell(4, 1, 8, this.columnsToFormat).style(defaultStyles.statisticsRowStyle);
this.ws.cell(4, 3, 8, 3).style({
let currentRowIndex = 7;
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
currentRowIndex++;
}
this.ws.cell(4, 1, currentRowIndex, this.columnsToFormat).style(defaultStyles.statisticsRowStyle);
this.ws.cell(4, 3, currentRowIndex, 3).style({
alignment: {
horizontal: 'left',
},
});
this.ws.cell(8, 3).style({
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
}
this.ws.cell(this.quiz.sessionConfig.confidenceSliderEnabled ? currentRowIndex - 1 : currentRowIndex, 3, currentRowIndex, 3).style({
numberFormat: '#,##0',
});
this.ws.cell(10, 1, 11, this.columnsToFormat).style(defaultStyles.attendeeHeaderGroupRowStyle);
this.ws.cell(12, 1, 12, this.columnsToFormat).style(defaultStyles.attendeeHeaderRowStyle);
this.ws.cell(12, 1).style({
currentRowIndex += 2;
this.ws.cell(currentRowIndex, 1, currentRowIndex, this.columnsToFormat).style(defaultStyles.attendeeHeaderGroupRowStyle);
this.ws.cell(++currentRowIndex, 1, currentRowIndex, this.columnsToFormat).style(defaultStyles.attendeeHeaderRowStyle);
this.ws.cell(currentRowIndex, 1).style({
alignment: {
horizontal: 'left',
},
});
this.ws.row(12).filter({
firstRow: 12,
this.ws.row(currentRowIndex).filter({
firstRow: currentRowIndex,
firstColumn: 1,
lastRow: 12,
lastColumn: this.columnsToFormat,
lastRow: currentRowIndex,
lastColumn: this.columnsToFormat - 1,
});
let nextStartRow = 18;
let dataWithoutCompleteCorrectQuestions = 0;
this.leaderBoardData.forEach((leaderboardItem, indexInList) => {
let hasNotAllQuestionsCorrect = false;
this.quiz.questionList.forEach((item, index) => {
if ([
QuestionType.SurveyQuestion, QuestionType.ABCDSingleChoiceQuestion,
].includes(item.TYPE) && leaderboardItem.correctQuestions.indexOf((index)) === -1) {
if (![
QuestionType.SurveyQuestion, QuestionType.ABCDSingleChoiceQuestion,
].includes(item.TYPE) && leaderboardItem.correctQuestions.indexOf((index)) === -1) {
hasNotAllQuestionsCorrect = true;
}
});
......@@ -117,57 +124,59 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
dataWithoutCompleteCorrectQuestions++;
return;
}
let nextColumnIndex = 3;
nextStartRow++;
const targetRow = indexInList + 13;
let nextColumnIndex = 2;
currentRowIndex++;
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
this.ws.cell(targetRow, nextColumnIndex++).style({
this.ws.cell(currentRowIndex, nextColumnIndex++).style({
alignment: {
horizontal: 'center',
},
});
}
this.ws.cell(targetRow, nextColumnIndex++).style({
this.ws.cell(currentRowIndex, nextColumnIndex++).style({
alignment: {
horizontal: 'center',
},
numberFormat: '#,##0;',
});
this.ws.cell(targetRow, nextColumnIndex).style({
this.ws.cell(currentRowIndex, nextColumnIndex).style({
alignment: {
horizontal: 'center',
},
numberFormat: '#,##0;',
});
});
if (nextStartRow === 18) {
this.ws.cell(13, 1, 13, this.columnsToFormat, true).style(Object.assign({}, defaultStyles.attendeeEntryRowStyle, {
if (dataWithoutCompleteCorrectQuestions === this.leaderBoardData.length) {
this.ws.cell(++currentRowIndex, 1, currentRowIndex, this.columnsToFormat, true).style(Object.assign({}, defaultStyles.attendeeEntryRowStyle, {
alignment: {
horizontal: 'center',
},
}));
nextStartRow++;
} else {
this.ws.cell(13, 1, (this.leaderBoardData.length + 12 - dataWithoutCompleteCorrectQuestions), this.columnsToFormat)
this.ws.cell(currentRowIndex, 1, (this.leaderBoardData.length + currentRowIndex - 1 - dataWithoutCompleteCorrectQuestions),
this.columnsToFormat)
.style(defaultStyles.attendeeEntryRowStyle);
}
currentRowIndex += 6;
this.ws.cell(nextStartRow++, 1, nextStartRow++, this.columnsToFormat).style(defaultStyles.attendeeHeaderGroupRowStyle);
this.ws.cell(currentRowIndex, 1, currentRowIndex, this.columnsToFormat).style(defaultStyles.attendeeHeaderGroupRowStyle);
currentRowIndex++;
this.ws.cell(nextStartRow, 1, nextStartRow, this.columnsToFormat).style(defaultStyles.attendeeHeaderRowStyle);
this.ws.cell(nextStartRow, 1).style({
this.ws.cell(currentRowIndex, 1, currentRowIndex, this.columnsToFormat).style(defaultStyles.attendeeHeaderRowStyle);
this.ws.cell(currentRowIndex, 1).style({
alignment: {
horizontal: 'left',
},
});
nextStartRow++;
currentRowIndex++;
this.ws.cell(nextStartRow, 1, (this.leaderBoardData.length + (nextStartRow - 1)), this.columnsToFormat)
this.ws.cell(currentRowIndex, 1, (this.leaderBoardData.length + (currentRowIndex - 1)), this.columnsToFormat)
.style(defaultStyles.attendeeEntryRowStyle);
this.leaderBoardData.forEach((leaderboardItem, indexInList) => {
let nextColumnIndex = 3;
const targetRow = indexInList + nextStartRow;
const targetRow = indexInList + currentRowIndex;
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
this.ws.cell(targetRow, nextColumnIndex++).style({
alignment: {
......@@ -252,16 +261,15 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
let nextColumnIndex = 1;
this.ws.cell(currentRowIndex, nextColumnIndex).string(this.mf('export.attendee_complete_correct'));
currentRowIndex += 2;
currentRowIndex += 1;
this.ws.cell(currentRowIndex, nextColumnIndex++).string(this.mf('export.attendee'));
if (this._isCasRequired) {
this.ws.cell(currentRowIndex, nextColumnIndex++).string(this.mf('export.cas_account_id'));
this.ws.cell(currentRowIndex, nextColumnIndex++).string(this.mf('export.cas_account_email'));
}
this.ws.cell(currentRowIndex, nextColumnIndex++).string(this.mf('export.correct_questions'));
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
this.ws.cell(currentRowIndex, nextColumnIndex++).string(this.mf('export.average_confidence'));
}
......@@ -287,13 +295,9 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
this.ws.cell(targetRow, nextColumnIndex++).string(profile.username[0]);
this.ws.cell(targetRow, nextColumnIndex++).string(profile.mail[0]);
}
const correctQuestionNumbers = this.leaderBoardData[indexInList].correctQuestions.map((item) => item + 1);
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
this.ws.cell(targetRow, nextColumnIndex++).string(correctQuestionNumbers.join(', '));
if (this.responsesWithConfidenceValue.length > 0) {
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(leaderboardItem.confidenceValue));
}
if (this.responsesWithConfidenceValue.length > 0) {
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(leaderboardItem.confidenceValue));
}
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(leaderboardItem.responseTime));
......@@ -307,7 +311,7 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
nextColumnIndex = 1;
this.ws.cell(nextStartRow, nextColumnIndex).string(this.mf('export.attendee_all_entries'));
nextStartRow += 2;
nextStartRow++;
this.ws.cell(nextStartRow, nextColumnIndex++).string(this.mf('export.attendee'));
......@@ -330,38 +334,31 @@ export class SummaryExcelWorksheet extends ExcelWorksheet implements IExcelWorks
const targetRow = indexInList + nextStartRow;
this.ws.cell(targetRow, nextColumnIndex++).string(responseItem.name);
if (this._isCasRequired) {
const profile = MemberDAO.getMembersOfQuiz(this.quiz.name).filter((nick: IMemberEntity) => {
const profile = MemberDAO.getMembersOfQuiz(this.quiz.name).find((nick: IMemberEntity) => {
return nick.name === responseItem.name;
})[0].casProfile;
}).casProfile;
this.ws.cell(targetRow, nextColumnIndex++).string(profile.username[0]);
this.ws.cell(targetRow, nextColumnIndex++).string(profile.mail[0]);
}
const leaderboardItem = this._leaderBoardData.filter((item) => item.name === responseItem.name)[0];
const leaderboardItem = this._leaderBoardData.find((item) => item.name === responseItem.name);
if (leaderboardItem) {
if (leaderboardItem.correctQuestions.length > 0) {
const correctQuestionNumbers = this._leaderBoardData[indexInList].correctQuestions.map((item) => item + 1);
const correctQuestionNumbers = leaderboardItem.correctQuestions.map((item) => item + 1);
this.ws.cell(targetRow, nextColumnIndex++).string(correctQuestionNumbers.join(', '));
}
if (this.quiz.sessionConfig.confidenceSliderEnabled) {
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(this._leaderBoardData[indexInList].confidenceValue));
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(leaderboardItem.confidenceValue));
}
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(this._leaderBoardData[indexInList].responseTime));
this.ws.cell(targetRow, nextColumnIndex++)
.number(Math.round(this._leaderBoardData[indexInList].responseTime / this._leaderBoardData[indexInList].correctQuestions.length));
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(leaderboardItem.responseTime));
this.ws.cell(targetRow, nextColumnIndex++).number(Math.round(leaderboardItem.responseTime / leaderboardItem.correctQuestions.length));
} else {
this.ws.cell(targetRow, nextColumnIndex++).string(this.mf('export.correct_questions_none_available'));
}
});
}
protected getLeaderboardData(): Array<ILeaderBoardItemBase> {
const leaderBoard = new Leaderboard();
const { correctResponses } = leaderBoard.buildLeaderboard(this.quiz);
return leaderBoard.sortBy(correctResponses, 'score');
}
private addLogoImage(): void {
this.ws.addImage({
path: path.join(staticStatistics.pathToAssets, 'images', 'logo_transparent.png'),
......
import MemberDAO from '../db/MemberDAO';
import { SurveyQuestionEntity } from '../entities/question/SurveyQuestionEntity';
import { IMemberEntity } from '../interfaces/entities/Member/IMemberEntity';
import { IExcelWorksheet } from '../interfaces/iExcel';
import { ExcelWorksheet } from './ExcelWorksheet';
import { calculateNumberOfAnswers } from './lib/excel_function_library';
......@@ -161,22 +160,17 @@ export class SurveyExcelWorksheet extends ExcelWorksheet implements IExcelWorksh
this.ws.cell(9, nextColumnIndex++).string(this.mf('export.time'));
let nextStartRow = 9;
this.leaderBoardData.forEach((leaderboardItem) => {
MemberDAO.getMembersOfQuiz(this.quiz.name).forEach((nickItem, indexInList) => {
nextColumnIndex = 1;
nextStartRow++;
this.ws.cell(nextStartRow, nextColumnIndex++).string(leaderboardItem.name);
const nickItem = MemberDAO.getMembersOfQuiz(this.quiz.name).find((nick: IMemberEntity) => {
return nick.name === leaderboardItem.name;
});
this.ws.cell(nextStartRow, nextColumnIndex++).string(nickItem.name);
if (this._isCasRequired) {
const profile = nickItem.casProfile;
this.ws.cell(nextStartRow, nextColumnIndex++).string(profile.username[0]);
this.ws.cell(nextStartRow, nextColumnIndex++).string(profile.mail[0]);
}
const chosenAnswer: Array<string> = <any>nickItem.responses[this._questionIndex].value;
chosenAnswer.forEach((answerIndex: string, index: number) => {
chosenAnswer[index] = this._question.answerOptionList[parseInt(answerIndex, 10)].answerText;
});
const chosenAnswer: Array<string> = (<Array<any>>nickItem.responses[this._questionIndex].value).map(
answerIndex => this._question.answerOptionList[parseInt(answerIndex, 10)].answerText);
this.ws.cell(nextStartRow, nextColumnIndex++).string(chosenAnswer.join(', '));
if (this.responsesWithConfidenceValue.length > 0) {
this.ws.cell(nextStartRow, nextColumnIndex++).number(Math.round(nickItem.responses[this._questionIndex].confidence));
......
......@@ -41,6 +41,7 @@ export class ExcelTheme {
alignment: {
wrapText: true,
vertical: 'top',
horizontal: 'left',
},
},
statisticsRowStyle: {
......
......@@ -37,7 +37,7 @@ export class Leaderboard {
case QuestionType.SingleChoiceQuestion:
case QuestionType.YesNoSingleChoiceQuestion:
case QuestionType.TrueFalseSingleChoiceQuestion:
return this.isCorrectSingleChoiceQuestion(<number>response.value, <AbstractChoiceQuestionEntity>question) ? 1 : -1;
return this.isCorrectSingleChoiceQuestion(<number>response.value[0], <AbstractChoiceQuestionEntity>question) ? 1 : -1;
case QuestionType.MultipleChoiceQuestion:
return this.isCorrectMultipleChoiceQuestion(<Array<number>>response.value, <AbstractChoiceQuestionEntity>question);
case QuestionType.ABCDSingleChoiceQuestion:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment