Skip to content

Commit

Permalink
Export datatree-output-component to csv
Browse files Browse the repository at this point in the history
added export option for statistics views

Signed-off-by: hriday-panchasara <hriday.panchasara@ericsson.com>
  • Loading branch information
hriday-panchasara authored and bhufmann committed May 20, 2022
1 parent b15ad94 commit f904b71
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface AbstractOutputProps {
tooltipComponent: TooltipComponent | null;
tooltipXYComponent: TooltipXYComponent | null;
traceId: string;
traceName?: string;
range: TimeRange;
nbEvents: number;
viewRange: TimeRange;
Expand Down Expand Up @@ -43,14 +44,15 @@ export interface AbstractOutputProps {
export interface AbstractOutputState {
outputStatus: string;
styleModel?: OutputStyleModel;
optionsDropdownOpen?: boolean;
optionsDropdownOpen: boolean;
additionalOptions?: boolean;
}

export abstract class AbstractOutputComponent<P extends AbstractOutputProps, S extends AbstractOutputState> extends React.Component<P, S> {

private readonly DEFAULT_HANDLE_WIDTH = 30;

private mainOutputContainer: React.RefObject<HTMLDivElement>;
protected mainOutputContainer: React.RefObject<HTMLDivElement>;

private optionsMenuRef: React.RefObject<HTMLDivElement>;

Expand All @@ -77,7 +79,7 @@ export abstract class AbstractOutputComponent<P extends AbstractOutputProps, S e
data-for="tooltip-component">
<div
id={this.props.traceId + this.props.outputDescriptor.id + 'handle'}
className={this.state.optionsDropdownOpen !== undefined ? 'widget-handle-with-options' : 'widget-handle'}
className={this.state.additionalOptions ? 'widget-handle-with-options' : 'widget-handle'}
style={{ width: this.getHandleWidth(), height: this.props.style.height }}
>
{this.renderTitleBar()}
Expand All @@ -96,7 +98,7 @@ export abstract class AbstractOutputComponent<P extends AbstractOutputProps, S e
<button className='remove-component-button' onClick={this.closeComponent}>
<FontAwesomeIcon icon={faTimes} />
</button>
{this.state.optionsDropdownOpen !== undefined && <div className='options-menu-container'>
{this.state.additionalOptions !== undefined && <div className='options-menu-container'>
<button title="Show View Options" className='options-menu-button' onClick={this.openOptionsMenu}>
<FontAwesomeIcon icon={faBars} />
</button>
Expand Down Expand Up @@ -142,6 +144,12 @@ export abstract class AbstractOutputComponent<P extends AbstractOutputProps, S e
abstract resultsAreEmpty(): boolean;

protected showOptions(): React.ReactNode {
return <React.Fragment>
{this.state.additionalOptions && this.showAdditionalOptions()}
</React.Fragment>;
}

protected showAdditionalOptions(): React.ReactNode {
return <></>;
}

Expand Down Expand Up @@ -173,8 +181,8 @@ export abstract class AbstractOutputComponent<P extends AbstractOutputProps, S e
});
}

private closeOptionsMenu(event: Event): void {
if (event.target instanceof Node && this.optionsMenuRef.current?.contains(event.target)) {
protected closeOptionsMenu(event?: Event): void {
if (event && event.target instanceof Node && this.optionsMenuRef.current?.contains(event.target)) {
return;
}
this.closeOptionsDropDown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export class DataTreeOutputComponent extends AbstractOutputComponent<AbstractOut
collapsedNodes: [],
orderedNodes: [],
columns: [{title: 'Name', sortable: true}],
optionsDropdownOpen: false,
additionalOptions: true
};
}

Expand Down Expand Up @@ -188,4 +190,51 @@ export class DataTreeOutputComponent extends AbstractOutputComponent<AbstractOut
this._debouncedFetchSelectionData();
}
}

private async exportOutput(): Promise<void> {
const focusContainer = document.getElementById(this.props.traceId + this.props.outputDescriptor.id + 'focusContainer');
if (focusContainer) {
const table = focusContainer.querySelector('div:nth-child(2) > table');
if (table) {
const rows = table.querySelectorAll('tr');

const csvArray = [];
for (let i = 0; i < rows.length; i++) {
const row = [];
const cols = rows[i].querySelectorAll('td, th');
for (let j = 0; j < cols.length - 1; j++) {
let data;
const content = cols[j].textContent;
if (content) {
data = content.replace(/\s*\|/g, '');
} else {
data = content;
}
row.push(data);
}
csvArray.push(row.join(','));
}
const tableString = csvArray.join('\n');

const link = document.createElement('a');
link.setAttribute('href', `data:text/csv;charset=utf-8,${encodeURIComponent(tableString)}`);
link.setAttribute('download', (this.props.traceName ?? 'export') + ' - ' + this.props.outputDescriptor.name);

link.style.display = 'none';
document.body.appendChild(link);

link.click();

document.body.removeChild(link);
}
}
}

protected showAdditionalOptions(): React.ReactNode {
return <React.Fragment>
<ul>
<li className='drop-down-list-item' key={0} onClick={() => this.exportOutput()}>Export to csv</li>
</ul>
</React.Fragment>;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
outputStatus: ResponseStatus.RUNNING,
tableColumns: [],
optionsDropdownOpen: false,
showToggleColumns: false
showToggleColumns: false,
additionalOptions: true
};

this.frameworkComponents = {
Expand Down Expand Up @@ -711,7 +712,13 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
</React.Fragment>;
}

protected showOptions(): React.ReactNode {
protected closeOptionsDropDown(): void {
this.setState({
showToggleColumns: false
});
}

protected showAdditionalOptions(): React.ReactNode {
return <React.Fragment>
<ul>
<li className='drop-down-list-item' key={0} onClick={() => {
Expand All @@ -721,11 +728,4 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
{this.state.showToggleColumns && <div className='toggle-columns-table'>{this.renderToggleColumnsTable()}</div>}
</React.Fragment>;
}

protected closeOptionsDropDown(): void {
this.setState({
showToggleColumns: false
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr
markerLayerData: undefined,
collapsedNodes: [],
columns: [],
collapsedMarkerNodes: []
collapsedMarkerNodes: [],
optionsDropdownOpen: false
};
this.selectedMarkerCategories = this.props.markerCategories;
this.onToggleCollapse = this.onToggleCollapse.bind(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class TraceContextComponent extends React.Component<TraceContextProps, Tr
private readonly DEFAULT_COMPONENT_LEFT: number = 0;
private readonly SCROLLBAR_PADDING: number = 12;
private readonly DEFAULT_CHART_OFFSET = 200;
private readonly MIN_COMPONENT_HEIGHT: number = 2;

private unitController: TimeGraphUnitController;
private historyHandler: UnitControllerHistoryHandler;
Expand Down Expand Up @@ -453,6 +454,7 @@ export class TraceContextComponent extends React.Component<TraceContextProps, Tr
tooltipComponent: this.tooltipComponent.current,
tooltipXYComponent: this.tooltipXYComponent.current,
traceId: this.state.experiment.UUID,
traceName: this.props.experiment.name,
outputDescriptor: output,
markerCategories: this.props.markerCategoriesMap.get(output.id),
markerSetId: this.props.markerSetId,
Expand Down Expand Up @@ -544,6 +546,7 @@ export class TraceContextComponent extends React.Component<TraceContextProps, Tr
y: 1,
w: 1,
h: this.DEFAULT_COMPONENT_HEIGHT,
minH: this.MIN_COMPONENT_HEIGHT,
});
} else {
newNonTimeScaleLayouts.push({
Expand All @@ -552,6 +555,7 @@ export class TraceContextComponent extends React.Component<TraceContextProps, Tr
y: 1,
w: 1,
h: this.DEFAULT_COMPONENT_HEIGHT,
minH: this.MIN_COMPONENT_HEIGHT,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ export class XYOutputComponent extends AbstractTreeOutputComponent<AbstractOutpu
columns: [{title: 'Name', sortable: true}],
allMax: 0,
allMin: 0,
cursor: 'default'
cursor: 'default',
optionsDropdownOpen: false
};

this.afterChartDraw = this.afterChartDraw.bind(this);
Expand Down
52 changes: 52 additions & 0 deletions packages/react-components/style/output-components-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,58 @@
text-overflow: ellipsis;
white-space: nowrap;
}
.title-bar-label:hover {
background-color: var(--theia-list-hoverBackground);
}
.remove-component-button:hover {
cursor: pointer;
background-color: var(--theia-list-hoverBackground);
}
.share-component-container {
align-self: start;
justify-self: center;
position: relative;
display: inline-block;
}
.share-component-button {
background: none;
border: none;
color: var(--theia-ui-font-color0)
}
.share-component-button:hover {
cursor: pointer;
background-color: var(--theia-list-hoverBackground);
}
.share-component-drop-down {
position: absolute;
top: 100%;
left: 50%;
padding: 0;
z-index: 2;
min-width: 180px;
background: var(--theia-menu-background);
color: var(--theia-menu-foreground);
font-size: var(--theia-ui-font-size1);
box-shadow: 0px 1px 6px var(--theia-widget-shadow);
border: 1px solid var(--theia-menu-border);
}
.share-component-drop-down > ul {
list-style-type: none;
margin: 0;
padding: 0;
display: table;
width: 100%;
}
.drop-down-list-item {
padding: 8px 12px;
background-color: var(--theia-menu-background);
color: var(--theia-menu-foreground);
}
.drop-down-list-item:hover {
background: var(--theia-menu-selectionBackground);
color: var(--theia-menu-selectionForeground);
opacity: 1;
}
.remove-component-button {
background: none;
border: none;
Expand Down

0 comments on commit f904b71

Please sign in to comment.