CorrelationAnalysis.vue 3.78 KB
Newer Older
1
<template>
2
3
4
  <div style="height: 100%; width: 100%">

    <div id="data-box-section" style="height: 25%;">
5
6
7
8
9
10
11
12
      <data-box header="X and Y variables"
                dataType="numerical"
                v-on:update="update_xyData">
      </data-box>
      <data-box header="Annotations"
                dataType="categorical"
                v-on:update="update_annotationData">
      </data-box>
13
    </div>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

    <input id="run-analysis-btn"
           type="button"
           @click="runAnalysisWrapper"
           value="Run Analysis"
           :disabled="disabled"/>

    <div id="visualisation-section" style="height: 75%;">
      <svg width="100%" height="100%">
        <g :style="{transform: `translate(${margin.left}px, ${margin.top}px)`}">
          <circle :cx="scales.x(point.x)" :cy="scales.y(point.y)" r="4" v-for="point in points"></circle>
        </g>
      </svg>
    </div>

29
  </div>
30
31
32
33
</template>


<script>
34
35
  import DataBox from '../DataBox.vue'
  import requestHandling from '../mixins/request-handling'
36
  import * as d3 from 'd3'
37
38
  export default {
    name: 'correlation-analysis',
39
    data () {
40
      return {
41
42
        width: 0,
        height: 0,
43
44
45
46
47
48
49
        xyData: [],
        annotationData: [],
        get args () {
          return {
            x: `$${this.xyData[0]}$`,
            y: `$${this.xyData[1]}$`
          }
50
51
52
53
54
55
56
57
58
59
60
61
62
        },
        margin: {
          left: 50,
          top: 50,
          right: 50,
          bottom: 50
        },
        analysisResults: {},
        scales: {
          x: null,
          y: null
        },
        points: []
63
64
      }
    },
65
66
67
    computed: {
      disabled () {
        return this.xyData.length !== 2
68
69
70
71
72
73
74
75
76
77
      },
      padded () {
        const width = this.width - this.margin.left - this.margin.right
        const height = this.height - this.margin.top - this.margin.bottom
        return { width, height }
      }
    },
    watch: {
      analysisResults: function () {
        this.updateChart()
78
79
      }
    },
80
81
82
83
84
85
86
    mounted() {
      window.addEventListener('resize', this.onResize)
      this.onResize() // initial call
    },
    beforeDestroy() {
      window.removeEventListener('resize', this.onResize)
    },
87
88
89
90
91
92
93
    components: {
      DataBox
    },
    mixins: [
      requestHandling
    ],
    methods: {
94
      runAnalysisWrapper () {
95
        // function made available via requestHandling mixin
96
        this.runAnalysis({job_name: 'compute-correlation', args: this.args})
97
          .then(response => {
98
99
100
            const results = JSON.parse(response)
            results.data = JSON.parse(results.data)
            this.analysisResults = results
101
          })
102
103
104
105
106
107
          .catch(error => console.error(error))
      },
      onResize () {
        const section = this.$el.querySelector('#visualisation-section')
        this.height = section.clientHeight
        this.width = section.clientWidth
108
109
110
111
112
113
      },
      update_xyData (ids) {
        this.xyData = ids
      },
      update_annotationData (ids) {
        this.annotationData = ids
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
      },
      updateChart () {
        this.points = Object.keys(this.analysisResults.data.id).map(key => {
          return {
            x: this.analysisResults.data[this.analysisResults.x_label][key],
            y: this.analysisResults.data[this.analysisResults.y_label][key],
            id: this.analysisResults.data.id[key]
          }
        })
        this.scales.x = d3.scaleLinear()
          .domain(d3.extent(this.points.map(d => d.x)))
          .range([0, this.padded.width])
        this.scales.y = d3.scaleLinear()
          .domain(d3.extent(this.points.map(d => d.y)))
          .range([this.padded.height, 0])
129
      }
130
131
132
133
134
135
    }
  }
</script>


<style scoped>
136
  #data-box-section {
137
138
139
140
    display: flex;
    flex-direction: row;
    justify-content: space-around;
  }
141

142
143
144
145
  #run-analysis-btn {
    width: 100%;
    height: 20px;
  }
146
</style>