diff js/pCoordCSstats.js @ 2:a64ece32a01a draft default tip

"planemo upload for repository https://github.com/ImmPortDB/immport-galaxy-tools/tree/master/flowtools/cs_overview commit a46097db0b6056e1125237393eb6974cfd51eb41"
author azomics
date Tue, 28 Jul 2020 08:32:36 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/js/pCoordCSstats.js	Tue Jul 28 08:32:36 2020 -0400
@@ -0,0 +1,418 @@
+// Copyright (c) 2016 Northrop Grumman.
+// All rights reserved.
+
+/*
+ * Initialize variables for parallelCoordinates display
+*/
+var pcApp = pcApp || {};
+
+pcApp.allSamples = [];
+pcApp.selectedSamples = [];
+pcApp.origData;
+pcApp.flowData;
+pcApp.updatedData;
+pcApp.headers = [];
+pcApp.foreground;
+pcApp.background;
+
+var displayAll = function() {
+  displayParallelPlot();
+}
+/*
+ * Display the Population Legend
+*/
+var displaySmpTable = function() {
+  $('#popTablePC tbody').empty();
+  pcApp.origData.map(function(d) {
+    $('#popTablePC tbody').append('<tr><td align="center">'
+        + '<input type="checkbox" id="' + d.SampleName + '" '
+        + 'checked class="popSelectPC" value='
+        + d.SampleNumber + '/></td><td title="' + newSmpNames[d.SampleName]
+        + '">' + newSmpNames[d.SampleName]
+        + '</td><td><span style="background-color:'
+        + color_palette[0][d.SampleNumber + 1][0]
+        + '">&nbsp;&nbsp;&nbsp;</span></td></tr>');
+  });
+
+  $('#popSelectAllPC').click(function() {
+    var checkAll = $("#popSelectAllPC").prop('checked');
+    if (checkAll) {
+      $(".popSelectPC").prop("checked", true);
+    } else {
+      $(".popSelectPC").prop("checked", false);
+    }
+    pcApp.selectedSamples = [];
+    $('.popSelectPC').each(function() {
+      if (this.checked) {
+        pcApp.selectedSamples.push(parseInt(this.value));
+      }
+    })
+    displayTableGrid();
+    if (checkAll) {
+      displayParallelPlot();
+    } else {
+      updateParallelForeground();
+    }
+  });
+
+  $('.popSelectPC').click(function() {
+    if ($('.popSelectPC').length == $(".popSelectPC:checked").length) {
+      $('#popSelectAllPC').prop("checked",true);
+    } else {
+      $('#popSelectAllPC').prop("checked",false);
+    }
+    pcApp.selectedSamples = [];
+    $('.popSelectPC').each(function() {
+      if (this.checked) {
+         pcApp.selectedSamples.push(parseInt(this.value));
+      }
+    })
+    displayTableGrid();
+    updateParallelForeground();
+  });
+  updateSmpTable();
+};
+
+var updateSmpTable = function() {
+  $('.popSelectPC').each(function() {
+    var smp = parseInt(this.value);
+    if ($.inArray(smp,pcApp.selectedSamples) > -1) {
+      this.checked = true;
+    } else {
+      this.checked = false;
+    }
+  })
+}
+
+var displayTableGrid = function() {
+  var colTable = [],
+      colNames = [],
+      pctargets = [],
+      updatedHeaders = [],
+      displayData = [],
+      targetCol = 0,
+      textCol = [],
+      colOrder = [],
+      tableHTML = [];
+
+  $("#tableDivPC").empty();
+  pcApp.updatedData = $.extend(true,[],pctablecontent);
+  pcApp.updatedData.forEach(function(d, idx){
+    d.SampleName = idx + 1;
+    delete(d.FileID);
+  });
+
+  updatedHeaders = Object.keys(pcApp.updatedData[0]);
+  displayData = pcApp.updatedData.filter(function(d,i) {
+    if ($.inArray(i,pcApp.selectedSamples) > -1) {
+      return d;
+    }
+  });
+
+  targetCol = updatedHeaders.length - 2;
+  updatedHeaders.forEach(function(d,i){
+    colTable.push("<th>" + d + "</th>");
+    colNames.push({"data":d});
+    if (i < targetCol){
+      pctargets.push(i);
+    }
+  });
+  textCol = [targetCol, targetCol + 1];
+  colOrder = textCol.concat(pctargets);
+  tableHTML = [
+      '<table id="pcTable" class="pctable display compact nowrap" cellspacing="0" width="100%">',
+      '<thead>',
+      '<tr>',
+      colTable.join("\n"),
+      '</tr>',
+      '</thead>',
+      '</table>',
+  ];
+
+  $('#tableDivPC').html(tableHTML.join("\n"));
+  var pcTable = $('#pcTable').DataTable({
+      columns: colNames,
+      data: displayData,
+      order: [[ targetCol, "asc" ]],
+      pageLength: 10,
+      //paging: false,
+      scrollY: 250,
+      scrollCollapse: true,
+      scrollX: true,
+      dom: '<"top"B>t<"bottom"lip><"clear">',
+      columnDefs: [{
+          targets: pctargets,
+          className: "dt-body-right",
+          render: function(data,type,row){
+              return parseFloat(data).toFixed(2) + '%';
+          }
+        }, {
+          targets: [targetCol, targetCol+1],
+          className: "dt-body-center"
+        }, {
+          targets:[targetCol],
+          render: function(data, type, row){
+              return 'Sample' + parseInt(data);
+          }
+      }],
+      buttons: [
+          'copy', 'pdfHtml5','csvHtml5', 'colvis'
+      ],
+      colReorder: {order:colOrder},
+      select: true
+  });
+
+  $('#pcTable').on('mouseover', 'tr', function() {
+    var data = pcTable.row(this).data();
+    if (data != undefined) {
+      var smp = parseInt(data.SampleName) - 1;
+      pcApp.selectedSamples = [smp];
+      updateParallelForeground();
+    }
+  });
+  $('#pcTable').on('mouseleave', 'tr', function() {
+    pcApp.selectedSamples = [];
+    $('.popSelectPC').each(function() {
+      if (this.checked) {
+        pcApp.selectedSamples.push(parseInt(this.value));
+      }
+      updateParallelForeground();
+    })
+  });
+};
+/*
+ * Display The Main Plot
+*/
+var displayParallelPlot = function() {
+  var margin = {top: 30, right: 10, bottom: 10, left: 10},
+      h = 300,
+      w = $("#plotDivPC").width(),
+      width = w - margin.left - margin.right,
+      height = h - margin.top - margin.bottom,
+      y  = {},
+      dragging = {},
+      ymax = 0;
+
+  $("#plotDivPC").empty();
+  $("#plotDivPC").height(h);
+  var svg = d3.select("#plotDivPC").append("svg")
+      .attr("width", width + margin.left + margin.right)
+      .attr("height", height + margin.top + margin.bottom)
+    .append("g")
+      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
+
+  var x = d3.scale.ordinal().rangePoints([0, width], 1);
+  var line = d3.svg.line();
+  var axis = d3.svg.axis()
+      .orient("left")
+      .tickFormat(d3.format("d"))
+      .ticks(5);
+
+  for (var m = 0, n = pcApp.flowData.length; m < n; m++){
+    for (var p in pcApp.flowData[m]){
+      if (+pcApp.flowData[m][p] > ymax){
+        ymax = +pcApp.flowData[m][p];
+      }
+    }
+  }
+
+  // Y axis label
+  svg.append("text")
+      .attr("class", "ylabel")
+      .attr("transform", "rotate(-90)")
+      .attr("y", 0 - margin.left)
+      .attr("x",0 - (height / 2))
+      .attr("dy", "1em")
+      .style("text-anchor", "middle")
+      .text("Fraction of population in sample");
+
+  var dimensions = d3.keys(pcApp.flowData[0]).filter(function(d) {
+    return (y[d] = d3.scale.linear()
+        .domain([0,parseInt(ymax)+1])
+        .range([height, 0]));
+  });
+  x.domain(dimensions);
+
+  function path(d) {
+    return line(dimensions.map(function(p) { return [x(p), y[p](d[p])]; }));
+  }
+
+  function position(d) {
+    var v = dragging[d];
+    return v == null ? x(d) : v;
+  }
+
+  function transition(g) {
+    return g.transition().duration(500);
+  }
+
+  function brush() {
+    var actives = dimensions.filter(function(p) { return !y[p].brush.empty(); });
+    var extents = actives.map(function(p) { return y[p].brush.extent(); });
+    var selectedSamples = pcApp.origData.filter(function(d) {
+      var smp = parseInt(d.SampleNumber);
+      var tf = actives.every(function(p,i) {
+        return extents[i][0] <= pcApp.flowData[smp][p] &&
+                      pcApp.flowData[smp][p] <= extents[i][1];
+      });
+      if (tf) {
+        return smp.toString();
+      }
+    });
+    pcApp.selectedSamples = selectedSamples.map(function(d) {
+      return parseInt(d.SampleNumber);
+    });
+
+    updateParallelForeground();
+    updateSmpTable()
+    displayTableGrid();
+  }
+  // Display paths in light gray color, to use as reference
+  pcApp.background = svg.append("g")
+      .attr("class", "background")
+    .selectAll("path")
+      .data(pcApp.flowData)
+    .enter().append("path")
+      .attr("d", path);
+
+  // Add foreground lines for focus, color by population.
+  pcApp.foreground = svg.append("g")
+      .attr("class", "foreground")
+    .selectAll("path")
+      .data(pcApp.origData)
+    .enter().append("path")
+      .attr("d", function(d) {
+        var smp = d.SampleNumber;
+        return path(pcApp.flowData[smp]); })
+      .attr("stroke",function(d){
+        var smp = d.SampleNumber + 1;
+        return color_palette[0][smp][0];})
+      .attr("stroke-width", 1);
+
+  // Add a group element for each dimension.
+  var g = svg.selectAll(".dimension")
+      .data(dimensions)
+    .enter().append("g")
+      .attr("class", "dimension")
+      .attr("transform", function(d) { return "translate(" + x(d) + ")"; })
+      .call(d3.behavior.drag()
+        .origin(function(d) { return {x: x(d)}; })
+        .on("dragstart", function(d) {
+          dragging[d] = x(d);
+          pcApp.background.attr("visibility", "hidden");})
+        .on("drag", function(d) {
+          dragging[d] = Math.min(width, Math.max(0, d3.event.x));
+          pcApp.foreground.attr("d", path);
+          dimensions.sort(function(a, b) { return position(a) - position(b); });
+          x.domain(dimensions);
+          g.attr("transform", function(d) { return "translate(" + position(d) + ")"; }); })
+        .on("dragend", function(d) {
+          delete dragging[d];
+          transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")");
+          transition(pcApp.foreground).attr("d", path);
+          pcApp.background
+              .attr("d", path)
+            .transition()
+              .delay(500)
+              .duration(0)
+              .attr("visibility", null);
+        }));
+
+  // Add an axis and title.
+  g.append("g")
+      .attr("class", "axis")
+      .each(function(d) { d3.select(this).call(axis.scale(y[d])); });
+  g.append("g")
+      .attr("class", "xlabel")
+    .append("text")
+      .style("text-anchor", "middle")
+      .attr("y", -9)
+      .text(function(d) { return d; });
+
+  // Add and store a brush for each axis.
+  g.append("g")
+      .attr("class", "brush")
+      .each(function(d) { d3.select(this).call(y[d].brush = d3.svg.brush().y(y[d]).on("brush", brush)); })
+    .selectAll("rect")
+      .attr("x", -8)
+      .attr("width", 16);
+
+  // Control line opacity.
+  $('#PCline_opacity').on('change', (function() {
+    var val = $(this).val();
+    $('#plotDivPC .foreground path').css('stroke-opacity', val.toString());
+    $('#pc_opacity').html((Math.round(val*10000)/100) + "%");
+  }));
+};
+
+var updateParallelForeground = function() {
+  pcApp.foreground[0].map(function(d) {
+    var smp = parseInt(d['__data__']['SampleNumber'])
+    if ($.inArray(smp,pcApp.selectedSamples) < 0) {
+      d.style.display = "none";
+    } else {
+      d.style.display = null;
+    }
+  });
+};
+/*
+ * Retrieve the data, then call display functions
+*/
+var displayParallelCoordinates = function() {
+/*    var inputFile = "./csOverview.tsv";
+    d3.tsv(inputFile, function(error, data) {
+         if (error) {
+            alert("Problem Retrieving Data");
+            return;
+        }
+  */
+  pcApp.origData = $.extend(true,[], pctablecontent);
+  pcApp.headers = Object.keys(pcApp.origData[0]);
+  pcApp.headers.splice(pcApp.headers.indexOf("FileID"), 1);
+  pcApp.origData.forEach(function(d,idx){
+      d.SampleNumber = idx;
+//    delete d.FileID;
+  })
+  /*
+   * For the plot use only the proportion of each
+   * population per sample. Store in flowData
+  */
+  pcApp.flowData = $.extend(true,[],pctablecontent);
+  pcApp.flowData.forEach(function(d,idx){
+    delete d.SampleName;
+    delete d.FileID;
+    delete d.Comment;
+  });
+  for (var i = 0, j = pcApp.flowData.length; i < j ; i++) {
+    pcApp.allSamples.push(i);
+    pcApp.selectedSamples.push(i);
+  }
+  displaySmpTable();
+  displayTableGrid();
+  displayParallelPlot();
+
+  $("#resetPCDisplay").on("click",function() {
+    var opcty = ".8";
+    for (var i = 0, j = pcApp.flowData.length; i < j; i++) {
+      pcApp.allSamples.push(i);
+      pcApp.selectedSamples.push(i);
+    }
+    $("#smpSelectAllPC").prop('checked',true);
+    $(".smpSelectPC").prop("checked",true);
+
+    $('#plotDivPC .foreground path').css('stroke-opacity', opcty);
+    $('#pc_opacity').html("80%");
+    $('#PCline_opacity').val(0.8);
+
+    displaySmpTable();
+    displayTableGrid();
+    displayParallelPlot();
+  });
+
+  $(window).on('resize',function() {
+    waitForFinalEvent(function() {
+      displayAll();
+    }, 500, "resizePC");
+  });
+//    });
+};