Survivalplot.vue 3.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<template>
    <chart v-on:resize="resize">
        <control-panel class="fjs-control-panel" name="Survivalplot Panel">
            <data-box class="fjs-data-box"
                      header="Duration [numerical]"
                      :data-types="['numerical']"
                      v-on:update="updateDurationVariable">
            </data-box>
            <data-box class="fjs-data-box"
                      header="Groups (optional) [categorical]"
                      :data-types="['categorical']"
                      v-on:update="updateGroupVariable">
            </data-box>
            <data-box class="fjs-data-box"
                      header="Observed (optional) [categorical]"
                      :data-types="['categorical']"
                      v-on:update="updateObservedVariable">
            </data-box>
        </control-panel>
        <svg :height="height" :width="width">
            <g :transform="`translate(${margin.left}, ${margin.top})`">

            </g>
        </svg>
    </chart>
</template>

<script>
  import ControlPanel from '../components/ControlPanel.vue'
  import Chart from '../components/Chart.vue'
  import DataBox from '../components/DataBox.vue'
  import RunAnalysis from '../mixins/run-analysis'
  import store from '../../store/store'
  import deepFreeze from 'deep-freeze-strict'
  import * as d3 from 'd3'
  import Crosshair from '../components/Crosshair.vue'
  export default {
    name: 'survivalplot',
    components: {DataBox, Chart, ControlPanel},
    mixins: [RunAnalysis],
    data () {
      return {
        height: 0,
        width: 0,
        durationVariables: [],
        groupVariables: [],
        observedVariables: [],
        estimator: 'KaplanMeier',
        results: {}
      }
    },
    computed: {
      args () {
        return {
          durations: this.durationVariables,
          categories: this.groupVariables,
          event_observed: this.observedVariables,
          estimator: this.estimator,
          id_filter: store.getters.filter('ids'),
          subsets: store.getters.subsets
        }
      },
      validArgs () {
        return this.durations.length === 1
      },
      margin () {
        const left = this.width / 15
        const top = this.height / 15
        const right = this.width / 15
        const bottom = this.height / 15
        return {left, top, right, bottom}
      },
      padded () {
        const width = this.width - this.margin.left - this.margin.right
        const height = this.height - this.margin.top - this.margin.bottom
        return {width, height}
      }
    },
    methods: {
      updateDurationVariable (ids) {
        this.durationVariables = ids
      },
      updateGroupVariable (ids) {
        this.groupVariables = ids
      },
      updateObservedVariable (ids) {
        this.observedVariables = ids
      },
      resize (width, height) {
        this.width = width
        this.height = height
      },
      runAnalysisWrapper (args) {
        this.runAnalysis('survival-analysis', args)
          .then(response => {
            const results = JSON.parse(response)
            deepFreeze(results) // massively improve performance by telling Vue that the objects properties won't change
            this.results = results
          })
          .catch(error => console.error(error))
      }
    },
    watch: {
      'args': {
        handler: function (newArgs) {
          if (this.validArgs) {
            this.runAnalysisWrapper(newArgs)
          }
        }
      }
    }
  }
</script>

<style lang="sass" scoped>
    @import '~assets/base.sass'

</style>

<!--CSS for dynamically created components-->
<style lang="sass">

</style>