Skip to content

Commit

Permalink
Merge pull request #1037 from jplag/report-viewer/documentation
Browse files Browse the repository at this point in the history
Report viewer documentation
  • Loading branch information
sebinside authored Apr 24, 2023
2 parents 5c7e313 + fecccd6 commit f54f77f
Show file tree
Hide file tree
Showing 27 changed files with 416 additions and 96 deletions.
17 changes: 16 additions & 1 deletion report-viewer/src/components/ClusterRadarChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,29 @@ const props = defineProps({

let hasNoMember = false

/**
* @returns The id of the first member of the cluster.
*/
function getIdOfFirstSubmission() {
const firstMember = props.cluster.members.keys().next().value
hasNoMember = !firstMember
return firstMember
}

function createLabelsFor(member: string): Array<string> {
/**
* @param member The member to create the labels for.
* @returns The labels for the member.
*/
function createLabelsFor(member: string) {
let matchedWith = new Array<string>()
props.cluster.members.get(member)?.forEach((m) => matchedWith.push(m.matchedWith))
return matchedWith
}

/**
* @param member The member to create the data set for.
* @returns The data set for the member.
*/
function createDataSetFor(member: string) {
let data = new Array<number>()
props.cluster.members
Expand All @@ -61,6 +72,10 @@ function createDataSetFor(member: string) {
return data
}

/**
* @param num The number to round.
* @returns The rounded number.
*/
function roundToTwoDecimals(num: number): number {
return Math.round((num + Number.EPSILON) * 100) / 100
}
Expand Down
7 changes: 7 additions & 0 deletions report-viewer/src/components/ClustersList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,17 @@ defineProps({

const dialog = ref(false)

/**
* Toggles the dialog visibility.
*/
function toggleDialog() {
dialog.value = !dialog.value
}

/**
* @param cluster The cluster to get the members from.
* @returns The concatenated string of the first 5 members of the cluster.
*/
function getMemberNames(cluster: ClusterListElement) {
const membersIterator = cluster.members.keys()
const members = Array.from(membersIterator)
Expand Down
11 changes: 6 additions & 5 deletions report-viewer/src/components/CodePanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,13 @@ defineEmits(['lineSelected', 'toggleCollapse'])
* 103 : "#FFFF"
* ...
* }
* @type {Ref<UnwrapRef<{}>>}
*/
const coloringArray: Ref<Record<number, string>> = ref({})

/**
* @param lines Array of lines to check.
* @returns true if all lines are empty, false otherwise.
*/
function isEmpty(lines: string[]) {
return lines.length === 0 || lines.every((line) => !line.trim())
}
Expand All @@ -146,7 +150,6 @@ function isEmpty(lines: string[]) {
* When a line is clicked it uses this link id
* to scroll into vie the linked line in the linked file of the other submission.
* Key is line number, value is id of linked line.
* @type {Ref<UnwrapRef<{}>>}
*/
const linksArray: Ref<Record<number, { panel?: number; file?: string; line?: number }>> = ref({})

Expand All @@ -162,9 +165,7 @@ const isLast: Ref<Record<number, boolean>> = ref({})
*/
const isFirst: Ref<Record<number, boolean>> = ref({})

/**
* Initializing the the upper arrays.
*/
// Initializing the the upper arrays.
props.matches?.forEach((m) => {
for (let i = m.start; i <= m.end; i++) {
//assign match color to line
Expand Down
37 changes: 37 additions & 0 deletions report-viewer/src/components/ComparisonsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,39 @@ const props = defineProps({
}
})

/**
* Formats the match percentage to a string with 2 decimal places.
* @param num The number to format.
* @returns The formatted number.
*/
function formattedMatchPercentage(num: number) {
return (num * 100).toFixed(2)
}

const dialog: Ref<Array<boolean>> = ref([])
props.topComparisons.forEach(() => dialog.value.push(false))

/**
* @param submissionId Id to get name for
* @returns The display name of the submission with the given id.
*/
function displayName(submissionId: string) {
return store().submissionDisplayName(submissionId)
}

/**
* Toggles the dialog with the given index.
* @param index The index of the dialog to toggle.
*/
function toggleDialog(index: number) {
dialog.value[index] = true
}

/**
* Navigate to the comparison view with the given ids.
* @param firstId The id of the first submission.
* @param secondId The id of the second submission.
*/
function navigateToComparisonView(firstId: string, secondId: string) {
if (!store().single) {
router.push({
Expand All @@ -140,14 +158,28 @@ function navigateToComparisonView(firstId: string, secondId: string) {
}
}

/**
* @param id1 First Id
* @param id2 Second Id
* @returns Whether the two ids are in a cluster together.
*/
function isInCluster(id1: string, id2: string) {
return props.clusters.some((c: Cluster) => c.members.includes(id1) && c.members.includes(id2))
}

/**
* @param id SubmissionId to check
* @returns Whether the name should be hidden.
*/
function isAnonymous(id: string) {
return store().anonymous.has(id)
}

/**
* @param id First Id
* @param others Other Ids that need to be in the cluster
* @returns The clusters that the two ids are in together.
*/
function getParticipatingMatchesForId(id: string, others: Array<string>) {
let matches: Array<{ matchedWith: string; percentage: number }> = []
props.topComparisons.forEach((comparison) => {
Expand Down Expand Up @@ -188,6 +220,11 @@ const clustersWithParticipatingMatches: Array<ClusterListElement> = props.cluste
}
)

/**
* @param id1 First Id to check
* @param id2 Second Id to check
* @returns All clusters that contain both ids.
*/
function getClustersFor(id1: string, id2: string): Array<ClusterListElement> {
return clustersWithParticipatingMatches.filter((c) => c.members.has(id1) && c.members.has(id2))
}
Expand Down
4 changes: 2 additions & 2 deletions report-viewer/src/components/DistributionDiagram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ const options = ref({
}
})

//We watch the given distributions parameter. When the distribution of another metric is passed, the diagram is
//updated with the new data.
/* We watch the given distributions parameter. When the distribution of another metric is passed, the diagram is
updated with the new data. */
watch(
() => props.distribution,
(val) => {
Expand Down
12 changes: 6 additions & 6 deletions report-viewer/src/components/FilesContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ const emit = defineEmits(['toggle-collapse', 'lineSelected'])

/**
* Passes lineSelected event, emitted from LineOfCode, to parent.
* @param e
* @param index
* @param file
* @param line
* @param e event from clicking on the line
* @param index index of the file in the files array
* @param file path of the file
* @param line line number of the line
*/
function lineSelected(e: unknown, index: number, file: string, line: number) {
emit('lineSelected', e, index, file, line)
}

/**
* converts the submissionId to the name in the path of file. If the length of path exceeds 40, then the file path displays the abbreviation.
* @param match
* @param submissionId
* @param file files path
* @param submissionId id of submission
* @return new path of file
*/
function convertSubmissionIdToName(file: string, submissionId: string): string {
Expand Down
5 changes: 5 additions & 0 deletions report-viewer/src/components/IDsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ defineProps({
})

const emit = defineEmits(['idSent'])

/**
* Emits the ids that should be anonymous
* @param ids The ids that should be anonymous
*/
function emitIdsSent(ids: string[]) {
emit('idSent', ids)
}
Expand Down
1 change: 1 addition & 0 deletions report-viewer/src/components/LineOfCode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<script setup lang="ts">
import { onUpdated, ref } from 'vue'
import hljs from 'highlight.js'
import IDsList from '@/components/IDsList.vue'

const props = defineProps({
/**
Expand Down
3 changes: 3 additions & 0 deletions report-viewer/src/components/TextInformation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ defineProps({

const isCollapsed = ref(false)

/**
* Toggles the collapsed state of the additional info container.
*/
function toggleIsCollapsed() {
isCollapsed.value = !isCollapsed.value
}
Expand Down
7 changes: 7 additions & 0 deletions report-viewer/src/model/Cluster.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Represents a cluster identified by the clustering algorithm.
* A cluster is a group of similar submissions.
* @property averageSimilarity - The average similarity of the submissions in the cluster.
* @property strength - The strength of the cluster
* @property members - The ids of the submissions in the cluster
*/
export type Cluster = {
averageSimilarity: number
strength: number
Expand Down
9 changes: 9 additions & 0 deletions report-viewer/src/model/ClusterListElement.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
/**
* Stores the identified clusters, with information about the matches between the submissions.
* @property averageSimilarity - The average similarity of the submissions in the cluster.
* @property strength - The strength of the cluster
* @property members - The ids of the submissions in the cluster, and the matches between them
*/
type ClusterListElement = {
averageSimilarity: number
strength: number
members: ClusterListElementMember
}
/**
* The ids of the submissions in the cluster, and the matches between them
*/
type ClusterListElementMember = Map<string, Array<{ matchedWith: string; percentage: number }>>
export type { ClusterListElement, ClusterListElementMember }
57 changes: 54 additions & 3 deletions report-viewer/src/model/Comparison.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,73 +24,124 @@ export class Comparison {

private _filesOfFirstSubmission: Map<string, SubmissionFile>

/**
* @return Map of all files of the first submission
*/
get filesOfFirstSubmission(): Map<string, SubmissionFile> {
return this._filesOfFirstSubmission
}

/**
* Set the files of the first submission
* @param value Map to set to
*/
set filesOfFirstSubmission(value: Map<string, SubmissionFile>) {
this._filesOfFirstSubmission = value
}

private _filesOfSecondSubmission: Map<string, SubmissionFile>

/**
* @return Map of all files of the second submission
*/
get filesOfSecondSubmission(): Map<string, SubmissionFile> {
return this._filesOfSecondSubmission
}

/**
* Set the files of the second submission
* @param value Map to set to
*/
set filesOfSecondSubmission(value: Map<string, SubmissionFile>) {
this._filesOfSecondSubmission = value
}

private _colors: Array<string>

/**
* @return Array of all colors used to display the matches
*/
get colors(): Array<string> {
return this._colors
}

/**
* Set the colors used to display the matches
* @param value Colors to set to
*/
set colors(value: Array<string>) {
this._colors = value
}

private _allMatches: Array<Match>

/**
* @return Array of all matches
*/
get allMatches(): Array<Match> {
return this._allMatches
}

/**
* Set the array of all matches
* @param value Matches to set to
*/
set allMatches(value: Array<Match>) {
this._allMatches = value
}

private _matchesInFirstSubmission: Map<string, Array<MatchInSingleFile>>

/**
* @return Map of all matches in the first submission
*/
get matchesInFirstSubmission(): Map<string, Array<MatchInSingleFile>> {
return this._matchesInFirstSubmission
}

/**
* Set the matches in the first submission
* @param value Matches in the first submission to set to
*/
set matchesInFirstSubmission(value: Map<string, Array<MatchInSingleFile>>) {
this._matchesInFirstSubmission = value
}

private _matchesInSecondSubmissions: Map<string, Array<MatchInSingleFile>>

/**
* @return Map of all matches in the second submission
*/
get matchesInSecondSubmissions(): Map<string, Array<MatchInSingleFile>> {
return this._matchesInSecondSubmissions
}

/**
* Set the matches in the second submission
* @param value Matches in the first submission to set to
*/
set matchesInSecondSubmissions(value: Map<string, Array<MatchInSingleFile>>) {
this._matchesInSecondSubmissions = value
}

get firstSubmissionId(): string {
/**
* @return Id of the first submission
*/
get firstSubmissionId() {
return this._firstSubmissionId
}

get secondSubmissionId(): string {
/**
* @return Id of the second submission
*/
get secondSubmissionId() {
return this._secondSubmissionId
}

get similarity(): number {
/**
* @return Similarity of the two submissions
*/
get similarity() {
return this._similarity
}
}
Loading

0 comments on commit f54f77f

Please sign in to comment.