Commit 5cea7d9e authored by Lukas Pravda's avatar Lukas Pravda
Browse files

improve default ligand layout

parent cc50865c
...@@ -38,10 +38,19 @@ class Depiction { ...@@ -38,10 +38,19 @@ class Depiction {
this.atoms = data.atoms.map(x => new Atom(x)); this.atoms = data.atoms.map(x => new Atom(x));
this.bonds = new Array<Bond>(); this.bonds = new Array<Bond>();
let bds = new Set<string>();
data.bonds.forEach(x => { data.bonds.forEach(x => {
var atomA = this.atoms.find(e => e.name == x.bgn); let atomA = this.atoms.find(e => e.name == x.bgn);
var atomB = this.atoms.find(e => e.name == x.end); let atomB = this.atoms.find(e => e.name == x.end);
var bond = new Bond(atomA, atomB, x.coords, x.style); let bond = new Bond(atomA, atomB, x.coords, x.style);
let bondFlag = [atomA.name, atomB.name].sort().join("_");
if (!bds.has(bondFlag)) {
bds.add(bondFlag);
atomA.connectivity++;
atomB.connectivity++;
}
this.bonds.push(bond); this.bonds.push(bond);
}); });
...@@ -67,16 +76,9 @@ class Depiction { ...@@ -67,16 +76,9 @@ class Depiction {
} }
// ideally we want to find an atom which is part just a single bond to get nice initial position. // ideally we want to find an atom which is part just a single bond to get nice initial position.
// If there is no such atom any will do // If there is no such atom any will do
let searchStruct = new Map<string, number>();
this.bonds.forEach(x => {
searchStruct.set(x.bgn.name, searchStruct.get(x.bgn.name) === undefined ? 1 : searchStruct.get(x.bgn.name) + 1);
searchStruct.set(x.end.name, searchStruct.get(x.end.name) === undefined ? 1 : searchStruct.get(x.end.name) + 1);
});
searchStruct = this.sortMap(searchStruct); // ascending order so we hit those with less partners sooner.
let thisAtomName = [...searchStruct.keys()].find(x => atomNames.findIndex(y => y === x) !== -1) let atoms = this.atoms.filter(x => atomNames.includes(x.name)).sort((x, y) => x.connectivity - y.connectivity);
let thisAtom = this.atoms.find(x => x.name === thisAtomName); let thisAtom = atoms[0];
let bond = this.bonds.find(x => x.containsAtom(thisAtom)); let bond = this.bonds.find(x => x.containsAtom(thisAtom));
let otherAtom = bond.getOtherAtom(thisAtom); let otherAtom = bond.getOtherAtom(thisAtom);
...@@ -231,10 +233,13 @@ class Atom { ...@@ -231,10 +233,13 @@ class Atom {
name: string; name: string;
labels: any; labels: any;
position: Vector2D; position: Vector2D;
connectivity: number
constructor(item: any) { constructor(item: any) {
this.name = item.name; this.name = item.name;
this.labels = item.labels; this.labels = item.labels;
this.position = new Vector2D(item.x, item.y) this.position = new Vector2D(item.x, item.y);
this.connectivity = 0;
} }
/** /**
...@@ -337,7 +342,6 @@ class Bond { ...@@ -337,7 +342,6 @@ class Bond {
coords: string; coords: string;
style: string; style: string;
/** /**
*Creates an instance of the bond. *Creates an instance of the bond.
* @param {Atom} a * @param {Atom} a
...@@ -348,7 +352,7 @@ class Bond { ...@@ -348,7 +352,7 @@ class Bond {
this.bgn = a; this.bgn = a;
this.end = b; this.end = b;
this.coords = coords; this.coords = coords;
this.style = style.replace("stroke-width:2px", "stroke-width:4px");; this.style = style.replace("stroke-width:2px", "stroke-width:4px");
} }
......
...@@ -688,15 +688,17 @@ class Visualization { ...@@ -688,15 +688,17 @@ class Visualization {
this.presentBindingSite.interactionNodes this.presentBindingSite.interactionNodes
.filter((x: Model.InteractionNode) => !x.residue.isLigand) .filter((x: Model.InteractionNode) => !x.residue.isLigand)
.forEach((x: Model.InteractionNode) => { .forEach((x: Model.InteractionNode) => {
let lnks = this.presentBindingSite.links let links = this.presentBindingSite.links.filter((y: Model.LigandResidueLink) => y.containsNode(x) && y.getLinkClass() !== 'hydrophobic');
.filter((y: Model.LigandResidueLink) => y.containsNode(x))
links = links.length == 0 ? this.presentBindingSite.links.filter((y: Model.LigandResidueLink) => y.containsNode(x)) : links;
let atom_names = links
.map((y: Model.LigandResidueLink) => [].concat.apply([], y.interaction.map(z => z.sourceAtoms))); .map((y: Model.LigandResidueLink) => [].concat.apply([], y.interaction.map(z => z.sourceAtoms)));
let concated = [].concat.apply([], lnks); let concated = [].concat.apply([], atom_names);
let position: Vector2D = this.depiction.getInitalNodePosition(concated); let position: Vector2D = this.depiction.getInitalNodePosition(concated);
x.x = position.x + Math.random() * 110; x.x = position.x + Math.random() * 55;
x.y = position.y + Math.random() * 110; x.y = position.y + Math.random() * 55;
}); });
...@@ -730,11 +732,10 @@ class Visualization { ...@@ -730,11 +732,10 @@ class Visualization {
let forceLink = d3.forceLink() let forceLink = d3.forceLink()
.links(this.links.filter((x: Model.LigandResidueLink) => x.getLinkClass() !== 'hydrophobic')) .links(this.links.filter((x: Model.LigandResidueLink) => x.getLinkClass() !== 'hydrophobic'))
.distance(70) .distance(5);
.strength(0.5);
let charge = d3.forceManyBody().strength(-100).distanceMin(40).distanceMax(80); let charge = d3.forceManyBody().strength(-80).distanceMin(10).distanceMax(20);
let collision = d3.forceCollide().radius(45); let collision = d3.forceCollide(50).iterations(10).strength(0.5);
this.simulation = d3.forceSimulation(this.presentBindingSite.interactionNodes) this.simulation = d3.forceSimulation(this.presentBindingSite.interactionNodes)
.force('link', forceLink) .force('link', forceLink)
......
...@@ -182,8 +182,11 @@ namespace Model { ...@@ -182,8 +182,11 @@ namespace Model {
public containsResidue(n: Residue): boolean { public containsResidue(n: Residue): boolean {
return (this.target.residue.equals(n) || this.source.residue.equals(n)); return (this.target.residue.equals(n) || this.source.residue.equals(n));
}
} public getOtherNode(node: InteractionNode) {
return this.source.equals(node) ? this.target : this.source;
}
abstract getLinkClass(): string; abstract getLinkClass(): string;
abstract hasClash(): boolean; abstract hasClash(): boolean;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment