Skip to content

Commit

Permalink
Merge pull request #1145 from jplag/report-viewer/redesign
Browse files Browse the repository at this point in the history
Report Viewer Redesign
  • Loading branch information
sebinside authored Jul 10, 2023
2 parents 183d16c + 5a84e6e commit 9f48d6f
Show file tree
Hide file tree
Showing 59 changed files with 2,256 additions and 2,261 deletions.
1,035 changes: 682 additions & 353 deletions report-viewer/package-lock.json

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions report-viewer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
"prepare": "cd .. && husky install report-viewer/.husky"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/vue-fontawesome": "^3.0.3",
"chart.js": "^3.9.1",
"chartjs-plugin-datalabels": "^2.2.0",
"gitart-vue-dialog": "^3.1.0",
"highlight.js": "^11.8.0",
"jszip": "^3.10.0",
"pinia": "^2.1.4",
Expand All @@ -40,15 +43,17 @@
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/test-utils": "^2.4.0",
"@vue/tsconfig": "^0.4.0",
"autoprefixer": "^10.4.14",
"eslint": "^8.44.0",
"eslint-plugin-vue": "^9.15.1",
"husky": "^8.0.0",
"jsdom": "^22.1.0",
"lint-staged": "^13.2.3",
"npm-run-all": "^4.1.5",
"typescript": "^5.1.6",
"postcss": "^8.4.24",
"prettier": "^2.8.8",

"tailwindcss": "^3.3.2",
"typescript": "^5.1.6",
"vite": "^4.3.9",
"vitest": "^0.32.4",
"vue-tsc": "^1.8.4"
Expand Down
7 changes: 7 additions & 0 deletions report-viewer/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-env node */
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
72 changes: 26 additions & 46 deletions report-viewer/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,50 +1,30 @@
<script setup lang="ts">
import { RouterView } from 'vue-router'
</script>

<template>
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport" />
<RouterView />
<div :class="{ dark: store().uiState.useDarkMode }">
<div
class="min-h-screen max-h-fit max-w-screen text-black dark:text-amber-50 bg-backgorund-light dark:bg-backgorund-dark"
>
<RouterView class="max-h-screen overflow-hidden" />
<Button
class="absolute right-2 bottom-2 w-12 text-center h-12 flex justify-center items-center"
@click="store().changeUseDarkMode()"
>
<FontAwesomeIcon
class="text-2xl"
:icon="store().uiState.useDarkMode ? ['fas', 'sun'] : ['fas', 'moon']"
/>
</Button>
</div>
</div>
</template>

<style>
@font-face {
font-family: 'JetBrains Mono NL';
src: url('./fonts/jetbrains-mono/JetBrainsMonoNL-Light.ttf');
}
@font-face {
font-family: 'JetBrains Mono NL';
src: url('./fonts/jetbrains-mono/JetBrainsMonoNL-Bold.ttf');
font-weight: bold;
}
:root {
--primary-color: #e2eafc;
--primary-color-light: #edf2fb;
--primary-color-dark: #d7e3fc;
--secondary-color: #b6ccfe;
--secondary-color-light: #c1d3fe;
--secondary-color-dark: #abc4ff;
--background-color: #ffffff;
--on-primary-color: #303030;
--on-secondary-color: #000000;
--on-background-color: #303030;
--shadow-color: #777777;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
<script setup lang="ts">
import { RouterView } from 'vue-router'
import Button from './components/ButtonComponent.vue'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faMoon, faSun } from '@fortawesome/free-solid-svg-icons'
import store from './stores/store'
html,
body,
#app {
height: 100%;
width: 100%;
margin: 0;
}
</style>
library.add(faMoon)
library.add(faSun)
</script>
1 change: 0 additions & 1 deletion report-viewer/src/assets/double_arrow_black_18dp.svg

This file was deleted.

13 changes: 0 additions & 13 deletions report-viewer/src/assets/double_arrow_black_24dp.svg

This file was deleted.

1 change: 0 additions & 1 deletion report-viewer/src/assets/help_outline_black_18dp.svg

This file was deleted.

1 change: 0 additions & 1 deletion report-viewer/src/assets/help_outline_black_24dp.svg

This file was deleted.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

This file was deleted.

This file was deleted.

12 changes: 0 additions & 12 deletions report-viewer/src/assets/keyboard_double_arrow_left_black_18dp.svg

This file was deleted.

This file was deleted.

This file was deleted.

Binary file removed report-viewer/src/assets/logo-nobg.png
Binary file not shown.
21 changes: 0 additions & 21 deletions report-viewer/src/assets/radar-chart-configuration.ts

This file was deleted.

