Skip to main content

Assessment & read-only

Apollon has a grading workflow on top of the editor: switch the editor into assessment mode, attach a score and feedback to individual diagram elements, highlight elements, and subscribe to which element the grader selected. The same readonly switch also gives you a plain non-editable viewer. This is the workflow Artemis uses to grade modeling exercises.

Read-only viewer

Pass readonly to render a diagram nobody can edit — for previews, summaries, or a graded result.

import { Apollon, type UMLModel } from "@tumaet/apollon"
import "@tumaet/apollon/style.css"

export function DiagramViewer({ model }: { model: UMLModel }) {
return <Apollon readonly defaultModel={model} style={{ height: 400 }} />
}

Imperatively, it's the readonly constructor option (toggle later with editor.setReadonly(true)):

import { ApollonEditor, type UMLModel } from "@tumaet/apollon"

function mountViewer(container: HTMLElement, model: UMLModel) {
return new ApollonEditor(container, { model, readonly: true })
}

Assessment mode

Construct the editor in ApollonMode.Assessment (or call editor.setMode(ApollonMode.Assessment) later), then attach an Assessment to each element you grade with addOrUpdateAssessment.

import { ApollonEditor, ApollonMode, type Assessment } from "@tumaet/apollon"
import "@tumaet/apollon/style.css"

const container = document.getElementById("apollon")
if (!container) throw new Error("#apollon container missing")

const editor = new ApollonEditor(container, { mode: ApollonMode.Assessment })

const assessment: Assessment = {
modelElementId: "node-1",
elementType: "Class",
score: 2,
feedback: "Good — but the association multiplicity is missing.",
}
editor.addOrUpdateAssessment(assessment)

// Assessments live on the model, keyed by element id:
const all: Record<string, Assessment> = editor.model.assessments

The Assessment shape

FieldTypeNotes
modelElementIdstringThe diagram element this assessment grades. Required.
elementTypestringThe element's type (e.g. "Class"). Required.
scorenumberPoints awarded. Required.
feedbackstring?Free-text feedback.
labelstring?Short label shown on the element.
labelColorstring?CSS color for the label.
correctionStatus{ status: "CORRECT" | "INCORRECT" | "NOT_VALIDATED"; description?: string }?For automated/suggested feedback review.

Highlight elements

setElementHighlights tints elements by id with a CSS color — e.g. to mark the elements that still need feedback. Use translucent colors so the element's own text stays readable. Highlights are ephemeral: they are not serialized into the model and not shared over collaboration. Pass null or an empty map to clear.

import { ApollonEditor } from "@tumaet/apollon"

function highlightMissing(editor: ApollonEditor) {
editor.setElementHighlights(
new Map([
["node-2", "rgba(0, 123, 255, 0.35)"],
["node-5", "rgba(0, 123, 255, 0.35)"],
])
)
}

React to the element being assessed

subscribeToAssessmentSelection fires with the ids of the elements the grader selected, so you can show the matching feedback form. Like every subscribeTo* method it returns a numeric id you pass to editor.unsubscribe to tear down.

import { ApollonEditor } from "@tumaet/apollon"

function watchAssessmentSelection(editor: ApollonEditor) {
const subId = editor.subscribeToAssessmentSelection((selectedElementIds) => {
// open the feedback form for selectedElementIds[0], etc.
console.log("assessing", selectedElementIds)
})
return () => editor.unsubscribe(subId)
}

See also