Skip to content

Commit

Permalink
Implement Tooltip
Browse files Browse the repository at this point in the history
Signed-off-by: maria-ericsson <maria.chowdhury@ericsson.com>
  • Loading branch information
maria-ericsson committed Oct 23, 2020
1 parent 91f685f commit fb31e85
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 69 deletions.
115 changes: 57 additions & 58 deletions viewer-prototype/src/browser/style/output-components-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
.output-container {
display: flex;
color: var(--theia-ui-font-color0)
}

.widget-handle {
}
.widget-handle {
background-color: var(--theia-layout-color4);
display: grid;
grid-template-rows: 25px 1fr;
}
.title-bar-label {
}
.title-bar-label {
text-align: center;
writing-mode: vertical-rl;
height: 50%;
Expand All @@ -19,78 +19,77 @@
user-select: none;
align-self: center;
justify-self: center;
}
.remove-component-button {
}

.remove-component-button {
background: none;
border: none;
padding: 2px 8px;
align-self: center;
justify-self: center;
color: var(--theia-ui-font-color0)
}

.main-output-container {
}
.main-output-container {
display: flex;
}

.output-component-tree {
}
.output-component-tree {
overflow-y: scroll;
white-space: pre-wrap;
}

.output-component-chart {
}
.output-component-chart {
align-self: center;
text-align: center;
}

#timegraph-main {
width: 100%;
display: flex;
}

#main {
}

#tooltip-box {
position:absolute;
overflow:hidden;
z-index :2;
top: 80px;
right: 20px;
background-color: rgb(247, 231, 8);
width: 250px;
height: auto;
opacity: 0.8;
font-size: 13px;
font-family: arial;
text-align: left;
color: black;
padding-inline-start: 10px;
}

#timegraph-main {
width:100%;
overflow-y:scroll;
position:relative;
height: 300px;
z-index:1;
}

#main {
border: 1px solid;
margin: 10px 0;
overflow: hidden;
}

canvas {
}
canvas {
display: block;
}

.innerContainer {
}
.innerContainer {
width: 100%;
}

.table-tree>tbody>tr:nth-child(1)>th {
background-color: var(--theia-editor-background);
position: sticky;
top: 0;
}

.table-tree th, .table-tree td {
padding: 3px 5px;
text-align: left;
border-bottom: 1px solid #333;
border-right: 1px solid #333;
white-space: nowrap;
min-width: 50px;
}

.timegraph-tree tr {
/* TODO: Fix row alignment, this number is arbitrary, it works [on my machine], but it should match line height in timeline-chart */
line-height: 18px;
position: relative;
white-space: nowrap;
top: 50%;
padding: 0 0;
}

#input-filter-tree {
}

#input-filter-tree {
background-color: var(--theia-input-background);
border: none;
border-bottom: 1px solid var(--theia-input-foreground);
padding: 3px;
width: 180px;
color: var(--theia-input-placeholder-foreground)
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { EntryTree } from './utils/filtrer-tree/entry-tree';
import { listToTree, getAllExpandedNodeIds } from './utils/filtrer-tree/utils';
import hash from '../../../common/utils/value-hash';
import ColumnHeader from './utils/filtrer-tree/column-header';

import { TooltipComponent } from './utils/tooltip-component';
type TimegraphOutputProps = AbstractOutputProps & {
addWidgetResizeHandler: (handler: () => void) => void;
};
Expand All @@ -30,15 +30,17 @@ type TimegraphOutputState = AbstractOutputState & {
timegraphTree: TimeGraphEntry[];
collapsedNodes: number[];
columns: ColumnHeader[];
isElementSelected: boolean;
isTooltipOpened: boolean;
};

export class TimegraphOutputComponent extends AbstractTreeOutputComponent<TimegraphOutputProps, TimegraphOutputState> {
private totalHeight = 0;
private rowController: TimeGraphRowController;
private chartLayer: TimeGraphChart;
private vscrollLayer: TimeGraphVerticalScrollbar;
private horizontalContainer: React.RefObject<HTMLDivElement>;

private toolTipObject: { [key: string]: string } = {};
private toolTipPosition: { x: number, y: number } = { x: 0, y: 0 };
private tspDataProvider: TspDataProvider;
private styleMap = new Map<string, TimeGraphRowElementStyle>();

Expand All @@ -50,9 +52,13 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
outputStatus: ResponseStatus.RUNNING,
timegraphTree: [],
collapsedNodes: [],
columns: []
columns: [],
isElementSelected: false,
isTooltipOpened: false,
};
this.onToggleCollapse = this.onToggleCollapse.bind(this);
this.closeTooltip = this.closeTooltip.bind(this);
this.openTooltip = this.openTooltip.bind(this);
this.tspDataProvider = new TspDataProvider(this.props.tspClient, this.props.traceId, this.props.outputDescriptor.id);
this.rowController = new TimeGraphRowController(this.props.style.rowHeight, this.totalHeight);
this.horizontalContainer = React.createRef();
Expand All @@ -68,13 +74,27 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
};
this.chartLayer = new TimeGraphChart('timeGraphChart', providers, this.rowController);
this.vscrollLayer = new TimeGraphVerticalScrollbar('timeGraphVerticalScrollbar', this.rowController);
this.chartLayer.registerRowElementMouseInteractions({
mouseover: el => {
const X_MAX = 700;
const Y_MAX = 250;
const TOOLTIP_OFFSET = 80;
el.position.x = Math.min(el.position.x, X_MAX - (1.5 * TOOLTIP_OFFSET));
el.position.y = Math.min(el.position.y, Y_MAX - (1.5 * TOOLTIP_OFFSET));
this.toolTipPosition.x = (el.position.x > 0.5 * X_MAX) ? el.position.x - TOOLTIP_OFFSET : el.position.x + 0.5 * TOOLTIP_OFFSET;
this.toolTipPosition.y = (el.position.y > 0.5 * Y_MAX) ? el.position.y - TOOLTIP_OFFSET : el.position.y + 0.5 * TOOLTIP_OFFSET;
this.onElementSelected(this.chartLayer.getElementById(el.id));
this.closeTooltip();
this.openTooltip();

}

});
this.rowController.onVerticalOffsetChangedHandler(() => {
if (this.treeRef.current) {
this.treeRef.current.scrollTop = this.rowController.verticalOffset;
}
});

