From 97ba036e005018e3ee8fdecb203d135cd4fd9c21 Mon Sep 17 00:00:00 2001 From: Eric Weitz Date: Mon, 7 Apr 2025 08:54:59 -0400 Subject: [PATCH 1/4] Add pathway options for description, tooltips --- src/js/ideogram.js | 13 ++++++++++--- src/js/kit/pathway-viewer.js | 30 ++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/js/ideogram.js b/src/js/ideogram.js index 2afc1368..65bf41b9 100644 --- a/src/js/ideogram.js +++ b/src/js/ideogram.js @@ -359,7 +359,10 @@ export default class Ideogram { * @param {String} outerSelector DOM selector of container, e.g. "#my-diagram" * @param {Object} dimensions Height and width of pathway diagram * @param {Boolean} showClose Whether to show close button - * @param {Function} geneNodeHoverFn Function to call upon hovering diagram node + * @param {Function} geneNodeHoverFn Function to call upon hovering gene + * @param {Function} pathwayNodeClickFn Function to call upon clicking pathway + * @param {Boolean} showDescription Whether to display pathway description + * @param {Boolean} showDefaultTooltips Whether to display default tooltips */ static drawPathway( pwId, sourceGene, destGene, @@ -367,7 +370,9 @@ export default class Ideogram { dimensions={height: 440, width: 900}, showClose=true, geneNodeHoverFn=undefined, - pathwayNodeClickFn=undefined + pathwayNodeClickFn=undefined, + showDescription=true, + showDefaultTooltips=true ) { _drawPathway( pwId, sourceGene, destGene, @@ -375,7 +380,9 @@ export default class Ideogram { dimensions=dimensions, showClose=showClose, geneNodeHoverFn=geneNodeHoverFn, - pathwayNodeClickFn=pathwayNodeClickFn + pathwayNodeClickFn=pathwayNodeClickFn, + showDescription=showDescription, + showDefaultTooltips=showDefaultTooltips ); } diff --git a/src/js/kit/pathway-viewer.js b/src/js/kit/pathway-viewer.js index 37f72731..f9afdc30 100644 --- a/src/js/kit/pathway-viewer.js +++ b/src/js/kit/pathway-viewer.js @@ -302,6 +302,8 @@ export async function drawPathway( showClose=true, geneNodeHoverFn, pathwayNodeClickFn, + showDescription, + showDefaultTooltips, retryAttempt=0 ) { const pvjsScript = document.querySelector(`script[src="${PVJS_URL}"]`); @@ -324,6 +326,7 @@ export async function drawPathway( pwId, sourceGene, destGene, outerSelector, dimensions, showClose, geneNodeHoverFn, pathwayNodeClickFn, + showDescription, retryAttempt++ ); }, 250); @@ -390,7 +393,9 @@ export async function drawPathway( const pathwayViewer = new Pvjs(pvjsContainer, pvjsProps); addHeader(pwId, pathwayJson, pathwayContainer, showClose); - addFooter(pathwayJson, pathwayContainer); + if (showDescription) { + addFooter(pathwayJson, pathwayContainer); + } // zoomToEntity(sourceEntityId); @@ -414,10 +419,15 @@ export async function drawPathway( } }); - geneNode.setAttribute(`data-tippy-content`, tooltipContent); + if (showDefaultTooltips) { + geneNode.setAttribute(`data-tippy-content`, tooltipContent); + } }); - const tippyConfig = getTippyConfig(); - tippy('g.GeneProduct[data-tippy-content]', tippyConfig); + if (showDefaultTooltips) { + const tippyConfig = getTippyConfig(); + tippyConfig.trigger = 'mouseenter'; + tippy('g.GeneProduct[data-tippy-content]', tippyConfig); + } // Add click handler to pathway nodes in this pathway diagram if (pathwayNodeClickFn) { @@ -433,11 +443,15 @@ export async function drawPathway( pathwayNodeClickFn(event, pathwayId); }); - // Indicate this new pathway can be rendered on click - const tooltipContent = 'Click to show pathway'; - pathwayNode.setAttribute('data-tippy-content', tooltipContent); + if (showDefaultTooltips) { + // Indicate this new pathway can be rendered on click + const tooltipContent = 'Click to show pathway'; + pathwayNode.setAttribute('data-tippy-content', tooltipContent); + } }); - tippy('g.Pathway[data-tippy-content]', tippyConfig); + if (showDefaultTooltips) { + tippy('g.Pathway[data-tippy-content]', tippyConfig); + } } } From 8d4383ae6a8de3c4626295d8cd04f22634bdcc78 Mon Sep 17 00:00:00 2001 From: Eric Weitz Date: Tue, 8 Apr 2025 07:59:58 -0400 Subject: [PATCH 2/4] Demonstrate how to use onWillShowAnnotTooltip --- examples/vanilla/gene-leads.html | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/vanilla/gene-leads.html b/examples/vanilla/gene-leads.html index 0e74d9a9..f9828142 100644 --- a/examples/vanilla/gene-leads.html +++ b/examples/vanilla/gene-leads.html @@ -207,6 +207,13 @@

Gene LeadsEnrich your gene search

} } + async function onWillShowAnnotTooltip(annot) { + if (annot.then) { + return await annot + } + return annot + } + /** Ideogram has no 3rd party analytics, but lets you easily hook in your own */ function reportFoundGenes() { console.log(this.relatedGenesAnalytics) @@ -246,7 +253,8 @@

Gene LeadsEnrich your gene search

onLoad: plotGeneFromUrl, onPlotFoundGenes: reportFoundGenes, onHoverLegend: reportLegendMetrics, - onClickAnnot + onClickAnnot, + onWillShowAnnotTooltip } const annotsInList = 'all'; From fda957b85544a50eb3631fdf8c7b8b14a6f1af36 Mon Sep 17 00:00:00 2001 From: Eric Weitz Date: Tue, 8 Apr 2025 08:50:49 -0400 Subject: [PATCH 3/4] Improve pathway ontology configurability --- src/js/ideogram.js | 10 +++++++++- src/js/kit/pathway-viewer.js | 21 +++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/js/ideogram.js b/src/js/ideogram.js index 65bf41b9..50db97ad 100644 --- a/src/js/ideogram.js +++ b/src/js/ideogram.js @@ -70,7 +70,8 @@ import { import { drawPathway as _drawPathway, - getPathwayGenes as _getPathwayGenes + getPathwayGenes as _getPathwayGenes, + getPathwayAnnotations } from './kit/pathway-viewer.js'; import { @@ -362,6 +363,7 @@ export default class Ideogram { * @param {Function} geneNodeHoverFn Function to call upon hovering gene * @param {Function} pathwayNodeClickFn Function to call upon clicking pathway * @param {Boolean} showDescription Whether to display pathway description + * @param {Boolean} showOntologies Whether to display ontology annotations * @param {Boolean} showDefaultTooltips Whether to display default tooltips */ static drawPathway( @@ -372,6 +374,7 @@ export default class Ideogram { geneNodeHoverFn=undefined, pathwayNodeClickFn=undefined, showDescription=true, + showOntologies=true, showDefaultTooltips=true ) { _drawPathway( @@ -382,6 +385,7 @@ export default class Ideogram { geneNodeHoverFn=geneNodeHoverFn, pathwayNodeClickFn=pathwayNodeClickFn, showDescription=showDescription, + showOntologies=showOntologies, showDefaultTooltips=showDefaultTooltips ); } @@ -407,4 +411,8 @@ export default class Ideogram { static getPathwayGenes() { return _getPathwayGenes(); } + + static getPathwayOntologies(pathwayJson, selectedOntology) { + return getPathwayAnnotations(pathwayJson, selectedOntology); + } } diff --git a/src/js/kit/pathway-viewer.js b/src/js/kit/pathway-viewer.js index f9afdc30..bea496f7 100644 --- a/src/js/kit/pathway-viewer.js +++ b/src/js/kit/pathway-viewer.js @@ -227,7 +227,7 @@ function parsePwAnnotations(entitiesById, keys, ontology) { return pwAnnotations; } -function getPathwayAnnotations(pathwayJson) { +export function getPathwayAnnotations(pathwayJson, selectedOntology) { const entitiesById = pathwayJson.entitiesById; const keys = Object.keys(entitiesById).filter(k => k.startsWith('http://identifiers.org')); const sentenceCases = { @@ -238,12 +238,19 @@ function getPathwayAnnotations(pathwayJson) { 'Disease' // 'Pathway Ontology' // maybe later ]; - const pathwayAnnotationsList = ontologies.map(ontology => { + let selectedOntologies = ontologies; + if (selectedOntology) { + selectedOntologies = ontologies.find( + ontology => ontology.toLowerCase() === selectedOntology.toLowerCase() + ); + } + const pathwayAnnotationsList = selectedOntologies.map(ontology => { const pwAnnotations = parsePwAnnotations(entitiesById, keys, ontology); const links = pwAnnotations.map(pwa => { const id = pwa.xrefIdentifier.replace(':', '_'); const url = `https://purl.obolibrary.org/obo/${id}`; - return `${pwa.term}`; + const cls = 'class="_ideoPathwayOntologyLink"'; + return `${pwa.term}`; }).join(', '); const refinedOntology = sentenceCases[ontology] ?? ontology; @@ -281,9 +288,10 @@ export function getPathwayGenes() { } -function addFooter(pathwayJson, pathwayContainer) { +function addFooter(pathwayJson, pathwayContainer, showOntologies) { const description = getDescription(pathwayJson); - const pathwayAnnotations = getPathwayAnnotations(pathwayJson); + const pathwayAnnotations = + showOntologies ? getPathwayAnnotations(pathwayJson) : ''; const footer = `
` + `
` + @@ -303,6 +311,7 @@ export async function drawPathway( geneNodeHoverFn, pathwayNodeClickFn, showDescription, + showOntologies, showDefaultTooltips, retryAttempt=0 ) { @@ -394,7 +403,7 @@ export async function drawPathway( addHeader(pwId, pathwayJson, pathwayContainer, showClose); if (showDescription) { - addFooter(pathwayJson, pathwayContainer); + addFooter(pathwayJson, pathwayContainer, showOntologies); } // zoomToEntity(sourceEntityId); From a469f9e8640f2666629647ca77457b2a5dc0facc Mon Sep 17 00:00:00 2001 From: Eric Weitz Date: Tue, 8 Apr 2025 08:52:52 -0400 Subject: [PATCH 4/4] Fix find for selectedOntologies --- src/js/kit/pathway-viewer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/kit/pathway-viewer.js b/src/js/kit/pathway-viewer.js index bea496f7..d0240e8c 100644 --- a/src/js/kit/pathway-viewer.js +++ b/src/js/kit/pathway-viewer.js @@ -240,9 +240,9 @@ export function getPathwayAnnotations(pathwayJson, selectedOntology) { ]; let selectedOntologies = ontologies; if (selectedOntology) { - selectedOntologies = ontologies.find( + selectedOntologies = [ontologies.find( ontology => ontology.toLowerCase() === selectedOntology.toLowerCase() - ); + )]; } const pathwayAnnotationsList = selectedOntologies.map(ontology => { const pwAnnotations = parsePwAnnotations(entitiesById, keys, ontology);