-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add details panel for graph selection info #22
Merged
Merged
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
b0cec30
Replace the dot-based transition graph with webview cytoscape
jonlamb-gh 964c9d5
Update product icons
jonlamb-gh a47d1e8
Revise the node resource script
jonlamb-gh 9eb662c
Update graph classes
jonlamb-gh 05bf021
Add third-party licenses directory and function docs with attributions
jonlamb-gh 3585c57
Move the js into a function so we dont leak the vscode object
jonlamb-gh daef54b
Add graph context menu to log selected node timelines
jonlamb-gh ab6ebb3
Add details panel for graph selection info
jonlamb-gh 0c6dc55
Address review comments
jonlamb-gh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
(function () { | ||
const vscode = acquireVsCodeApi(); | ||
|
||
const eventsHeader = document.getElementById("eventsHeader"); | ||
const eventDetails = document.getElementById("eventDetails"); | ||
const timelinesHeader = document.getElementById("timelinesHeader"); | ||
const timelineDetails = document.getElementById("timelineDetails"); | ||
const interactionsHeader = document.getElementById("interactionsHeader"); | ||
const interactionDetails = document.getElementById("interactionDetails"); | ||
|
||
window.addEventListener("message", (event) => { | ||
const message = event.data; | ||
clearAll(); | ||
if (message.events !== undefined && message.events.length > 0) { | ||
constructEvents(message.events); | ||
} | ||
if (message.timelines !== undefined && message.timelines.length > 0) { | ||
constructTimelines(message.timelines); | ||
} | ||
if (message.interactions !== undefined && message.interactions.length > 0) { | ||
constructInteractions(message.interactions); | ||
} | ||
}); | ||
|
||
clearAll(); | ||
|
||
function clearAll() { | ||
clearEvents(); | ||
clearTimelines(); | ||
clearInteractions(); | ||
} | ||
|
||
function clearEvents() { | ||
eventsHeader.hidden = true; | ||
eventsHeader.innerHTML = ""; | ||
eventDetails.hidden = true; | ||
eventDetails.rowsData = []; | ||
} | ||
|
||
function constructEvents(events) { | ||
eventsHeader.innerHTML = "Events"; | ||
eventsHeader.hidden = false; | ||
|
||
eventDetails.columnDefinitions = [ | ||
{ columnDataKey: "Col0", title: "Event Name" }, | ||
{ columnDataKey: "Col1", title: "Timeline Name" }, | ||
{ columnDataKey: "Col2", title: "Timeline ID" }, | ||
{ columnDataKey: "Col3", title: "Count" }, | ||
]; | ||
eventDetails.rowsData = events.map((ev) => { | ||
return { Col0: ev.name, Col1: ev.timeline.name, Col2: ev.timeline.id, Col3: ev.count }; | ||
}); | ||
eventDetails.hidden = false; | ||
} | ||
|
||
function clearTimelines() { | ||
timelinesHeader.hidden = true; | ||
timelinesHeader.innerHTML = ""; | ||
timelineDetails.hidden = true; | ||
timelineDetails.rowsData = []; | ||
} | ||
|
||
function constructTimelines(timelines) { | ||
timelinesHeader.innerHTML = "Timelines"; | ||
timelinesHeader.hidden = false; | ||
|
||
timelineDetails.columnDefinitions = [ | ||
{ columnDataKey: "Col0", title: "Timeline Name" }, | ||
{ columnDataKey: "Col1", title: "Timeline ID" }, | ||
]; | ||
timelineDetails.rowsData = timelines.map((tl) => { | ||
return { Col0: tl.name, Col1: tl.id }; | ||
}); | ||
timelineDetails.hidden = false; | ||
} | ||
|
||
function clearInteractions() { | ||
interactionsHeader.hidden = true; | ||
interactionsHeader.innerHTML = ""; | ||
interactionDetails.hidden = true; | ||
interactionDetails.rowsData = []; | ||
} | ||
|
||
function constructInteractions(interactions) { | ||
interactionsHeader.innerHTML = "Interactions"; | ||
interactionsHeader.hidden = false; | ||
|
||
const containsEvents = interactions.some( | ||
(it) => it.sourceEvent !== undefined || it.destinationEvent !== undefined | ||
); | ||
|
||
interactionDetails.columnDefinitions = []; | ||
if (containsEvents) { | ||
interactionDetails.columnDefinitions.push({ columnDataKey: "Col0", title: "Source Event Name" }); | ||
} | ||
interactionDetails.columnDefinitions.push( | ||
{ columnDataKey: "Col1", title: "Source Timeline Name" }, | ||
{ columnDataKey: "Col2", title: "Source Timeline ID" } | ||
); | ||
if (containsEvents) { | ||
interactionDetails.columnDefinitions.push({ columnDataKey: "Col3", title: "Destination Event Name" }); | ||
} | ||
interactionDetails.columnDefinitions.push( | ||
{ columnDataKey: "Col4", title: "Destination Timeline Name" }, | ||
{ columnDataKey: "Col5", title: "Destination Timeline ID" }, | ||
{ columnDataKey: "Col6", title: "Count" } | ||
); | ||
interactionDetails.rowsData = interactions.map((it) => { | ||
if (containsEvents) { | ||
return { | ||
Col0: it.sourceEvent, | ||
Col1: it.sourceTimeline.name, | ||
Col2: it.sourceTimeline.id, | ||
Col3: it.destinationEvent, | ||
Col4: it.destinationTimeline.name, | ||
Col5: it.destinationTimeline.id, | ||
Col6: it.count, | ||
}; | ||
} else { | ||
return { | ||
Col1: it.sourceTimeline.name, | ||
Col2: it.sourceTimeline.id, | ||
Col4: it.destinationTimeline.name, | ||
Col5: it.destinationTimeline.id, | ||
Col6: it.count, | ||
}; | ||
} | ||
}); | ||
interactionDetails.hidden = false; | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,6 +140,21 @@ | |
} | ||
} | ||
|
||
function postShowSelectionDetails() { | ||
const selectedNodes = cy | ||
.nodes() | ||
.filter((n) => n.hasClass("selected")) | ||
.map((n) => n.id()); | ||
const selectedEdges = cy | ||
.edges() | ||
.filter((e) => e.hasClass("selected")) | ||
.map((e) => e.data("idx")); | ||
vscode.postMessage({ | ||
command: "showDetailsForSelection", | ||
data: { nodes: selectedNodes, edges: selectedEdges }, | ||
}); | ||
} | ||
|
||
function constructGraph() { | ||
if (nodeElements.length == 0 && edgeElements.length == 0) { | ||
// Do nothing until we've gotten data from the vscode | ||
|
@@ -306,6 +321,7 @@ | |
item.addClass("selected").predecessors().addClass("selected"); | ||
break; | ||
} | ||
postShowSelectionDetails(); | ||
}); | ||
cy.on("unselect", function (evt) { | ||
let item = evt.target; | ||
|
@@ -319,6 +335,7 @@ | |
cy.elements().removeClass("selected"); | ||
break; | ||
} | ||
postShowSelectionDetails(); | ||
}); | ||
cy.on("cxttap", function (evt) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const numSelectedNodes = cy | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import * as vscode from "vscode"; | ||
import * as fs from "fs"; | ||
import * as handlebars from "handlebars"; | ||
import * as api from "./modalityApi"; | ||
import { getNonce } from "./webviewUtil"; | ||
|
||
// N.B. to clear the details panel, provide an empty object or empty arrays | ||
export interface ShowDetailsParams { | ||
events?: EventDetails[]; | ||
timelines?: TimelineDetails[]; | ||
interactions?: InteractionDetails[]; | ||
} | ||
|
||
export interface InteractionDetails { | ||
sourceEvent?: string; | ||
sourceTimeline: TimelineDetails; | ||
destinationEvent?: string; | ||
destinationTimeline: TimelineDetails; | ||
count?: number; | ||
} | ||
|
||
export interface TimelineDetails { | ||
id: string; | ||
name?: string; | ||
} | ||
|
||
export interface EventDetails { | ||
name: string; | ||
timeline: TimelineDetails; | ||
count?: number; | ||
} | ||
|
||
export class DetailsPanelProvider implements vscode.WebviewViewProvider { | ||
public static readonly viewType = "auxon.details.panelView"; | ||
private view?: vscode.WebviewView = undefined; | ||
|
||
constructor(private readonly apiClient: api.Client, private readonly extensionUri: vscode.Uri) {} | ||
|
||
public register(context: vscode.ExtensionContext) { | ||
context.subscriptions.push( | ||
vscode.window.registerWebviewViewProvider(DetailsPanelProvider.viewType, this), | ||
vscode.commands.registerCommand("auxon.details.show", (params) => this.showDetails(params)) | ||
); | ||
} | ||
|
||
public resolveWebviewView( | ||
webviewView: vscode.WebviewView, | ||
_context: vscode.WebviewViewResolveContext, | ||
_token: vscode.CancellationToken | ||
) { | ||
this.view = webviewView; | ||
|
||
webviewView.webview.options = { | ||
enableScripts: true, | ||
}; | ||
|
||
webviewView.webview.html = this.generateHtmlContent(webviewView.webview); | ||
} | ||
|
||
private generateHtmlContent(webview: vscode.Webview): string { | ||
const webviewUiToolkitJsUri = webview.asWebviewUri( | ||
vscode.Uri.joinPath(this.extensionUri, "resources", "dist", "webviewuitoolkit.min.js") | ||
); | ||
const detailsPanelJsUri = webview.asWebviewUri( | ||
vscode.Uri.joinPath(this.extensionUri, "resources", "detailsPanel.js") | ||
); | ||
|
||
const templateUri = vscode.Uri.joinPath(this.extensionUri, "templates", "detailsPanel.html"); | ||
const templateText = fs.readFileSync(templateUri.fsPath, "utf8"); | ||
const template = handlebars.compile(templateText); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably load/compile the template in a less granular scope, like maybe the panel constructor. |
||
|
||
const html = template({ | ||
cspSource: webview.cspSource, | ||
nonce: getNonce(), | ||
webviewUiToolkitJsUri, | ||
detailsPanelJsUri, | ||
}); | ||
|
||
return html; | ||
} | ||
|
||
private showDetails(params: ShowDetailsParams) { | ||
this.view.webview.postMessage(params); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the whole element is being hidden, we can probably put the content for these headers in the template itself, and not worry about having to set
innerHTML
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this, but they still show up on initialization when the panel loads. Not sure why, but I assume it's something to do with the flex box display/styling.