From 534315badf1160a66c3aa045a7f0c1093e46e06a Mon Sep 17 00:00:00 2001 From: Rodrigo Pinto Date: Fri, 6 May 2022 11:15:45 -0400 Subject: [PATCH] Select chart components from a selection in the events table Select corresponding chart components from the events table. Clicking on a line in the events table will cause a chart like "Thread Status" to scroll vertically to the row which has the element that corresponds to the clicked event. For each line in the timegraph tree, parse the metadata in the TimeGraphEntry received from the server and try to find matches with the key / values pairs of the clicked event. It will select the entry which has the most matches. When extending the selection, only the last selected event will be used to broadcast the selection (multi-line selection). This PR requires the following pull requests: https://git.eclipse.org/r/c/tracecompass.incubator/org.eclipse.tracecompass.incubator/+/193246 https://github.com/eclipse-cdt-cloud/tsp-typescript-client/pull/63 https://github.com/eclipse-cdt-cloud/timeline-chart/pull/204 The corresponding Trace Server Protocol (TSP) update: https://github.com/eclipse-cdt-cloud/trace-server-protocol/pull/83 Signed-off-by: Rodrigo Pinto Signed-off-by: Bernd Hufmann --- .../src/components/table-output-component.tsx | 14 +-- .../components/timegraph-output-component.tsx | 101 +++++++++++++++++- .../components/utils/filter-tree/utils.tsx | 5 + 3 files changed, 112 insertions(+), 8 deletions(-) diff --git a/packages/react-components/src/components/table-output-component.tsx b/packages/react-components/src/components/table-output-component.tsx index 670dc5fa6..936d8ffba 100644 --- a/packages/react-components/src/components/table-output-component.tsx +++ b/packages/react-components/src/components/table-output-component.tsx @@ -103,7 +103,7 @@ export class TableOutputComponent extends AbstractOutputComponentthis.checkFocus(event)} + onFocus={event => this.checkFocus(event)} className={this.props.backgroundTheme === 'light' ? 'ag-theme-balham' : 'ag-theme-balham-dark'} style={{ height: this.props.style.height, width: this.props.outputWidth }}> { @@ -65,6 +66,7 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent this.doHandleSelectionChangedSignal(payload); + private pendingSelection: TimeGraphEntry | undefined; constructor(props: TimegraphOutputProps) { super(props); @@ -76,7 +78,8 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent { + this.pendingSelection = undefined; if (model) { this.selectedElement = this.chartLayer.getStateById(model.id); } else { @@ -285,6 +289,19 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent { + if (el.metadata) { + let cnt = 0; + Object.entries(el.metadata).forEach(([key, values]) => { + if (typeof (payload.load) !== 'string') { + const val = payload.load[key]; + if (val !== undefined) { + const num = Number(val); + // at least one value in array needs to match + const result = values.find((value: string | number) => (num !== undefined && num === value) || (val === value)); + if (result !== undefined) { + cnt++; + } + } + } + }); + if (cnt > max) { + max = cnt; + element = el; + } + } + }); + + } + return element; + } + private getMarkersLayerHeight() { const rowHeight = 20; const scrollbarHeight = 10; @@ -533,6 +592,14 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent node.id === entry?.id); + if (foundNode) { + let parentId: number | undefined = foundNode.parentId; + const ids: number[] = []; + while (parentId && parentId >= 0) { + ids.push(parentId); + foundNode = this.state.timegraphTree.find(node => node.id === parentId); + parentId = foundNode?.parentId; + } + + let newList = [...this.state.collapsedNodes]; + ids.forEach(parentIds => { + const exist = this.state.collapsedNodes.find(expandId => expandId === parentIds); + if (exist !== undefined) { + newList = newList.filter(collapsed => parentIds !== collapsed); + } + }); + const retVal = newList.length === this.state.collapsedNodes.length; + this.setState({ collapsedNodes: newList }, this.updateTotalHeight); + return retVal; + } + } + + private selectAndReveal(item: TimeGraphEntry) { + const rowIndex = getIndexOfNode(item.id, listToTree(this.state.timegraphTree, this.state.columns), this.state.collapsedNodes); + this.chartLayer.selectAndReveal(rowIndex); + } + } diff --git a/packages/react-components/src/components/utils/filter-tree/utils.tsx b/packages/react-components/src/components/utils/filter-tree/utils.tsx index 348c13fad..30afdcfa1 100644 --- a/packages/react-components/src/components/utils/filter-tree/utils.tsx +++ b/packages/react-components/src/components/utils/filter-tree/utils.tsx @@ -57,3 +57,8 @@ export const getAllExpandedNodeIds = (nodes: TreeNode[],collapsedNodes: number[] }); return visibleIds; }; + +export const getIndexOfNode = (id: number, nodes: TreeNode[], collapsedNodes: number[]): number => { + const ids = getAllExpandedNodeIds(nodes, collapsedNodes); + return ids.findIndex(eId => eId === id); +};