felicity-lims/frontend/vite/src/views/dashboard/Peformance.vue

228 lines
7.7 KiB
Vue
Raw Normal View History

2022-04-09 22:57:06 +08:00
<script lang="ts" setup>
import LoadingMessage from "../../components/Spinners/LoadingMessage.vue"
2022-04-09 22:57:06 +08:00
import { storeToRefs } from 'pinia'
import { onMounted, watch, ref } from 'vue'
import { Chart } from '@antv/g2';
import { Bar } from '@antv/g2plot';
2022-04-09 22:57:06 +08:00
import { useDashBoardStore } from '../../stores';
import { IProcess } from '../../stores/dashboard';
const dashBoardStore = useDashBoardStore()
const { dashboard } = storeToRefs(dashBoardStore)
2022-04-09 22:57:06 +08:00
onMounted(() => {
dashBoardStore.getSampleProcessPeformance()
dashBoardStore.getAnalysisProcessPeformance()
})
watch(() => dashboard.value.filterRange.from, (filter, prev) => {
resetSampleGraphs()
2022-04-09 22:57:06 +08:00
dashBoardStore.getSampleProcessPeformance()
})
const prRTP = ref({} as IProcess)
const prRTS = ref({} as IProcess)
const prSTV = ref({} as IProcess)
const prVTP = ref({} as IProcess)
watch(() => dashboard.value.peformanceStats.sample, (processes, prev) => {
2022-04-09 22:57:06 +08:00
processes?.forEach(process => {
const donutData = [
{ item: 'On-Time', count: process?.counts?.totalNotLate, percent: (process?.counts?.totalNotLate/process?.counts?.totalSamples) * 100 },
{ item: 'Delayed', count: process?.counts?.totalLate, percent: (process?.counts?.totalLate/process?.counts?.totalSamples) * 100 },
]
switch (process?.process) {
case "received_to_published":
prRTP.value = process;
plotLateDonut(donutData, 'process-rtp')
break;
case "received_to_submitted":
prRTS.value = process;
plotLateDonut(donutData, 'process-rts')
break;
case "submitted_to_verified":
prSTV.value = process;
plotLateDonut(donutData, 'process-stv')
break;
case "verified_to_published":
prVTP.value = process;
plotLateDonut(donutData, 'process-vtp')
break;
default:
break;
}
})
})
const analProcess = ref({} as IProcess)
watch(() => dashboard.value.currentPeformance, (process, prev) => {
resetAPGraphs()
2022-04-09 22:57:06 +08:00
dashBoardStore.getAnalysisProcessPeformance()
})
watch(() => dashboard.value.peformanceStats.analysis, (process, prev) => {
2022-04-09 22:57:06 +08:00
analProcess.value = process[0]
const services: any[] = [];
2022-04-09 22:57:06 +08:00
process[0]?.groups?.forEach(group => {
services.push({ analysis: group?.service, value: group?.processAverage, total: group?.totalSamples})
2022-04-09 22:57:06 +08:00
})
plotAnalyses(services, 'process-service')
})
const plotAnalyses = (data:any, elem: string) => {
const barPlot = new Bar(elem, {
data,
xField: 'value',
yField: 'analysis',
seriesField: '',
meta: {
analysis: {
alias: 'Analysis',
},
value: {
alias: 'process average in days',
},
},
label: {
position: 'middle', // 'left', 'middle', 'right'
},
minBarWidth: 5,
maxBarWidth: 20,
2022-04-09 22:57:06 +08:00
});
barPlot.render();
2022-04-09 22:57:06 +08:00
}
const plotLateDonut = (data: any, elem: string) => {
const chart = new Chart({
container: elem,
autoFit: true,
height: 150,
width: 300,
});
chart.data(data);
chart.scale('percent', {
formatter: (val) => {
val = val * 100 + '%';
return val;
},
});
chart.coordinate('theta', {
radius: 0.75,
innerRadius: 0.6,
});
chart.tooltip({
showTitle: false,
showMarkers: false,
itemTpl: '<li class="g2-tooltip-list-item"><span style="background-color:{color};" class="g2-tooltip-marker"></span>{name}: {value}</li>',
});
chart
.annotation()
chart
.interval()
.adjust('stack')
.position('percent')
.color('item')
.label('percent', (percent) => {
return {
content: (data) => {
return `${percent * 100}%`;
},
};
})
.tooltip('item*percent', (item, percent) => {
percent = percent * 100 + '%';
return {
name: item,
value: percent,
};
});
chart.interaction('element-active');
chart.render()
}
const resetAPGraphs = () => {
document.getElementById('ap-graphs')!.innerHTML = ""
document.getElementById('ap-graphs')!.innerHTML = `<div id="process-service" class="mt-3"></div>`
}
const resetSampleGraphs = () => {
document.getElementById('rtp-graph')!.innerHTML = ""
document.getElementById('rtp-graph')!.innerHTML = `<div id="process-rtp" class="mt-3"></div>`
document.getElementById('rts-graph')!.innerHTML = ""
document.getElementById('rts-graph')!.innerHTML = `<div id="process-rts" class="mt-3"></div>`
document.getElementById('stv-graph')!.innerHTML = ""
document.getElementById('stv-graph')!.innerHTML = `<div id="process-stv" class="mt-3"></div>`
document.getElementById('vtp-graph')!.innerHTML = ""
document.getElementById('vtp-graph')!.innerHTML = `<div id="process-vtp" class="mt-3"></div>`
}
2022-04-09 22:57:06 +08:00
</script>
2021-12-05 04:39:12 +08:00
<template>
2022-04-09 22:57:06 +08:00
<h1 class="text-xl text-gray-700 font-semibold">Process peformance for samples in average days</h1>
2021-12-05 04:39:12 +08:00
<hr class="my-2">
<div v-if="dashboard.fetchingSampePeformanceStats" class="text-start my-4 w-100">
<LoadingMessage message="fetching updated sample peformance stats ..." />
</div>
2021-12-05 04:39:12 +08:00
<div class="flex flex-wrap justify-start">
<div class="mr-4 items-center content-center">
2022-04-15 16:32:24 +08:00
<div class="bg-white shadow rounded-sm px-6 pt-3 pb-5 border border-white mr-8 text-center">
2021-12-05 04:39:12 +08:00
<div class="font-semibold text-gray-400 text-l">received to published</div>
2022-04-09 22:57:06 +08:00
<div class="mr-4 font-bold text-gray-600 text-xl">{{ prRTP?.counts?.processAverage ?? 0 }} days</div>
2021-12-05 04:39:12 +08:00
</div>
<div id="rtp-graph">
<div id="process-rtp" class="mt-3"></div>
</div>
2021-12-05 04:39:12 +08:00
</div>
<div class="mr-4 items-center content-center">
2022-04-15 16:32:24 +08:00
<div class="bg-white shadow rounded-sm px-6 pt-3 pb-5 border border-white mr-8 text-center">
2022-04-09 22:57:06 +08:00
<div class="font-semibold text-gray-400 text-l">received to submitted</div>
<div class="mr-4 font-bold text-gray-600 text-xl">{{ prRTS?.counts?.processAverage ?? 0 }} days</div>
2021-12-05 04:39:12 +08:00
</div>
<div id="rts-graph">
<div id="process-rts" class="mt-3"></div>
</div>
2021-12-05 04:39:12 +08:00
</div>
<div class="mr-4 items-center content-center">
2022-04-15 16:32:24 +08:00
<div class="bg-white shadow rounded-sm px-6 pt-3 pb-5 border border-white mr-8 text-center">
2022-04-09 22:57:06 +08:00
<div class="font-semibold text-gray-400 text-l">submitted to verified</div>
<div class="mr-4 font-bold text-gray-600 text-xl">{{ prSTV?.counts?.processAverage ?? 0 }} days</div>
2021-12-05 04:39:12 +08:00
</div>
<div id="stv-graph">
<div id="process-stv" class="mt-3"></div>
</div>
2021-12-05 04:39:12 +08:00
</div>
<div class="mr-4 items-center content-center">
2022-04-15 16:32:24 +08:00
<div class="bg-white shadow rounded-sm px-6 pt-3 pb-5 border border-white mr-8 text-center">
2021-12-05 04:39:12 +08:00
<div class="font-semibold text-gray-400 text-l">verified to published</div>
2022-04-09 22:57:06 +08:00
<div class="mr-4 font-bold text-gray-600 text-xl">{{ prVTP?.counts?.processAverage ?? 0 }} days</div>
2021-12-05 04:39:12 +08:00
</div>
<div id="vtp-graph">
<div id="process-vtp" class="mt-3"></div>
</div>
2021-12-05 04:39:12 +08:00
</div>
</div>
2022-04-09 22:57:06 +08:00
<h1 class="mt-4 text-xl text-gray-700 font-semibold">
<span>Process peformance by anayses service</span>
<select name="" id="" class="ml-8 p-1" @change="dashBoardStore.setCurrentPeformance($event)">
<option
v-for="performance in dashboard.performances" :key="performance"
2022-04-09 22:57:06 +08:00
:value="performance"
:selected="performance === dashboard.currentPeformance"
2022-04-09 22:57:06 +08:00
>{{ performance }}</option>
</select>
</h1>
2021-12-05 04:39:12 +08:00
<hr class="my-2">
<div v-if="dashboard.fetchingAnalysisPeformanceStats" class="text-start my-4 w-100">
<LoadingMessage message="fetching analysis peformance stats ..." />
</div>
<div id="ap-graphs">
<div id="process-service" class="mt-3"></div>
</div>
2021-12-05 04:39:12 +08:00
</template>