ui.ts 14.1 KB
Newer Older
Lukas Pravda's avatar
Lukas Pravda committed
1 2
// #region help
let helpLigands = `
3
    <table class='pdb-lig-env-help-table'>
Lukas Pravda's avatar
Lukas Pravda committed
4 5
        <tr>
            <td>
6
                <div class="pdb-lig-env-help-residue" style="background: #80A0F0; "></div>
Lukas Pravda's avatar
Lukas Pravda committed
7
            </td>
8
            <td>hydrophobic</td>
Lukas Pravda's avatar
Lukas Pravda committed
9
            <td>
10
                <div class="pdb-lig-env-help-residue" style="background: #C048C0;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
11
            </td>
Lukas Pravda's avatar
Lukas Pravda committed
12
            <td>negatively charged</td>
Lukas Pravda's avatar
Lukas Pravda committed
13 14 15
        </tr>
        <tr>
            <td>
16
                <div class="pdb-lig-env-help-residue" style="background: #15A4A4;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
17 18 19
            </td>
            <td>aromatic</td>
            <td>
20
                <div class="pdb-lig-env-help-residue" style="background: #15C015;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
21
            </td>
22 23
            <td>polar</td>
            <td>
Lukas Pravda's avatar
Lukas Pravda committed
24 25 26
        </tr>
        <tr>
            <td>
27
                <div class="pdb-lig-env-help-residue" style="background: #F08080;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
28
            </td>
Lukas Pravda's avatar
Lukas Pravda committed
29
            <td>cystein</td>
Lukas Pravda's avatar
Lukas Pravda committed
30
            <td>
31
                <div class="pdb-lig-env-help-residue" style="background: #00BFFF;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
32
            </td>
Lukas Pravda's avatar
Lukas Pravda committed
33
            <td>water</td>
Lukas Pravda's avatar
Lukas Pravda committed
34 35 36
        </tr>
        <tr>
            <td>
37
                <div class="pdb-lig-env-help-residue" style="background: #F01505;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
38
            </td>
Lukas Pravda's avatar
Lukas Pravda committed
39
            <td>positively charged</td>
Lukas Pravda's avatar
Lukas Pravda committed
40
            <td>
41
                <div class="pdb-lig-env-help-residue" style="background: #F2F2F2;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
42
            </td>
Lukas Pravda's avatar
Lukas Pravda committed
43
            <td>other</td>
Lukas Pravda's avatar
Lukas Pravda committed
44 45 46
        </tr>
        <tr>
            <td>
47
                 <div class="pdb-lig-env-help-residue" style="background: #F09048;"></div>
48
            </td>
Lukas Pravda's avatar
Lukas Pravda committed
49
            <td>glycine</td>
50
            <td>
51
                <div class="pdb-lig-env-help-residue" style="background: white; border: 1.2px solid black;"></div>
Lukas Pravda's avatar
Lukas Pravda committed
52 53
            </td>
            <td>bound molecule</td>
54 55 56 57 58 59
        </tr>
        <tr>
        <td></td>
        <td><a href="https://www.ncbi.nlm.nih.gov/glycans/snfg.html" target="blank">glycans (SNFG)</a></td>
        <td></td>
        <td></td>
Lukas Pravda's avatar
Lukas Pravda committed
60 61 62 63
        </tr>
    </table>
    `
let helpBonds = `
64
<table class='pdb-lig-env-help-table' style="border-bottom: 0.5px solid black; padding-bottom: 10px;">
Lukas Pravda's avatar
Lukas Pravda committed
65 66
<tr>
    <td>
Lukas Pravda's avatar
Lukas Pravda committed
67
        <hr style="border: 0 none; border-top: 5px dashed #AD4379; background: none; height: 0;" />
Lukas Pravda's avatar
Lukas Pravda committed
68 69 70
    </td>
    <td>aromatic</td>
    <td>
Lukas Pravda's avatar
Lukas Pravda committed
71
            <hr style="border: 0 none; border-top: 5px dashed #FF5050; background: none; height: 0;" />
Lukas Pravda's avatar
Lukas Pravda committed
72 73 74 75 76 77 78 79 80
    </td>
    <td>clashes</td>
</tr>
<tr>
    <td>
            <hr style="border: 0 none; border-top: 5px solid black; background: none; height: 0;" />
    </td>
    <td>covalent</td>
    <td>
Lukas Pravda's avatar
Lukas Pravda committed
81
            <hr style="border: 0 none; border-top: 5px dashed #3F26BF; background: none; height: 0;" />
Lukas Pravda's avatar
Lukas Pravda committed
82 83 84 85 86 87
    </td>
    <td>electrostatic</td>

</tr>
<tr>
    <td>
Lukas Pravda's avatar
Lukas Pravda committed
88
        <hr style="border: 0 none; border-top: 5px solid #008080; background: none; height: 0;" />
Lukas Pravda's avatar
Lukas Pravda committed
89 90 91 92 93 94 95 96
    </td>
    <td>metal</td>
    <td></td>
    <td>hydrophobic</td>
</tr>

<tr>
    <td>
Lukas Pravda's avatar
Lukas Pravda committed
97
        <hr style="border: 0 none; border-top: 5px dashed #9B7653; background: none; height: 0;" />
Lukas Pravda's avatar
Lukas Pravda committed
98 99 100 101
    </td>
    <td>vdw</td>
</tr>
</table>`
Lukas Pravda's avatar
Lukas Pravda committed
102 103 104 105 106 107 108 109 110 111
// <table class="pdb-lig-env-help-table" style="margin-top: 5px;">
// <tr>
//     <td>
//         <hr style="border: 0 none; border-top: 5px solid black; background: none; height: 0;" />
//     </td>
//     <td>covalent</td>
//     <td>
//         <hr style="border: 0 none; border-top: 5px dashed black; background: none; height: 0;" />
//     </td>
//     <td>non-covalent</td>
Lukas Pravda's avatar
Lukas Pravda committed
112
// </tr>
Lukas Pravda's avatar
Lukas Pravda committed
113
// </table>`
Lukas Pravda's avatar
Lukas Pravda committed
114 115 116 117 118 119

