Mercurial > repos > immport-devteam > cs_overview
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1:bca68066a957 | 2:a64ece32a01a |
|---|---|
| 1 // Copyright (c) 2016 Northrop Grumman. | |
| 2 // All rights reserved. | |
| 3 | |
| 4 /* | |
| 5 * Initialize variables for parallelCoordinates display | |
| 6 */ | |
| 7 var pcApp = pcApp || {}; | |
| 8 | |
| 9 pcApp.allSamples = []; | |
| 10 pcApp.selectedSamples = []; | |
| 11 pcApp.origData; | |
| 12 pcApp.flowData; | |
| 13 pcApp.updatedData; | |
| 14 pcApp.headers = []; | |
| 15 pcApp.foreground; | |
| 16 pcApp.background; | |
| 17 | |
| 18 var displayAll = function() { | |
| 19 displayParallelPlot(); | |
| 20 } | |
| 21 /* | |
| 22 * Display the Population Legend | |
| 23 */ | |
| 24 var displaySmpTable = function() { | |
| 25 $('#popTablePC tbody').empty(); | |
| 26 pcApp.origData.map(function(d) { | |
| 27 $('#popTablePC tbody').append('<tr><td align="center">' | |
| 28 + '<input type="checkbox" id="' + d.SampleName + '" ' | |
| 29 + 'checked class="popSelectPC" value=' | |
| 30 + d.SampleNumber + '/></td><td title="' + newSmpNames[d.SampleName] | |
| 31 + '">' + newSmpNames[d.SampleName] | |
| 32 + '</td><td><span style="background-color:' | |
| 33 + color_palette[0][d.SampleNumber + 1][0] | |
| 34 + '"> </span></td></tr>'); | |
| 35 }); | |
| 36 | |
| 37 $('#popSelectAllPC').click(function() { | |
| 38 var checkAll = $("#popSelectAllPC").prop('checked'); | |
| 39 if (checkAll) { | |
| 40 $(".popSelectPC").prop("checked", true); | |
| 41 } else { | |
| 42 $(".popSelectPC").prop("checked", false); | |
| 43 } | |
| 44 pcApp.selectedSamples = []; | |
| 45 $('.popSelectPC').each(function() { | |
| 46 if (this.checked) { | |
| 47 pcApp.selectedSamples.push(parseInt(this.value)); | |
| 48 } | |
| 49 }) | |
| 50 displayTableGrid(); | |
| 51 if (checkAll) { | |
| 52 displayParallelPlot(); | |
| 53 } else { | |
| 54 updateParallelForeground(); | |
| 55 } | |
| 56 }); | |
| 57 | |
| 58 $('.popSelectPC').click(function() { | |
| 59 if ($('.popSelectPC').length == $(".popSelectPC:checked").length) { | |
| 60 $('#popSelectAllPC').prop("checked",true); | |
| 61 } else { | |
| 62 $('#popSelectAllPC').prop("checked",false); | |
| 63 } | |
| 64 pcApp.selectedSamples = []; | |
| 65 $('.popSelectPC').each(function() { | |
| 66 if (this.checked) { | |
| 67 pcApp.selectedSamples.push(parseInt(this.value)); | |
| 68 } | |
| 69 }) | |
| 70 displayTableGrid(); | |
| 71 updateParallelForeground(); | |
| 72 }); | |
| 73 updateSmpTable(); | |
| 74 }; | |
| 75 | |
| 76 var updateSmpTable = function() { | |
| 77 $('.popSelectPC').each(function() { | |
| 78 var smp = parseInt(this.value); | |
| 79 if ($.inArray(smp,pcApp.selectedSamples) > -1) { | |
| 80 this.checked = true; | |
| 81 } else { | |
| 82 this.checked = false; | |
| 83 } | |
| 84 }) | |
| 85 } | |
| 86 | |
| 87 var displayTableGrid = function() { | |
| 88 var colTable = [], | |
| 89 colNames = [], | |
| 90 pctargets = [], | |
| 91 updatedHeaders = [], | |
| 92 displayData = [], | |
| 93 targetCol = 0, | |
| 94 textCol = [], | |
| 95 colOrder = [], | |
| 96 tableHTML = []; | |
| 97 | |
| 98 $("#tableDivPC").empty(); | |
| 99 pcApp.updatedData = $.extend(true,[],pctablecontent); | |
| 100 pcApp.updatedData.forEach(function(d, idx){ | |
| 101 d.SampleName = idx + 1; | |
| 102 delete(d.FileID); | |
| 103 }); | |
| 104 | |
| 105 updatedHeaders = Object.keys(pcApp.updatedData[0]); | |
| 106 displayData = pcApp.updatedData.filter(function(d,i) { | |
| 107 if ($.inArray(i,pcApp.selectedSamples) > -1) { | |
| 108 return d; | |
| 109 } | |
| 110 }); | |
| 111 | |
| 112 targetCol = updatedHeaders.length - 2; | |
| 113 updatedHeaders.forEach(function(d,i){ | |
| 114 colTable.push("<th>" + d + "</th>"); | |
| 115 colNames.push({"data":d}); | |
| 116 if (i < targetCol){ | |
| 117 pctargets.push(i); | |
| 118 } | |
| 119 }); | |
| 120 textCol = [targetCol, targetCol + 1]; | |
| 121 colOrder = textCol.concat(pctargets); | |
| 122 tableHTML = [ | |
| 123 '<table id="pcTable" class="pctable display compact nowrap" cellspacing="0" width="100%">', | |
| 124 '<thead>', | |
| 125 '<tr>', | |
| 126 colTable.join("\n"), | |
| 127 '</tr>', | |
| 128 '</thead>', | |
| 129 '</table>', | |
| 130 ]; | |
| 131 | |
| 132 $('#tableDivPC').html(tableHTML.join("\n")); | |
| 133 var pcTable = $('#pcTable').DataTable({ | |
| 134 columns: colNames, | |
| 135 data: displayData, | |
| 136 order: [[ targetCol, "asc" ]], | |
| 137 pageLength: 10, | |
| 138 //paging: false, | |
| 139 scrollY: 250, | |
| 140 scrollCollapse: true, | |
| 141 scrollX: true, | |
| 142 dom: '<"top"B>t<"bottom"lip><"clear">', | |
| 143 columnDefs: [{ | |
| 144 targets: pctargets, | |
| 145 className: "dt-body-right", | |
| 146 render: function(data,type,row){ | |
| 147 return parseFloat(data).toFixed(2) + '%'; | |
| 148 } | |
| 149 }, { | |
| 150 targets: [targetCol, targetCol+1], | |
| 151 className: "dt-body-center" | |
| 152 }, { | |
| 153 targets:[targetCol], | |
| 154 render: function(data, type, row){ | |
| 155 return 'Sample' + parseInt(data); | |
| 156 } | |
| 157 }], | |
| 158 buttons: [ | |
| 159 'copy', 'pdfHtml5','csvHtml5', 'colvis' | |
| 160 ], | |
| 161 colReorder: {order:colOrder}, | |
| 162 select: true | |
| 163 }); | |
| 164 | |
| 165 $('#pcTable').on('mouseover', 'tr', function() { | |
| 166 var data = pcTable.row(this).data(); | |
| 167 if (data != undefined) { | |
| 168 var smp = parseInt(data.SampleName) - 1; | |
| 169 pcApp.selectedSamples = [smp]; | |
| 170 updateParallelForeground(); | |
| 171 } | |
| 172 }); | |
| 173 $('#pcTable').on('mouseleave', 'tr', function() { | |
| 174 pcApp.selectedSamples = []; | |
| 175 $('.popSelectPC').each(function() { | |
| 176 if (this.checked) { | |
| 177 pcApp.selectedSamples.push(parseInt(this.value)); | |
| 178 } | |
| 179 updateParallelForeground(); | |
| 180 }) | |
| 181 }); | |
| 182 }; | |
| 183 /* | |
| 184 * Display The Main Plot | |
| 185 */ | |
| 186 var displayParallelPlot = function() { | |
| 187 var margin = {top: 30, right: 10, bottom: 10, left: 10}, | |
| 188 h = 300, | |
| 189 w = $("#plotDivPC").width(), | |
| 190 width = w - margin.left - margin.right, | |
| 191 height = h - margin.top - margin.bottom, | |
| 192 y = {}, | |
| 193 dragging = {}, | |
| 194 ymax = 0; | |
| 195 | |
| 196 $("#plotDivPC").empty(); | |
| 197 $("#plotDivPC").height(h); | |
| 198 var svg = d3.select("#plotDivPC").append("svg") | |
| 199 .attr("width", width + margin.left + margin.right) | |
| 200 .attr("height", height + margin.top + margin.bottom) | |
| 201 .append("g") | |
| 202 .attr("transform", "translate(" + margin.left + "," + margin.top + ")") | |
| 203 | |
| 204 var x = d3.scale.ordinal().rangePoints([0, width], 1); | |
| 205 var line = d3.svg.line(); | |
| 206 var axis = d3.svg.axis() | |
| 207 .orient("left") | |
| 208 .tickFormat(d3.format("d")) | |
| 209 .ticks(5); | |
| 210 | |
| 211 for (var m = 0, n = pcApp.flowData.length; m < n; m++){ | |
| 212 for (var p in pcApp.flowData[m]){ | |
| 213 if (+pcApp.flowData[m][p] > ymax){ | |
| 214 ymax = +pcApp.flowData[m][p]; | |
| 215 } | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 // Y axis label | |
| 220 svg.append("text") | |
| 221 .attr("class", "ylabel") | |
| 222 .attr("transform", "rotate(-90)") | |
| 223 .attr("y", 0 - margin.left) | |
| 224 .attr("x",0 - (height / 2)) | |
| 225 .attr("dy", "1em") | |
| 226 .style("text-anchor", "middle") | |
| 227 .text("Fraction of population in sample"); | |
| 228 | |
| 229 var dimensions = d3.keys(pcApp.flowData[0]).filter(function(d) { | |
| 230 return (y[d] = d3.scale.linear() | |
| 231 .domain([0,parseInt(ymax)+1]) | |
| 232 .range([height, 0])); | |
| 233 }); | |
| 234 x.domain(dimensions); | |
| 235 | |
| 236 function path(d) { | |
| 237 return line(dimensions.map(function(p) { return [x(p), y[p](d[p])]; })); | |
| 238 } | |
| 239 | |
| 240 function position(d) { | |
| 241 var v = dragging[d]; | |
| 242 return v == null ? x(d) : v; | |
| 243 } | |
| 244 | |
| 245 function transition(g) { | |
| 246 return g.transition().duration(500); | |
| 247 } | |
| 248 | |
| 249 function brush() { | |
| 250 var actives = dimensions.filter(function(p) { return !y[p].brush.empty(); }); | |
| 251 var extents = actives.map(function(p) { return y[p].brush.extent(); }); | |
| 252 var selectedSamples = pcApp.origData.filter(function(d) { | |
| 253 var smp = parseInt(d.SampleNumber); | |
| 254 var tf = actives.every(function(p,i) { | |
| 255 return extents[i][0] <= pcApp.flowData[smp][p] && | |
| 256 pcApp.flowData[smp][p] <= extents[i][1]; | |
| 257 }); | |
| 258 if (tf) { | |
| 259 return smp.toString(); | |
| 260 } | |
| 261 }); | |
| 262 pcApp.selectedSamples = selectedSamples.map(function(d) { | |
| 263 return parseInt(d.SampleNumber); | |
| 264 }); | |
| 265 | |
| 266 updateParallelForeground(); | |
| 267 updateSmpTable() | |
| 268 displayTableGrid(); | |
| 269 } | |
| 270 // Display paths in light gray color, to use as reference | |
| 271 pcApp.background = svg.append("g") | |
| 272 .attr("class", "background") | |
| 273 .selectAll("path") | |
| 274 .data(pcApp.flowData) | |
| 275 .enter().append("path") | |
| 276 .attr("d", path); | |
| 277 | |
| 278 // Add foreground lines for focus, color by population. | |
| 279 pcApp.foreground = svg.append("g") | |
| 280 .attr("class", "foreground") | |
| 281 .selectAll("path") | |
| 282 .data(pcApp.origData) | |
| 283 .enter().append("path") | |
| 284 .attr("d", function(d) { | |
| 285 var smp = d.SampleNumber; | |
| 286 return path(pcApp.flowData[smp]); }) | |
| 287 .attr("stroke",function(d){ | |
| 288 var smp = d.SampleNumber + 1; | |
| 289 return color_palette[0][smp][0];}) | |
| 290 .attr("stroke-width", 1); | |
| 291 | |
| 292 // Add a group element for each dimension. | |
| 293 var g = svg.selectAll(".dimension") | |
| 294 .data(dimensions) | |
| 295 .enter().append("g") | |
| 296 .attr("class", "dimension") | |
| 297 .attr("transform", function(d) { return "translate(" + x(d) + ")"; }) | |
| 298 .call(d3.behavior.drag() | |
| 299 .origin(function(d) { return {x: x(d)}; }) | |
| 300 .on("dragstart", function(d) { | |
| 301 dragging[d] = x(d); | |
| 302 pcApp.background.attr("visibility", "hidden");}) | |
| 303 .on("drag", function(d) { | |
| 304 dragging[d] = Math.min(width, Math.max(0, d3.event.x)); | |
| 305 pcApp.foreground.attr("d", path); | |
| 306 dimensions.sort(function(a, b) { return position(a) - position(b); }); | |
| 307 x.domain(dimensions); | |
| 308 g.attr("transform", function(d) { return "translate(" + position(d) + ")"; }); }) | |
| 309 .on("dragend", function(d) { | |
| 310 delete dragging[d]; | |
| 311 transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")"); | |
| 312 transition(pcApp.foreground).attr("d", path); | |
| 313 pcApp.background | |
| 314 .attr("d", path) | |
| 315 .transition() | |
| 316 .delay(500) | |
| 317 .duration(0) | |
| 318 .attr("visibility", null); | |
| 319 })); | |
| 320 | |
| 321 // Add an axis and title. | |
| 322 g.append("g") | |
| 323 .attr("class", "axis") | |
| 324 .each(function(d) { d3.select(this).call(axis.scale(y[d])); }); | |
| 325 g.append("g") | |
| 326 .attr("class", "xlabel") | |
| 327 .append("text") | |
| 328 .style("text-anchor", "middle") | |
| 329 .attr("y", -9) | |
| 330 .text(function(d) { return d; }); | |
| 331 | |
| 332 // Add and store a brush for each axis. | |
| 333 g.append("g") | |
| 334 .attr("class", "brush") | |
| 335 .each(function(d) { d3.select(this).call(y[d].brush = d3.svg.brush().y(y[d]).on("brush", brush)); }) | |
| 336 .selectAll("rect") | |
| 337 .attr("x", -8) | |
| 338 .attr("width", 16); | |
| 339 | |
| 340 // Control line opacity. | |
| 341 $('#PCline_opacity').on('change', (function() { | |
| 342 var val = $(this).val(); | |
| 343 $('#plotDivPC .foreground path').css('stroke-opacity', val.toString()); | |
| 344 $('#pc_opacity').html((Math.round(val*10000)/100) + "%"); | |
| 345 })); | |
| 346 }; | |
| 347 | |
| 348 var updateParallelForeground = function() { | |
| 349 pcApp.foreground[0].map(function(d) { | |
| 350 var smp = parseInt(d['__data__']['SampleNumber']) | |
| 351 if ($.inArray(smp,pcApp.selectedSamples) < 0) { | |
| 352 d.style.display = "none"; | |
| 353 } else { | |
| 354 d.style.display = null; | |
| 355 } | |
| 356 }); | |
| 357 }; | |
| 358 /* | |
| 359 * Retrieve the data, then call display functions | |
| 360 */ | |
| 361 var displayParallelCoordinates = function() { | |
| 362 /* var inputFile = "./csOverview.tsv"; | |
| 363 d3.tsv(inputFile, function(error, data) { | |
| 364 if (error) { | |
| 365 alert("Problem Retrieving Data"); | |
| 366 return; | |
| 367 } | |
| 368 */ | |
| 369 pcApp.origData = $.extend(true,[], pctablecontent); | |
| 370 pcApp.headers = Object.keys(pcApp.origData[0]); | |
| 371 pcApp.headers.splice(pcApp.headers.indexOf("FileID"), 1); | |
| 372 pcApp.origData.forEach(function(d,idx){ | |
| 373 d.SampleNumber = idx; | |
| 374 // delete d.FileID; | |
| 375 }) | |
| 376 /* | |
| 377 * For the plot use only the proportion of each | |
| 378 * population per sample. Store in flowData | |
| 379 */ | |
| 380 pcApp.flowData = $.extend(true,[],pctablecontent); | |
| 381 pcApp.flowData.forEach(function(d,idx){ | |
| 382 delete d.SampleName; | |
| 383 delete d.FileID; | |
| 384 delete d.Comment; | |
| 385 }); | |
| 386 for (var i = 0, j = pcApp.flowData.length; i < j ; i++) { | |
| 387 pcApp.allSamples.push(i); | |
| 388 pcApp.selectedSamples.push(i); | |
| 389 } | |
| 390 displaySmpTable(); | |
| 391 displayTableGrid(); | |
| 392 displayParallelPlot(); | |
| 393 | |
| 394 $("#resetPCDisplay").on("click",function() { | |
| 395 var opcty = ".8"; | |
| 396 for (var i = 0, j = pcApp.flowData.length; i < j; i++) { | |
| 397 pcApp.allSamples.push(i); | |
| 398 pcApp.selectedSamples.push(i); | |
| 399 } | |
| 400 $("#smpSelectAllPC").prop('checked',true); | |
| 401 $(".smpSelectPC").prop("checked",true); | |
| 402 | |
| 403 $('#plotDivPC .foreground path').css('stroke-opacity', opcty); | |
| 404 $('#pc_opacity').html("80%"); | |
| 405 $('#PCline_opacity').val(0.8); | |
| 406 | |
| 407 displaySmpTable(); | |
| 408 displayTableGrid(); | |
| 409 displayParallelPlot(); | |
| 410 }); | |
| 411 | |
| 412 $(window).on('resize',function() { | |
| 413 waitForFinalEvent(function() { | |
| 414 displayAll(); | |
| 415 }, 500, "resizePC"); | |
| 416 }); | |
| 417 // }); | |
| 418 }; |
