From a2ad10d1837271b2a024d0eaae56614823845c81 Mon Sep 17 00:00:00 2001 From: Jonathan Foucher <jfoucher@gmail.com> Date: Tue, 16 Aug 2022 09:50:17 +0200 Subject: [PATCH] add future risks to results graph. Fixes https://app.asana.com/0/1202404842967175/1202775629585966 --- app/Repository/GraphDataRepository.php | 5 + .../Evaluations/Single/Components/Buttons.vue | 2 +- .../Single/Components/Step3/AttackGraph.vue | 2 + .../Components/Step3/ExpositionGraph.vue | 5 + .../Step4/CyberRiskGraphElement.vue | 2 +- .../Components/Step4/MeasureLevelSelector.vue | 2 +- .../Components/Step5/FutureRiskGraph.vue | 94 +++++++++++++++++++ .../Evaluations/Single/View/index.vue | 6 +- 8 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 resources/js/components/Evaluations/Single/Components/Step5/FutureRiskGraph.vue diff --git a/app/Repository/GraphDataRepository.php b/app/Repository/GraphDataRepository.php index 9885ef4c..dd48a13a 100644 --- a/app/Repository/GraphDataRepository.php +++ b/app/Repository/GraphDataRepository.php @@ -71,12 +71,17 @@ public function getExpositionDataForEvaluation(Evaluation $evaluation): array return $dl->danger_id === $danger->id; }); + // the points for this danger are the total points for this danger, + // divided by the number of appllicable scenarios $values[] = $v / $danger->scenarios->count() * $dangerLevel->level->getPointsAttribute(); } $total = collect($values)->sum(); $percentages = collect($values)->map(function ($val) use ($total) { + if ($val === 0.0 || $total === 0.0) { + return 0; + } return $val / $total * 100; }); diff --git a/resources/js/components/Evaluations/Single/Components/Buttons.vue b/resources/js/components/Evaluations/Single/Components/Buttons.vue index db75ab5c..1ad7a19e 100644 --- a/resources/js/components/Evaluations/Single/Components/Buttons.vue +++ b/resources/js/components/Evaluations/Single/Components/Buttons.vue @@ -101,7 +101,7 @@ export default { this.$store.dispatch('getAllGraphsForEvaluation', this.evaluation.id) this.drafting = false - //this.$router.push('/evaluations') + // this.$router.push('/evaluations') }, async next () { this.saving = true diff --git a/resources/js/components/Evaluations/Single/Components/Step3/AttackGraph.vue b/resources/js/components/Evaluations/Single/Components/Step3/AttackGraph.vue index 0bfe9049..861009d1 100644 --- a/resources/js/components/Evaluations/Single/Components/Step3/AttackGraph.vue +++ b/resources/js/components/Evaluations/Single/Components/Step3/AttackGraph.vue @@ -31,10 +31,12 @@ export default { responsive: true, scales: { r: { + min: 0, ticks: { color: '#000', backdropColor: 'rgba(255,255,255, 0.5)', z: 10, + callback: function (value) { if (Number.isInteger(value)) { return value; } }, }, pointLabels: { display: true, diff --git a/resources/js/components/Evaluations/Single/Components/Step3/ExpositionGraph.vue b/resources/js/components/Evaluations/Single/Components/Step3/ExpositionGraph.vue index 00d44d81..1bfc90cd 100644 --- a/resources/js/components/Evaluations/Single/Components/Step3/ExpositionGraph.vue +++ b/resources/js/components/Evaluations/Single/Components/Step3/ExpositionGraph.vue @@ -33,6 +33,11 @@ export default { maxRotation: 40, minRotation: 40 } + }, + y: { + min: 0, + max: 100, + beginAtZero: true, } }, }, diff --git a/resources/js/components/Evaluations/Single/Components/Step4/CyberRiskGraphElement.vue b/resources/js/components/Evaluations/Single/Components/Step4/CyberRiskGraphElement.vue index 387045d0..4d03f6da 100644 --- a/resources/js/components/Evaluations/Single/Components/Step4/CyberRiskGraphElement.vue +++ b/resources/js/components/Evaluations/Single/Components/Step4/CyberRiskGraphElement.vue @@ -1,5 +1,5 @@ <template> - <div class="graph-element row" v-if="singleData.labels.length"> + <div v-if="singleData.labels.length" class="graph-element row"> <div class="graph-legend col-3 mr-0 pr-0 text-muted"> <span :title="fullLabel">{{singleData.labels[0]}}</span> </div> diff --git a/resources/js/components/Evaluations/Single/Components/Step4/MeasureLevelSelector.vue b/resources/js/components/Evaluations/Single/Components/Step4/MeasureLevelSelector.vue index ae7e955e..e323389e 100644 --- a/resources/js/components/Evaluations/Single/Components/Step4/MeasureLevelSelector.vue +++ b/resources/js/components/Evaluations/Single/Components/Step4/MeasureLevelSelector.vue @@ -14,7 +14,7 @@ :expected-level="measureLevel.expected_level" /> <!-- EN ATTENTE RETOUR CLIENT --> -<!-- <p class="text-center my-4">Efficacité <i class="fas fa-angle-double-right px-2"></i> Efficacité</p>--> + <!-- <p class="text-center my-4">Efficacité <i class="fas fa-angle-double-right px-2"></i> Efficacité</p>--> <MeasureActionForm ref="MeasureActionForm" diff --git a/resources/js/components/Evaluations/Single/Components/Step5/FutureRiskGraph.vue b/resources/js/components/Evaluations/Single/Components/Step5/FutureRiskGraph.vue new file mode 100644 index 00000000..ec4c59d7 --- /dev/null +++ b/resources/js/components/Evaluations/Single/Components/Step5/FutureRiskGraph.vue @@ -0,0 +1,94 @@ +<template> + <Bar v-if="loaded && chartData" :chart-data="chartData" :chart-options="options" /> + <div v-else class=" text-center"> + <i class="fas fa-spin fa-spinner"></i> + </div> +</template> + +<script> +import { Bar } from 'vue-chartjs/legacy' +import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale} from 'chart.js' + +ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale) + +export default { + name: 'FutureRiskGraph', + components: { + Bar, + }, + props: ['evaluation'], + data() { + return { + loaded: this.$store.state.graphs[this.evaluation.id] && this.$store.state.graphs[this.evaluation.id].risks && this.$store.state.graphs[this.evaluation.id].futurerisks, + options: { + plugins: { + legend: { + display: false + }, + }, + scales: { + x: { + ticks: { + autoSkip: false, + maxRotation: 40, + minRotation: 40, + } + }, + y: { + min: 0, + max: 100, + beginAtZero: true, + } + }, + }, + } + }, + computed: { + chartData() { + if (!this.$store.state.graphs[this.evaluation.id] || !this.$store.state.graphs[this.evaluation.id].risks) { + return null; + } + const labels = this.$store.state.graphs[this.evaluation.id].risks.labels.map(l => { + return l.match(/.{1,40}(\s|$)/g) + }); + const data = this.$store.state.graphs[this.evaluation.id].risks.data; + const data2 = this.$store.state.graphs[this.evaluation.id].futurerisks.data; + + return { + labels, + datasets: [ + { + data, + backgroundColor: 'black', + borderColor: 'black', + // barThickness : 1, + }, + { + data: data2, + backgroundColor: 'white', + borderColor: 'black', + borderWidth: 2, + // barThickness : 1, + }, + ] + } + } + }, + async mounted () { + this.loaded = false + if (typeof this.$store.state.graphs[this.evaluation.id] === 'undefined' || typeof this.$store.state.graphs[this.evaluation.id].risks === 'undefined') { + await this.$store.dispatch('getGraphForEvaluation', { + name: 'risks', + id: this.evaluation.id + }) + } + if (typeof this.$store.state.graphs[this.evaluation.id] === 'undefined' || typeof this.$store.state.graphs[this.evaluation.id].futurerisks === 'undefined') { + await this.$store.dispatch('getGraphForEvaluation', { + name: 'futurerisks', + id: this.evaluation.id + }) + } + this.loaded = true + } +} +</script> diff --git a/resources/js/components/Evaluations/Single/View/index.vue b/resources/js/components/Evaluations/Single/View/index.vue index 59384172..34c3fa97 100644 --- a/resources/js/components/Evaluations/Single/View/index.vue +++ b/resources/js/components/Evaluations/Single/View/index.vue @@ -36,7 +36,7 @@ </div> </div> <div class="card-body"> - <ExpositionGraph :evaluation="evaluation" /> + <FutureRiskGraph :evaluation="evaluation" /> </div> </div> </div> @@ -59,13 +59,13 @@ import PlanAction from '../Components/Results/PlanAction' import MaturityCyber from '../Components/Results/MaturityCyber' import Historic from '../Components/Results/Historic' import NotFound from "../../../Errors/NotFound"; -import ExpositionGraph from "../Components/Step3/ExpositionGraph"; +import FutureRiskGraph from "../Components/Step5/FutureRiskGraph"; export default { name: 'SingleEvaluationView', components: { - ExpositionGraph, + FutureRiskGraph, NotFound, Dangers, Measures, -- GitLab