// #endregion help



class UI {
Lukas Pravda's avatar
Lukas Pravda committed
120
    private parent: HTMLElement;
Lukas Pravda's avatar
Lukas Pravda committed
121 122
    private display: Visualization;

Lukas Pravda's avatar
Lukas Pravda committed
123 124 125 126 127
    private residueLabel: d3.Selection<d3.BaseType, {}, HTMLElement, any>; //label used to display ligand ids
    private tooltip: d3.Selection<d3.BaseType, {}, HTMLElement, any>; // mouseover tooltips

    private originalWidth: number;
    private originalHeight: number;
Lukas Pravda's avatar
Lukas Pravda committed
128 129 130


    constructor(element: HTMLElement, vis: Visualization) {
Lukas Pravda's avatar
Lukas Pravda committed
131
        this.parent = element;
Lukas Pravda's avatar
Lukas Pravda committed
132 133
        this.display = vis;

Lukas Pravda's avatar
Lukas Pravda committed
134 135 136 137
        this.originalWidth = this.parent.offsetWidth;
        this.originalHeight = this.parent.offsetHeight;


Lukas Pravda's avatar
Lukas Pravda committed
138 139
    }

Lukas Pravda's avatar
Lukas Pravda committed
140 141 142 143
    /**
     * Registers UI elements on the top of SVG canvas with interactions
     * and ligands
     *
144
     * @param {Config.UIParameters} p Object with annotation which
Lukas Pravda's avatar
Lukas Pravda committed
145 146 147 148
     * UI elements should be created.
     * @returns
     * @memberof UI
     */
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
    public register(p: Config.UIParameters) {
        let toolbar = undefined;
        let dynamicPanel = undefined;

        if (p.menu) {
            toolbar = d3.select(this.parent)
                .append('div')
                .classed('pdb-lig-env-toolbar-container', true)
                .on('mouseover', () => this.displayToolbarPanel(true))
                .on('mouseout', () => this.displayToolbarPanel(false));

            toolbar.append('div')
                .classed('pdb-lig-env-menu-panel', true)
                .append('i')
                .attr('title', 'Menu')
                .attr('class', 'icon icon-common icon-bars');

            dynamicPanel = toolbar.append('div')
                .classed('pdb-lig-env-menu-panel', true)
                .attr('id', 'pdb-lig-env-menu-dynamic-panel')
                .style('display', 'none')
                .style('opacity', 0);

            if (p.help) {
                dynamicPanel.append('i')
                    .attr('id', 'pdb-lig-env-help-btn')
                    .attr('title', 'Help')
                    .attr('class', 'icon icon-common icon-question-circle')
                    .on('click', () => this.showHelp());

                let cont = d3.select(this.parent).append('div').attr('id', 'pdb-lig-env-help-container')
                let navbar = cont.append('div').classed('pdb-lig-env-help-navbar', true);

                navbar.append('a')
                    .classed('active', true)
                    .attr('id', 'pdb-lig-env-help-residues-btn')
                    .text('Ligands and residues')
                    .on('click', () => this.changeHelp(true));

                navbar.append('a')
                    .attr('id', 'pdb-lig-env-help-bonds-btn')
                    .text('Interactions')
                    .on('click', () => this.changeHelp(false));

                cont.append('div').attr('id', 'pdb-lig-env-help-ligands').html(helpLigands);
                cont.append('div').attr('id', 'pdb-lig-env-help-bonds').html(helpBonds);
            }

            if (p.downloadImage) {
                dynamicPanel.append('i')
                    .attr('id', 'pdb-lig-env-screenshot-btn')
                    .attr('title', 'Screenshot')
                    .attr('class', 'icon icon-common icon-camera')
                    .on('click', () => this.saveSVG());
            }

            if (p.downloadData) {
                dynamicPanel.append('i')
                    .attr('id', 'pdb-lig-env-download-btn')
                    .attr('title', 'Download interactions')
                    .attr('class', 'icon icon-common icon-download')
                    .on('click', () => this.download());
            }


            if (p.center) {
                dynamicPanel.append('i')
                    .attr('id', 'pdb-lig-env-center-btn')
                    .attr('title', 'Center screen')
                    .attr('class', 'icon icon-common icon-crosshairs')
                    .on('click', () => this.center());
            }

            if (p.fullScreen) {
                dynamicPanel.append('i')
                    .attr('id', 'pdb-lig-env-fullscreen-btn')
                    .attr('title', 'Toggle Expanded')
                    .attr('class', 'icon icon-common icon-fullscreen')
                    .on('click', () => this.fullScreen());
            }

            if (p.reinitialize) {
                dynamicPanel.append('i')
                    .attr('id', 'pdb-lig-env-home-btn')
                    .attr('title', 'Reinitialize')
                    .attr('class', 'icon icon-common icon-sync-alt')
                    .on('click', () => this.reinitialize());
            }
237 238 239 240 241 242 243 244 245

            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());
            }
Lukas Pravda's avatar
Lukas Pravda committed
246 247
        }