17 changes: 17 additions & 0 deletions report-viewer/src/components/ButtonComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!--
Base Component for Buttons
-->
<template>
<Interactable
class="px-2 py-1 flex items-center text-center justify-center"
@click="(e) => $emit('click', e)"
>
<slot></slot>
</Interactable>
</template>

<script setup lang="ts">
import Interactable from './InteractableComponent.vue'

defineEmits(['click'])
</script>
124 changes: 59 additions & 65 deletions report-viewer/src/components/ClusterRadarChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
participants in the cluster.
-->
<template>
<div class="wrapper">
<div v-if="!hasNoMember" class="wrapper">
<select v-model="selectedMember">
<option v-for="(member, index) in cluster.members.keys()" :key="index">
{{ member }}
</option>
</select>
<RadarChart :chartData="chartData" :options="options" class="chart"></RadarChart>
<div class="flex flex-col">
<div v-if="!hasNoMember" class="flex-grow flex flex-col">
<DropDownSelector
:options="selectedOptions"
@selectionChanged="(value) => updateChartData(value)"
/>
<RadarChart :chartData="chartData" :options="options" class="flex-grow"></RadarChart>
</div>
<div v-if="hasNoMember" class="no-member">
<div v-else>
<span>This cluster has no members.</span>
</div>
</div>
Expand All @@ -23,11 +22,12 @@ import type { PropType, Ref } from 'vue'
import type { ChartData } from 'chart.js'
import type { ClusterListElement } from '@/model/ClusterListElement'

import { ref, watch } from 'vue'
import { computed, ref } from 'vue'
import { RadarChart } from 'vue-chart-3'
import { Chart, registerables } from 'chart.js'
import ChartDataLabels from 'chartjs-plugin-datalabels'
import { radarChartStyle, radarChartOptions } from '@/assets/radar-chart-configuration'
import DropDownSelector from './DropDownSelector.vue'
import { graphColors } from '@/utils/ColorUtils'

Chart.register(...registerables)
Chart.register(ChartDataLabels)
Expand All @@ -39,16 +39,11 @@ const props = defineProps({
}
})

let hasNoMember = false
let hasNoMember = props.cluster.members.size == 0

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

const idOfFirstSubmission = selectedOptions.length > 0 ? selectedOptions[0] : ''

/**
* @param member The member to create the labels for.
Expand All @@ -66,64 +61,63 @@ function createLabelsFor(member: string) {
*/
function createDataSetFor(member: string) {
let data = new Array<number>()
props.cluster.members
.get(member)
?.forEach((m) => data.push(roundToTwoDecimals(m.percentage * 100)))
props.cluster.members.get(member)?.forEach((m) => data.push(+(m.similarity * 100).toFixed(2)))
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
const radarChartStyle = {
fill: true,
backgroundColor: graphColors.contentFill,
borderColor: graphColors.contentBorder,
pointBackgroundColor: graphColors.pointFill,
pointBorderColor: graphColors.contentBorder,
borderWidth: 1
}

const selectedMember = ref(getIdOfFirstSubmission())
const radarChartOptions = computed(() => {
return {
legend: {
display: false
},
scales: {
r: {
suggestedMin: 50,
suggestedMax: 100,
ticks: {
color: graphColors.ticksAndFont.value,
backdropColor: 'rgba(0,0,0,0)'
},
grid: {
color: graphColors.gridLines.value
},
angleLines: {
color: graphColors.gridLines.value
}
}
},
plugins: {
datalabels: {
color: graphColors.ticksAndFont.value
}
}
}
})

const chartData: Ref<ChartData<'radar', (number | null)[], unknown>> = ref({
labels: createLabelsFor(getIdOfFirstSubmission()),
labels: createLabelsFor(idOfFirstSubmission),
datasets: [
{
...radarChartStyle,
label: getIdOfFirstSubmission(),
data: createDataSetFor(getIdOfFirstSubmission())
label: idOfFirstSubmission,
data: createDataSetFor(idOfFirstSubmission)
}
]
})

const options = ref(radarChartOptions)

watch(
() => selectedMember.value,
(val) => {
chartData.value = {
labels: createLabelsFor(val),
datasets: [
{
...radarChartStyle,
label: val,
data: createDataSetFor(val)
}
]
}
}
)
</script>

<style scoped>
.wrapper {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.no-member {
display: flex;
flex-direction: row;
justify-content: center;
function updateChartData(value: string) {
chartData.value.datasets[0].data = createDataSetFor(value)
chartData.value.datasets[0].label = value
chartData.value.labels = createLabelsFor(value)
}
.chart {
height: 50vw;
}
</style>
</script>
Loading

0 comments on commit 9f48d6f

Please sign in to comment.