Skip to content

Commit

Permalink
Metabolic pathways visualisation (#731): internal pathways api integr…
Browse files Browse the repository at this point in the history
…ation + layout fixes
  • Loading branch information
DmitriiKrasnov committed Jan 28, 2022
1 parent 2a628f9 commit 403c6c4
Show file tree
Hide file tree
Showing 14 changed files with 203 additions and 241 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ const sbgnStylesheet = require('cytoscape-sbgn-stylesheet');
const $ = require('jquery');

const SCALE = 0.3;
const elementOptionsType = {
NODE: 'nodes',
EDGE: 'edges'
};

export default class ngbCytoscapePathwayController {
constructor($element, $scope, $compile, $window, $timeout, dispatcher, cytoscapeSettings) {
Expand Down Expand Up @@ -71,27 +67,25 @@ export default class ngbCytoscapePathwayController {
}
this.$timeout(() => {
const sbgnStyle = sbgnStylesheet(Cytoscape);
// Object.keys(sbgnStyle).forEach(key => {
// if(sbgnStyle[key].selector === 'edge') {
// Object.keys(sbgnStyle[key].properties).forEach(propKey => {
// if(sbgnStyle[key].properties[propKey].name === 'curve-style') {
// sbgnStyle[key].properties[propKey].value = 'taxi';
// }
// });
// }
// });
// sbgnStyle.edge['curve-style'] = 'taxi';
// const savedState = JSON.parse(localStorage.getItem(this.storageName) || '{}');
// const savedLayout = savedState.layout ? savedState.layout[this.elements.id] : undefined;
// let elements, layoutSettings;
const savedState = JSON.parse(localStorage.getItem(this.storageName) || '{}');
const savedLayout = savedState.layout ? savedState.layout[this.elements.id] : undefined;
let elements;
if (savedLayout) {
elements = {
nodes: this.getPlainNodes(savedLayout.nodes),
edges: savedLayout.edges
};
} else {
elements = {
nodes: this.positionedNodes(this.elements.nodes),
edges: this.elements.edges
};
}
this.viewer = Cytoscape({
container: this.cytoscapeContainer,
style: sbgnStyle,
layout: {name: 'preset'},
elements: {
nodes: this.positionedNodes(this.elements.nodes),
edges: this.elements.edges,
},
elements: elements,
});
const layout = this.viewer.layout(this.settings.loadedLayout);
layout.on('layoutready', () => {
Expand Down Expand Up @@ -120,7 +114,7 @@ export default class ngbCytoscapePathwayController {
layout.run();
const viewerContext = this;
this.actionsManager = {
ZOOM_STEP: 0.25,
ZOOM_STEP: 0.125,
duration: 250,
zoom: () => viewerContext.viewer.zoom(),
zoomIn() {
Expand All @@ -137,6 +131,16 @@ export default class ngbCytoscapePathwayController {
this.canZoomIn = zoom < viewerContext.viewer.maxZoom();
this.canZoomOut = zoom > viewerContext.viewer.minZoom();
},
restoreDefault: () => {
this.viewer.batch(() => {
this.viewer.remove(this.viewer.nodes());
this.viewer.remove(this.viewer.edges());
this.viewer.add(this.positionedNodes(this.elements.nodes));
this.viewer.add(this.elements.edges);
});
// viewerContext.viewer.layout(this.settings.defaultLayout).run();
viewerContext.saveLayout();
},
canZoomIn: true,
canZoomOut: true,
ready: true
Expand Down Expand Up @@ -195,32 +199,12 @@ export default class ngbCytoscapePathwayController {
}, []);
}

applyOptions(elements, type) {
if (!this.elementsOptions) {
return;
}
switch (type) {
case elementOptionsType.NODE: {
return elements.reduce((r, cv) => {
if (this.elementsOptions.nodes[cv.data.id]) {
cv.data = {
...cv.data,
...this.elementsOptions.nodes[cv.data.id]
};
}
r.push(cv);
return r;
}, []);
}
}
}

positionedNodes(nodes) {
nodes.forEach(node => {
if (node.data.bbox) {
node.position = {
x: node.data.bbox.x/SCALE,
y: node.data.bbox.y/SCALE
x: node.data.bbox.x / SCALE,
y: node.data.bbox.y / SCALE
};
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,6 @@
export default {
viewer: {},
style: {
node: {
'content': 'data(id)',
'width': 175,
'height': 60,
'text-opacity': 1,
'text-valign': 'center',
'text-halign': 'center',
'shape': 'rectangle',
'label': 'data(id)',
'background-opacity': 0,
'opacity': 0,
'color': '#000',
'border-width': 1
},
edge: {
'curve-style': 'bezier',
'width': 1,
'line-color': '#37474F',
'target-arrow-color': '#37474F',
'target-arrow-shape': 'triangle',
'overlay-color': '#4285F4',
'overlay-padding': '4px',
'underlay-color': '#4285F4',
'underlay-padding': '3px',
'underlay-opacity': '0'
},
edgeLabel: {
'text-rotation': 'none',
'content': 'data(label)',
'font-size': '12px',
'font-weight': 'bold',
'text-background-color': '#fff',
'text-background-opacity': 1,
'color': '#2c4f9e'
}
},
style: {},
defaultLayout: {
name: 'dagre',
rankDir: 'TB'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,15 @@ export default class ngbInternalPathwaysResultController extends baseController
}

async initialize() {
if (!this.ngbPathwaysService.currentInternalPathwaysId) {
if (!this.ngbPathwaysService.currentInternalPathway) {
return;
}
const {data, error} = await this.ngbInternalPathwaysResultService.getPathwayTreeById(this.ngbPathwaysService.currentInternalPathwaysId);
const {data, error} = await this.ngbInternalPathwaysResultService.getPathwayTree(this.ngbPathwaysService.currentInternalPathway);
if (error) {
this.treeError = error;
} else {
this.treeError = false;
this.selectedTree = data.tree;
this.selectedTreeName = data.name;
this.selectedTree = data;
}
this.loading = false;
this.$timeout(() => this.$scope.$apply());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
.ngb-cytoscape-container {
width: 100%;
height: 100%;
min-height: 500px;
.ngb-pathway-cytoscape-container {
flex: 1;
position: relative;
}

.internal-pathway-container-error {
Expand All @@ -11,7 +9,7 @@
}

.internal-pathway-container {
margin: 2px 10px;
margin: 2px 0;
height: calc(100% - 4px);
display: flex;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
export default class ngbInternalPathwaysResultService {

currentReferenceId = null;

constructor(genomeDataService, dispatcher) {
this.dispatcher = dispatcher;
this.genomeDataService = genomeDataService;
Expand All @@ -11,24 +8,22 @@ export default class ngbInternalPathwaysResultService {
return new ngbInternalPathwaysResultService(genomeDataService, dispatcher);
}

async getPathwayTreeById(id) {
if(!id) {
async getPathwayTree(treeConfig) {
if(!treeConfig.id) {
return {
data: null,
error: false
};
}
const xml = require(`./xml/${id}.xml`);
const xml = await this.genomeDataService.loadPathwayFileById(treeConfig.id);
try {
const convert = require('sbgnml-to-cytoscape');
const data = convert(xml);
data.id = treeConfig.id;
data.name = treeConfig.name;
if (data) {
data.id = id;
return {
data: {
name: id,
tree: data
},
data: data,
error: false
};
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</div>
<md-progress-linear md-mode="query"></md-progress-linear>
</div>
<div class="internal-pathway-container" ng-if="!$ctrl.loading">
<div class="internal-pathway-container" layout="column" ng-if="!$ctrl.loading">
<div layout="row">
<md-button
aria-label="back"
Expand All @@ -13,11 +13,11 @@
type="button">
<ng-md-icon class="icon_info_outline" icon="chevron_left" size="24"></ng-md-icon>
</md-button>
<span class="blast-search-result-title">{{$ctrl.selectedTreeName}}</span>
<span class="blast-search-result-title">{{$ctrl.selectedTree.name}}</span>
</div>
<div class="u-height__full tree-container" flex layout="column">
<md-content flex layout="column">
<div class="md-padding ngb-cytoscape-container" layout="column">
<div class="md-padding ngb-pathway-cytoscape-container">
<div class="internal-pathway-container-error" ng-if="$ctrl.treeError">
{{$ctrl.treeError}}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const RESIZE_DELAY = 300;
export default class ngbInternalPathwaysTableController extends baseController {
dispatcher;
isProgressShown = true;
isEmptyResult = false;
errorMessageList = [];
debounce = (new Debounce()).debounce;
gridOptions = {
Expand Down Expand Up @@ -39,7 +38,7 @@ export default class ngbInternalPathwaysTableController extends baseController {
};
events = {
'pathways:internalPathways:page:change': this.loadData.bind(this),
'pathways:internalPathways:search': this.loadData.bind(this),
'pathways:internalPathways:search': this.initialize.bind(this),
'read:show:pathways': this.loadData.bind(this)
};

Expand Down Expand Up @@ -87,10 +86,10 @@ export default class ngbInternalPathwaysTableController extends baseController {
}
});
await this.loadData();
this.isProgressShown = false;
}

async loadData() {
this.isProgressShown = true;
try {
await this.ngbInternalPathwaysTableService.searchInternalPathways(this.ngbPathwaysService.currentSearch);
const dataLength = this.ngbInternalPathwaysTableService.internalPathways.length;
Expand All @@ -106,9 +105,7 @@ export default class ngbInternalPathwaysTableController extends baseController {
} else {
this.isEmptyResults = true;
}
this.isProgressShown = false;
} catch (errorObj) {
this.isProgressShown = false;
this.onError(errorObj.message);
}
this.$timeout(() => this.$scope.$apply());
Expand All @@ -121,7 +118,10 @@ export default class ngbInternalPathwaysTableController extends baseController {
rowClick(row, event) {
const entity = row.entity;
if (entity) {
this.ngbPathwaysService.currentInternalPathwaysId = row.entity.xml;
this.ngbPathwaysService.currentInternalPathway = {
id: row.entity.id,
name: row.entity.name
};
this.changeState({state: 'INTERNAL_PATHWAYS_RESULT'});
} else {
event.stopImmediatePropagation();
Expand All @@ -136,7 +136,7 @@ export default class ngbInternalPathwaysTableController extends baseController {
const {columns} = this.gridApi.saveState.save();
const fieldTitleMap = (
o => Object.keys(o).reduce(
(r, k) => Object.assign(r, { [o[k]]: k }), {}
(r, k) => Object.assign(r, {[o[k]]: k}), {}
)
)(this.ngbInternalPathwaysTableService.columnTitleMap);
const mapNameToField = function ({name}) {
Expand Down
Loading

0 comments on commit 403c6c4

Please sign in to comment.