this.chartLayer.onSelectedRowElementChanged(model => {
if (model) {
const el = this.chartLayer.getElementById(model.id);
Expand All @@ -93,6 +113,18 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
this.rowController.verticalOffset = this.treeRef.current.scrollTop;
}
}
closeTooltip = (): void => {
this.setState({
isTooltipOpened: false
});
};

openTooltip(): void {
this.setState({
isElementSelected: true,
isTooltipOpened: true
});
}

async componentDidMount(): Promise<void> {
this.waitAnalysisCompletion();
Expand Down Expand Up @@ -157,8 +189,11 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
renderChart(): React.ReactNode {
return <React.Fragment>
{this.state.outputStatus === ResponseStatus.COMPLETED ?
<div id='timegraph-main' className='ps__child--consume' onWheel={ev => { ev.preventDefault(); ev.stopPropagation(); }} style={{ height: this.props.style.height }} >
{this.renderTimeGraphContent()}
<div id='timegraph-main' className='ps__child--consume' onMouseLeave={_ev => this.closeTooltip()} onWheel={ev => { ev.preventDefault(); ev.stopPropagation(); }}>
{this.renderTimeGraphContent()}
{this.state.isElementSelected && this.state.isTooltipOpened &&
<TooltipComponent tooltip={this.toolTipObject} position={this.toolTipPosition}></TooltipComponent>
}
</div> :
'Analysis running...'}
</React.Fragment>;
Expand Down Expand Up @@ -209,8 +244,7 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
layer={[this.vscrollLayer]}
></ReactTimeGraphContainer>;
}

private async onElementSelected(element: TimeGraphRowElement | undefined) {
async getToolTipObject(element: TimeGraphRowElement | undefined): Promise<{ [key: string]: string }> {
if (element && this.props.viewRange) {
const elementRange = element.model.range;
const offset = this.props.viewRange.getOffset();
Expand All @@ -225,11 +259,16 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
...responseModel.model,
'Row': element.row.model.name
};
SignalManager.getInstance().fireTooltipSignal(tooltipObject);
this.toolTipObject = tooltipObject;
this.forceUpdate();
return this.toolTipObject;
}
}
return {};
}
async onElementSelected(element: TimeGraphRowElement | undefined): Promise<void> {
SignalManager.getInstance().fireTooltipSignal(await this.getToolTipObject(element))
}

private async fetchTimegraphData(range: TimelineChart.TimeGraphRange, resolution: number) {
const treeNodes = listToTree(this.state.timegraphTree, this.state.columns);
const orderedTreeIds = getAllExpandedNodeIds(treeNodes, this.state.collapsedNodes);
Expand Down Expand Up @@ -359,3 +398,4 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react';
import { Component } from 'react';

interface TooltipProps {
tooltip: { [key: string]: string };
position: { x: number, y: number };
}

interface TooltipStates {
style: { top: string, left: string };

}

export class TooltipComponent extends Component<TooltipProps, TooltipStates> {
constructor(props: TooltipProps) {
super(props);
this.state = { style: { top: props.position.y + 'px', left: props.position.x + 'px' } };
}

tooltipRef: React.RefObject<HTMLDivElement> = React.createRef();

renderTooltip(): React.ReactNode {
const tooltipArray: React.ReactNode[] = [];
if (this.props.tooltip) {
const keys = Object.keys(this.props.tooltip);
keys.forEach(key => {
tooltipArray.push(<p key={key}>{key + ': ' + this.props.tooltip[key]}</p>);
});
}
else {
console.log('Tooltip null');
}
return <React.Fragment>
{tooltipArray.map(element => element)}
</React.Fragment>;
}

render(): React.ReactNode {
return <div id='tooltip-box' ref={this.tooltipRef} style={this.state.style}>
{this.renderTooltip()}
</div>;
}
}

0 comments on commit fb31e85

Please sign in to comment.