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 + '">&nbsp;&nbsp;&nbsp;</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 };