248
        if (p.tooltip) {
Lukas Pravda's avatar
Lukas Pravda committed
249
            this.tooltip = d3.select(this.parent).append('div')
250 251
                .classed('pdb-lig-env-label', true)
                .attr('id', 'pdb-lig-env-tooltip')
Lukas Pravda's avatar
Lukas Pravda committed
252 253 254
                .style('opacity', 0)
        }

255
        if (p.residueLabel) {
Lukas Pravda's avatar
Lukas Pravda committed
256
            this.residueLabel = d3.select(this.parent).append('div')
257 258
                .classed('pdb-lig-env-label', true)
                .attr('id', 'pdb-lig-env-residue-label')
Lukas Pravda's avatar
Lukas Pravda committed
259 260 261
                .style('opacity', 0)
        }

262
        if (this.tooltip !== undefined) {
Lukas Pravda's avatar
Lukas Pravda committed
263 264 265
            this.parent.addEventListener(Config.interactionClickEvent, e => this.nodeMouseEnterEventHandler(e));
            this.parent.addEventListener(Config.interactionMouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
            this.parent.addEventListener(Config.interactionMouseoutEvent, () => this.nodeMouseLeaveEventHandler());
266 267 268
        }

        if (this.residueLabel !== undefined) {
Lukas Pravda's avatar
Lukas Pravda committed
269 270
            this.parent.addEventListener(Config.interactionShowLabelEvent, e => this.showLigandLabel(e));
            this.parent.addEventListener(Config.interactionHideLabelEvent, () => this.hideLigandLabel());
271
        }
Lukas Pravda's avatar
Lukas Pravda committed
272 273 274 275
    }

    // #region UI methods
    private saveSVG() {
Lukas Pravda's avatar
Lukas Pravda committed
276
        this.display.saveSvg();
Lukas Pravda's avatar
Lukas Pravda committed
277 278 279
    }

    private reinitialize() {
Lukas Pravda's avatar
Lukas Pravda committed
280
        this.display.reinitialize()
Lukas Pravda's avatar
Lukas Pravda committed
281 282 283
    }

    private download() {
Lukas Pravda's avatar
Lukas Pravda committed
284
        this.display.downloadInteractionsData()
Lukas Pravda's avatar
Lukas Pravda committed
285 286 287
    }

    private center() {
Lukas Pravda's avatar
Lukas Pravda committed
288
        this.display.centerScene()
Lukas Pravda's avatar
Lukas Pravda committed
289 290 291
    }

    private changeHelp(showResidues: boolean) {
292 293 294 295
        let ligHelpBtn = d3.select(this.parent).select('#pdb-lig-env-help-residues-btn');
        let bondHelpBtn = d3.select(this.parent).select('#pdb-lig-env-help-bonds-btn');
        let bondHelpSection = d3.select(this.parent).select('#pdb-lig-env-help-bonds');
        let ligHelpSection = d3.select(this.parent).select('#pdb-lig-env-help-ligands');
Lukas Pravda's avatar
Lukas Pravda committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310

        if (showResidues) {
            bondHelpBtn.classed('active', false);
            ligHelpBtn.classed('active', true);
            bondHelpSection.style('display', 'none');
            ligHelpSection.style('display', 'block');

        } else {
            ligHelpBtn.classed('active', false);
            bondHelpBtn.classed('active', true);
            bondHelpSection.style('display', 'block');
            ligHelpSection.style('display', 'none');
        }
    }

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
    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);
        }
    }

