Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slight changes to the report json format #1189

Merged
merged 21 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/main/java/de/jplag/JPlagResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class JPlagResult {
private final int[] similarityDistribution; // 10-element array representing the similarity distribution of the detected matches.

private List<ClusteringResult<Submission>> clusteringResult;
private final int SIMILARITY_DISTRIBUTION_SIZE = 10;
private final int SIMILARITY_DISTRIBUTION_SIZE = 100;

public JPlagResult(List<JPlagComparison> comparisons, SubmissionSet submissions, long durationInMillis, JPlagOptions options) {
// sort by similarity (descending)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@
import de.jplag.reporting.reportobject.model.TopComparison;

public class MetricMapperTest {
private static final List<Integer> EXPECTED_AVG_DISTRIBUTION = List.of(29, 23, 19, 17, 13, 11, 7, 5, 3, 2);
private static final List<Integer> EXPECTED_MAX_DISTRIBUTION = List.of(50, 48, 20, 13, 10, 1, 3, 1, 0, 0);
private static final List<Integer> EXPECTED_AVG_DISTRIBUTION = List.of(1, 0, 0, 2, 3, 15, 5, 2, 16, 5, 2, 18, 3, 21, 2, 1, 5, 0, 14, 32, 25, 4, 2,
12, 3, 2, 5, 5, 0, 5, 1, 5, 2, 5, 4, 5, 3, 5, 18, 21, 30, 4, 3, 10, 2, 3, 17, 28, 4, 10, 2, 4, 3, 0, 2, 20, 4, 0, 19, 5, 25, 9, 4, 18, 1,
1, 1, 0, 31, 15, 35, 38, 40, 43, 45, 49, 50, 50, 50, 53, 60, 71, 73, 74, 80, 83, 87, 93, 95, 99, 102, 105, 106, 110, 113, 113, 117, 117,
122, 124);
private static final List<Integer> EXPECTED_MAX_DISTRIBUTION = List.of(130, 129, 124, 116, 114, 110, 110, 108, 103, 101, 99, 97, 96, 92, 82, 81,
70, 67, 64, 63, 59, 56, 52, 50, 50, 50, 49, 47, 43, 5, 6, 11, 4, 2, 3, 20, 37, 5, 0, 2, 33, 30, 19, 4, 5, 24, 40, 6, 3, 9, 2, 3, 18, 3, 5,
1, 4, 1, 0, 0, 5, 5, 14, 5, 42, 4, 18, 0, 0, 10, 4, 3, 17, 33, 4, 4, 3, 4, 39, 0, 20, 2, 4, 9, 0, 5, 0, 8, 23, 4, 2, 39, 3, 4, 1, 0, 3,
33, 2, 1);
Kr0nox marked this conversation as resolved.
Show resolved Hide resolved
private final MetricMapper metricMapper = new MetricMapper(Submission::getName);

@Test
Expand Down
8 changes: 4 additions & 4 deletions report-viewer/src/components/DistributionDiagram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const props = defineProps({
}
})

const maxVal = ref(Math.max(...props.distribution.distribution))
const maxVal = ref(Math.max(...props.distribution.getTenthPercentileFormattedValues()))
const labels = [
'91-100%',
'81-90%',
Expand Down Expand Up @@ -51,7 +51,7 @@ const chartData = ref({
datasets: [
{
...dataSetStyle.value,
data: props.distribution.distribution
data: props.distribution.getTenthPercentileFormattedValues()
Kr0nox marked this conversation as resolved.
Show resolved Hide resolved
}
]
})
Expand Down Expand Up @@ -109,12 +109,12 @@ watch(
datasets: [
{
...dataSetStyle.value,
data: val.distribution
data: val.getTenthPercentileFormattedValues()
}
]
}

maxVal.value = Math.max(...val.distribution)
maxVal.value = Math.max(...val.getTenthPercentileFormattedValues())
options.value.scales.x.suggestedMax = maxVal.value + 5
}
)
Expand Down
11 changes: 6 additions & 5 deletions report-viewer/src/model/Distribution.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export default class Distribution {
private readonly _distribution: Array<number>
export default abstract class Distribution {
protected readonly _distribution: Array<number>

constructor(distribution: Array<number>) {
this._distribution = distribution
}

get distribution(): Array<number> {
return this._distribution
}
/**
* Returns the distribution summed at every tenth percentile
*/
public abstract getTenthPercentileFormattedValues(): Array<number>
}
18 changes: 18 additions & 0 deletions report-viewer/src/model/PercentileDistribution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Distribution from './Distribution'

export default class HundredValueDistribution extends Distribution {
constructor(distribution: number[]) {
super(distribution)
}

/**
* Returns the distribution summed at every tenth percentile
*/
public getTenthPercentileFormattedValues(): number[] {
const tenValueArray = new Array<number>(10).fill(0)
for (let i = 0; i < 100; i++) {
tenValueArray[Math.floor(i / 10)] += this._distribution[i]
}
return tenValueArray
}
}
11 changes: 11 additions & 0 deletions report-viewer/src/model/TenthPercentileDistribution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Distribution from './Distribution'

export default class TenValueDistribution extends Distribution {
constructor(distribution: number[]) {
super(distribution)
}

public getTenthPercentileFormattedValues(): number[] {
return this._distribution
}
}
71 changes: 68 additions & 3 deletions report-viewer/src/model/factories/OverviewFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import versionJson from '@/version.json'
import Distribution from '../Distribution'
import MetricType from '../MetricType'
import { BaseFactory } from './BaseFactory'
import PercentileDistribution from '../PercentileDistribution'
import TenValueDistribution from '../TenthPercentileDistribution'

export class OverviewFactory extends BaseFactory {
Kr0nox marked this conversation as resolved.
Show resolved Hide resolved
static reportViewerVersion: Version =
Expand Down Expand Up @@ -68,18 +70,47 @@ export class OverviewFactory extends BaseFactory {
private static extractDistributions(
json: Record<string, unknown>
): Record<MetricType, Distribution> {
const distributionsMap = json.distributions as Record<string, Array<number>>
if (json.distributions) {
return this.extractDistributionsFromMap(json.distributions as Record<string, Array<number>>)
} else if (json.metrics) {
return this.extractDistributionsFromMetrics(json.metrics as Array<Record<string, unknown>>)
}
throw new Error('No distributions found')
}

private static extractDistributionsFromMap(
distributionsMap: Record<string, Array<number>>
): Record<MetricType, Distribution> {
const distributions = {} as Record<MetricType, Distribution>
for (const [key, value] of Object.entries(distributionsMap)) {
distributions[key as MetricType] = new Distribution(value as Array<number>)
distributions[key as MetricType] = new PercentileDistribution(value as Array<number>)
}
return distributions
}

private static extractDistributionsFromMetrics(
metrics: Array<Record<string, unknown>>
): Record<MetricType, Distribution> {
return {
[MetricType.AVERAGE]: new TenValueDistribution(metrics[0].distribution as Array<number>),
[MetricType.MAXIMUM]: new TenValueDistribution(metrics[1].distribution as Array<number>)
}
}

private static extractTopComparisons(
json: Record<string, unknown>
): Array<ComparisonListElement> {
const jsonComparisons = json.top_comparisons as Array<Record<string, unknown>>
if (json.top_comparisons) {
return this.extractTopComparisonsFromMap(
json.top_comparisons as Array<Record<string, unknown>>
)
} else if (json.metrics) {
return this.extractTopComparisonsFromMetrics(json.metrics as Array<Record<string, unknown>>)
}
throw new Error('No top comparisons found')
}

private static extractTopComparisonsFromMap(jsonComparisons: Array<Record<string, unknown>>) {
const comparisons = [] as Array<ComparisonListElement>
let counter = 0
for (const topComparison of jsonComparisons) {
Expand All @@ -93,6 +124,40 @@ export class OverviewFactory extends BaseFactory {
}
return comparisons
}

private static extractTopComparisonsFromMetrics(metrics: Array<Record<string, unknown>>) {
const averageSimilarities: Map<string, number> = new Map<string, number>()
const comparisons = [] as Array<ComparisonListElement>

// Average
Kr0nox marked this conversation as resolved.
Show resolved Hide resolved
for (const comparison of metrics[0].topComparisons as Array<Record<string, unknown>>) {
averageSimilarities.set(
(comparison.first_submission as string) + '-' + (comparison.second_submission as string),
comparison.similarity as number
)
}

// Max
Kr0nox marked this conversation as resolved.
Show resolved Hide resolved
let counter = 0
for (const comparison of metrics[1].topComparisons as Array<Record<string, unknown>>) {
const avg = averageSimilarities.get(
(comparison.first_submission as string) + '-' + (comparison.second_submission as string)
)
comparisons.push({
sortingPlace: counter++,
id: counter,
firstSubmissionId: comparison.first_submission as string,
secondSubmissionId: comparison.second_submission as string,
similarities: {
[MetricType.AVERAGE]: avg as number,
[MetricType.MAXIMUM]: comparison.similarity as number
}
})
}

return comparisons
}

private static extractClusters(json: Record<string, unknown>): Array<Cluster> {
if (!json.clusters) {
return []
Expand Down
Loading