dots-viewer: make pipeline dot references clickable for navigation

When GStreamer pipeline graphs contain references to other pipeline dot files,
users should be able to navigate between related pipeline views by clicking
on these references. This enables exploring complex pipeline hierarchies
where one pipeline references sub-pipelines.

The implementation detects text elements containing pipeline-dot references,
styles them as web links, and handles click events to navigate to the
referenced pipeline while preserving existing text selection and drag
functionality for other elements.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9547>
This commit is contained in:
Thibault Saunier 2025-08-05 11:38:05 -04:00 committed by GStreamer Marge Bot
parent 28684cba1a
commit 4d5fa1c43b

View File

@ -65,6 +65,10 @@ furnished to do so, subject to the following conditions:
graphDiv.addEventListener('mousedown', function(e) {
if (e.target.tagName === 'text' || e.target.tagName === 'tspan') {
if (e.target.textContent && e.target.textContent.startsWith("pipeline-dot=") && e.target.textContent.includes(".dot")) {
// Let the pipeline dot click handler take precedence
return;
}
e.stopPropagation();
// Allow normal text selection behavior
return true;
@ -73,14 +77,17 @@ furnished to do so, subject to the following conditions:
graphDiv.addEventListener('mouseover', function(e) {
if (e.target.tagName === 'text' || e.target.tagName === 'tspan') {
e.target.style.cursor = 'text';
if (!(e.target.textContent && e.target.textContent.startsWith("pipeline-dot=") && e.target.textContent.includes(".dot"))) {
e.target.style.cursor = 'text';
}
}
});
graphDiv.addEventListener('mouseout', function(e) {
if (e.target.tagName === 'text' || e.target.tagName === 'tspan') {
// Reset cursor when leaving text elements
e.target.style.cursor = '';
if (!(e.target.textContent && e.target.textContent.startsWith("pipeline-dot=") && e.target.textContent.includes(".dot"))) {
e.target.style.cursor = '';
}
}
});
}
@ -125,6 +132,53 @@ furnished to do so, subject to the following conditions:
document.body.removeChild(downloadLink);
URL.revokeObjectURL(url);
});
// Make pipeline dot references clickable for navigation between pipeline views
$("#graph svg .cluster").each(function() {
$(this).find("text, tspan").each(function() {
var element = this;
if (element.textContent && element.textContent.startsWith("pipeline-dot=") && element.textContent.includes(".dot")) {
// Extract the pipeline dot filename from the text
var pipelineDot = element.textContent;
if (pipelineDot.includes("pipeline-dot=\"")) {
pipelineDot = pipelineDot.replace(/pipeline-dot="([^"]+)"/, "$1");
} else {
pipelineDot = pipelineDot.replace(/pipeline-dot=([^\s]+)/, "$1");
}
// Style as a clickable link
$(element).css({
'text-decoration': 'underline',
'cursor': 'pointer',
'color': '#007acc'
});
// Add click handler for navigation
$(element).off('click.pipeline-nav').on('click.pipeline-nav', function(evt) {
evt.preventDefault();
evt.stopPropagation();
var newUrl = window.location.origin + "/?pipeline=" + encodeURIComponent(pipelineDot);
window.location.href = newUrl;
});
// Add hover effects
$(element).hover(
function() {
$(this).css({
'color': '#0056b3',
'cursor': 'pointer'
});
},
function() {
$(this).css({
'color': '#007acc',
'cursor': 'pointer'
});
}
);
}
});
});
}
});
});