Lukas Pravda's avatar
Lukas Pravda committed
326
    private showHelp() {
327 328
        let el = d3.select(this.parent).select('#pdb-lig-env-help-container');
        let btn = d3.select(this.parent).select('#pdb-lig-env-help-btn');
Lukas Pravda's avatar
Lukas Pravda committed
329 330 331 332 333 334 335 336 337 338 339 340

        if (el.style('display') === 'block') {
            el.style('display', 'none');
            el.style('opacity', 0);
            btn.style('color', '');
        } else {
            el.style('display', 'block');
            el.style('opacity', 1);
            btn.style('color', '#637ca0');
        }
    }

Lukas Pravda's avatar
Lukas Pravda committed
341
    private displayToolbarPanel(show: boolean) {
342 343
        let dynPanel = d3.select(this.parent).select('#pdb-lig-env-menu-dynamic-panel');
        let el = d3.select(this.parent).select('#pdb-lig-env-help-container');
Lukas Pravda's avatar
Lukas Pravda committed
344 345 346 347 348 349 350 351 352 353 354 355 356

        if (!dynPanel && !el) return;

        if (show || el.style('display') === 'block') {
            dynPanel.style('display', 'block');
            dynPanel.style('opacity', 0.9);
        } else {

            dynPanel.style('display', 'none');
            dynPanel.style('opacity', 0);
        }
    }

Lukas Pravda's avatar
Lukas Pravda committed
357 358 359 360 361 362
    /**
     * Switch component view and full screen.
     *
     * @private
     * @memberof UI
     */
Lukas Pravda's avatar
Lukas Pravda committed
363
    private fullScreen() {
364
        let btn = d3.select(this.parent).select('#pdb-lig-env-fullscreen-btn');
Lukas Pravda's avatar
Lukas Pravda committed
365 366

        if (btn.attr('class') === 'icon icon-common icon-fullscreen') {
367 368
            this.display.fullScreen = true;

Lukas Pravda's avatar
Lukas Pravda committed
369 370 371
            this.parent.parentElement.style.width = '100%'
            this.parent.parentElement.style.height = '100%'
            this.parent.parentElement.style.position = 'fixed';
Lukas Pravda's avatar
Lukas Pravda committed
372 373
            this.parent.parentElement.style.top = '0';
            this.parent.parentElement.style.left = '0';
Lukas Pravda's avatar
Lukas Pravda committed
374 375
            this.parent.parentElement.style.zIndex = '10000000000000';

Lukas Pravda's avatar
Lukas Pravda committed
376 377
            btn.classed('icon-fullscreen', false);
            btn.classed('icon-fullscreen-collapse', true);
Lukas Pravda's avatar
Lukas Pravda committed
378 379

            this.display.centerScene();
Lukas Pravda's avatar
Lukas Pravda committed
380
        } else {
Lukas Pravda's avatar
Lukas Pravda committed
381
            this.display.fullScreen = true;
Lukas Pravda's avatar
Lukas Pravda committed
382 383 384 385 386 387

            this.parent.parentElement.style.width = `${this.originalWidth}px`;
            this.parent.parentElement.style.height = `${this.originalHeight}px`;
            this.parent.parentElement.style.position = 'relative';
            this.parent.parentElement.style.zIndex = '';

388 389 390
            btn.classed('icon-fullscreen', true);
            btn.classed('icon-fullscreen-collapse', false);

Lukas Pravda's avatar
Lukas Pravda committed
391 392 393
            this.display.centerScene();


Lukas Pravda's avatar
Lukas Pravda committed
394 395
        }
    }
Lukas Pravda's avatar
Lukas Pravda committed
396
    // #endregion UI methods
397 398 399

    // #region event handlers
    private nodeMouseEnterEventHandler(e: any) {
Lukas Pravda's avatar
Lukas Pravda committed
400

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
        this.tooltip.transition()
            .duration(200)
            .style('opacity', .9);

        this.tooltip.html(e.detail.tooltip);

    }

    private nodeMouseLeaveEventHandler() {
        this.tooltip.transition()
            .duration(200)
            .style('opacity', 0);

    }

    private showLigandLabel(e: any) {
        this.residueLabel.transition()
            .duration(200)
            .style('opacity', .9);

        this.residueLabel.html(e.detail.label);

    }

    private hideLigandLabel() {
        this.residueLabel.transition()
            .duration(200)
            .style('opacity', 0);
    }
    // #endregion event handlers

Lukas Pravda's avatar
Lukas Pravda committed
432
}