/* globals d3, OpenSeadragon, intLegend, intPlot, geneFilters */ var OsViewer; // eslint-disable-next-line no-unused-vars function interactionPlot(id, settings, data) { if (typeof settings.nodeSize === 'undefined') { settings.nodeSize = 20; } if (typeof settings.width === 'undefined') { settings.width = 940; } if (typeof settings.height === 'undefined') { settings.height = 650; } if (typeof settings.showLabels === 'undefined') { settings.showLabels = true; } if (typeof settings.passive === 'undefined') { settings.passive = false; } var plot = {}; plot.svg = d3.select('#' + id) .append('svg') .attr('width', settings.width) .attr('height', settings.height); plot.link = plot.svg .append('g') .attr('class', 'link'); plot.node = plot.svg .append('g') .attr('class', 'nodecontainer'+ (settings.passive?' passive':'')); plot.addData = function(inData, idx) { if (!inData || !inData.nodes) { return; } var p = this; var nodes = p.node.selectAll('g') .data(inData.nodes, function(d) { return d.id; }) .enter() .append('g') .attr('transform', function (d) { return 'translate(' + d.x + ',' + d.y + ')'; }) .attr('cx', function (d) { return d.x; }) .attr('cy', function (d) { return d.y; }) .attr('id', function (d) { return d.id; }) .attr('class', function (d) { return d.class + ' ' + idx; }); if (!settings.passive) { nodes.call(d3.drag().on('drag', function () { nudge(p, d3.select(this), d3.event); })); } p.links = p.link.selectAll('line') .data(inData.links, function(d) { return d.class; }) .enter() .append('line') .attr('x1', function (d) { return p.node.select('#'+d.source).attr('cx'); }) .attr('y1', function (d) { return p.node.select('#'+d.source).attr('cy'); }) .attr('x2', function (d) { return p.node.select('#'+d.target).attr('cx'); }) .attr('y2', function (d) { return p.node.select('#'+d.target).attr('cy'); }) .attr('title', function (d) { return d.title; }) .attr('class', function (d) { return d.class + ' ' + idx; }); var anchor = nodes.append('a') .attr('xlink:href', function (d) { return d.url; }) .attr('title', function (d) { return d.title; }) .on('mouseover', function(d) { d3.selectAll('.'+d.id) .classed('highlight', true); }).on('mouseout', function() { d3.selectAll('g.link line').classed('highlight', false); }); anchor.append('circle') .attr('r', settings.nodeSize); if (settings.showLabels) { anchor.append('text') .each(function (d) { var arr = d.name.split(' '); if (arr !== undefined) { for (var i = 0; i < arr.length; i++) { d3.select(this).append('tspan') .text(arr[i]) .attr('dy', 0.35.toPrecision(3) + 'em') .attr('x', '-0.5'); } } }); } }; plot.removeData = function(idx) { var p = this; p.svg.selectAll('.'+idx).remove(); }; if (typeof data !== 'undefined') { plot.addData(data, 'idx1'); } return plot; } // eslint-disable-next-line no-unused-vars function interactionPlotLegend(id, nodeSize, width, height) { if (typeof nodeSize === 'undefined') { nodeSize = 8; } if (typeof width === 'undefined') { width = 200; } if (typeof height === 'undefined') { height = 220; } var legend = {}; legend.svg = d3.select('#' + id) .append('svg') .attr('width', width) .attr('height', height); var links = [ {name: 'Matching filter', type: 'circle', class: 'filterMatch'}, /*{name: 'IntAct BioGrid OpenCell', type: 'line', class: 'int_intact_biogrid_opencell'}, {name: 'IntAct BioGrid', type: 'line', class: 'int_intact_biogrid'}, {name: 'IntAct OpenCell', type: 'line', class: 'int_intact_opencell'}, {name: 'BioGrid OpenCell', type: 'line', class: 'int_biogrid_opencell'},*/ {name: '4 datasets', type: 'line', class: 'int_count_4'}, {name: '3 datasets', type: 'line', class: 'int_count_3'}, {name: '2 datasets', type: 'line', class: 'int_count_2'}, {name: '1 dataset', type: 'line', class: 'int_count_1'}, ]; legend.general = legend.svg .append('g') .attr('class', 'general') .attr('transform', 'translate(4, '+(height-(links.length)*2*nodeSize)+')'); legend.highlight = legend.svg .append('g') .attr('class', 'highlight') .attr('transform', 'translate(4, 0)'); legend.updateLegend = function(data, lgnd) { lgnd.selectAll('g.lgndItem').remove(); var lgndItem = lgnd.selectAll('g') .data(data) .enter() .append('g') .attr('class', 'lgndItem') .attr('transform', function (d, i) { return 'translate(0, '+((i)*nodeSize*2+10)+')'; }); lgndItem.each(function(d) { d3.select(this) .append('text') .attr('dy', 0.5 + 'em') .attr('x', nodeSize*2 + 4) .text(d.name) .call(D3wrap, width-10); if (d.type === 'line') { d3.select(this) .append('line') .attr('x1', 0) .attr('y1', 2) .attr('x2', nodeSize*2) .attr('y2', 2) .attr('title', function (dThis) { return dThis.name; }) .attr('class', function (dThis) { return dThis.class; }); } else if (d.type === 'circle') { d3.select(this).append('circle') .attr('r', nodeSize) .attr('cx', nodeSize) .attr('title', function (dThis) { return dThis.name; }) .attr('class', function (dThis) { return dThis.class??null; }) .style('fill', function (dThis) { return dThis.fill??null; }) .style('stroke', function (dThis) { return dThis.stroke??null; }); } }); }; legend.updateLegend(links, legend.general); return legend; } function nudge(plot, el, ev) { el .attr('transform', function(d) { d.x = parseFloat(d.x) + Math.round(ev.dx, 0); d.y = parseFloat(d.y) + Math.round(ev.dy, 0); return 'translate(' + d.x + ',' + d.y + ')'; }) .attr('cx', function(d) { return parseFloat(d.x) + Math.round(ev.dx, 0); }) .attr('cy', function(d) { return parseFloat(d.y) + Math.round(ev.dy, 0); }); plot.svg.selectAll('g.link line').each(function(d) { if (d.source === el.attr('id')) { d3.select(this) .attr('x1', el.attr('cx')) .attr('y1', el.attr('cy')); } if (d.target === el.attr('id')) { d3.select(this) .attr('x2', el.attr('cx')) .attr('y2', el.attr('cy')); } }); if (d3.event.preventDefault) { d3.event.preventDefault(); } else { d3.event.returnValue = false; } $(el.node()).closest('.cytoscapeplot_interaction').trigger('change'); } function filterInteractionGenes() { $('.cytoscapeplot_interaction circle').removeClass('filterMatch'); $.each(geneFilters.genes, function(i, gene) { $('.cytoscapeplot_interaction #int'+gene+' circle').addClass('filterMatch'); }); } function highlightInteractionGenes(id, highlight) { var $el = $('#'+id).closest('.cytoscapeplot_interaction'); if (!highlight) highlight = $el.closest('.interactionWrapper').find('.slideToggle').find('.active').attr('id'); if (highlight == 'highlight_off') { clearInteractionHighlight(id); return; } var ensgs = []; $el.find('.nodecontainer g').each(function() { ensgs.push(this.id.replace('int', '')); }); $.getJSON({ url: '/interaction/interaction_ajax.php', data: { highlight: highlight, gene: $el.find('.nodecontainer g.centerGene').attr('id').replace('int', ''), ensgs: ensgs.join(','), } }).done(function (data) { clearInteractionHighlight(id); $.each(data.genes, function(gene, fill) { $el.find('#int'+gene+' circle').css('fill', fill); }); filterInteractionGenes(); var l = $el.data('intLegend'); if (l) l.updateLegend(data.lgnd, l.highlight); }); } function clearInteractionHighlight(id) { var $el = $('#'+id).closest('.cytoscapeplot_interaction'); $el.find('.nodecontainer g circle').css('fill', ''); var l = $el.data('intLegend'); if (l) l.updateLegend([], l.highlight); } function attemptInteractionFullscreen() { const element = $(this).closest('.interactionWrapper')[0]; if (!document.fullscreenElement) { element.dataset.originalWidth = element.clientWidth.toString(); element.dataset.originalHeight = element.clientHeight.toString(); } if (element.requestFullscreen) { element.requestFullscreen(); } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(); } else if (element.msRequestFullscreen) { element.msRequestFullscreen(); } else { throw new Error('Cannot open fullscreen'); } } $(function() { $('#filterGenes').on('change', filterInteractionGenes); $('.slideToggle').on('toggle', function() {$(this).closest('.interactionWrapper').find('.cytoscapeplot_interaction').trigger('highlightGenes');}); $('.interactionFullscreen').on('click', attemptInteractionFullscreen); $('.interactionReset').on('click', function() {$(this).closest('.interactionWrapper').find('.cytoscapeplot_interaction').trigger('reset');}); $('.cytoscapeplot_interaction').on('change', function() { $(this).closest('.interactionWrapper').find('.interactionReset').show(); }); $('.cytoscapeplot_interaction').on('click', 'a', function (evt, force) { if (evt.ctrlKey) { return true; } if ($(this).closest('.nodecontainer').hasClass('passive')) { return true; } var $g = $(this).closest('g'); if (!force && $g.hasClass('centerGene')) { return false; } if ($g.attr('id')) { var el = $(this).closest('.cytoscapeplot_interaction'); var p = el.data('intPlot'); if (!$g.attr('idx')) { $.getJSON({ url: '/interaction/interaction_ajax.php', data: { ensg_id: $g.attr('id').replace('int', ''), assay_id: $g.closest('.cytoscapeplot_interaction').attr('id').replace('intPlot', ''), cx: $g.attr('cx'), cy: $g.attr('cy'), } }).done(function (data) { var idx = 'idx'+Math.floor(Math.random() * 26) + Date.now(); $g.addClass('expanded').attr('idx', idx); var fromIdx = $g.attr('class').match(/idx\d+/g); if (fromIdx) { idx += ' '+fromIdx.join(' '); } p.addData(data, idx); filterInteractionGenes(); el.trigger('highlightGenes'); $g.closest('.cytoscapeplot_interaction').trigger('change'); }); } else { p.removeData($g.attr('idx')); $g.attr('idx', null); } } return false; }); $('.cytoscapeplot_interaction').on('highlightGenes', function(evt, highlight) { highlightInteractionGenes(evt.target.id, highlight); }); $('.cytoscapeplot_interaction').on('clearHighlight', function(evt) { clearInteractionHighlight(evt.target.id); }); $('.cytoscapeplot_interaction').on('reset', function() { var $g = $(this).find('.centerGene'); if (!$g.attr('idx')) { $g.attr('idx', 'idx1'); } $g.removeClass('idx1').find('a').trigger('click', true).trigger('click', true); }); // METABOLIC DETAILS $('#metabolic_detail').each(function() { var $table = $(this); if (!$(this).find('#pathwaySeadragon').length) return; // Seadragon OsViewer = OpenSeadragon({ id: "pathwaySeadragon", prefixUrl: "/images_static/", preserveViewport: true, showHomeControl: false, mouseNavEnabled: true, showZoomControl: true, showFullPageControl: true, gestureSettingsMouse: { dblClickToZoom: true, clickToZoom: false }, }); $.get($(this).find('#pathwaySeadragon').attr('src'), function(svg) { var $svg = $(svg); var ensg_id = $table.attr('ensg_id'); $svg.find('g.subsystem text').remove(); // Load seadragon var org_w = 1*$svg.attr('width'); var org_h = 1*$svg.attr('height'); var tSize = 1000; OsViewer.open({ width: org_w, tileSource: { height: org_h, width: org_w, tileSize: tSize, getTileUrl: function() { return '/images_static/pixel.php?w='+tSize+'&h='+tSize; } } }); // Add SVG overlays var overlay = OsViewer.svgOverlay(); $svg.children().each(function() { overlay.node().appendChild(this); }); // Add pointers for toobox buttons & gene labels $("div[title='Zoom in']").css({'cursor': 'pointer'}); $("div[title='Zoom out']").css({'cursor': 'pointer'}); $("div[title='Toggle full page']").css({'cursor': 'pointer'}); $('g.enz').css({'cursor': 'pointer'}); // Navigate to gene page on gene label click $('g.enz').click(function() { window.location.href = '/'+$(this).attr('class').match(/ENSG\d+/)[0]+'/interaction'; }); // Highlight current $('g.'+ensg_id).addClass('pathwayCurrent'); // Zoom to links $('tr.enz .pathwayLinks a').on("click", function() { var this_ensg_id = $(this).closest('tr').attr('class').match(/ENSG\d+/)[0]; var $gs = $('g.'+this_ensg_id); var idx = $(this).parent().data('idx'); if (typeof idx === 'undefined') { idx = 0; } else { idx += $(this).hasClass('next')? 1 : -1; } if (idx < 0) { idx = $gs.length-1; } else if (idx > $gs.length-1) { idx = 0; } $(this).parent().data('idx', idx); var $g = $gs.eq(idx); var x = $g.offset().left - $g.closest('svg').offset().left; var y = $g.offset().top - $g.closest('svg').offset().top; OsViewer.viewport.panTo(OsViewer.viewport.viewerElementToViewportCoordinates(new OpenSeadragon.Point(x, y)), false); OsViewer.viewport.zoomTo(0.0007); return false; }); // Hover highlight $('tr.enz, g.enz').on("mouseover", function() { $('.'+$(this).attr('class').match(/ENSG\d+/)[0]).addClass('pathwayHighlight'); }).on("mouseout", function() { $('.'+$(this).attr('class').match(/ENSG\d+/)[0]).removeClass('pathwayHighlight'); }); $('tr.enz').find('td:gt(1)').on("mouseover", function() { $(this).closest('table').find('tbody tr td:nth-child('+($(this).index()+1)+')').addClass('pathwayHighlight'); }).on("mouseout", function() { $(this).closest('table').find('tbody tr td:nth-child('+($(this).index()+1)+')').removeClass('pathwayHighlight'); }); }, 'text'); }); });