diff --git a/report-viewer/src/components/ComparisonTableFilter.vue b/report-viewer/src/components/ComparisonTableFilter.vue index b2e47a29b..5e35d13b5 100644 --- a/report-viewer/src/components/ComparisonTableFilter.vue +++ b/report-viewer/src/components/ComparisonTableFilter.vue @@ -45,7 +45,7 @@ import ToolTipComponent from './ToolTipComponent.vue' import ButtonComponent from './ButtonComponent.vue' import OptionsSelector from './optionsSelectors/OptionsSelectorComponent.vue' import { store } from '@/stores/store' -import { MetricType, metricToolTips } from '@/model/MetricType' +import { MetricJsonIdentifier, MetricTypes } from '@/model/MetricType' import type { ToolTipLabel } from '@/model/ui/ToolTip' const props = defineProps({ @@ -93,7 +93,9 @@ const searchStringValue = computed({ function changeSortingMetric(index: number) { store().uiState.comparisonTableSortingMetric = - index < tableSortingMetricOptions.length ? tableSortingMetricOptions[index] : MetricType.AVERAGE + index < tableSortingMetricOptions.length + ? tableSortingMetricOptions[index].identifier + : MetricJsonIdentifier.AVERAGE_SIMILARITY store().uiState.comparisonTableClusterSorting = tableSortingOptions.value[index] == 'Cluster' } @@ -101,15 +103,17 @@ function getSortingMetric() { if (store().uiState.comparisonTableClusterSorting && props.enableClusterSorting) { return tableSortingOptions.value.indexOf('Cluster') } - return tableSortingMetricOptions.indexOf(store().uiState.comparisonTableSortingMetric) + return tableSortingMetricOptions.findIndex( + (m) => m.identifier == store().uiState.comparisonTableSortingMetric + ) } -const tableSortingMetricOptions = [MetricType.AVERAGE, MetricType.MAXIMUM] +const tableSortingMetricOptions = MetricTypes.METRIC_LIST const tableSortingOptions = computed(() => { const options: (ToolTipLabel | string)[] = tableSortingMetricOptions.map((metric) => { return { - displayValue: metricToolTips[metric].longName, - tooltip: metricToolTips[metric].tooltip + displayValue: metric.longName, + tooltip: metric.tooltip } }) if (props.enableClusterSorting) { diff --git a/report-viewer/src/components/ComparisonsTable.vue b/report-viewer/src/components/ComparisonsTable.vue index d1856c770..4fdf1cf30 100644 --- a/report-viewer/src/components/ComparisonsTable.vue +++ b/report-viewer/src/components/ComparisonsTable.vue @@ -21,12 +21,12 @@ @@ -34,12 +34,12 @@ @@ -102,10 +102,18 @@
- {{ (item.similarities[MetricType.AVERAGE] * 100).toFixed(2) }}% + {{ + MetricTypes.AVERAGE_SIMILARITY.format( + item.similarities[MetricTypes.AVERAGE_SIMILARITY.shortName] + ) + }}
- {{ (item.similarities[MetricType.MAXIMUM] * 100).toFixed(2) }}% + {{ + MetricTypes.MAXIMUM_SIMILARITY.format( + item.similarities[MetricTypes.MAXIMUM_SIMILARITY.shortName] + ) + }}
@@ -175,7 +183,7 @@ import { library } from '@fortawesome/fontawesome-svg-core' import { faUserGroup } from '@fortawesome/free-solid-svg-icons' import { generateHues } from '@/utils/ColorUtils' import ToolTipComponent from './ToolTipComponent.vue' -import { MetricType, metricToolTips } from '@/model/MetricType' +import { MetricJsonIdentifier, MetricTypes } from '@/model/MetricType' import NameElement from './NameElement.vue' import ComparisonTableFilter from './ComparisonTableFilter.vue' @@ -251,28 +259,32 @@ function getFilteredComparisons(comparisons: ComparisonListElement[]) { } // metric search - const searchPerMetric: Record = { - [MetricType.AVERAGE]: [], - [MetricType.MAXIMUM]: [] - } + const searchPerMetric: Record = {} as Record< + MetricJsonIdentifier, + string[] + > + MetricTypes.METRIC_JSON_IDENTIFIERS.forEach((m) => { + searchPerMetric[m] = [] + }) metricSearches.forEach((s) => { const regexResult = /^(?:(avg|max):)([<>]=?[0-9]+%?$)/.exec(s) if (regexResult) { const metricName = regexResult[1] - let metric = MetricType.AVERAGE - for (const m of [MetricType.AVERAGE, MetricType.MAXIMUM]) { - if (metricToolTips[m].shortName.toLowerCase() == metricName) { + let metric = MetricTypes.AVERAGE_SIMILARITY + for (const m of MetricTypes.METRIC_LIST) { + if (m.shortName.toLowerCase() == metricName) { metric = m break } } - searchPerMetric[metric].push(regexResult[2]) + searchPerMetric[metric.identifier].push(regexResult[2]) } else { - searchPerMetric[MetricType.AVERAGE].push(s) - searchPerMetric[MetricType.MAXIMUM].push(s) + MetricTypes.METRIC_JSON_IDENTIFIERS.forEach((m) => { + searchPerMetric[m].push(s) + }) } }) - for (const metric of [MetricType.AVERAGE, MetricType.MAXIMUM]) { + for (const metric of MetricTypes.METRIC_JSON_IDENTIFIERS) { for (const search of searchPerMetric[metric]) { const regexResult = /([<>]=?)([0-9]+)%?/.exec(search)! const operator = regexResult[1] diff --git a/report-viewer/src/components/distributionDiagram/DistributionDiagram.vue b/report-viewer/src/components/distributionDiagram/DistributionDiagram.vue index 65ee66ed8..1e762854a 100644 --- a/report-viewer/src/components/distributionDiagram/DistributionDiagram.vue +++ b/report-viewer/src/components/distributionDiagram/DistributionDiagram.vue @@ -18,16 +18,16 @@ import { Chart, registerables } from 'chart.js' import ChartDataLabels from 'chartjs-plugin-datalabels' import { graphColors } from '@/utils/ColorUtils' import type { Distribution } from '@/model/Distribution' -import { MetricType } from '@/model/MetricType' import { store } from '@/stores/store' import DistributionDiagramOptions from './DistributionDiagramOptions.vue' +import type { MetricJsonIdentifier } from '@/model/MetricType' Chart.register(...registerables) Chart.register(ChartDataLabels) const props = defineProps({ distributions: { - type: Object as PropType>, + type: Object as PropType>, required: true }, xScale: { diff --git a/report-viewer/src/components/distributionDiagram/DistributionDiagramOptions.vue b/report-viewer/src/components/distributionDiagram/DistributionDiagramOptions.vue index ffb52474b..81a2b24b2 100644 --- a/report-viewer/src/components/distributionDiagram/DistributionDiagramOptions.vue +++ b/report-viewer/src/components/distributionDiagram/DistributionDiagramOptions.vue @@ -7,7 +7,8 @@ title="Metric:" :defaultSelected="store().uiState.distributionChartConfig.metric" @selection-changed=" - (metric: MetricType) => (store().uiState.distributionChartConfig.metric = metric) + (metric: MetricJsonIdentifier) => + (store().uiState.distributionChartConfig.metric = metric) " /> diff --git a/report-viewer/src/model/Comparison.ts b/report-viewer/src/model/Comparison.ts index 1c84d7c4f..df51f8a93 100644 --- a/report-viewer/src/model/Comparison.ts +++ b/report-viewer/src/model/Comparison.ts @@ -1,7 +1,6 @@ import type { Match } from './Match' import type { SubmissionFile } from '@/model/File' import { MatchInSingleFile } from './MatchInSingleFile' -import type { MetricType } from './MetricType' /** * Comparison model used by the ComparisonView @@ -9,7 +8,7 @@ import type { MetricType } from './MetricType' export class Comparison { private readonly _firstSubmissionId: string private readonly _secondSubmissionId: string - private readonly _similarities: Record + private readonly _similarities: Record private readonly _filesOfFirstSubmission: SubmissionFile[] private readonly _filesOfSecondSubmission: SubmissionFile[] private readonly _allMatches: Array @@ -19,7 +18,7 @@ export class Comparison { constructor( firstSubmissionId: string, secondSubmissionId: string, - similarities: Record, + similarities: Record, filesOfFirstSubmission: SubmissionFile[], filesOfSecondSubmission: SubmissionFile[], allMatches: Array, diff --git a/report-viewer/src/model/ComparisonListElement.ts b/report-viewer/src/model/ComparisonListElement.ts index 4c7b767dc..8a98128b2 100644 --- a/report-viewer/src/model/ComparisonListElement.ts +++ b/report-viewer/src/model/ComparisonListElement.ts @@ -1,4 +1,4 @@ -import type { MetricType } from './MetricType' +import type { MetricJsonIdentifier } from './MetricType' /** * Comparison model used by the Comparison Table in Overview. Only the needed attributes to display are included. @@ -16,6 +16,6 @@ export type ComparisonListElement = { id: number firstSubmissionId: string secondSubmissionId: string - similarities: Record + similarities: Record clusterIndex: number } diff --git a/report-viewer/src/model/MetricType.ts b/report-viewer/src/model/MetricType.ts index 5fc4897be..9dfa7c773 100644 --- a/report-viewer/src/model/MetricType.ts +++ b/report-viewer/src/model/MetricType.ts @@ -1,28 +1,148 @@ -/** - * This enum maps the metric type to the index they have in the generated JSON and respectively in the store. - */ -export enum MetricType { - AVERAGE = 'AVG', - MAXIMUM = 'MAX' +export enum MetricJsonIdentifier { + AVERAGE_SIMILARITY = 'AVG', + MAXIMUM_SIMILARITY = 'MAX', + MINIMUM_SIMILARITY = 'MIN', + INTERSECTION = 'INTERSECTION', + SYMMETRIC = 'SYMMETRIC', + LONGEST_MATCH = 'LONGEST_MATCH', + OVERALL = 'OVERALL' } -export type MetricToolTipData = { - longName: string - shortName: string - tooltip: string +export abstract class MetricType { + private readonly _shortName: string + private readonly _longName: string + private readonly _tooltip: string + private readonly _identifier: MetricJsonIdentifier + + constructor( + shortName: string, + longName: string, + tooltip: string, + identifier: MetricJsonIdentifier + ) { + this._shortName = shortName + this._longName = longName + this._tooltip = tooltip + this._identifier = identifier + } + + get shortName() { + return this._shortName + } + + get longName() { + return this._longName + } + + get tooltip() { + return this._tooltip + } + + get identifier() { + return this._identifier + } + + abstract format(value: number): string } -export const metricToolTips: Record = { - [MetricType.AVERAGE]: { - longName: 'Average Similarity', - shortName: 'AVG', - tooltip: - 'The average similarity of the two files.\nA high similarity indicates that the programms work in a similar way.' - }, - [MetricType.MAXIMUM]: { - longName: 'Maximum Similarity', - shortName: 'MAX', - tooltip: - 'The maximum similarity of the two files.\nUseful if programms are very different in size.' +class IdentityMetricType extends MetricType { + constructor( + shortName: string, + longName: string, + tooltip: string, + identifier: MetricJsonIdentifier + ) { + super(shortName, longName, tooltip, identifier) + } + + format(value: number): string { + return value.toString() + } +} + +class PercentageMetricType extends MetricType { + constructor( + shortName: string, + longName: string, + tooltip: string, + identifier: MetricJsonIdentifier + ) { + super(shortName, longName, tooltip, identifier) + } + + format(value: number): string { + return `${(value * 100).toFixed(2)}%` + } +} + +export namespace MetricTypes { + export const AVERAGE_SIMILARITY = new PercentageMetricType( + 'AVG', + 'Average Similarity', + 'The average similarity of the two files.\nA high similarity indicates that the programs work in a similar way.', + MetricJsonIdentifier.AVERAGE_SIMILARITY + ) + export const MAXIMUM_SIMILARITY = new PercentageMetricType( + 'MAX', + 'Maximum Similarity', + 'The maximum similarity of the two files.\nUseful if programs are very different in size.', + MetricJsonIdentifier.MAXIMUM_SIMILARITY + ) + export const MINIMUM_SIMILARITY = new PercentageMetricType( + 'MIN', + 'Minimum Similarity', + 'The minimum similarity of the two files.', + MetricJsonIdentifier.MINIMUM_SIMILARITY + ) + export const INTERSECTION = new IdentityMetricType( + 'INTER', + 'Matched Tokens', + 'The number of tokens that are matched between the two files.', + MetricJsonIdentifier.INTERSECTION + ) + export const SYMMETRIC = new PercentageMetricType( + 'SYM', + 'Symmetric Similarity', + 'A symmetric similarity measure.', + MetricJsonIdentifier.SYMMETRIC + ) + export const LONGEST_MATCH = new IdentityMetricType( + 'LONG', + 'Longest Match', + 'The number of tokens in the longest match.', + MetricJsonIdentifier.LONGEST_MATCH + ) + export const OVERALL = new IdentityMetricType( + 'ALL', + 'Overall', + 'Sum of both submission lengths.', + MetricJsonIdentifier.OVERALL + ) + + export const METRIC_LIST: MetricType[] = [ + AVERAGE_SIMILARITY, + MAXIMUM_SIMILARITY, + MINIMUM_SIMILARITY, + INTERSECTION, + SYMMETRIC, + LONGEST_MATCH, + OVERALL + ] + + export const METRIC_MAP: Record = {} as Record< + MetricJsonIdentifier, + MetricType + > + for (const metric of METRIC_LIST) { + METRIC_MAP[metric.identifier] = metric } + export const METRIC_JSON_IDENTIFIERS = [ + MetricJsonIdentifier.AVERAGE_SIMILARITY, + MetricJsonIdentifier.MAXIMUM_SIMILARITY, + MetricJsonIdentifier.MINIMUM_SIMILARITY, + MetricJsonIdentifier.INTERSECTION, + MetricJsonIdentifier.SYMMETRIC, + MetricJsonIdentifier.LONGEST_MATCH, + MetricJsonIdentifier.OVERALL + ] } diff --git a/report-viewer/src/model/Overview.ts b/report-viewer/src/model/Overview.ts index 56841636f..16e91862b 100644 --- a/report-viewer/src/model/Overview.ts +++ b/report-viewer/src/model/Overview.ts @@ -1,7 +1,7 @@ import type { Distribution } from './Distribution' import type { Cluster } from '@/model/Cluster' import type { ComparisonListElement } from './ComparisonListElement' -import type { MetricType } from './MetricType' +import type { MetricJsonIdentifier } from './MetricType' import type { Language } from './Language' /** @@ -16,7 +16,7 @@ export class Overview { private readonly _dateOfExecution: string private readonly _durationOfExecution: number private readonly _topComparisons: Array - private readonly _distributions: Record + private readonly _distributions: Record private readonly _clusters: Array private readonly _totalComparisons: number @@ -29,7 +29,7 @@ export class Overview { dateOfExecution: string, durationOfExecution: number, topComparisons: Array, - distributions: Record, + distributions: Record, clusters: Array, totalComparisons: number ) { diff --git a/report-viewer/src/model/factories/ComparisonFactory.ts b/report-viewer/src/model/factories/ComparisonFactory.ts index 9305ad630..b872af43c 100644 --- a/report-viewer/src/model/factories/ComparisonFactory.ts +++ b/report-viewer/src/model/factories/ComparisonFactory.ts @@ -4,7 +4,7 @@ import { store } from '@/stores/store' import { getMatchColorCount } from '@/utils/ColorUtils' import slash from 'slash' import { BaseFactory } from './BaseFactory' -import { MetricType } from '../MetricType' +import { MetricJsonIdentifier } from '../MetricType' import type { SubmissionFile } from '../File' /** @@ -66,10 +66,12 @@ export class ComparisonFactory extends BaseFactory { ) } - private static extractSimilarities(json: Record): Record { - const similarities = {} as Record + private static extractSimilarities( + json: Record + ): Record { + const similarities = {} as Record for (const [key, value] of Object.entries(json)) { - similarities[key as MetricType] = value + similarities[key as MetricJsonIdentifier] = value } return similarities } diff --git a/report-viewer/src/model/factories/OptionsFactory.ts b/report-viewer/src/model/factories/OptionsFactory.ts index 3cd5a30bd..346e70840 100644 --- a/report-viewer/src/model/factories/OptionsFactory.ts +++ b/report-viewer/src/model/factories/OptionsFactory.ts @@ -1,6 +1,6 @@ import type { CliClusterOptions, CliMergingOptions, CliOptions } from '../CliOptions' import { ParserLanguage } from '../Language' -import { MetricType } from '../MetricType' +import { MetricJsonIdentifier, MetricTypes } from '../MetricType' import { BaseFactory } from './BaseFactory' export class OptionsFactory extends BaseFactory { @@ -9,6 +9,7 @@ export class OptionsFactory extends BaseFactory { } private static extractOptions(json: Record): CliOptions { + const similarityMetricIdentifier = json['similarity_metric'] as MetricJsonIdentifier return { language: json['language'] as ParserLanguage, minTokenMatch: json['min_token_match'] as number, @@ -18,7 +19,10 @@ export class OptionsFactory extends BaseFactory { subDirectoryName: (json['subdirectory_name'] as string) ?? '', fileSuffixes: json['file_suffixes'] as string[], exclusionFileName: (json['exclusion_file_name'] as string) ?? '', - similarityMetric: json['similarity_metric'] as MetricType, + similarityMetric: + MetricTypes.METRIC_LIST.find( + (metric) => metric.identifier === similarityMetricIdentifier + ) ?? MetricTypes.AVERAGE_SIMILARITY, similarityThreshold: json['similarity_threshold'] as number, maxNumberComparisons: json['max_comparisons'] as number, clusterOptions: this.extractClusterOptions(json['cluster'] as Record), @@ -29,7 +33,7 @@ export class OptionsFactory extends BaseFactory { private static extractClusterOptions(json: Record): CliClusterOptions { return { enabled: json['enabled'] as boolean, - similarityMetric: MetricType.AVERAGE, + similarityMetric: MetricTypes.AVERAGE_SIMILARITY, spectralBandwidth: json['spectral_bandwidth'] as number, spectralGaussianProcessVariance: json['spectral_gaussian_variance'] as number, spectralMinRuns: json['spectral_min_runs'] as number, diff --git a/report-viewer/src/model/factories/OverviewFactory.ts b/report-viewer/src/model/factories/OverviewFactory.ts index e388353e1..1ff3aa795 100644 --- a/report-viewer/src/model/factories/OverviewFactory.ts +++ b/report-viewer/src/model/factories/OverviewFactory.ts @@ -5,7 +5,7 @@ import { store } from '@/stores/store' import { Version, minimalReportVersion, reportViewerVersion } from '../Version' import { getLanguageParser } from '../Language' import { Distribution } from '../Distribution' -import { MetricType } from '../MetricType' +import { MetricJsonIdentifier } from '../MetricType' import { BaseFactory } from './BaseFactory' /** @@ -59,10 +59,10 @@ export class OverviewFactory extends BaseFactory { private static extractDistributions( json: Record> - ): Record { - const distributions = {} as Record + ): Record { + const distributions = {} as Record for (const [key, value] of Object.entries(json)) { - distributions[key as MetricType] = new Distribution(value as Array) + distributions[key as MetricJsonIdentifier] = new Distribution(value as Array) } return distributions } @@ -79,7 +79,7 @@ export class OverviewFactory extends BaseFactory { id: counter, firstSubmissionId: topComparison.first_submission as string, secondSubmissionId: topComparison.second_submission as string, - similarities: topComparison.similarities as Record + similarities: topComparison.similarities as Record } comparisons.push({ ...comparison, diff --git a/report-viewer/src/model/ui/DistributionChartConfig.ts b/report-viewer/src/model/ui/DistributionChartConfig.ts index cc260dec0..3a67e0e08 100644 --- a/report-viewer/src/model/ui/DistributionChartConfig.ts +++ b/report-viewer/src/model/ui/DistributionChartConfig.ts @@ -1,11 +1,11 @@ import type { BucketOptions } from '../Distribution' -import type { MetricType } from '../MetricType' +import type { MetricJsonIdentifier } from '../MetricType' /** * Configuration for the distribution chart. */ export interface DistributionChartConfig { - metric: MetricType + metric: MetricJsonIdentifier xScale: 'linear' | 'logarithmic' bucketCount: BucketOptions } diff --git a/report-viewer/src/stores/state.ts b/report-viewer/src/stores/state.ts index d12bdac29..81b7a1bf4 100644 --- a/report-viewer/src/stores/state.ts +++ b/report-viewer/src/stores/state.ts @@ -1,5 +1,5 @@ import type { SubmissionFile } from '@/model/File' -import type { MetricType } from '@/model/MetricType' +import type { MetricJsonIdentifier } from '@/model/MetricType' import type { DistributionChartConfig } from '@/model/ui/DistributionChartConfig' import type { FileSortingOptions } from '@/model/ui/FileSortingOptions' @@ -39,7 +39,7 @@ export interface State { export interface UIState { useDarkMode: boolean - comparisonTableSortingMetric: MetricType + comparisonTableSortingMetric: MetricJsonIdentifier comparisonTableClusterSorting: boolean distributionChartConfig: DistributionChartConfig fileSorting: FileSortingOptions diff --git a/report-viewer/src/stores/store.ts b/report-viewer/src/stores/store.ts index e722cbbd2..3d61200c9 100644 --- a/report-viewer/src/stores/store.ts +++ b/report-viewer/src/stores/store.ts @@ -1,6 +1,6 @@ import { defineStore } from 'pinia' import type { State, UIState } from './state' -import { MetricType } from '@/model/MetricType' +import { MetricJsonIdentifier } from '@/model/MetricType' import type { SubmissionFile, File } from '@/model/File' import { FileSortingOptions } from '@/model/ui/FileSortingOptions' @@ -23,10 +23,10 @@ const store = defineStore('store', { }, uiState: { useDarkMode: window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches, - comparisonTableSortingMetric: MetricType.AVERAGE, + comparisonTableSortingMetric: MetricJsonIdentifier.AVERAGE_SIMILARITY, comparisonTableClusterSorting: false, distributionChartConfig: { - metric: MetricType.AVERAGE, + metric: MetricJsonIdentifier.AVERAGE_SIMILARITY, xScale: 'linear', bucketCount: 10 }, diff --git a/report-viewer/src/views/ClusterView.vue b/report-viewer/src/views/ClusterView.vue index 06044eca3..1c079dff1 100644 --- a/report-viewer/src/views/ClusterView.vue +++ b/report-viewer/src/views/ClusterView.vue @@ -95,7 +95,7 @@ import Container from '@/components/ContainerComponent.vue' import TextInformation from '@/components/TextInformation.vue' import type { Cluster } from '@/model/Cluster' import type { ClusterListElement, ClusterListElementMember } from '@/model/ClusterListElement' -import { MetricType } from '@/model/MetricType' +import { MetricType, MetricTypes } from '@/model/MetricType' import type { Overview } from '@/model/Overview' import { computed, ref, onErrorCaptured, type PropType, type Ref } from 'vue' import { redirectOnError } from '@/router' @@ -135,7 +135,7 @@ const comparisonTableOptions = [ tooltip: 'Comparisons between the cluster members\nand other submissions.' } ] -const usedMetric = MetricType.AVERAGE +const usedMetric: MetricType = MetricTypes.AVERAGE_SIMILARITY const comparisons = computed(() => props.overview.topComparisons.filter( @@ -147,7 +147,7 @@ const comparisons = computed(() => let counter = 0 comparisons.value - .sort((a, b) => b.similarities[usedMetric] - a.similarities[usedMetric]) + .sort((a, b) => b.similarities[usedMetric.identifier] - a.similarities[usedMetric.identifier]) .forEach((c) => { c.sortingPlace = counter++ c.id = counter @@ -164,7 +164,7 @@ const relatedComparisons = computed(() => ) counter = 0 relatedComparisons.value - .sort((a, b) => b.similarities[usedMetric] - a.similarities[usedMetric]) + .sort((a, b) => b.similarities[usedMetric.identifier] - a.similarities[usedMetric.identifier]) .forEach((c) => { c.sortingPlace = counter++ c.id = counter @@ -177,7 +177,7 @@ for (const member of props.cluster.members) { .forEach((c) => { membersComparisons.push({ matchedWith: c.firstSubmissionId === member ? c.secondSubmissionId : c.firstSubmissionId, - similarity: c.similarities[usedMetric] + similarity: c.similarities[usedMetric.identifier] }) }) clusterMemberList.set(member, membersComparisons) diff --git a/report-viewer/src/views/ComparisonView.vue b/report-viewer/src/views/ComparisonView.vue index e0a0860db..756311bc8 100644 --- a/report-viewer/src/views/ComparisonView.vue +++ b/report-viewer/src/views/ComparisonView.vue @@ -24,9 +24,11 @@
- {{ (comparison.similarities[MetricType.AVERAGE] * 100).toFixed(2) }}% + {{ + MetricTypes.AVERAGE_SIMILARITY.format( + comparison.similarities[MetricTypes.AVERAGE_SIMILARITY.identifier] + ) + }} {{ - metricToolTips[options.similarityMetric].longName + options.similarityMetric.longName }} {{ options.similarityThreshold @@ -41,7 +41,7 @@

Clustering:

{{ - metricToolTips[options.clusterOptions.similarityMetric].longName + options.clusterOptions.similarityMetric.longName }} {{ options.clusterOptions.algorithm @@ -135,7 +135,6 @@ import { Overview } from '@/model/Overview' import { onErrorCaptured, type PropType } from 'vue' import { redirectOnError } from '@/router' import type { CliOptions } from '@/model/CliOptions' -import { metricToolTips } from '@/model/MetricType' defineProps({ overview: {