-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Competence Document KPI matrix (#202)
* Add KpiMatrixAssignment.cs * Add KpiMatrixOutcome.cs * Add KpiMatrixOutcomeStatus.cs * Add KpiMatrixCollection.cs * Remove old repo code (incorrectly added) * Add KpiMatrixComponent.cs * Rewrite data format (not done) * Add component to CompetenceDocumentService.cs * Remove old KpiMatrixCollection.cs * Fix naming issues in kpi matrix component * Fix data format issues in getLegend method * Add outcomes to components * Implement outcomes in KpiMatrixComponent.cs * Change get color logic * Fix color issues in kpi matrix cells * Fix spacing and remove comments * Fix unit tests with new parameter * Fix unit test issue in kpi matrix component * Implement PR feedback * Implement PR feedback * Add competence profile component create table cell method * Implement create table cell method * Fix borders in kpi matrix * Add "Val" parameter for shading * Add "Val" property to shading * Apply shading directly to TableCellProperties * Add default color values for shading * Fix shading and border errors * Revert "Fix shading and border errors" This reverts commit 27210e6. * Change order of borders * Add distinct filtering in criteria * Fix error for unit tests * Add order by functionality * fix kpi matrix header row bug * fix merge request bugs --------- Co-authored-by: Neal Geilen <[email protected]> Co-authored-by: Bas Bakens <[email protected]> Co-authored-by: Kalle Pronk <[email protected]>
- Loading branch information
1 parent
bdbc2e9
commit bb59e9d
Showing
6 changed files
with
226 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
using DocumentFormat.OpenXml; | ||
using DocumentFormat.OpenXml.Packaging; | ||
using DocumentFormat.OpenXml.Wordprocessing; | ||
using Epsilon.Abstractions; | ||
using Epsilon.Abstractions.Components; | ||
|
||
namespace Epsilon.Components; | ||
|
||
public class KpiMatrixComponent : AbstractCompetenceComponent | ||
{ | ||
|
||
public KpiMatrixComponent(IAsyncEnumerable<LearningDomainSubmission> submissions, IEnumerable<LearningDomain?> domains, IEnumerable<LearningDomainOutcome> outcomes) | ||
: base(submissions, domains, outcomes) | ||
{ | ||
} | ||
|
||
public override async Task<Body?> AddToWordDocument(MainDocumentPart mainDocumentPart) | ||
{ | ||
var body = mainDocumentPart.Document.Body; | ||
// Create a table, with rows for the outcomes and columns for the assignments. | ||
var table = new Table(); | ||
|
||
|
||
// Set table properties for formatting. | ||
table.AppendChild(new TableProperties( | ||
new TableWidth { Width = "0", Type = TableWidthUnitValues.Auto, })); | ||
table.AppendChild(new TableGrid()); | ||
|
||
// Calculate the header row height based on the longest assignment name. | ||
var headerRowHeight = 0; | ||
var anyAssignments = false; | ||
|
||
await foreach (var sub in Submissions) | ||
{ | ||
anyAssignments = true; | ||
headerRowHeight = Math.Max(headerRowHeight, sub.Assignment?.Length ?? 10); | ||
|
||
} | ||
|
||
if (anyAssignments) | ||
{ | ||
headerRowHeight *= 111; | ||
} | ||
|
||
// Create the table header row. | ||
var headerRow = new TableRow(); | ||
headerRow.AppendChild(new TableRowProperties(new TableRowHeight { Val = (UInt32Value)(uint)headerRowHeight, })); | ||
|
||
// Empty top-left cell. | ||
headerRow.AppendChild(CreateTableCell("2500", GetBorders(), null, new Paragraph(new Run(new Text(" "))))); | ||
|
||
var index = 0; | ||
await foreach (var sub in Submissions) | ||
{ | ||
var shading = new Shading | ||
{ | ||
Val = ShadingPatternValues.Clear, | ||
Fill = index % 2 == 0 | ||
? "FFFFFF" | ||
: "d3d3d3", | ||
}; | ||
|
||
var cell = CreateTableCell("100", GetBorders(), shading); | ||
|
||
cell.FirstChild.Append(new TextDirection { Val = TextDirectionValues.TopToBottomLeftToRightRotated, }); | ||
Check warning on line 65 in Epsilon/Components/KpiMatrixComponent.cs GitHub Actions / Build .NET solution
|
||
|
||
cell.Append(new Paragraph(new Run(new Text(sub.Assignment ?? "Not found")))); | ||
headerRow.AppendChild(cell); | ||
|
||
|
||
index++; | ||
} | ||
|
||
table.AppendChild(headerRow); | ||
|
||
|
||
var listOfCriteria = Submissions | ||
.SelectMany(static e => e.Criteria | ||
.Select(static result => result ) | ||
.ToAsyncEnumerable()); | ||
|
||
// Add the outcome rows. | ||
await foreach (var outcomeCriterion in listOfCriteria.Distinct().OrderBy(static a => a.Id)) | ||
{ | ||
var row = new TableRow(); | ||
var outcome = Outcomes.FirstOrDefault(o => o.Id == outcomeCriterion.Id); | ||
|
||
// Create a new paragraph for outcome.Name | ||
if (outcome != null) | ||
{ | ||
var paragraphForOutcomeName = new Paragraph(new Run(new Text(outcome.Name))) | ||
{ | ||
ParagraphProperties = new ParagraphProperties { Justification = new Justification { Val = JustificationValues.Center, }, }, | ||
}; | ||
row.AppendChild(CreateTableCell("2500", GetBorders(), null, paragraphForOutcomeName)); | ||
} | ||
|
||
await foreach (var sub in Submissions) | ||
{ | ||
var criteria = sub.Criteria.FirstOrDefault(c => c.Id == outcome?.Id); | ||
var result = sub.Results.FirstOrDefault(r => r.Outcome.Id == outcome?.Id); | ||
|
||
var status = GetStatus(result?.Grade, criteria?.MasteryPoints); | ||
var fillColor = GetColor(status); | ||
if (string.IsNullOrEmpty(fillColor)) | ||
{ | ||
fillColor = "FFFFFF"; // default color code | ||
} | ||
|
||
var shading = new Shading { Val = ShadingPatternValues.Clear, Fill = fillColor, }; | ||
var cell = CreateTableCell("100", GetBorders(), shading); | ||
var text = result != null ? result.Outcome.Value.ShortName : ""; | ||
var paragraph = new Paragraph(); | ||
var run = new Run(new Text(text)); | ||
paragraph.Append(run); | ||
paragraph.ParagraphProperties = new ParagraphProperties() | ||
{ | ||
Justification = new Justification() { Val = JustificationValues.Center, }, | ||
}; | ||
|
||
cell.Append(paragraph); | ||
row.AppendChild(cell); | ||
} | ||
|
||
table.AppendChild(row); | ||
} | ||
|
||
body?.Append(new Paragraph(new Run(new Text("")))); | ||
body?.AppendChild(table); | ||
return body; | ||
} | ||
|
||
private static OutcomeGradeStatus GetStatus(double? grade, double? masteryPoints) | ||
{ | ||
if (grade.HasValue && masteryPoints.HasValue) | ||
{ | ||
return grade.Value >= masteryPoints.Value ? OutcomeGradeStatus.Mastered : OutcomeGradeStatus.NotMastered; | ||
} | ||
if (!grade.HasValue && masteryPoints.HasValue) | ||
{ | ||
return OutcomeGradeStatus.NotAssessed; | ||
} | ||
return OutcomeGradeStatus.NotGraded; | ||
} | ||
|
||
private static string GetColor(OutcomeGradeStatus status) | ||
{ | ||
return status switch | ||
{ | ||
OutcomeGradeStatus.Mastered => "#44F656", | ||
OutcomeGradeStatus.NotMastered => "#FA1818", | ||
OutcomeGradeStatus.NotAssessed => "#9F2B68", | ||
OutcomeGradeStatus.NotGraded => "FFFFFF", | ||
_ => "FFFFFF", | ||
}; | ||
} | ||
|
||
public static TableCell CreateTableCell(string? width, TableCellBorders borders, Shading? shading, params OpenXmlElement[]? elements) | ||
{ | ||
width ??= "300"; | ||
|
||
var cell = new TableCell(); | ||
|
||
var cellProperties = new TableCellProperties() | ||
{ | ||
TableCellBorders = (TableCellBorders)borders.CloneNode(true), | ||
TableCellWidth = new TableCellWidth { Type = TableWidthUnitValues.Dxa, Width = width, }, | ||
// TableCellVerticalAlignment = new TableCellVerticalAlignment() { Val = TableVerticalAlignmentValues.Center,}, | ||
}; | ||
|
||
if (shading != null) | ||
{ | ||
cellProperties.Shading = (Shading)shading.CloneNode(true); | ||
} | ||
|
||
if (elements != null) | ||
{ | ||
foreach (var element in elements) | ||
{ | ||
cell.Append(element.CloneNode(true)); | ||
} | ||
} | ||
cell.TableCellProperties = cellProperties; | ||
|
||
return cell; | ||
} | ||
|
||
private static TableCellBorders GetBorders() | ||
{ | ||
return new TableCellBorders( | ||
new TopBorder | ||
{ | ||
Val = BorderValues.Single, | ||
}, | ||
new LeftBorder | ||
{ | ||
Val = BorderValues.Single, | ||
}, | ||
new BottomBorder | ||
{ | ||
Val = BorderValues.Single, | ||
}, | ||
new RightBorder | ||
{ | ||
Val = BorderValues.Single, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters