icn3d 3.50.1 → 3.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/icn3d.module.js CHANGED
@@ -59492,7 +59492,7 @@ class ClickMenu {
59492
59492
  let definedAtomsHtml = ic.definedSetsCls.setAtomMenu(['protein'], bNucleotides);
59493
59493
  if($("#" + me.pre + "atomsCustomNucleotide").length && definedAtomsHtml) {
59494
59494
  $("#" + me.pre + "atomsCustomNucleotide").html(definedAtomsHtml);
59495
- me.htmlCls.dialogCls.openDlg('dl_2ddgm_r2dt', 'Show R2DT Diagram for Nucleotides');
59495
+ me.htmlCls.dialogCls.openDlg('dl_2ddgm_r2dt', 'Show R2DT Diagram for RNAs');
59496
59496
  $("#" + me.pre + "atomsCustomNucleotide").resizable();
59497
59497
  }
59498
59498
  else {
@@ -61421,7 +61421,7 @@ class SetMenu {
61421
61421
 
61422
61422
  html += this.getMenuText('2ddgmwrap', '2D Diagram', undefined, 1, 1);
61423
61423
  html += "<ul>";
61424
- html += this.getLink('2ddgm_r2dt', 'for Nucleotides' + me.htmlCls.wifiStr, 1, 2);
61424
+ html += this.getLink('2ddgm_r2dt', 'for RNAs' + me.htmlCls.wifiStr, 1, 2);
61425
61425
  html += this.getLink('2ddgm_igdgm', 'for Ig Domains' + me.htmlCls.wifiStr, 1, 2);
61426
61426
  if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined || me.cfg.align !== undefined || me.cfg.chainalign !== undefined) {
61427
61427
  html += this.getLink('mn2_2ddgm', 'for Chains ' + me.htmlCls.wifiStr, 1, 2);
@@ -61874,6 +61874,7 @@ class Dialog {
61874
61874
  let bLigplot = $('#' + me.pre + 'dl_ligplot').hasClass('ui-dialog-content'); // initialized
61875
61875
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
61876
61876
  let b2ddiagram = $('#' + me.pre + 'dl_2ddiagram').hasClass('ui-dialog-content'); // initialized
61877
+ let big2ddgm = $('#' + me.pre + 'dl_ig2ddgm').hasClass('ui-dialog-content'); // initialized
61877
61878
  let brnacanvas = $('#' + me.pre + 'dl_rnacanvas').hasClass('ui-dialog-content'); // initialized
61878
61879
  let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
61879
61880
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
@@ -61896,6 +61897,7 @@ class Dialog {
61896
61897
  id2flag.dl_contactmap = 'bContactmap2';
61897
61898
  id2flag.dl_2ddiagram = 'b2ddiagram2';
61898
61899
  id2flag.dl_rnacanvas = 'brnacanvas2';
61900
+ id2flag.dl_ig2ddgm = 'big2ddgm2';
61899
61901
  id2flag.dl_alignerrormap = 'bAlignerrormap2';
61900
61902
  id2flag.dl_interactionsorted = 'bTable2';
61901
61903
  id2flag.dl_alignment = 'bAlignmentInit2';
@@ -61913,6 +61915,7 @@ class Dialog {
61913
61915
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
61914
61916
  if(b2ddiagram) status.b2ddiagram2 = $('#' + me.pre + 'dl_2ddiagram').dialog( 'isOpen' );
61915
61917
  if(brnacanvas) status.brnacanvas2 = $('#' + me.pre + 'dl_rnacanvas').dialog( 'isOpen' );
61918
+ if(big2ddgm) status.big2ddgm2 = $('#' + me.pre + 'dl_ig2ddgm').dialog( 'isOpen' );
61916
61919
  if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
61917
61920
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
61918
61921
  if(bAlignmentInit) status.bAlignmentInit2 = $('#' + me.pre + 'dl_alignment').dialog( 'isOpen' );
@@ -62100,7 +62103,7 @@ class Dialog {
62100
62103
 
62101
62104
  let status = this.getDialogStatus().status;
62102
62105
 
62103
- if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_rmsdplot' || id === me.pre + 'dl_hbondplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_2ddiagram' || id === me.pre + 'dl_rnacanvas' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
62106
+ if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_rmsdplot' || id === me.pre + 'dl_hbondplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_2ddiagram' || id === me.pre + 'dl_rnacanvas' || id === me.pre + 'dl_ig2ddgm' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
62104
62107
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
62105
62108
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
62106
62109
 
@@ -63066,19 +63069,19 @@ class SetDialog {
63066
63069
  html += "</div>";
63067
63070
 
63068
63071
  html += me.htmlCls.divStr + "dl_2ddgm_r2dt' class='" + dialogClass + "'>";
63069
- html += this.addNotebookTitle('dl_2ddgm_r2dt', '2D Diagram for Nucleotides (R2DT)');
63070
- html += "1. Select a nucleotide chain to show 2D diagram:<br>";
63072
+ html += this.addNotebookTitle('dl_2ddgm_r2dt', '2D Diagram for RNAs (R2DT)');
63073
+ html += "1. Select a RNA chain to show 2D diagram:<br>";
63071
63074
  html += "<select style='max-width:200px' id='" + me.pre + "atomsCustomNucleotide' size='5' style='min-width:130px;'>";
63072
63075
  html += "</select><br>";
63073
63076
  html += "2. " + me.htmlCls.buttonStr + "applyr2dt'>R2DT Diagram</button>" + me.htmlCls.buttonStr + "applyfr3d' style='margin-left:12px'>2D Diagram with RNAcanvas</button><br><br>(Hints: Click on Residues in 2D to highlight in 3D. <br>Ctrl + click to select multiple residues.)<br>";
63074
63077
  html += "</div>";
63075
63078
 
63076
63079
  html += me.htmlCls.divStr + "dl_2ddgm_igdgm' class='" + dialogClass + "'>";
63077
- html += this.addNotebookTitle('dl_2ddgm_igdgm', '2D Diagram for Ig Domains (R2DT)');
63080
+ html += this.addNotebookTitle('dl_2ddgm_igdgm', '2D Diagram for Ig Domains');
63078
63081
  html += "1. Select a protein chain to show Ig diagram. An Excel file containing <br>the Ig diagram will be saved to your computer.<br>";
63079
63082
  html += "<select style='max-width:200px' id='" + me.pre + "atomsCustomProtein' size='5' style='min-width:130px;'>";
63080
63083
  html += "</select><br>";
63081
- html += me.htmlCls.buttonStr + "applyigdgm'>Show Ig Diagram</button><br>";
63084
+ html += "2. " + me.htmlCls.buttonStr + "applyigdgm' style='margin-right:12px;'>Show Ig Diagram</button>" + me.htmlCls.buttonStr + "saveigdgm'>Download Ig Diagrams in Excel</button><br>";
63082
63085
  html += "</div>";
63083
63086
 
63084
63087
  html += me.htmlCls.divStr + "dl_hbonds' class='" + dialogClass + "'>";
@@ -63436,6 +63439,20 @@ class SetDialog {
63436
63439
  html += '<div id="' + me.pre + 'rnacanvasDiv"></div>';
63437
63440
  html += "</div>";
63438
63441
 
63442
+
63443
+ me.ig2ddgmid = me.pre + 'ig2ddgm';
63444
+ html += me.htmlCls.divStr + "dl_ig2ddgm' style='background-color:white' class='" + dialogClass + "'>";
63445
+ html += this.addNotebookTitle('dl_ig2ddgm', '2D Diagram for Ig domains');
63446
+
63447
+ html += "<table><tr><td>Select an Ig domain:<br>";
63448
+ html += me.htmlCls.divNowrapStr + "<select id='" + me.pre + "iglist' size='2' style='min-width:130px;'>";
63449
+ html += "</select></td><td valign='top'>";
63450
+ html += me.htmlCls.space2 + buttonStrTmp + me.ig2ddgmid + '_svg">Download SVG</button></td></tr></table><br>';
63451
+
63452
+ html += '<div id="' + me.pre + 'ig2ddgmDiv"></div>';
63453
+ html += "</div>";
63454
+
63455
+
63439
63456
  html += me.htmlCls.divStr + "dl_alignerrormap' style='background-color:white' class='" + dialogClass + "'>";
63440
63457
  html += this.addNotebookTitle('dl_alignerrormap', 'PAE Map');
63441
63458
 
@@ -66708,7 +66725,17 @@ class Events {
66708
66725
  thisClass.setLogCmd('diagram 2d fr3d | ' + chainid, true);
66709
66726
  });
66710
66727
 
66711
- me.myEventCls.onIds("#" + me.pre + "applyigdgm", "click", async function(e) { let ic = me.icn3d;
66728
+ me.myEventCls.onIds("#" + me.pre + "saveigdgm", "click", async function(e) { let ic = me.icn3d;
66729
+ e.preventDefault();
66730
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
66731
+
66732
+ let chainid = $("#" + ic.pre + "atomsCustomProtein").val();
66733
+
66734
+ let bSave = true;
66735
+ await ic.diagram2dCls.drawIgdgm(chainid, bSave);
66736
+ thisClass.setLogCmd('download 2d ig | ' + chainid, true);
66737
+ });
66738
+ me.myEventCls.onIds("#" + me.pre + "applyigdgm", "click", async function(e) { let ic = me.icn3d;
66712
66739
  e.preventDefault();
66713
66740
  //if(!me.cfg.notebook) dialog.dialog( "close" );
66714
66741
 
@@ -66908,6 +66935,11 @@ class Events {
66908
66935
  ic.saveFileCls.saveFile(chainid + "_seq.txt", "text", [seq]);
66909
66936
  });
66910
66937
 
66938
+ me.myEventCls.onIds("#" + me.ig2ddgmid + "_svg", "click", function(e) { let ic = me.icn3d;
66939
+ e.preventDefault();
66940
+
66941
+ ic.saveFileCls.saveSvg("ig2ddgmSvg", ic.ig2ddgm_chainid + "_ig_2d.svg");
66942
+ });
66911
66943
 
66912
66944
  me.myEventCls.onIds("#" + me.linegraphid + "_svg", "click", function(e) { let ic = me.icn3d;
66913
66945
  e.preventDefault();
@@ -84990,6 +85022,28 @@ class ApplyClbonds {
84990
85022
  } // if
84991
85023
  } // if
84992
85024
 
85025
+ // add crosslink chemicals to the linked protein/nucleotide residues
85026
+ for(let structure in ic.structures) {
85027
+ let clbondArray = ic.clbondpnts[structure];
85028
+ if(clbondArray === undefined) {
85029
+ break;
85030
+ }
85031
+ for(let i = 0, il = clbondArray.length; i < il; i = i + 2) {
85032
+ let resid1 = clbondArray[i];
85033
+ let resid2 = clbondArray[i+1];
85034
+
85035
+ let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1]);
85036
+ let atom2 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2]);
85037
+
85038
+ if((ic.proteins.hasOwnProperty(atom1.serial) || ic.nucleotides.hasOwnProperty(atom1.serial)) && ic.chemicals.hasOwnProperty(atom2.serial)) {
85039
+ ic.residues[resid1] = me.hashUtilsCls.unionHash(ic.residues[resid1], ic.residues[resid2]);
85040
+ }
85041
+ else if((ic.proteins.hasOwnProperty(atom2.serial) || ic.nucleotides.hasOwnProperty(atom2.serial)) && ic.chemicals.hasOwnProperty(atom1.serial)) {
85042
+ ic.residues[resid2] = me.hashUtilsCls.unionHash(ic.residues[resid2], ic.residues[resid1]);
85043
+ }
85044
+ }
85045
+ }
85046
+
84993
85047
  return ic.residuesHashClbonds;
84994
85048
  }
84995
85049
 
@@ -85336,7 +85390,7 @@ class ApplyDisplay {
85336
85390
 
85337
85391
  // remove schematic labels
85338
85392
  //if(ic.labels !== undefined) ic.labels['schematic'] = undefined;
85339
- if(ic.labels !== undefined) delete ic.labels['schematic'];
85393
+ if(!bHighlight && ic.labels !== undefined) delete ic.labels['schematic'];
85340
85394
  /*
85341
85395
  if(bHighlight) {
85342
85396
  //let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(ic.hAtoms);
@@ -85357,6 +85411,7 @@ class ApplyDisplay {
85357
85411
  //var bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "O3'", "O3*") || me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "P");
85358
85412
  //let bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
85359
85413
  let nucleotidesAtoms = me.hashUtilsCls.intHash(atomHash, ic.nucleotides);
85414
+
85360
85415
  let bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(nucleotidesAtoms, ic.atoms));
85361
85416
 
85362
85417
  if(style === 'ribbon') {
@@ -85395,13 +85450,13 @@ class ApplyDisplay {
85395
85450
 
85396
85451
  //if(firstAtom.het) { // chemicals
85397
85452
  if(ic.chemicals.hasOwnProperty(firstAtom.serial)) { // chemicals
85398
- ic.residueLabelsCls.addNonCarbonAtomLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
85453
+ if(!bHighlight) ic.residueLabelsCls.addNonCarbonAtomLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
85399
85454
 
85400
85455
  let bSchematic = true;
85401
85456
  ic.stickCls.createStickRepresentation(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), chemicalSchematicRadius, chemicalSchematicRadius, undefined, bHighlight, bSchematic);
85402
85457
  }
85403
85458
  else { // nucleotides or proteins
85404
- ic.residueLabelsCls.addResidueLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), true);
85459
+ if(!bHighlight) ic.residueLabelsCls.addResidueLabels(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), true);
85405
85460
 
85406
85461
  if(bPhosphorusOnly) {
85407
85462
  ic.cylinderCls.createCylinderCurve(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), ["P"], ic.traceRadius, false, bHighlight);
@@ -91017,7 +91072,7 @@ class SetOption {
91017
91072
  ic.atoms[i].style2 = style;
91018
91073
  }
91019
91074
  }
91020
- else {
91075
+ else {
91021
91076
  for(let i in atoms) {
91022
91077
  ic.atoms[i].style = style;
91023
91078
  }
@@ -119256,7 +119311,7 @@ class ApplyCommand {
119256
119311
  ic.definedSetsCls.deleteSelectedSets();
119257
119312
  }
119258
119313
  else if(command == 'view interactions' || command == 'view 2d diagram') {
119259
- if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined) {
119314
+ if(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.mmdbafid !== undefined) {
119260
119315
  ic.ParserUtilsCls.set2DDiagrams(ic.inputid);
119261
119316
  }
119262
119317
  }
@@ -120771,27 +120826,31 @@ class DefinedSets {
120771
120826
  let colorStr =(atom === undefined || atom.color === undefined || atom.color.getHexString().toUpperCase() === 'FFFFFF') ? 'DDDDDD' : atom.color.getHexString();
120772
120827
  let color =(atom !== undefined && atom.color !== undefined) ? colorStr : '000000';
120773
120828
 
120774
- if(bNucleotide && atom) {
120829
+ if(bNucleotide) {
120775
120830
  // Handle nucleotide-specific logic
120776
- if(ic.nucleotides.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120831
+ if(atom && ic.nucleotides.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120777
120832
  let selectStr = (cnt == 0) ? "selected" : "";
120778
120833
 
120834
+ if(cnt == 0) this.selectSets([name]);
120835
+
120779
120836
  html += "<option value='" + name + "' style='color:#" + color + "' " + selectStr + ">" + name + "</option>";
120780
120837
  bFoundNucleotide = true;
120781
120838
  ++cnt;
120782
120839
  }
120783
120840
  }
120784
- else if(bProtein && atom) {
120841
+ else if(bProtein) {
120785
120842
  // Handle protein-specific logic
120786
- if(ic.proteins.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120843
+ if(atom && ic.proteins.hasOwnProperty(atom.serial) && name.split('_').length == 2 && !ic.structures.hasOwnProperty(name)) {
120787
120844
  let selectStr = (cnt == 0) ? "selected" : "";
120788
120845
 
120846
+ if(cnt == 0) this.selectSets([name]);
120847
+
120789
120848
  html += "<option value='" + name + "' style='color:#" + color + "' " + selectStr + ">" + name + "</option>";
120790
120849
  bFoundProtein = true;
120791
120850
  ++cnt;
120792
120851
  }
120793
120852
  }
120794
- else {
120853
+ else {
120795
120854
  if(commandnameArray.indexOf(name) != -1) {
120796
120855
  html += "<option value='" + name + "' style='color:#" + color + "' selected='selected'>" + name + "</option>";
120797
120856
  }
@@ -121974,6 +122033,20 @@ class LoadScript {
121974
122033
  await ic.diagram2dCls.drawIgdgm(chainid);
121975
122034
  ic.bRender = false;
121976
122035
  }
122036
+ else if(command.indexOf('update ig') == 0) {
122037
+ let paraArray = command.split(' ');
122038
+ let igIndex_igType = (paraArray.length == 3) ? paraArray[2] : '';
122039
+ await ic.diagram2dCls.show2DdgmForIg(igIndex_igType[0], igIndex_igType[1]);
122040
+ }
122041
+ else if(command.indexOf('download 2d ig') == 0) {
122042
+ let paraArray = command.split(' | ');
122043
+ let pos = command.lastIndexOf(' ');
122044
+ let chainid = (paraArray.length == 2) ? paraArray[1] : command.substr(pos + 1);
122045
+
122046
+ ic.bRender = true;
122047
+ await ic.diagram2dCls.drawIgdgm(chainid, true);
122048
+ ic.bRender = false;
122049
+ }
121977
122050
  else if(command.indexOf('add msa track') == 0) {
121978
122051
  //add msa track | chainid " + chainid + " | startpos " + startpos + " | type " + type + " | fastaList " + fastaList
121979
122052
  let paraArray = command.split(' | ');
@@ -129320,6 +129393,74 @@ class Diagram2d {
129320
129393
  //}
129321
129394
  }
129322
129395
  });
129396
+
129397
+ //$("#" + me.pre + "ig2ddgmDiv").html(svgHtml);
129398
+ $(document).on("change", "#" + me.pre + "iglist", async function(e) { thisClass.icn3d;
129399
+ let igIndex_igType = $("#" + me.pre + "iglist").val().split('_');
129400
+
129401
+ await thisClass.show2DdgmForIg(igIndex_igType[0], igIndex_igType[1]);
129402
+
129403
+ me.htmlCls.clickMenuCls.setLogCmd('update ig ' + igIndex_igType, true);
129404
+ });
129405
+
129406
+ // ig 2D diagram: 2D -> 3D
129407
+ $(document).on('click', '#ig2ddgmSvg .node', function(e) { let ic = thisClass.icn3d;
129408
+ // clear all node color
129409
+ thisClass.resetAllNodes('ig2ddgmSvg');
129410
+
129411
+ $(this).css({'font-size': '20px', 'font-weight': 'bold'});
129412
+
129413
+ //<text x="502.1" y="301.8" class="s9 c8547"><title>Ref. Num. 8547</title> N99 </text>
129414
+ let text = $(this).html().trim();
129415
+ let resnresi = text.substr(text.lastIndexOf(' ') + 1);
129416
+
129417
+ let resid = ic.ncbi2resid[ic.ig2ddgm_chainid + '_' + resnresi.substr(1)];
129418
+
129419
+ // highlight the selected residue
129420
+ if(ic.bCtrl || ic.bShift) {
129421
+ ic.hAtoms = me.hashUtilsCls.unionHash(ic.hAtoms, ic.residues[resid]);
129422
+ }
129423
+ else {
129424
+ ic.hAtoms = ic.residues[resid];
129425
+ }
129426
+
129427
+ ic.hlUpdateCls.showHighlight();
129428
+ });
129429
+
129430
+ // $(document).on('mouseout', '#ig2ddgmSvg .node', function(e) { let ic = thisClass.icn3d;
129431
+ // thisClass.resetAllNodes('ig2ddgmSvg');
129432
+ // });
129433
+
129434
+ // ig 2D diagram: 3D -> 2D
129435
+ $(document).on('icn3d.pick.click icn3d.pick.mouseover', function(ev, data) { let ic = thisClass.icn3d;
129436
+ // get the residues in the selection
129437
+ let ncbiresid = data;
129438
+ let resid = ic.ncbi2resid[ncbiresid];
129439
+
129440
+ if(ic.ig2ddgm_chainid && ic.resid2refnum && ic.resid2refnum[resid]) {
129441
+ let refnumLabel = ic.resid2refnum[resid];
129442
+ let refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
129443
+
129444
+ // clear all node color
129445
+ thisClass.resetAllNodes('ig2ddgmSvg');
129446
+
129447
+ // highlight the residue
129448
+ $("#ig2ddgmSvg .c" + refnumStr).css({'font-size': '20px', 'font-weight': 'bold'});
129449
+ }
129450
+ });
129451
+ }
129452
+
129453
+ // reset all nodes
129454
+ resetAllNodes(id) { let ic = this.icn3d; ic.icn3dui;
129455
+ // Select the SVG container
129456
+ const svg = document.getElementById(id);
129457
+
129458
+ // Select all text-related nodes: <text>
129459
+ const textElements = svg.querySelectorAll('text');
129460
+
129461
+ textElements.forEach((node) => {
129462
+ node.style = {};
129463
+ });
129323
129464
  }
129324
129465
 
129325
129466
  clickNode(node) { let ic = this.icn3d, me = ic.icn3dui;
@@ -129987,7 +130128,12 @@ class Diagram2d {
129987
130128
  html += " line.setAttribute('y2', node2.y);\n";
129988
130129
  html += " line.setAttribute('stroke', 'black');\n";
129989
130130
  html += " line.setAttribute('stroke-width', '1');\n";
129990
- html += " line.setAttribute('title', '" + type + "');\n";
130131
+ //html += " line.setAttribute('title', '" + type + "');\n";
130132
+
130133
+ html += " var title = document.createElementNS('http://www.w3.org/2000/svg', 'title');\n";
130134
+ html += " title.textContent = '" + pos1 + " - " + pos2 + "; " + type + "';\n";
130135
+ html += " line.appendChild(title);\n";
130136
+
129991
130137
  html += " rnaCanvas.drawing.domNode.appendChild(line);";
129992
130138
  html += "}\n";
129993
130139
  }
@@ -130008,10 +130154,12 @@ class Diagram2d {
130008
130154
  $("#" + me.pre + "rnacanvasDiv").html(html);
130009
130155
  }
130010
130156
 
130011
- async drawIgdgm(chainid) { let ic = this.icn3d, me = ic.icn3dui;
130157
+ async drawIgdgm(chainid, bDownload) { let ic = this.icn3d, me = ic.icn3dui;
130012
130158
  // select the current chain
130013
130159
  //ic.hAtoms = me.hashUtilsCls.cloneHash(ic.chains[chainid]);
130014
130160
 
130161
+ ic.ig2ddgm_chainid = chainid;
130162
+
130015
130163
  // run ig detection
130016
130164
  ic.bRunRefnumAgain = true;
130017
130165
  if(!ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
@@ -130035,7 +130183,7 @@ class Diagram2d {
130035
130183
 
130036
130184
  let igType = ic.ref2igtype[info.refpdbname];
130037
130185
 
130038
- if(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI') {
130186
+ if(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI' || igType == 'IgFN3') {
130039
130187
  bFound = true;
130040
130188
  }
130041
130189
 
@@ -130043,12 +130191,12 @@ class Diagram2d {
130043
130191
  }
130044
130192
 
130045
130193
  if(!bFound) {
130046
- var aaa = 1; //alert("The Ig type(s) for chain " + chainid + " is/are " + igTypeArray + ". Currently only IgV, IgC1, IgC2 and IgI types are supported for drawing Ig diagrams.");
130194
+ var aaa = 1; //alert("The Ig type(s) for chain " + chainid + " is/are " + igTypeArray + ". Currently only IgV, IgC1, IgC2, IgI and IgFN3 types are supported for drawing Ig diagrams.");
130047
130195
  return;
130048
130196
  }
130049
130197
 
130050
130198
  // get the hash of refnum to resn
130051
- let refnum2resn = {};
130199
+ ic.refnum2resn = {};
130052
130200
  for(let resid in ic.resid2refnum) {
130053
130201
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
130054
130202
  if(!atom) continue;
@@ -130061,88 +130209,154 @@ class Diagram2d {
130061
130209
 
130062
130210
  if(refnumLabel) {
130063
130211
  refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
130064
- if(!refnum2resn[domainid]) refnum2resn[domainid] = {};
130065
- refnum2resn[domainid][refnumStr] = resn + resid.split('_')[2];
130212
+ if(!ic.refnum2resn[domainid]) ic.refnum2resn[domainid] = {};
130213
+ ic.refnum2resn[domainid][refnumStr] = resn + resid.split('_')[2];
130066
130214
  }
130067
130215
  }
130068
130216
 
130069
- if(ic.bXlsx === undefined) {
130070
- let urlScript = "/Structure/icn3d/script/exceljs.min.js";
130071
- await me.getAjaxPromise(urlScript, 'script');
130217
+ if(bDownload) {
130218
+ if(ic.bXlsx === undefined) {
130219
+ let urlScript = "/Structure/icn3d/script/exceljs.min.js";
130220
+ await me.getAjaxPromise(urlScript, 'script');
130072
130221
 
130073
- ic.bXlsx = true;
130074
- }
130222
+ ic.bXlsx = true;
130223
+ }
130075
130224
 
130076
- const mainWorkbook = new ExcelJS.Workbook();
130225
+ const mainWorkbook = new ExcelJS.Workbook();
130077
130226
 
130078
- let ig2width = {'IgC1': 17, 'IgC2': 18, 'IgI': 19, 'IgV': 19};
130227
+ let ig2width = {'IgC1': 17, 'IgC2': 18, 'IgI': 19, 'IgV': 19};
130079
130228
 
130080
- for(let i = 0, il = igArray.length; i < il; ++i) {
130081
- let domainid = igArray[i].domainid;
130082
- let igType = igTypeArray[i];
130083
- if(!(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI')) {
130084
- mainWorkbook.addWorksheet((i + 1) + ". " + igType);
130085
- }
130086
- else {
130087
- let url = "/Structure/icn3d/template/igstrand_template_" + igType + ".xlsx";
130088
- let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', 'xlsx');
130089
-
130090
- const workbook = new ExcelJS.Workbook();
130091
- // Load the workbook from the buffer
130092
- await workbook.xlsx.load(arrayBuffer);
130093
- const worksheet = workbook.getWorksheet(1);
130094
-
130095
- const newSheet = mainWorkbook.addWorksheet();
130096
- // Clone the model to transfer styles and data
130097
- newSheet.model = worksheet.model;
130098
- newSheet.name = (i + 1) + ". " + igType;
130099
-
130100
- // Iterate over all rows that have values
130101
- newSheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
130102
- // Iterate over all cells in the row
130103
- row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
130104
- //console.log(`Cell [${rowNumber}, ${colNumber}] = ${cell.value}`);
130105
- if (cell.value && !isNaN(cell.value) && cell.value > 1000 && cell.value < 10000) {
130106
- if(refnum2resn[domainid].hasOwnProperty(cell.value)) {
130107
- cell.value = refnum2resn[domainid][cell.value];
130229
+ for(let i = 0, il = igArray.length; i < il; ++i) {
130230
+ let domainid = igArray[i].domainid;
130231
+ let igType = igTypeArray[i];
130232
+ if(!(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI' || igType == 'IgFN3')) {
130233
+ mainWorkbook.addWorksheet((i + 1) + ". " + igType);
130234
+ }
130235
+ else {
130236
+ let url = "/Structure/icn3d/template/igstrand_template_" + igType + ".xlsx";
130237
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', 'xlsx');
130238
+
130239
+ const workbook = new ExcelJS.Workbook();
130240
+ // Load the workbook from the buffer
130241
+ await workbook.xlsx.load(arrayBuffer);
130242
+ const worksheet = workbook.getWorksheet(1);
130243
+
130244
+ const newSheet = mainWorkbook.addWorksheet();
130245
+ // Clone the model to transfer styles and data
130246
+ newSheet.model = worksheet.model;
130247
+ newSheet.name = (i + 1) + ". " + igType;
130248
+
130249
+ // Iterate over all rows that have values
130250
+ newSheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
130251
+ // Iterate over all cells in the row
130252
+ row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
130253
+ //console.log(`Cell [${rowNumber}, ${colNumber}] = ${cell.value}`);
130254
+ if (cell.value && !isNaN(cell.value) && cell.value > 1000 && cell.value < 10000) {
130255
+ if(ic.refnum2resn[domainid].hasOwnProperty(cell.value)) {
130256
+ cell.value = ic.refnum2resn[domainid][cell.value];
130257
+ }
130258
+ else {
130259
+ cell.value = '';
130260
+ }
130108
130261
  }
130109
- else {
130262
+ else if(cell.value == 'NUMBERING') {
130110
130263
  cell.value = '';
130111
130264
  }
130112
- }
130113
- else if(cell.value == 'NUMBERING') {
130114
- cell.value = '';
130115
- }
130265
+ });
130116
130266
  });
130117
- });
130118
130267
 
130119
- // copy the original data
130120
- let colNum = ig2width[igType]; // some extra columns
130121
- for(let i = 1; i <= colNum; ++i) {
130122
- const sourceCol = worksheet.getColumn(i);
130268
+ // copy the original data
130269
+ let colNum = ig2width[igType]; // some extra columns
130270
+ for(let i = 1; i <= colNum; ++i) {
130271
+ const sourceCol = worksheet.getColumn(i);
130123
130272
 
130124
- // Copy values and styles
130125
- sourceCol.eachCell({ includeEmpty: true }, (cell, rowNumber) => {
130126
- const targetCell = newSheet.getRow(rowNumber).getCell(colNum + 2 + i);
130127
-
130128
- targetCell.value = cell.value;
130129
- targetCell.style = cell.style; // Copies font, borders, and fills
130130
- });
130273
+ // Copy values and styles
130274
+ sourceCol.eachCell({ includeEmpty: true }, (cell, rowNumber) => {
130275
+ const targetCell = newSheet.getRow(rowNumber).getCell(colNum + 2 + i);
130276
+
130277
+ targetCell.value = cell.value;
130278
+ targetCell.style = cell.style; // Copies font, borders, and fills
130279
+ });
130131
130280
 
130132
- // reset width for each column
130133
- newSheet.getColumn(colNum + 2 + i).width = worksheet.getColumn(i).width;
130281
+ // reset width for each column
130282
+ newSheet.getColumn(colNum + 2 + i).width = worksheet.getColumn(i).width;
130283
+ }
130134
130284
  }
130135
130285
  }
130136
- }
130137
130286
 
130138
- // Generate the workbook as a Buffer
130139
- const data = await mainWorkbook.xlsx.writeBuffer();
130287
+ // Generate the workbook as a Buffer
130288
+ const data = await mainWorkbook.xlsx.writeBuffer();
130289
+
130290
+ // Access the underlying ArrayBuffer
130291
+ ic.saveFileCls.saveFile(ic.inputid + '_ig_diagram.xlsx', 'xlsx', data);
130292
+ }
130293
+ else { // show interactive SVG
130294
+ // generate a dropdown menu
130295
+ let menuHtml = '';
130296
+ for(let i = 0, il = igArray.length; i < il; ++i) {
130297
+ igArray[i].domainid;
130298
+ let igType = igTypeArray[i];
130299
+
130300
+ let selStr = (i == 0) ? ' selected' : '';
130301
+ menuHtml += "<option value='" + i + '_' + igType + "' " + selStr + ">" + (i+1) + ". " + igType + "</option>";
130302
+ }
130303
+ $("#" + me.pre + "iglist").html(menuHtml);
130304
+
130305
+ await this.show2DdgmForIg(0, igTypeArray[0]); // default
130140
130306
 
130141
- // Access the underlying ArrayBuffer
130142
- ic.saveFileCls.saveFile(ic.inputid + '_ig_diagram.xlsx', 'xlsx', data);
130307
+ $("#" + me.pre + "iglist").resizable();
130308
+ }
130143
130309
 
130144
130310
  ic.drawCls.draw();
130145
130311
  }
130312
+
130313
+ async show2DdgmForIg(igIndex, igType) { let ic = this.icn3d, me = ic.icn3dui;
130314
+ if(!(igType == 'IgV' || igType == 'IgC1' || igType == 'IgC2' || igType == 'IgI' || igType == 'IgFN3')) {
130315
+ var aaa = 1; //alert("This Ig type " + igType + "has no 2D template yet...");
130316
+ return '';
130317
+ }
130318
+ else {
130319
+ let url = "/Structure/icn3d/template/igstrand_template_" + igType + ".svg";
130320
+ let svgHtml = await me.getAjaxPromise(url, 'text');
130321
+
130322
+ let igArray = ic.chain2igArray[ic.ig2ddgm_chainid];
130323
+ let domainid = igArray[igIndex].domainid;
130324
+
130325
+ // loop through all text node
130326
+ let lineArray = svgHtml.split('\n');
130327
+
130328
+ let html = '';
130329
+ for(let i = 0, il = lineArray.length; i < il; ++i) {
130330
+ let line = lineArray[i];
130331
+ if(line.indexOf('<text ') == 0) { // <text x="502.1" y="301.8" class="s9 c8547"><title>Ref. Num. 8547</title> 8547 </text>
130332
+ let pos = line.indexOf('</title> ');
130333
+ let refnumStr = line.substr(pos + 9).split(' ')[0];
130334
+ let refnum = parseInt(refnumStr);
130335
+
130336
+ if(!isNaN(refnumStr) && refnum > 1000 && refnum < 10000) {
130337
+ if(ic.refnum2resn[domainid].hasOwnProperty(refnumStr)) {
130338
+ let resn = ic.refnum2resn[domainid][refnumStr];
130339
+ let pos2 = line.indexOf('class=');
130340
+ html += line.substr(0, pos2) + 'class="node ' + line.substr(pos2 + 7, pos - (pos2 + 7)) + '</title> ' + resn + ' </text>';
130341
+ }
130342
+ else {
130343
+ html += line.substr(0, pos) + '</title> </text>';
130344
+ }
130345
+ }
130346
+ else {
130347
+ html += line + '\n';
130348
+ }
130349
+ }
130350
+ else {
130351
+ html += line + '\n';
130352
+ }
130353
+ }
130354
+
130355
+ $("#" + me.pre + "ig2ddgmDiv").html(html);
130356
+
130357
+ me.htmlCls.dialogCls.openDlg('dl_ig2ddgm', 'Show 2D diagram for Ig ' + (igIndex + 1) + '.' + igType + ' in ' + ic.ig2ddgm_chainid);
130358
+ }
130359
+ }
130146
130360
  }
130147
130361
 
130148
130362
  /**
@@ -136424,7 +136638,7 @@ class iCn3DUI {
136424
136638
  //even when multiple iCn3D viewers are shown together.
136425
136639
  this.pre = this.cfg.divid + "_";
136426
136640
 
136427
- this.REVISION = '3.50.0';
136641
+ this.REVISION = '3.51.0';
136428
136642
 
136429
136643
  // In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
136430
136644
  this.bNode = (Object.keys(window).length < 3) ? true : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icn3d",
3
- "version": "3.50.1",
3
+ "version": "3.51.0",
4
4
  "main": "./icn3d.js",
5
5
  "exports": {
6
6
  ".": {