Skip to content

Commit

Permalink
Add multi-select support to event tree items
Browse files Browse the repository at this point in the history
  • Loading branch information
jonlamb-gh committed Nov 7, 2023
1 parent e298ed1 commit ea113d9
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 10 deletions.
67 changes: 57 additions & 10 deletions vscode/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as api from "./modalityApi";
import * as commonNotebookCells from "../templates/common.json";
import * as eventTimingNotebookCells from "../templates/eventTiming.json";
import * as eventAttributeValuesNotebookCells from "../templates/eventAttributeValues.json";
import * as eventMultiAttributeValuesNotebookCells from "../templates/eventMultiAttributeValues.json";

export class EventsTreeDataProvider implements vscode.TreeDataProvider<EventsTreeItemData> {
selectedTimelineId?: api.TimelineId = undefined;
Expand All @@ -24,16 +25,16 @@ export class EventsTreeDataProvider implements vscode.TreeDataProvider<EventsTre
register(context: vscode.ExtensionContext) {
this.view = vscode.window.createTreeView("auxon.events", {
treeDataProvider: this,
canSelectMany: false,
canSelectMany: true,
});
context.subscriptions.push(
this.view,
vscode.commands.registerCommand("auxon.events.refresh", () => this.refresh()),
vscode.commands.registerCommand("auxon.events.setSelectedTimeline", (timelineId, timelineName) =>
this.setSelectedTimeline(timelineId, timelineName)
),
vscode.commands.registerCommand("auxon.events.createEventTimingNotebook", async (itemData) =>
this.createEventTimingNotebook(itemData)
vscode.commands.registerCommand("auxon.events.createEventTimingNotebook", async (item) =>
this.createEventTimingNotebook(item)
),
vscode.commands.registerCommand("auxon.events.createEventAttrNotebook", async (itemData) =>
this.createEventAttrNotebook(itemData)
Expand Down Expand Up @@ -93,16 +94,62 @@ export class EventsTreeDataProvider implements vscode.TreeDataProvider<EventsTre
}

async createEventTimingNotebook(item: EventNameTreeItemData) {
const varMap = this.templateVariableMap();
varMap["eventName"] = item.eventName;
await this.createJupyterNotebook(eventTimingNotebookCells.cells, varMap);
let selectedEventNames = this.view.selection.map((data) => data.eventName);
// Add the item the command was executed on, it may not be in the selection
selectedEventNames.push(item.eventName);
selectedEventNames = [...new Set(selectedEventNames)]; // dedupe
for (const eventName of selectedEventNames) {
const varMap = this.templateVariableMap();
varMap["eventName"] = eventName;
await this.createJupyterNotebook(eventTimingNotebookCells.cells, varMap);
}
}

async createEventAttrNotebook(item: EventAttributeTreeItemData) {
const varMap = this.templateVariableMap();
varMap["eventName"] = item.eventName;
varMap["eventAttribute"] = item.attribute;
await this.createJupyterNotebook(eventAttributeValuesNotebookCells.cells, varMap);
if (this.view.selection.length == 1) {
const varMap = this.templateVariableMap();
varMap["eventName"] = item.eventName;
varMap["eventAttribute"] = item.attribute;
await this.createJupyterNotebook(eventAttributeValuesNotebookCells.cells, varMap);
} else {
let selectedEventAttrs = [...this.view.selection, ...[item]];
selectedEventAttrs = [...new Set(selectedEventAttrs)]; // dedupe

const attributesByEvent = new Map<string, string[]>();
for (const ev of selectedEventAttrs) {
if (!(ev instanceof EventAttributeTreeItemData)) {
throw new Error("Internal error: event tree node not of expected type");
}
if (attributesByEvent.has(ev.eventName)) {
const attributes = attributesByEvent.get(ev.eventName);
attributes.push(ev.attribute);
} else {
const attributes = [];
attributes.push(ev.attribute);
attributesByEvent.set(ev.eventName, attributes);
}
}

attributesByEvent.forEach(async (attributes: string[], eventName: string) => {
const varMap = this.templateVariableMap();
varMap["eventName"] = eventName;
const cells = lodash.cloneDeep(eventMultiAttributeValuesNotebookCells.cells.slice(0, 2));
const srcCell = eventMultiAttributeValuesNotebookCells.cells[2];
const figShowCell = eventMultiAttributeValuesNotebookCells.cells[3];
const eventAttributesList = [];
for (let i = 0; i < attributes.length; i++) {
eventAttributesList.push("'event." + attributes[i] + "'");
varMap["eventAttribute" + i] = attributes[i];
const newSrc = srcCell.source[0].replace(/eventAttribute/g, "eventAttribute" + i);
cells[1].source.push(newSrc);
}
cells[1].source.push(figShowCell.source[0]);

varMap["eventAttributes"] = eventAttributesList.join(", ");

await this.createJupyterNotebook(cells, varMap);
});
}
}

async createJupyterNotebook(notebookSrcCells: object[], templateVarMap: object) {
Expand Down
1 change: 1 addition & 0 deletions vscode/templates/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
"# Import plotly\n",
"import plotly.io as pio\n",
"import plotly.express as px\n",
"import plotly.graph_objects as go\n",
"pio.renderers.default = 'notebook'\n"
]
}
Expand Down
71 changes: 71 additions & 0 deletions vscode/templates/eventMultiAttributeValues.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Request data frame\n",
"modality = Modality()\n",
"\n",
"df = modality.events_data_frame(\n",
" workspace_version_id='${workspaceVersionId}',\n",
" segments=[${segments}],\n",
" timeline_filter='_.timeline.id = ${timelineId}',\n",
" event_filter='_.name = \"${eventName}\"',\n",
" include_attrs=['event.timestamp', ${eventAttributes}])\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Scatter plot\n",
"fig = go.Figure()\n",
"fig.update_layout(title='Event Attribute Scatter Plot<br>${eventName} @ ${timelineName}')\n",
"fig.update_xaxes(title_text='event.timestamp')\n",
"fig.update_yaxes(title_text='Attribute Value')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig.add_trace(go.Scatter(name='_.${eventAttribute}', x=df['event.timestamp'], y=df['event.${eventAttribute}']))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": ["fig.show()"]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit ea113d9

Please sign in to comment.