From 75246de996cf2042c09e120cda36e200de1619d4 Mon Sep 17 00:00:00 2001
From: Kenzo-Hugo Hillion <kenzo-hugo.hillion1@pasteur.fr>
Date: Tue, 3 Dec 2019 17:51:07 +0100
Subject: [PATCH] add interactive options for doughnut graph

---
 frontend/src/components/Doughnut.vue | 116 ++++++++++++++++++++-------
 frontend/src/views/Stats.vue         |  53 ++++++++----
 2 files changed, 126 insertions(+), 43 deletions(-)

diff --git a/frontend/src/components/Doughnut.vue b/frontend/src/components/Doughnut.vue
index 2a6c068..2ba8c21 100644
--- a/frontend/src/components/Doughnut.vue
+++ b/frontend/src/components/Doughnut.vue
@@ -1,15 +1,34 @@
 <template>
   <v-card class="pa-2">
     <div class="card-body">
-      <div v-if="doughnutData.data">
-        <canvas :id="this.doughnutData.chartId"></canvas>
+      <div>
+        <canvas :id="chartId"></canvas>
       </div>
-      <div class="text-xs-center" v-else>
+      <!-- <div class="text-xs-center" v-else>
         <v-progress-circular
           indeterminate
           color="secondary"
         ></v-progress-circular>
-      </div>
+      </div> -->
+      <v-layout
+        align-center
+        wrap
+      >
+        <v-switch
+          v-model="displayLegend"
+          label="Display legend">
+        </v-switch>
+        <v-flex xs12 sm6>
+          <v-select
+            v-model="hideLabels"
+            :items="this.labels"
+            attach
+            chips
+            label="Hide fields"
+            multiple
+          ></v-select>
+        </v-flex>
+      </v-layout>
     </div>
   </v-card>
 </template>
@@ -24,37 +43,53 @@ export default {
       required: true,
     },
   },
