Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Scatterplot view #4

Merged
merged 4 commits into from over 1 year ago

2 participants

kleisb Hector Rovira
kleisb

No description provided.

Hector Rovira hrovira merged commit 3622579 into from
Hector Rovira hrovira closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 4 unique commits by 1 author.

Nov 12, 2012
Added scatterplot view files 08198d6
Cancer subtype, feature source and gene inputs are filled from data s…
…ources
3e856dc
Plotting works 46d38c5
Nov 13, 2012
Changed feature label typeahead to select 5e5e299
This page is out of date. Refresh to see the latest.
8  app/lib/router.js
@@ -3,6 +3,7 @@ module.exports = Backbone.Router.extend({
3 3
     routes:{
4 4
         '':'home_view',
5 5
         'twoD/:f1/:f2':'twod_view',
  6
+        'scatterplot':'scatterplot_view',
6 7
         'seqpeek':'seqpeek_view',
7 8
         'v/*uri/:view_name':'viewsByUri'
8 9
     },
@@ -22,6 +23,7 @@ module.exports = Backbone.Router.extend({
22 23
         "twoD": require("../views/2D_Distribution_view"),
23 24
         "kde": null,
24 25
         "parcoords": require("../views/parcoords_view"),
  26
+        "scatterplot": require("../views/scatterplot_view"),
25 27
         "seqpeek": require("../views/seqpeek_view")
26 28
     },
27 29
 
@@ -48,6 +50,12 @@ module.exports = Backbone.Router.extend({
48 50
         $(document.body).append(csview.render().el);
49 51
     },
50 52
 
  53
+    scatterplot_view:function () {
  54
+        var Scatterplot = require('../views/scatterplot_view');
  55
+        var scatterplotView = new Scatterplot();
  56
+        this.$el.html(scatterplotView.render().el);
  57
+    },
  58
+
51 59
     seqpeek_view:function () {
52 60
         var SeqPeek = require('../views/seqpeek_view');
53 61
         var seqpeekView = new SeqPeek();
311  app/views/scatterplot_view.js
... ...
@@ -0,0 +1,311 @@
  1
+var View = require('./view');
  2
+var template = require('./templates/scatterplot');
  3
+
  4
+module.exports = View.extend({
  5
+    template: template,
  6
+    label: "Scatterplot",
  7
+    className: "row-fluid",
  8
+
  9
+    initialize: function (options) {
  10
+        _.extend(this, options);
  11
+        _.bindAll(this,
  12
+            'afterRender',
  13
+            'initControls',
  14
+            'initFeatureLabelTypeahead',
  15
+            'initFeatureSourcesSelect',
  16
+            'initGeneTypeaheads',
  17
+            'initGraph',
  18
+            'initSubtypeDropdown',
  19
+            'isFeatureOfInterest',
  20
+            'updateSubtype',
  21
+            'updateGraph',
  22
+            'parseFeatureData',
  23
+            'loadFeatures1',
  24
+            'loadFeatures2');
  25
+        
  26
+        $.ajax({
  27
+            url:"svc/data/lookups/genes",
  28
+            type:"GET",
  29
+            dataType:"text",
  30
+            success:this.initGeneTypeaheads
  31
+        });
  32
+
  33
+        $.ajax({
  34
+            url:"svc/data/lookups/cancers",
  35
+            type:"GET",
  36
+            dataType:"text",
  37
+            success:this.initSubtypeDropdown
  38
+        });
  39
+
  40
+        $.ajax({
  41
+            url:"svc/data/lookups/features_of_interest",
  42
+            type:"GET",
  43
+            dataType:"text",
  44
+            success:this.initFeatureSourcesSelect
  45
+        });
  46
+
  47
+        this.drawGraph = _.once(this.initGraph);
  48
+
  49
+        this.feature_matrix = 'fmx_newMerge_05nov';
  50
+        this.feature_label_field = 'id';
  51
+
  52
+        this.data = {
  53
+            subtype: 'BRCA',
  54
+            gene1: 'TP53',
  55
+            gene2: 'TP53',
  56
+            source1: 'GNAB',
  57
+            source2: 'GNAB'
  58
+        }
  59
+    },
  60
+
  61
+    afterRender: function () {
  62
+        this.initControls();
  63
+    },
  64
+
  65
+    initControls: function () {
  66
+        var that = this;
  67
+        
  68
+        this.$el.find(".feature1-options .feature-label-select").change(function() {
  69
+            that.data.feature_id_1 = that.$el.find(".feature1-options .feature-label-select").val();
  70
+            that.loadFeatures1();
  71
+            that.parseFeatureData();
  72
+        });
  73
+
  74
+        this.$el.find(".feature2-options .feature-label-select").change(function() {
  75
+            that.data.feature_id_2 = that.$el.find(".feature2-options .feature-label-select").val();
  76
+            that.loadFeatures2();
  77
+            that.parseFeatureData();
  78
+        });
  79
+    },
  80
+
  81
+    initSubtypeDropdown: function(txt) {
  82
+        var that = this;
  83
+        var cancerlist = txt.trim().split("\n");
  84
+
  85
+        _.each(cancerlist, function(subtype) {
  86
+            var html = '<option>' + subtype + '</option>';
  87
+            that.$el.find(".subtype-select").append(html);
  88
+        });
  89
+
  90
+        this.$el.find(".subtype-select").change(function(e) {
  91
+            var subtype = that.$el.find(".subtype-select").val();
  92
+            that.updateSubtype(subtype);
  93
+        });
  94
+    },
  95
+
  96
+    initFeatureSourcesSelect: function(txt) {
  97
+        var that = this,
  98
+            items = txt.trim().split("\n");
  99
+
  100
+        this.features_of_interest = _.map(items, function (line) {
  101
+            var split = line.split("\t");
  102
+            return { "label":split[0], "regexp":split[1]};
  103
+        });
  104
+
  105
+        _.each(this.features_of_interest, function(s) {
  106
+            var html = '<option>' + s.label + '</option>';
  107
+            that.$el.find(".featuresource-select").append(html);
  108
+        });
  109
+
  110
+        this.$el.find(".feature1-options .featuresource-select").change(function() {
  111
+            that.data.source1 = that.$el.find(".feature1-options .featuresource-select").val();
  112
+            that.loadFeatures1();
  113
+        });
  114
+
  115
+        this.$el.find(".feature2-options .featuresource-select").change(function() {
  116
+            that.data.source2 = that.$el.find(".feature2-options .featuresource-select").val();
  117
+            that.loadFeatures2();
  118
+        });
  119
+    },
  120
+
  121
+    initGeneTypeaheads: function(txt) {
  122
+        var that = this;
  123
+        this.genelist = txt.trim().split("\n");
  124
+
  125
+        var source_fn = function (q, p) {
  126
+            p(_.compact(_.flatten(_.map(q.toLowerCase().split(" "), function (qi) {
  127
+                return _.map(that.genelist, function (geneitem) {
  128
+                    if (geneitem.toLowerCase().indexOf(qi) >= 0) return geneitem;
  129
+                });
  130
+            }))));
  131
+        };
  132
+
  133
+        this.$el.find(".genes-typeahead").typeahead({
  134
+            source: source_fn
  135
+        });
  136
+
  137
+        this.$el.find(".genes-typeahead").val(this.data.gene1);
  138
+    },
  139
+
  140
+    initGraph: function () {
  141
+        var plot_data = {
  142
+            DATATYPE : "vq.models.ScatterPlotData",
  143
+            CONTENTS : {
  144
+                PLOT : {
  145
+                    width : 768, height: 768,
  146
+                    dblclick_notifier : function() {},
  147
+                    vertical_padding : 80,
  148
+                    horizontal_padding: 80,
  149
+                    x_label_displacement: 40,
  150
+                    y_label_displacement: -70,
  151
+                    x_tick_displacement: 20,
  152
+                    enable_transitions: true
  153
+                },
  154
+                axis_font :"14px helvetica",
  155
+                tick_font :"14px helvetica",
  156
+                stroke_width: 1,
  157
+                radius: 4,
  158
+                data_array: this.data.plot_array,
  159
+                regression: 'none',
  160
+                xcolumnid: 'x',
  161
+                ycolumnid: 'y',
  162
+                valuecolumnid: 'id'
  163
+            }
  164
+        };
  165
+
  166
+        this.$el.find(".scatterplot-container").scatterplot(plot_data);
  167
+        this.trigger("post-render");
  168
+    },
  169
+
  170
+    updateGraph: function() {
  171
+        this.drawGraph();
  172
+
  173
+        this.$el.find(".scatterplot-container").scatterplot('reset_data', this.data.plot_array);
  174
+        this.$el.find(".scatterplot-container").scatterplot("enable_zoom");
  175
+    },
  176
+
  177
+    updateSubtype: function(subtype) {
  178
+        this.data.subtype = subtype;
  179
+    },
  180
+
  181
+    parseFeatureData: function() {
  182
+        var that = this,
  183
+            data = this.data;
  184
+
  185
+        if (data.feature_id_1 === undefined || data.feature_id_2 === undefined) {
  186
+            return;
  187
+        }
  188
+
  189
+        var values1 = data.feature_map_1[data.feature_id_1].values;
  190
+        var values2 = data.feature_map_2[data.feature_id_2].values;
  191
+
  192
+        data.plot_array = [];
  193
+
  194
+        _.each(values1, function(v1, key) {
  195
+            var v2 = values2[key];
  196
+
  197
+            if (v1 != 'NA' && v2 != 'NA')
  198
+            that.data.plot_array.push({
  199
+                x: v1,
  200
+                y: v2,
  201
+                id: key
  202
+            });
  203
+        });
  204
+
  205
+        this.updateGraph();
  206
+    },
  207
+
  208
+    isFeatureOfInterest:function (feature_id) {
  209
+        return _.any(this.features_of_interest, function (foi) {
  210
+            var queryPattern = foi.regexp.replace(/\*/g, ".*?");
  211
+            var queryRegex = new RegExp(queryPattern, 'gi');
  212
+            return queryRegex.test(feature_id);
  213
+        });
  214
+    },
  215
+
  216
+    initFeatureLabelTypeahead: function(feature_number) {
  217
+        var that = this,
  218
+            options_selector,
  219
+            features,
  220
+            feature_labels;
  221
+
  222
+        if (feature_number == 1) {
  223
+            options_selector = ".feature1-options";
  224
+            features = this.data.features1;
  225
+        }
  226
+        else {
  227
+            options_selector = ".feature2-options";
  228
+            features = this.data.features2;
  229
+        }
  230
+
  231
+        feature_labels = _
  232
+            .chain(features)
  233
+            .pluck(this.feature_label_field)
  234
+            .value();
  235
+
  236
+        var selector = options_selector + " .feature-label-select";
  237
+        this.$el.find(selector + " option").remove();
  238
+
  239
+        that.$el.find(selector).append('<option value="-1">select feature ... </option>');
  240
+        _.each(feature_labels, function(label) {
  241
+            var html = '<option>' + label + '</option>';
  242
+            that.$el.find(selector).append(html);
  243
+        });
  244
+    },
  245
+
  246
+    buildAllFeaturesQuery: function(subtype, gene) {
  247
+        var feature_query = "?cancer=" + subtype.toLowerCase() + "&gene=" + gene;
  248
+        return "/svc/lookups/qed_lookups/" + this.feature_matrix + "/" + feature_query;
  249
+    },
  250
+
  251
+    buildFeatureMap: function(features) {
  252
+        return _.reduce(features, function(memo, f) {
  253
+            memo[f.id] = f;
  254
+            return memo;
  255
+        }, {});
  256
+    },
  257
+
  258
+    loadFeatures1: function() {
  259
+        var that = this,
  260
+            query = this.buildAllFeaturesQuery(this.data.subtype, this.data.gene1);
  261
+
  262
+        $.ajax({
  263
+            type: 'GET',
  264
+            url: query,
  265
+            context: this,
  266
+            success: function(json) {
  267
+                var features = _.filter(json.items, function(f) {
  268
+                    return that.isFeatureOfInterest(f.id);
  269
+                });
  270
+
  271
+                if (features.length > 0) {
  272
+                    that.data.features1 = features;
  273
+                    that.data.feature_map_1 = that.buildFeatureMap(features);
  274
+                    that.initFeatureLabelTypeahead(1);
  275
+                }
  276
+                else {
  277
+                    that.data.features1 = undefined;
  278
+                    that.data.feature_map_1 = undefined;
  279
+                    that.data.feature_id_1 = undefined;
  280
+                }
  281
+            }
  282
+        });
  283
+    },
  284
+
  285
+    loadFeatures2: function() {
  286
+        var that = this,
  287
+            query = this.buildAllFeaturesQuery(this.data.subtype, this.data.gene2);
  288
+
  289
+        $.ajax({
  290
+            type: 'GET',
  291
+            url: query,
  292
+            context: this,
  293
+            success: function(json) {
  294
+                var features = _.filter(json.items, function(f) {
  295
+                    return that.isFeatureOfInterest(f.id);
  296
+                });
  297
+
  298
+                if (features.length > 0) {
  299
+                    that.data.features2 = features;
  300
+                    that.data.feature_map_2 = that.buildFeatureMap(features);
  301
+                    that.initFeatureLabelTypeahead(2);
  302
+                }
  303
+                else {
  304
+                    that.data.features2 = undefined;
  305
+                    that.data.feature_map_2 = undefined;
  306
+                    that.data.feature_id_2 = undefined;
  307
+                }
  308
+            }
  309
+        });
  310
+    }
  311
+});
20  app/views/templates/scatterplot.hbs
... ...
@@ -0,0 +1,20 @@
  1
+
  2
+<select class="subtype-select">
  3
+
  4
+</select>
  5
+
  6
+<div class="feature1-options">
  7
+    <select class="featuresource-select"></select>
  8
+
  9
+    <input class="input-small genes-typeahead" type="text" placeholder="gene 1 ...">
  10
+    <select style="width: 300px" class="feature-label-select"></select>
  11
+</div>
  12
+
  13
+<div class="feature2-options">
  14
+    <select class="featuresource-select"></select>
  15
+
  16
+    <input class="input-small genes-typeahead" type="text" placeholder="gene 2 ...">
  17
+    <select style="width: 300px" class="feature-label-select"></select>
  18
+</div>
  19
+
  20
+<div class="scatterplot-container"></div>
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.