Commit 3cc4c357 authored by Lukas Pravda's avatar Lukas Pravda
Browse files

allow atom names to be displayed

parent d323cd99
...@@ -70,6 +70,7 @@ namespace Config { ...@@ -70,6 +70,7 @@ namespace Config {
residueLabel: boolean; residueLabel: boolean;
tooltip: boolean; tooltip: boolean;
menu: boolean; menu: boolean;
names: boolean;
constructor() { constructor() {
this.reinitialize = true; this.reinitialize = true;
...@@ -82,6 +83,7 @@ namespace Config { ...@@ -82,6 +83,7 @@ namespace Config {
this.residueLabel = true; this.residueLabel = true;
this.tooltip = true; this.tooltip = true;
this.menu = true; this.menu = true;
this.names = true;
} }
} }
} }
\ No newline at end of file
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
* @class Depiction * @class Depiction
* @param {string} ccdId PDB CCD id. * @param {string} ccdId PDB CCD id.
* @param {Atom[]} atoms List of atoms. * @param {Atom[]} atoms List of atoms.
* @param {Bond[]} bonds Visual representation of bonds. * @param {Bond[]} bonds Visual representation of bonds.
* They do not correlate 1:1 with a number of bonds! * They do not correlate 1:1 with a number of bonds!
* @param {Vector2D} resolution x,y dimension of the image. Needs to be used * @param {Vector2D} resolution x,y dimension of the image. Needs to be used
* for a scene shift, so it is centered. * for a scene shift, so it is centered.
*/ */
class Depiction { class Depiction {
ccdId: string; ccdId: string;
...@@ -39,7 +39,7 @@ class Depiction { ...@@ -39,7 +39,7 @@ class Depiction {
this.bonds = new Array<Bond>(); this.bonds = new Array<Bond>();
let bds = new Set<string>(); let bds = new Set<string>();
data.bonds.forEach(x => { data.bonds.forEach(x => {
let atomA = this.atoms.find(e => e.name == x.bgn); let atomA = this.atoms.find(e => e.name == x.bgn);
let atomB = this.atoms.find(e => e.name == x.end); let atomB = this.atoms.find(e => e.name == x.end);
...@@ -58,14 +58,14 @@ class Depiction { ...@@ -58,14 +58,14 @@ class Depiction {
/** /**
* Returns an initial position of Residue node bound to a list of * Returns an initial position of Residue node bound to a list of
* atom. * atom.
* *
* Present implementation sorts all the partners based on the atom * Present implementation sorts all the partners based on the atom
* degree and then gets the one with the lovest degree and places * degree and then gets the one with the lovest degree and places
* the initial residue position along the vector pointing from it. * the initial residue position along the vector pointing from it.
* *
* @param {string[]} atomNames list of atom names the bound residue * @param {string[]} atomNames list of atom names the bound residue
* has a contact with. * has a contact with.
* @returns {Vector2D} Returns an initial placement of the residue in contact. * @returns {Vector2D} Returns an initial placement of the residue in contact.
* @memberof Depiction * @memberof Depiction
...@@ -90,11 +90,13 @@ class Depiction { ...@@ -90,11 +90,13 @@ class Depiction {
return new Vector2D(x, y); return new Vector2D(x, y);
} }
public draw() { public draw(atom_names: boolean = false) {
this.structure.selectAll("*").remove(); this.structure.selectAll("*").remove();
this.appendBondVisuals(); this.appendBondVisuals();
this.appendTexts();
if (atom_names) this.appendAtomNames();
else this.appendLabels();
} }
public highlightSubgraph(atoms: Array<string>, color: string = undefined) { public highlightSubgraph(atoms: Array<string>, color: string = undefined) {
...@@ -145,17 +147,35 @@ class Depiction { ...@@ -145,17 +147,35 @@ class Depiction {
.attr('d', (y: Bond) => y.coords); .attr('d', (y: Bond) => y.coords);
} }
/**
* Append atom name labels to the visualization.
*
* @memberof Depiction
*/
private appendAtomNames() {
this.structure.selectAll()
.data(this.atoms)
.enter()
.append('text')
.attr('filter', "url(#solid-background)")
.attr('style', 'font-size:21px;font-style:normal;font-weight:normal;fill-opacity:1;stroke:none;font-family:sans-serif;fill:#000000')
.attr('x', x => x.position.x)
.attr('y', x => x.position.y)
.attr('dominant-baseline', 'central')
.attr('text-anchor', 'middle')
.text(x => x.name);
}
/** /**
* Append depiction labels to the visualization. Because RDKIt places * Append depiction labels to the visualization. Because RDKIt places
* the labels slightly differently this information needs to be * the labels slightly differently this information needs to be
* consumed too, because we cannot use just atom position directly. * consumed too, because we cannot use just atom position directly.
* Also there are all sorts of colorful subscripts and superscripts, * Also there are all sorts of colorful subscripts and superscripts,
* so it is much easier to use it this way. * so it is much easier to use it this way.
* *
* @memberof Depiction * @memberof Depiction
*/ */
private appendTexts(): void { private appendLabels() {
let data = this.atoms let data = this.atoms
.filter(x => x.labels.length > 0) .filter(x => x.labels.length > 0)
?.map(x => x.labels) ?.map(x => x.labels)
...@@ -172,7 +192,6 @@ class Depiction { ...@@ -172,7 +192,6 @@ class Depiction {
.attr('dominant-baseline', (x: any) => x['dominant-baseline']) .attr('dominant-baseline', (x: any) => x['dominant-baseline'])
.attr('text-anchor', (x: any) => x['text-anchor']) .attr('text-anchor', (x: any) => x['text-anchor'])
.each(function (x: any) { .each(function (x: any) {
for (var i = 0; i < x.tspans.length; i++) { for (var i = 0; i < x.tspans.length; i++) {
d3.select(this) d3.select(this)
.append('tspan') .append('tspan')
...@@ -243,7 +262,7 @@ class Atom { ...@@ -243,7 +262,7 @@ class Atom {
} }
/** /**
* *
* *
* @param {Atom} other * @param {Atom} other
* @returns true if the atoms are equal * @returns true if the atoms are equal
...@@ -310,7 +329,7 @@ class Vector2D { ...@@ -310,7 +329,7 @@ class Vector2D {
/** /**
* Composes vectors to a single one. This is used in infering the * Composes vectors to a single one. This is used in infering the
* original placement of the residue nodes. * original placement of the residue nodes.
* *
* @static * @static
...@@ -359,7 +378,7 @@ class Bond { ...@@ -359,7 +378,7 @@ class Bond {
/** /**
* Get the other atom for a given bond. * Get the other atom for a given bond.
* *
* @param {Atom} other * @param {Atom} other
* @returns {Atom} The other atom from the bond. * @returns {Atom} The other atom from the bond.
* @throws {Error} if the atom is not part of that bond at all. * @throws {Error} if the atom is not part of that bond at all.
* @memberof Bond * @memberof Bond
......
...@@ -17,7 +17,7 @@ class Visualization { ...@@ -17,7 +17,7 @@ class Visualization {
private links: any; private links: any;
// #endregion // #endregion
// #region data properties // #region data properties
private environment: Model.Environment; private environment: Model.Environment;
private pdbId: string; private pdbId: string;
private bindingSites: Model.BindingSite[]; private bindingSites: Model.BindingSite[];
...@@ -190,7 +190,7 @@ class Visualization { ...@@ -190,7 +190,7 @@ class Visualization {
/** /**
* Download bound molecule interactions data from PDBe Graph API end point * Download bound molecule interactions data from PDBe Graph API end point
* /pdb/bound_molecule_interactions * /pdb/bound_molecule_interactions
* *
* Correct parameters can be obtained using API call: * Correct parameters can be obtained using API call:
* /pdb/bound_molecules * /pdb/bound_molecules
* *
...@@ -212,7 +212,7 @@ class Visualization { ...@@ -212,7 +212,7 @@ class Visualization {
/** /**
* Download carbohydrate interactions data from PDBe Graph API end point * Download carbohydrate interactions data from PDBe Graph API end point
* /pdb/carbohydrate_polymer_interactions * /pdb/carbohydrate_polymer_interactions
* *
* Correct parameters can be obtained using API call: * Correct parameters can be obtained using API call:
* /pdb/bound_molecules * /pdb/bound_molecules
* *
...@@ -235,10 +235,10 @@ class Visualization { ...@@ -235,10 +235,10 @@ class Visualization {
/** /**
* Download ligand interactions data from PDBe Graph API end point * Download ligand interactions data from PDBe Graph API end point
* /pdb/bound_ligand_interactions. * /pdb/bound_ligand_interactions.
* *
* Correct parameters can be obtained using API call: * Correct parameters can be obtained using API call:
* /pdb/bound_molecules * /pdb/bound_molecules
* *
* @param {string} pdbId pdb id * @param {string} pdbId pdb id
* @param {number} resId residue number aka: auth_seq_id * @param {number} resId residue number aka: auth_seq_id
* @param {string} chainId chain id aka: auth_asym_id * @param {string} chainId chain id aka: auth_asym_id
...@@ -256,7 +256,7 @@ class Visualization { ...@@ -256,7 +256,7 @@ class Visualization {
} }
/** /**
* Download ligand structure given the anotation generated by the * Download ligand structure given the anotation generated by the
* PDBeChem process. * PDBeChem process.
* *
* @param {string} ligandId * @param {string} ligandId
...@@ -285,6 +285,10 @@ class Visualization { ...@@ -285,6 +285,10 @@ class Visualization {
this.depiction.draw(); this.depiction.draw();
} }
public toggleDepiction(atomNames: boolean) {
this.depiction.draw(atomNames);
}
/** /**
* Add atom highlight to the ligand structure. The previous highlight * Add atom highlight to the ligand structure. The previous highlight
...@@ -318,7 +322,7 @@ class Visualization { ...@@ -318,7 +322,7 @@ class Visualization {
/** /**
* Add ligand interactions to the canvas * Add ligand interactions to the canvas
* *
* @param {*} data Data content of the API end point * @param {*} data Data content of the API end point
* /pdb/bound_ligand_interactions * /pdb/bound_ligand_interactions
* @memberof Visualization * @memberof Visualization
*/ */
...@@ -344,7 +348,7 @@ class Visualization { ...@@ -344,7 +348,7 @@ class Visualization {
/** /**
* Add bound molecule interactions to the canvas. * Add bound molecule interactions to the canvas.
* *
* @param {*} data Data content of the API end point * @param {*} data Data content of the API end point
* /pdb/bound_molecule_interactions * /pdb/bound_molecule_interactions
* @param {string} bmId Bound molecule id * @param {string} bmId Bound molecule id
* @memberof Visualization * @memberof Visualization
...@@ -472,8 +476,8 @@ class Visualization { ...@@ -472,8 +476,8 @@ class Visualization {
private computeBoundingBox(minX: number, maxX: number, minY: number, maxY: number) { private computeBoundingBox(minX: number, maxX: number, minY: number, maxY: number) {
// The width and the height of the graph // The width and the height of the graph
let molWidth = (maxX - minX) + 1; // +1 to avoid 0 division let molWidth = Math.max((maxX - minX), this.parent.offsetWidth);
let molHeight = (maxY - minY) + 1; let molHeight = Math.max((maxY - minY), this.parent.offsetHeight);
// how much larger the drawing area is than the width and the height // how much larger the drawing area is than the width and the height
let widthRatio = this.parent.offsetWidth / molWidth; let widthRatio = this.parent.offsetWidth / molWidth;
...@@ -495,8 +499,7 @@ class Visualization { ...@@ -495,8 +499,7 @@ class Visualization {
this.canvas.attr('transform', `translate(${xTrans}, ${yTrans}) scale(${minRatio})`); this.canvas.attr('transform', `translate(${xTrans}, ${yTrans}) scale(${minRatio})`);
// tell the zoomer what we did so that next we zoom, it uses the // tell the zoomer what we did so that next we zoom, it uses the
// transformation we entered here // transformation we entered here
let translation = d3.zoomIdentity.translate(xTrans, yTrans).scale(minRatio); let translation = d3.zoomIdentity.translate(xTrans, yTrans).scale(minRatio);
this.zoomHandler?.transform(this.svg, translation); this.zoomHandler?.transform(this.svg, translation);
} }
...@@ -761,7 +764,7 @@ class Visualization { ...@@ -761,7 +764,7 @@ class Visualization {
this.simulation = d3.forceSimulation(this.presentBindingSite.interactionNodes) this.simulation = d3.forceSimulation(this.presentBindingSite.interactionNodes)
.force('link', forceLink) .force('link', forceLink)
.force('charge', charge) //strength .force('charge', charge) //strength
.force('collision', collision) .force('collision', collision)
.on('tick', () => this.simulationStep()); .on('tick', () => this.simulationStep());
...@@ -771,7 +774,7 @@ class Visualization { ...@@ -771,7 +774,7 @@ class Visualization {
/** /**
* Setup display of interactions for bound molecule. * Setup display of interactions for bound molecule.
* * This includes: setup of links, nodes, simulation and subscribing to relevant events. * * This includes: setup of links, nodes, simulation and subscribing to relevant events.
* No depiction is required for this step. * No depiction is required for this step.
* *
...@@ -818,7 +821,7 @@ class Visualization { ...@@ -818,7 +821,7 @@ class Visualization {
this.simulation = d3.forceSimulation(this.presentBindingSite.interactionNodes) this.simulation = d3.forceSimulation(this.presentBindingSite.interactionNodes)
.force('link', forceLink) .force('link', forceLink)
.force('charge', charge) //strength .force('charge', charge) //strength
.force('collision', collision) .force('collision', collision)
.force('center', center) .force('center', center)
.on('tick', () => this.simulationStep()); .on('tick', () => this.simulationStep());
......
...@@ -234,6 +234,15 @@ class UI { ...@@ -234,6 +234,15 @@ class UI {
.attr('class', 'icon icon-common icon-sync-alt') .attr('class', 'icon icon-common icon-sync-alt')
.on('click', () => this.reinitialize()); .on('click', () => this.reinitialize());
} }
if (p.reinitialize) {
dynamicPanel.append('i')
.attr('id', 'pdb-lig-env-names-btn')
.attr('title', 'Show/hide atom names')
.attr('class', 'icon icon-common icon-font')
.classed('active', false)
.on('click', () => this.showNames());
}
} }
if (p.tooltip) { if (p.tooltip) {
...@@ -299,6 +308,21 @@ class UI { ...@@ -299,6 +308,21 @@ class UI {
} }
} }
private showNames() {
let btn = d3.select(this.parent).select('#pdb-lig-env-names-btn');
let isActive = btn.classed('active');
if (isActive) {
this.display.toggleDepiction(true);
btn.style('color', '#637ca0');
btn.classed('active', false);
} else {
this.display.toggleDepiction(false);
btn.style('color', '');
btn.classed('active', true);
}
}
private showHelp() { private showHelp() {
let el = d3.select(this.parent).select('#pdb-lig-env-help-container'); let el = d3.select(this.parent).select('#pdb-lig-env-help-container');
let btn = d3.select(this.parent).select('#pdb-lig-env-help-btn'); let btn = d3.select(this.parent).select('#pdb-lig-env-help-btn');
......
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