Commit fdb6a976 authored by Nurul Nadzirin's avatar Nurul Nadzirin
Browse files

Merge branch 'dev' into 'master'

Dev

See merge request !1
parents 539f622c 4dab3b43
......@@ -2,5 +2,4 @@
.mypy_cache
node_modules
build/*.js*
build/app*
\ No newline at end of file
build/*
\ No newline at end of file
......@@ -2,9 +2,7 @@ image: node:latest
before_script:
- npm install
- npm install --save-dev webpack
- node_modules/.bin/webpack --mode=production
- node_modules/.bin/tsc
- npm run build
pages:
script:
......
# RELEASE 0.1 - 28 January 2019
## RELEASE 0.2 - 24 February 2020
Component rembranded to `pdb-ligand-env`
### Features
* A lot of bug fixes and under the hood improvements
## RELEASE 0.1 - 28 January 2019
First release for public testing.
## Features
### Features
* Bound molecule interactions view
* Residue-level interactions view
......
# PDB ligand environment component
This is a web-component to display ligand structure in 2D along with its interactions. Ligand can be perceived as a set of covalently linked pdb residues (refered to as bound molecule) or a single pdb residue. This depiction can be enriched with a substructure highlight and binding site interactions.
## Step after cloning (use local server to see demo pages)
```shell
npm run-script build
cp demo/demo* build/ (this copies demo_component.html and demo_plugin.html to build folder)
cd build
python3 -m http.server
```
## Component modes
* Mode A: Display bound molecule and its interactions
* Mode B: Display ligand and its interactions
* Mode C: Display ligand (chemical component) only
| Mode A | Mode B | Mode C |
|:------------------: | :-------: | :-------: |
| <img src="https://www.ebi.ac.uk/~lpravda/imgs/1cbs_REA_200_A.png"/>| <img src="https://www.ebi.ac.uk/~lpravda/imgs/3d12_bm1.png"/> | <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=VIA&size=500"/> |
| [1cbs REA 200 A](https://www.ebi.ac.uk/pdbe/entry/pdb/1cbs/bound/REA) | 3D12 bm1 (`2xGLC-2xBGC-LXZ-NGA-GL0`)| [wwPDB CCD - VIA](https://pdbe.org/chem/VIA)
## How to use it
The component can be inserted into the pages by two different ways. Either as a `web-component` using html tag, or directly by using javascript as a `plugin`.
### Web-component
A few files needs to be imported in the page before the component is attempted to be loaded:
```html
<!-- D3 -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
<!-- UI icons -->
<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
<!-- Web component polyfill (only loads what it needs) -->
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8"></script>
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
charset="utf-8"></script>
<!--PDBe interactions component-->
<script type="module" src="pdb-ligand-env-component-0.2.0-min.js"></script>
```
#### A) Ligand interactions
```html
<pdb-ligand-env pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-ligand-env>
```
#### B) Bound molecule interactions
```html
<pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1"></pdb-ligand-env>
```
#### C) Ligand/chemical component
```html
<pdb-ligand-env pdb-res-name="CLR" zoom-on ></pdb-ligand-env>
```
The component contains a number of properties that can be set, in order to change data that are being displayed. First you need to define a component on the page:
```html
<pdb-ligand-env id='SIA-component'></pdb-ligand-env>
```
and then inject data you want to display e.g.:
```javascript
let chemUrl = `https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/SIA/annotation`;
let interactionsURL = "https://wwwdev.ebi.ac.uk/pdbe/graph-api/pdb/bound_ligand_interactions/4yy1/A/604";
let component = document.getElementById('SIA-component');
const depiction = await (await fetch(chemUrl)).json();
const interactionsData = await (await fetch(interactionsURL)).json();
const atomsToHighlight = ['C10', 'C11', 'O10'];
component.depiction = depiction;
component.ligandHighlight = atomsToHighlight;
component.interactions = interactionsData;
```
### Plugin
The component can be also added to DOM directly from JavaScript. There are some requirements
```html
<!-- D3 -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
<!-- UI icons -->
<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
<!--PDB ligand environment plugin-->
<script src="pdb-ligand-env-plugin-min.js"></script>
<link rel="stylesheet" href="pdb-ligand-env.css" />
```
and then the component can be instantiated as simply as:
```javascript
let component = document.getElementById('SIA-component');
let uiParams = {
reinitialize: true, // allow reinitialize option in the component menu
zoom: true, // allow scene zoom
fullScreen: true, // allow allow full screen option in the component menu
downloadImage: true, // allow image download from the component menu
downloadData: true, // allow interactions data download from compoment menu
center: true, // allow scene centering option from the component menu
help: false, // allow help option from the component menu
residueLabel: true, // show residue label
tooltip: true // show residue tooltip on mouse hover
};
this.display = new Visualization(this, uiParams);
// to display bound molecule interactions
this.display.initBoundMoleculeInteractions('3d12', 'bm1');
// to display ligand interactions
this.display.initLigandInteractions('1cbs', 200, 'A');
// to display chemical component only
this.display.initLigandDisplay('HEM');
````
## Parameters
| Parametr | Type | Required | Description |
|-------------------- | --------- | -------- | ------- |
| pdb-id | string | No | PDB id of a protein to retrieve interactions from. `(mode A and B only)` |
| bound-molecule-id | string | No | PDB bound molecule id `(mode A only)` |
| pdb-res-name | string | No | PDB residue name aka: *auth_comp_id* `(mode C only)`
| pdb-res-id | number | No | PDB residue id aka: *auth_seq_id* `(mode B only)`
| pdb-chain-id | string | No | PDB residue chain aka: *auth_asym_id* `(mode B only)`|
| substructure | string[] | No | List of atom names to be highlighted on the ligand structure |
| color | string | No | HEX representation of the color highlight. `(Default: #D3D3D3)` |
| zoom-on | boolean | No | Allow zoom functionality on the component level. |
<!doctype html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
<!-- UI icons -->
<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
<!-- Web component polyfill (only loads what it needs) -->
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js"
charset="utf-8"></script>
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
charset="utf-8"></script>
<!--PDBe interactions component-->
<script type="module" src="pdb-ligand-env-component-0.2.0-min.js"></script>
</head>
<body>
<!--Mode A-->
<div style="position: relative; float: left;">
<div style="width: 500px; height: 500px; position: relative">
<pdb-ligand-env pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-ligand-env>
</div>
</div>
<!--Mode B-->
<div style="position: relative; float: left;">
<div style="width: 500px; height: 500px; position: relative">
<pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1"></pdb-ligand-env>
</div>
</div>
<!--Mode C-->
<div style="position: relative; float: left;">
<div style="width: 500px; height: 500px; position: relative">
<pdb-ligand-env pdb-res-name="CLR" zoom-on></pdb-ligand-env>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="pdb-ligand-env.css" />
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
<!-- UI icons -->
<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
<!-- Web component polyfill (only loads what it needs) -->
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js"
charset="utf-8"></script>
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
charset="utf-8"></script>
<!--PDBe interactions plugin-->
<script src="pdb-ligand-env-plugin-min.js"></script>
<!--Initialize Visualization-->
<script>
document.addEventListener("DOMContentLoaded", function (event) {
//<!--Mode A-->
var eleLigInteraction = document.getElementById('ligand-interaction');
this.lidisplay = new Visualization(eleLigInteraction, undefined);
this.lidisplay.initLigandInteractions('1cbs', 200, 'A');
//<!--Mode B-->
var eleBoundInteraction = document.getElementById('boundmolecule-interaction');
this.bmdisplay = new Visualization(eleBoundInteraction, undefined);
this.bmdisplay.initBoundMoleculeInteractions('3d12', 'bm1');
//<!--Mode C-->
var eleChemComp = document.getElementById('chem-comp');
this.ccdisplay = new Visualization(eleChemComp, undefined);
this.ccdisplay.initLigandDisplay('HEM');
});
</script>
</head>
<body>
<!--Mode A-->
<div style="position: relative; float: left;">
<div style="width: 600px; height: 600px; position: relative">
<div id='ligand-interaction'></div>
</div>
</div>
<!--Mode B-->
<div style="position: relative; float: left;">
<div style="width: 600px; height: 600px; position: relative">
<div id='boundmolecule-interaction'></div>
</div>
<!--Mode C-->
<div style="position: relative; float: left;">
<div style="width: 600px; height: 600px; position: relative">
<div id='chem-comp'></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
......@@ -3,8 +3,7 @@
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<!--testing purposes only-->
<link rel="stylesheet" href="pdbe-interactions-styles.css" />
<link rel="stylesheet" href="pdbe-interactions-svgstyles.css" />
<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
<!-- MOL* -->
......@@ -12,8 +11,6 @@
href="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/css/molstar-light-0.0.1.css">
<script src="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/js/molstar-0.0.1.js"></script>
<script src="app.js"></script>
<!-- Web component polyfill (only loads what it needs) -->
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8">
</script>
......@@ -21,16 +18,17 @@
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
charset="utf-8"></script>
<script type="module" src="component.js"></script>
<script type="module" src="pdb-ligand-env-component-0.2.0-min.js"></script>
<script>
var renderBmInteractions = function (id, bmId) {
var int = `<pdb-interactions pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
var int =
`<pdb-ligand-env style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-ligand-env>`
document.getElementById('rt').innerHTML = int;
};
var renderLigandInteractions = function (id, chain, resId) {
var int =
`<pdb-interactions pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}"></pdb-interactions>`
`<pdb-ligand-env style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-ligand-env>`
document.getElementById('rt').innerHTML = int;
};
......@@ -71,8 +69,6 @@
query: "https://wwwdev.ebi.ac.uk/pdbe/coordinates/1cbs/ligandInteraction?&authAsymId=$A&authSeqNumber=$200&radius=5&dataSource=hydrogens"
};
}
console.log('Perceived parameters:');
console.log(params);
if (params.bmid === undefined) {
renderLigandInteractions(params.pdbid, params.chain, params.resid);
......@@ -94,7 +90,11 @@
showPDBeLogo: false,
assemblyId: 'preferred', //'deposited'
// selectInteraction: false,
ligandView: {auth_asym_Id: params.chain, auth_seq_id: params.resid, hydrogens: true},
ligandView: {
auth_asym_Id: params.chain,
auth_seq_id: params.resid,
hydrogens: true
},
backgroundColour: '0xFFFFFF',
//customColorList: [0xff0000, 0x0000ff],
//representationStyle: representationStyle//,
......@@ -112,25 +112,30 @@
<body>
<div style="position: relative; float: left;">
<div id="rt" style="width: 500px; height: 500px; border: 1px solid black; position: relative">
<div id="rt" style="width: 500px; height: 500px; position: relative">
</div>
</div>
<div style="position: relative; float: left;">
<div id='3dViewer' style="position:relative; width: 500px;height: 500px;"></div>
</div>
<!-- <div style="position: relative; float: left;">
<div id="rt" style="width: 500px; height: 500px; border: 1px solid black; position: relative">
<pdb-interactions pdb-id="3d11" bound-molecule-id="bm1"></pdb-interactions>
</div> -->
<div style="position: relative; float: left;">
<div id="rt 1" style="width: 500px; height: 500px; position: relative">
<pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-ligand-env>
</div>
</div>
<div style="position: relative; float: left;">
<div id="rt 1" style="width: 500px; height: 500px; position: relative">
<pdb-ligand-env pdb-id="2aw3" bound-molecule-id="bm1" zoom-on></pdb-ligand-env>
</div>
</div>
<!--
Further use in the app for bound molecule interactions:
<pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
<pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1"></pdb-ligand-env>
for ligand interactions:
<pdb-interactions pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdb-interactions>
<pdb-ligand-env pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdb-ligand-env>
-->
<script>
......
const gulp = require('gulp');
const path = require('path');
const del = require('del');
const concat = require('gulp-concat');
const header = require('gulp-header');
const minify = require("gulp-minify");
const PACKAGE_ROOT_PATH = process.cwd();
const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
const banner = ['/**',
` * ${PKG_JSON.name}`,
` * @version ${PKG_JSON.version}`,
' * @link https://gitlab.ebi.ac.uk/pdbe/web-components/ligand-env',
' * @license Apache 2.0',
' */',
''
].join('\n');
const license = ['/**',
' * Copyright 2019-2020 Lukas Pravda <lpravda@ebi.ac.uk>',
' * European Bioinformatics Institute (EBI, http://www.ebi.ac.uk/)',
' * European Molecular Biology Laboratory (EMBL, http://www.embl.de/)',
' * Licensed under the Apache License, Version 2.0 (the "License");',
' * you may not use this file except in compliance with the License.',
' * You may obtain a copy of the License at ',
' * http://www.apache.org/licenses/LICENSE-2.0',
' * ',
' * Unless required by applicable law or agreed to in writing, software',
' * distributed under the License is distributed on an "AS IS" BASIS, ',
' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
' * See the License for the specific language governing permissions and ',
' * limitations under the License.',
' */',
''
].join('\n');
gulp.task('clean', function () {
return del([`build/${PKG_JSON.name}-component-${PKG_JSON.version}.js`, '!build']);
});
gulp.task('concatCSS', () => {
return gulp.src(['src/styles/pdb-ligand-env-svg.css'])
.pipe(concat(`${PKG_JSON.name}-svg.css`))
.pipe(header(license, {}))
.pipe(header(banner, {}))
.pipe(gulp.dest('build/'));
});
gulp.task('copyIndex', () => {
return gulp.src(['dependencies/index.html'])
.pipe(concat(`index.html`))
.pipe(gulp.dest('build/'));
});
gulp.task('copyMapping', () => {
return gulp.src(['dependencies/het_mapping.json'])
.pipe(concat(`het_mapping.json`))
.pipe(gulp.dest('build/'));
});
gulp.task('copyXML', () => {
return gulp.src(['dependencies/pdb-snfg-visuals.xml'])
.pipe(concat(`pdb-snfg-visuals.xml`))
.pipe(gulp.dest('build/'));
});
gulp.task('concat', () => {
return gulp.src([`build/${PKG_JSON.name}-plugin.js`, `build/${PKG_JSON.name}-component-init.js`])
.pipe(concat(`${PKG_JSON.name}-component-${PKG_JSON.version}.js`))
.pipe(header(license, {}))
.pipe(header(banner, {}))
.pipe(minify({
noSource: true
}))
.pipe(gulp.dest('build/'));
});
gulp.task('minifyPlugin', () => {
return gulp.src([`build/${PKG_JSON.name}-plugin.js`])
.pipe(concat(`${PKG_JSON.name}-plugin.js`))
.pipe(header(license, {}))
.pipe(header(banner, {}))
.pipe(minify({
noSource: true
}))
.pipe(gulp.dest('build/'));
});
gulp.task('default', gulp.series('clean', 'concat', 'concatCSS',
'copyXML', 'copyIndex', 'copyMapping', 'minifyPlugin'));
\ No newline at end of file
This diff is collapsed.
{
"name": "interactions",
"version": "1.0.0",
"name": "pdb-ligand-env",
"version": "0.2.0",
"description": "",
"main": "app.js",
"dependencies": {
"@types/d3": "^5.0.1",
"@types/d3-tip": "^3.5.5",
"d3": "^5.7.0",
"d3": "^5.15.0",
"d3-tip": "^0.9.1",
"d3scription": "^1.0.1",
"lit-element": "^2.1.0",
"typescript": "^3.1.6"
"lit-element": "^2.2.1",
"typescript": "^3.7.4"
},
"devDependencies": {
"@babel/core": "^7.3.3",
"@babel/plugin-transform-runtime": "^7.2.0",
"@babel/preset-env": "^7.3.1",
"@babel/runtime": "^7.3.1",
"@webcomponents/webcomponentsjs": "^2.1.3",
"@babel/core": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@babel/runtime": "^7.8.3",
"@webcomponents/webcomponentsjs": "^2.4.1",
"babel-loader": "^8.0.5",
"browser-sync": "^2.26.7",
"camelcase": "^5.0.0",
"clean-webpack-plugin": "^1.0.1",
"css-loader": "^2.1.0",
"del": "^5.1.0",
"eslint": "^4.12.0",
"file-loader": "^3.0.1",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-header": "^2.0.9",
"gulp-minify": "^3.1.0",
"live-server": "^1.2.1",
"npm-run-all": "^4.1.3",
"onchange": "^6.1.0",
"style-loader": "^0.23.1",
"ts-node": "^7.0.1",
"url-loader": "^1.1.2",
......@@ -34,12 +40,12 @@
"webpack-cli": "^3.3.10"
},
"scripts": {
"tsc:w": "tsc -w",
"prestart": "tsc",
"serve": "live-server build --watch=src/**/*.html,src/bundle.js,src/**/*.css",
"start": "npm-run-all --parallel serve tsc:w",
"webpack": "webpack",
"buildComponent": "webpack --mode=development"
"tscW": "tsc -w",
"serve": "live-server build --watch=build",
"start": "npm-run-all --parallel watch serve",
"build": "tsc && webpack --mode=development && gulp",
"watch": "onchange 'src/**/*' -- npm run build",
"buildProduction": "tsc && webpack --mode=production && gulp"
},
"author": "Lukas Pravda",
"license": "Apache License 2.0"
......
// Import the LitElement base class and html helper function
import { LitElement, html } from 'lit-element';
// Extend the LitElement base class
class pdbInteractions extends LitElement {
//Get properties / attribute values
static get properties() {
return {
'pdb-id': { type: String },
'bound-molecule-id': { type: String },
'pdb-res-id': { type: Number },
'pdb-chain-id': { type: String }
};
}
constructor() {
super();
}
render() {
return html`
${!this['pdb-id'] ?
html`<div style='text-align:center;font-weight:bold;margin-top:20px;'>Error: Specify valid 'pdb-id' attribute to render the component.<div>` :
html``
}
`;
}
updated(changedProperties) {
if (this['pdb-id']) {
this.display = new Visualization(this);
if (this['bound-molecule-id']) {
this.display.initialiseBoundMolecule(this['pdb-id'], this['bound-molecule-id']);
}
else {
this.display.initialiseLigand(this['pdb-id'], this['pdb-res-id'], this['pdb-chain-id'])