-  updated() {
-    this.createChart(this.doughnutData.chartId);
+  watch: {
+    doughnutData(val) {
+      this.updateChart();
+    },
+    displayLegend(val) {
+      this.updateChartOptions();
+    },
+    hideLabels() {
+      this.updateChartData();
+    }
+  },
+  data() {
+    return {
+      myChart: {},
+      options: {},
+      colors: [],
+      chartId: "myChart",
+      displayLegend: true,
+      labels: [],
+      hideLabels: [],
+    }
+  },
+  mounted() {
+    this.createChart(this.chartId);
   },
   methods: {
     createChart(chartId) {
       const ctx = document.getElementById(chartId);
-      const colors = [];
-      for (var i = 0; i<Object.keys(this.doughnutData.data).length; i++) {
-        colors.push(this.generateColor())
-      }
-      const data = {
-        labels: Object.keys(this.doughnutData.data),
-        datasets: [
-          {
-            data: Object.values(this.doughnutData.data),
-            backgroundColor: colors,
-          },
-        ],
-      };
-      const options = {
-        legend: {
-          display: true,
-        }
-      };
-      // eslint-disable-next-line
-      const myChart = new Chart(ctx, {
-        data: data,
+      this.myChart = new Chart(ctx, {
+        data: this.data,
         type: 'doughnut',
-        options: options,
+        options: this.options,
       });
     },
+    updateChart() {
+      this.dataDict = this.doughnutData.data;
+      this.labels = Object.keys(this.doughnutData.data);
+      this.generateColorList();
+      this.updateChartOptions();
+      this.updateChartData();
+    },
+    generateColorList() {
+      this.color = [];
+      for (var i = 0; i<Object.keys(this.doughnutData.data).length; i++) {
+        this.colors.push(this.generateColor())
+      }
+    },
     generateColor() {
       var letters = '0123456789ABCDEF';
       var color = '#';
@@ -63,6 +98,31 @@ export default {
       }
       return color;
     },
+    updateChartOptions() {
+      this.options = {
+        legend: {
+          display: this.displayLegend,
+        }
+      };
+      this.myChart.options = this.options;
+      this.myChart.update();
+    },
+    updateChartData() {
+      const dataDict = Object.assign({}, this.dataDict);
+      for (let i=0; i < this.hideLabels.length; i++) {
+        delete dataDict[this.hideLabels[i]];
+      };
+      this.myChart.data = {
+        labels: Object.keys(dataDict),
+        datasets: [
+          {
+            data: Object.values(dataDict),
+            backgroundColor: this.colors,
+          },
+        ],
+      };
+      this.myChart.update();
+    }
   },
 };
 </script>
diff --git a/frontend/src/views/Stats.vue b/frontend/src/views/Stats.vue
index b88ed6c..e74d222 100644
--- a/frontend/src/views/Stats.vue
+++ b/frontend/src/views/Stats.vue
@@ -37,8 +37,8 @@
                     background-color="primary"
                     :items="this.geneLengthChoice"
                     label="Window Length"
-                    value=400
                     color="secondary"
+                    v-model="geneLengthWindowSize"
                   ></v-select>
                 </v-flex>
                 <v-flex xs4 md2>
@@ -46,8 +46,8 @@
                     background-color="primary"
                     :items="this.stopAtChoice"
                     label="Stop at"
-                    value=5000
                     color="secondary"
+                    v-model="stopAt"
                   ></v-select>
                 </v-flex>
               </v-toolbar>
@@ -64,9 +64,10 @@
                 <v-flex xs4 md2>
                   <v-select
                     background-color="primary"
-                    :items="this.selectLevel"
-                    value="phylum"
+                    :items="selectLevel"
                     color="secondary"
+                    label="Level"
+                    v-model="taxLevel"
                   ></v-select>
                 </v-flex>
               </v-toolbar>
@@ -86,6 +87,7 @@ import Histogram from '@/components/Histogram.vue';
 import CountCard from '@/components/CountCard.vue';
 import Doughnut from '@/components/Doughnut.vue';
 
+
 export default {
   name: 'home',
   data() {
@@ -96,27 +98,36 @@ export default {
       geneCountTaxo: {},
       geneCountFull: {},
       geneLengthWindowSize: 400,
-      stopAtChoice: [5000, 10000],
-      geneLengthChoice: [200, 400, 500, 1000],
       stopAt: 5000,
       taxoCounts: {},
-      selectLevel: ['kingdom', 'phylum', 'genus']
+      taxLevel: 'phylum',
     };
   },
+  computed: {
+    stopAtChoice() {
+      return [5000, 10000];
+    },
+    geneLengthChoice() {
+      return [200, 400, 500, 1000];
+    },
+    selectLevel() {
+      return ['kingdom', 'superkingdom', 'phylum', 'class', 'order', 'family', 'genus'];
+    }
+  },
   mounted() {
-    this.getGeneLength(this.geneLengthWindowSize, this.stopAt);
+    this.getGeneLength();
     this.getGeneCountsAll();
     this.getGeneCountsFunctions();
     this.getGeneCountsTaxo();
     this.getGeneCountsFull();
-    this.getTaxoCounts('phylum');
+    this.getTaxoCounts();
   },
   methods: {
-    getGeneLength(geneLengthWindowSize, stopAt) {
+    getGeneLength() {
       axios.get('/api/catalog/v1/genes/gene_length', {
         params: {
-          'window_size': geneLengthWindowSize,
-          'stop_at': stopAt,
+          'window_size': this.geneLengthWindowSize,
+          'stop_at': this.stopAt,
         },
         headers: {
           Accept: 'application/json',
@@ -218,20 +229,21 @@ export default {
         console.log(error);
       });
     },
-    getTaxoCounts(level) {
+    getTaxoCounts() {
       axios.get('/api/catalog/v1/genes/taxonomy_counts', {
         params: {
-          level: level,
+          level: this.taxLevel,
         },
         headers: {
           Accept: 'application/json',
         },
       })
       .then((response) => {
+        const chartId = 'taxo_distri_' + this.taxLevel
         this.taxoCounts = {
           data: response.data.results.counts,
           level: response.data.results.level,
-          chartId: 'taxo_distri',
+          chartId: chartId,
         };
       })
       .catch((error) => {
@@ -244,5 +256,16 @@ export default {
     countcard: CountCard,
     doughnut: Doughnut,
   },
+  watch: {
+  	taxLevel(val) {
+      this.getTaxoCounts();
+    },
+    stopAt(val) {
+      this.getGeneLength();
+    },
+    geneLengthWindowSize(val) {
+      this.getGeneLength();
+    },
+  }
 };
 </script>
-- 
GitLab