|
|
|
|
@@ -1,39 +1,45 @@
|
|
|
|
|
<template>
|
|
|
|
|
<section class="p-4 mr-0.5 space-y-2 h-full w-[calc(100vw_-_316px)] overflow-y-auto scrollbar float-right">
|
|
|
|
|
<!-- cover plate -->
|
|
|
|
|
<div v-show="isCoverPlate" class="w-[calc(100vw_-_300px)] h-screen-main fixed bottom-0 right-0 bg-gradient-to-tr from-neutral-500/50 to-neutral-900/50 z-[1]">
|
|
|
|
|
</div>
|
|
|
|
|
<!-- title -->
|
|
|
|
|
<p class="h2 text-base">Conformance Checking Results<span class="material-symbols-outlined text-base align-middle ml-2" v-tooltip.bottom="tooltip.results" type="text">info</span></p>
|
|
|
|
|
<!-- total group -->
|
|
|
|
|
<ul class=" text-neutral-10 text-sm flex gap-2 py-2">
|
|
|
|
|
<li class=" bg-cfm-primary rounded-full px-4 py-1 space-x-2">
|
|
|
|
|
<span class="material-symbols-outlined text-base align-middle mr-2">check_circle</span>Conforming<span>3,890</span>
|
|
|
|
|
<span class="material-symbols-outlined text-base align-middle mr-2">check_circle</span>Conforming<span>{{ data.counts.conforming }}</span>
|
|
|
|
|
</li>
|
|
|
|
|
<li class=" bg-cfm-secondary rounded-full px-4 py-1 space-x-2">
|
|
|
|
|
<span class="material-symbols-outlined text-base align-middle mr-2">cancel</span>Not Conforming<span>27,230</span>
|
|
|
|
|
<span class="material-symbols-outlined text-base align-middle mr-2">cancel</span>Not Conforming<span>{{ data.counts.not_conforming }}</span>
|
|
|
|
|
</li>
|
|
|
|
|
<li class=" bg-neutral-700 rounded-full px-4 py-1 space-x-2">
|
|
|
|
|
<iconNA class="inline-block mr-1"></iconNA>Not Applicable<span>7,780</span>
|
|
|
|
|
<li class=" bg-neutral-700 rounded-full px-4 py-1 space-x-2" v-show="data.counts.not_applicable != 0">
|
|
|
|
|
<iconNA class="inline-block mr-1"></iconNA>Not Applicable<span>{{ data.counts.not_applicable }}</span>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<!-- chart -->
|
|
|
|
|
<div class="flex gap-4 w-full">
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
|
|
|
<div class="flex gap-4">
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-1/2">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Conformance Rate<span class="material-symbols-outlined text-sm align-middle ml-2" v-tooltip.bottom="tooltip.rate">info</span></span>
|
|
|
|
|
<span class="text-2xl">10%</span>
|
|
|
|
|
</p>
|
|
|
|
|
<span>Conformance Rate<span class="material-symbols-outlined text-sm align-middle ml-2" v-tooltip.bottom="tooltip.rate">info</span></span>
|
|
|
|
|
<span class="text-2xl">{{ data.charts.rate.rate }}%</span>
|
|
|
|
|
</p>
|
|
|
|
|
<Chart type="line" :data="rateChartData" :options="rateChartOptions" class=""/>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-1/2">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Cases<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl"><span class="text-cfm-primary">3.89K</span>/38.9K</span>
|
|
|
|
|
</p>
|
|
|
|
|
<span>Cases<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl"><span class="text-cfm-primary">{{ data.charts.cases.conforming }}</span> / {{ data.charts.cases.total }}</span>
|
|
|
|
|
</p>
|
|
|
|
|
<Chart type="bar" :data="casesChartData" :options="casesChartOptions" class=""/>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
|
|
|
<!-- Fitness 暫時不做 basis-1/3 → basis-1/2 -->
|
|
|
|
|
<!-- <div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Fitness<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl">13.5</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<span>Fitness<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl">{{ data.charts.fitness }}</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div> -->
|
|
|
|
|
</div>
|
|
|
|
|
<!-- effect -->
|
|
|
|
|
<section>
|
|
|
|
|
@@ -41,34 +47,56 @@
|
|
|
|
|
<div class="flex gap-4 w-full">
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/2">
|
|
|
|
|
<p class="h2 pl-2 mb-2">Throughput Time</p>
|
|
|
|
|
<p class="pl-2 space-x-2">
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">48</span>
|
|
|
|
|
<span>vs</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">56</span>
|
|
|
|
|
<span>days,</span>
|
|
|
|
|
<span class="text-2xl font-medium">-8</span>
|
|
|
|
|
<span>days of difference.</span>
|
|
|
|
|
</p>
|
|
|
|
|
<div v-if="data.effect.time !== null">
|
|
|
|
|
<p class="pl-2 space-x-2" v-if="data.effect.time.not_conforming === null">
|
|
|
|
|
<span>All cases are conforming to set rules. Average throughput time is</span>
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">{{ data.effect.time.conforming }}</span>
|
|
|
|
|
<span>days.</span>
|
|
|
|
|
</p>
|
|
|
|
|
<p class="pl-2 space-x-2" v-else-if="data.effect.time.conforming === null">
|
|
|
|
|
<span>None of the cases is conforming to set rules. Average throughput time is</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">{{ data.effect.time.not_conforming }}</span>
|
|
|
|
|
<span>days.</span>
|
|
|
|
|
</p>
|
|
|
|
|
<p class="pl-2 space-x-2 max-w-full" v-else>
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">{{ data.effect.time.conforming }}</span>
|
|
|
|
|
<span>vs</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">{{ data.effect.time.not_conforming }}</span>
|
|
|
|
|
<span>days,</span>
|
|
|
|
|
<span class="text-2xl font-medium">{{ data.effect.time.difference }}</span>
|
|
|
|
|
<span>days of difference.</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/2">
|
|
|
|
|
<p class="h2 pl-2 mb-2">Activities per Case</p>
|
|
|
|
|
<p class="pl-2 space-x-2">
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">7.0</span>
|
|
|
|
|
<span>vs</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">3.9</span>
|
|
|
|
|
<span>activities,</span>
|
|
|
|
|
<span class="text-2xl font-medium">3.1</span>
|
|
|
|
|
<span>activities of difference.</span>
|
|
|
|
|
</p>
|
|
|
|
|
<div v-if="data.effect.tasks !== null">
|
|
|
|
|
<p class="pl-2 space-x-2" v-if="data.effect.tasks.not_conforming === null">
|
|
|
|
|
<span>All cases are conforming to set rules. Average activities in per cases is</span>
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">{{ data.effect.tasks.conforming }}</span> .
|
|
|
|
|
</p>
|
|
|
|
|
<p class="pl-2 space-x-2" v-else-if="data.effect.tasks.conforming === null">
|
|
|
|
|
<span>None of the cases is conforming to set rules. Average activities in per cases is</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">{{ data.effect.tasks.not_conforming }}</span> .
|
|
|
|
|
</p>
|
|
|
|
|
<p class="pl-2 space-x-2 max-w-full" v-else>
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">{{ data.effect.tasks.conforming }}</span>
|
|
|
|
|
<span>vs</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">{{ data.effect.tasks.not_conforming }}</span>
|
|
|
|
|
<span>activities,</span>
|
|
|
|
|
<span class="text-2xl font-medium">{{ data.effect.tasks.difference }}</span>
|
|
|
|
|
<span>activities of difference.</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
<!-- Issues group -->
|
|
|
|
|
<section>
|
|
|
|
|
<p class="h2 text-base">Non-conformance Issues</p>
|
|
|
|
|
<div class="flex gap-4 w-full">
|
|
|
|
|
<div class="flex gap-4 w-full" v-if="data.issues !== null">
|
|
|
|
|
<!-- Issues chart -->
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-full">
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-full" v-if="null">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Time Trend<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl"><span class="text-cfm-secondary">3.89K</span>/38.9K</span>
|
|
|
|
|
@@ -79,106 +107,7 @@
|
|
|
|
|
<p class="h2 pl-2 mb-2">Issue List</p>
|
|
|
|
|
<table class="text-sm min-w-full table-fixed">
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr v-for="(trace, key) in traceList" :key="key">
|
|
|
|
|
<td class="p-2 pl-6 truncate max-w-0 w-1/3">
|
|
|
|
|
<span class="material-symbols-outlined disc text-sm align-middle mr-1">fiber_manual_record</span>{{ trace.issue }}
|
|
|
|
|
</td>
|
|
|
|
|
<td class="p-2 min-w-[96px] w-2/5">
|
|
|
|
|
<div class="h-4 w-full bg-neutral-300 rounded-sm overflow-hidden">
|
|
|
|
|
<div class="h-full bg-primary" :style="trace.value"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td class="p-2 text-right truncate">{{ trace.count }}</td>
|
|
|
|
|
<td class="p-2 text-center">{{ trace.ratio }}%</td>
|
|
|
|
|
<td class="p-2 text-center">
|
|
|
|
|
<div class="btn btn-sm btn-c-primary cursor-pointer" @click="issusModal = true">More</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
<!-- title -->
|
|
|
|
|
<p class="h2 text-base">Conformance Checking Results<span class="material-symbols-outlined text-base align-middle ml-2" v-tooltip.bottom="tooltip.results" type="text">info</span></p>
|
|
|
|
|
<!-- total group -->
|
|
|
|
|
<ul class=" text-neutral-10 text-sm flex gap-2 py-2">
|
|
|
|
|
<li class=" bg-cfm-primary rounded-full px-4 py-1 space-x-2">
|
|
|
|
|
<span class="material-symbols-outlined text-base align-middle mr-2">check_circle</span>Conformance<span>3,890</span>
|
|
|
|
|
</li>
|
|
|
|
|
<li class=" bg-cfm-secondary rounded-full px-4 py-1 space-x-2">
|
|
|
|
|
<span class="material-symbols-outlined text-base align-middle mr-2">cancel</span>Non-Conformance<span>27,230</span>
|
|
|
|
|
</li>
|
|
|
|
|
<li class=" bg-neutral-700 rounded-full px-4 py-1 space-x-2">
|
|
|
|
|
<iconNA class="inline-block mr-1"></iconNA>Not Applicable<span>7,780</span>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<!-- chart -->
|
|
|
|
|
<div class="flex gap-4 w-full">
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Conformance Rate<span class="material-symbols-outlined text-sm align-middle ml-2" v-tooltip.bottom="tooltip.rate">info</span></span>
|
|
|
|
|
<span class="text-2xl">10%</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Cases<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl"><span class="text-cfm-primary">3.89K</span>/38.9K</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/3">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Fitness<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl">13.5</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- effect -->
|
|
|
|
|
<section>
|
|
|
|
|
<p class="h2 text-base">Effect</p>
|
|
|
|
|
<div class="flex gap-4 w-full">
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/2">
|
|
|
|
|
<p class="h2 pl-2 mb-2">Throughput Time</p>
|
|
|
|
|
<p class="pl-2 space-x-2">
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">48</span>
|
|
|
|
|
<span>vs</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">56</span>
|
|
|
|
|
<span>days,</span>
|
|
|
|
|
<span class="text-2xl font-medium">-8</span>
|
|
|
|
|
<span>days of difference.</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 basis-1/2">
|
|
|
|
|
<p class="h2 pl-2 mb-2">Activities per Case</p>
|
|
|
|
|
<p class="pl-2 space-x-2">
|
|
|
|
|
<span class="text-cfm-primary text-2xl font-medium">7.0</span>
|
|
|
|
|
<span>vs</span>
|
|
|
|
|
<span class="text-cfm-secondary text-2xl font-medium">3.9</span>
|
|
|
|
|
<span>activities,</span>
|
|
|
|
|
<span class="text-2xl font-medium">3.1</span>
|
|
|
|
|
<span>activities of difference.</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
<!-- Issues group -->
|
|
|
|
|
<section>
|
|
|
|
|
<p class="h2 text-base">Non-conformance Issues</p>
|
|
|
|
|
<div class="flex gap-4 w-full">
|
|
|
|
|
<!-- Issues chart -->
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-full">
|
|
|
|
|
<p class="h2 pl-2 flex justify-between items-center">
|
|
|
|
|
<span>Time Trend<span class="material-symbols-outlined text-sm align-middle ml-2">info</span></span>
|
|
|
|
|
<span class="text-2xl"><span class="text-cfm-secondary">3.89K</span>/38.9K</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- Issues list -->
|
|
|
|
|
<div class="border rounded border-neutral-300 p-2 bg-neutral-10 w-full">
|
|
|
|
|
<p class="h2 pl-2 mb-2">Issue List</p>
|
|
|
|
|
<table class="text-sm min-w-full table-fixed">
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr v-for="(trace, key) in traceList" :key="key">
|
|
|
|
|
<tr v-for="(trace, key) in data.issues" :key="key">
|
|
|
|
|
<td class="p-2 pl-6 truncate max-w-0 w-1/3">
|
|
|
|
|
<span class="material-symbols-outlined disc text-sm align-middle mr-1">fiber_manual_record</span>{{ trace.issue }}
|
|
|
|
|
</td>
|
|
|
|
|
@@ -204,34 +133,52 @@
|
|
|
|
|
<script>
|
|
|
|
|
import iconNA from '@/components/icons/IconNA.vue';
|
|
|
|
|
import MoreModal from './MoreModal.vue';
|
|
|
|
|
import { storeToRefs } from 'pinia';
|
|
|
|
|
import ConformanceStore from '@/stores/conformance.js';
|
|
|
|
|
import getNumberLabel from '@/module/numberLabel.js';
|
|
|
|
|
import { setLineChartData, setBarChartData } from '@/module/setChartData.js';
|
|
|
|
|
import abbreviateNumber from '@/module/abbreviateNumber.js';
|
|
|
|
|
import getMoment from 'moment';
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
setup() {
|
|
|
|
|
const conformanceStore = ConformanceStore();
|
|
|
|
|
const { conformanceTempReportData } = storeToRefs(conformanceStore);
|
|
|
|
|
|
|
|
|
|
return { conformanceTempReportData, conformanceStore }
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
data: {
|
|
|
|
|
counts: {
|
|
|
|
|
conforming: '--',
|
|
|
|
|
not_conforming: '--',
|
|
|
|
|
not_applicable: 0,
|
|
|
|
|
},
|
|
|
|
|
charts: {
|
|
|
|
|
rate: {
|
|
|
|
|
rate: '--',
|
|
|
|
|
chart: {},
|
|
|
|
|
},
|
|
|
|
|
cases: {
|
|
|
|
|
conforming: '--',
|
|
|
|
|
total: '--',
|
|
|
|
|
chart: {},
|
|
|
|
|
},
|
|
|
|
|
fitness: '--',
|
|
|
|
|
},
|
|
|
|
|
effect: {
|
|
|
|
|
time: null,
|
|
|
|
|
tasks: null,
|
|
|
|
|
},
|
|
|
|
|
issues: null
|
|
|
|
|
},
|
|
|
|
|
isCoverPlate: false,
|
|
|
|
|
issusModal: false,
|
|
|
|
|
traceList: [
|
|
|
|
|
{
|
|
|
|
|
id: 1,
|
|
|
|
|
issue: 'Skip',
|
|
|
|
|
value: this.progressWidth(80),
|
|
|
|
|
count: '1,234,567,890',
|
|
|
|
|
ratio: 80,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
issue: 'Order Switch',
|
|
|
|
|
value: this.progressWidth(30),
|
|
|
|
|
count: '567,890',
|
|
|
|
|
ratio: 30,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
issue: 'Activity不包含到院、出院、出院、出院',
|
|
|
|
|
value: this.progressWidth(70),
|
|
|
|
|
count: '4,567,890',
|
|
|
|
|
ratio: 70,
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
rateChartData: null,
|
|
|
|
|
rateChartOptions: null,
|
|
|
|
|
casesChartData: null,
|
|
|
|
|
casesChartOptions: null,
|
|
|
|
|
tooltip: {
|
|
|
|
|
results: {
|
|
|
|
|
value: 'This page will perform a conformance check based on the filtering results of the map.',
|
|
|
|
|
@@ -246,6 +193,14 @@ export default {
|
|
|
|
|
iconNA,
|
|
|
|
|
MoreModal,
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
conformanceTempReportData: {
|
|
|
|
|
handler: function(newValue) {
|
|
|
|
|
// this.data = newValue;
|
|
|
|
|
this.data = this.setConformanceTempReportData(newValue);
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
/**
|
|
|
|
|
* set progress bar width
|
|
|
|
|
@@ -255,7 +210,235 @@ export default {
|
|
|
|
|
progressWidth(value){
|
|
|
|
|
return `width:${value}%;`
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Number to percentage
|
|
|
|
|
* @param {number} val
|
|
|
|
|
* @returns {string} 轉換完成的百分比字串
|
|
|
|
|
*/
|
|
|
|
|
getPercentLabel(val){
|
|
|
|
|
return (val * 100 === 100) ? (val * 100) : (val * 100).toFixed(1);
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* Convert seconds to days
|
|
|
|
|
* @param {number} sec
|
|
|
|
|
* @returns {number} day
|
|
|
|
|
*/
|
|
|
|
|
convertSecToDay(sec) {
|
|
|
|
|
return (sec / 86400)
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* set conformance report data
|
|
|
|
|
* @param {object} data new watch's value
|
|
|
|
|
*/
|
|
|
|
|
setConformanceTempReportData(data){
|
|
|
|
|
let sum = Object.values(data.counts).reduce((acc, cur) => acc + cur, 0);
|
|
|
|
|
let rate = ((data.counts.conforming / sum) * 100).toFixed(1);
|
|
|
|
|
let isNullTime = value => value === null ? null : getNumberLabel((value / 86400).toFixed(1));
|
|
|
|
|
let isNullCase = value => value === null ? null : getNumberLabel(value.toFixed(1));
|
|
|
|
|
|
|
|
|
|
let result = {
|
|
|
|
|
counts: {
|
|
|
|
|
conforming: getNumberLabel(data.counts.conforming),
|
|
|
|
|
not_conforming: getNumberLabel(data.counts.not_conforming),
|
|
|
|
|
not_applicable: getNumberLabel(data.counts.not_applicable),
|
|
|
|
|
},
|
|
|
|
|
charts: {
|
|
|
|
|
rate: {
|
|
|
|
|
rate: rate,
|
|
|
|
|
data: setLineChartData(data.charts.rate.data, data.charts.rate.x_axis.max, data.charts.rate.x_axis.min),
|
|
|
|
|
},
|
|
|
|
|
cases: {
|
|
|
|
|
conforming: getNumberLabel(data.counts.conforming),
|
|
|
|
|
total: getNumberLabel(sum),
|
|
|
|
|
data: {
|
|
|
|
|
conforming: setBarChartData(data.charts.cases.data.filter(item => item.label === 'conforming').map(item => item.data)[0]),
|
|
|
|
|
not_conforming: setBarChartData(data.charts.cases.data.filter(item => item.label === 'not-conforming').map(item => item.data)[0]),
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
fitness: getNumberLabel(data.charts.fitness),
|
|
|
|
|
},
|
|
|
|
|
effect: {
|
|
|
|
|
time: {
|
|
|
|
|
conforming: isNullTime(data.effect.time.conforming),
|
|
|
|
|
not_conforming: isNullTime(data.effect.time.not_conforming),
|
|
|
|
|
difference: isNullTime(data.effect.time.conforming - data.effect.time.not_conforming),
|
|
|
|
|
},
|
|
|
|
|
tasks: {
|
|
|
|
|
conforming: isNullCase(data.effect.tasks.conforming),
|
|
|
|
|
not_conforming: isNullCase(data.effect.tasks.not_conforming),
|
|
|
|
|
difference: isNullCase(data.effect.tasks.conforming - data.effect.tasks.not_conforming),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
issues: data.issues.map(item => {
|
|
|
|
|
return {
|
|
|
|
|
no: item.no,
|
|
|
|
|
issue: item.description,
|
|
|
|
|
value: `width:${this.getPercentLabel(item.count / sum)}%;`,
|
|
|
|
|
count: item.count,
|
|
|
|
|
ratio: this.getPercentLabel(item.count / sum),
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
};
|
|
|
|
|
this.setRateChartData(result.charts.rate.data); // 建立圖表 Rate Chart.js
|
|
|
|
|
this.setCasesChartData(result.charts.cases.data.conforming, result.charts.cases.data.not_conforming, data.charts.cases.x_axis.max, data.charts.cases.x_axis.min); // 建立圖表 Cases Chart.js
|
|
|
|
|
return result;
|
|
|
|
|
},
|
|
|
|
|
setRateChartData(data){
|
|
|
|
|
this.rateChartData = {
|
|
|
|
|
labels:[],
|
|
|
|
|
datasets: [
|
|
|
|
|
{
|
|
|
|
|
label: 'Rate',
|
|
|
|
|
data: data,
|
|
|
|
|
fill: false,
|
|
|
|
|
pointRadius: 0, // 隱藏點
|
|
|
|
|
pointHoverRadius: 0, // 隱藏點的 hover
|
|
|
|
|
tension: 0.4,
|
|
|
|
|
borderColor: '#0099FF',
|
|
|
|
|
x: 'x',
|
|
|
|
|
y: 'y',
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
this.rateChartOptions = {
|
|
|
|
|
responsive: true,
|
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
|
aspectRatio: 0.6,
|
|
|
|
|
plugins: {
|
|
|
|
|
legend: false, // 圖例
|
|
|
|
|
tooltip: {
|
|
|
|
|
enabled: false // 隱藏 工具提示框
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
scales: {
|
|
|
|
|
x: {
|
|
|
|
|
type: 'time',
|
|
|
|
|
// time: {
|
|
|
|
|
// max: '2022-01-12T02:29:42',
|
|
|
|
|
// min: '2022-01-03T00:56:25',
|
|
|
|
|
// displayFormats: {
|
|
|
|
|
// day: 'yyyy/M/d'
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
ticks: {
|
|
|
|
|
maxRotation: 0, // 不旋轉 lable 0~50
|
|
|
|
|
color: '#334155',
|
|
|
|
|
source: 'data',
|
|
|
|
|
align: 'inner', // label 在軸線的位置
|
|
|
|
|
callback: function(value, index, values) {
|
|
|
|
|
return (index === 0 || index === values.length - 1) ? getMoment(value).format('YYYY/M/D') : null;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
display: false, // 隱藏 x 軸網格
|
|
|
|
|
},
|
|
|
|
|
border: {
|
|
|
|
|
color: '#334155',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
y: {
|
|
|
|
|
beginAtZero: true, // scale 包含 0
|
|
|
|
|
suggestedMin: 0,
|
|
|
|
|
suggestedMax: 1,
|
|
|
|
|
ticks:{ // 設定間隔數值
|
|
|
|
|
includeBounds: true,
|
|
|
|
|
color: '#334155',
|
|
|
|
|
align: 'inner',
|
|
|
|
|
callback: function(value, index, values) {
|
|
|
|
|
if (value === 0) return `${value * 100}%`;
|
|
|
|
|
else if (value === 1) return `${value * 100}%`;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
display: false, // 隱藏 y 軸網格
|
|
|
|
|
},
|
|
|
|
|
border: {
|
|
|
|
|
color: '#334155',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
setCasesChartData(conformingData, notConformingData, xMax, xMin){
|
|
|
|
|
this.casesChartData = {
|
|
|
|
|
datasets: [
|
|
|
|
|
{
|
|
|
|
|
type: 'bar',
|
|
|
|
|
label: 'Conforming',
|
|
|
|
|
data: conformingData,
|
|
|
|
|
backgroundColor: '#0099FF',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 'bar',
|
|
|
|
|
label: 'Not Conforming',
|
|
|
|
|
data: notConformingData,
|
|
|
|
|
backgroundColor: '#FFAA44',
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
this.casesChartOptions = {
|
|
|
|
|
responsive: true,
|
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
|
aspectRatio: 0.8,
|
|
|
|
|
plugins: {
|
|
|
|
|
tooltips: {
|
|
|
|
|
mode: 'index',
|
|
|
|
|
intersect: false
|
|
|
|
|
},
|
|
|
|
|
legend: false, // 圖例
|
|
|
|
|
},
|
|
|
|
|
scales: {
|
|
|
|
|
x: {
|
|
|
|
|
stacked: true,
|
|
|
|
|
ticks: {
|
|
|
|
|
autoSkip: false,
|
|
|
|
|
maxRotation: 0, // 不旋轉 lable 0~50
|
|
|
|
|
color: '#334155',
|
|
|
|
|
align: 'center', // label 在軸線的位置
|
|
|
|
|
callback: function(value, index, values) {
|
|
|
|
|
if(index === 0) return getMoment(xMin).format('yyyy/M/D');
|
|
|
|
|
else if(index === values.length - 1) return getMoment(xMax).format('yyyy/M/D');
|
|
|
|
|
else return null;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
display: false, // 隱藏 x 軸網格
|
|
|
|
|
},
|
|
|
|
|
border: {
|
|
|
|
|
color: '#334155',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
y: {
|
|
|
|
|
stacked: true,
|
|
|
|
|
beginAtZero: true, // scale 包含 0
|
|
|
|
|
ticks:{
|
|
|
|
|
color: '#334155',
|
|
|
|
|
align: 'inner',
|
|
|
|
|
callback: function(value, index, values) {
|
|
|
|
|
if (index === 0) return abbreviateNumber(value);
|
|
|
|
|
else if (index === values.length - 1) return abbreviateNumber(value);
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
// display: false, // 隱藏 y 軸網格
|
|
|
|
|
color: function(context) {
|
|
|
|
|
return context.tick.value === 0 ? '#334155' : null;
|
|
|
|
|
},
|
|
|
|
|
drawTicks: false,
|
|
|
|
|
},
|
|
|
|
|
border: {
|
|
|
|
|
color: '#334155',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.$emitter.on('coverPlate', boolean => {
|
|
|
|
|
this.isCoverPlate = boolean;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
<style scoped>
|
|
|
|
|
|