icn3d 3.33.2 → 3.34.1

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.js CHANGED
@@ -13188,6 +13188,7 @@ class Dialog {
13188
13188
  let bGraph = $('#' + me.pre + 'dl_graph').hasClass('ui-dialog-content'); // initialized
13189
13189
  let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
13190
13190
  let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
13191
+ let bLigplot = $('#' + me.pre + 'dl_ligplot').hasClass('ui-dialog-content'); // initialized
13191
13192
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
13192
13193
  let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
13193
13194
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
@@ -13197,13 +13198,14 @@ class Dialog {
13197
13198
  let bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
13198
13199
 
13199
13200
  status.bSelectannotationsInit2 = false, status.bGraph2 = false, status.bLineGraph2 = false;
13200
- status.bScatterplot2 = false, status.bTable2 = false, status.bAlignmentInit2 = false;
13201
+ status.bScatterplot2 = false, status.bLigplot2 = false, status.bTable2 = false, status.bAlignmentInit2 = false;
13201
13202
  status.bTwoddgmInit2 = false, status.bTwodctnInit2 = false, status.bSetsInit2 = false;
13202
13203
 
13203
13204
  id2flag.dl_selectannotations = 'bSelectannotationsInit2';
13204
13205
  id2flag.dl_graph = 'bGraph2';
13205
13206
  id2flag.dl_linegraph = 'bLineGraph2';
13206
- id2flag.dl_scatterplot = 'bScatterplot2';
13207
+ id2flag.dl_scatterplot = 'bScatterplot2';
13208
+ id2flag.dl_ligplot = 'bLigplot2';
13207
13209
  id2flag.dl_contactmap = 'bContactmap2';
13208
13210
  id2flag.dl_alignerrormap = 'bAlignerrormap2';
13209
13211
  id2flag.dl_interactionsorted = 'bTable2';
@@ -13216,6 +13218,7 @@ class Dialog {
13216
13218
  if(bGraph) status.bGraph2 = $('#' + me.pre + 'dl_graph').dialog( 'isOpen' );
13217
13219
  if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
13218
13220
  if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
13221
+ if(bLigplot) status.bLigplot2 = $('#' + me.pre + 'dl_ligplot').dialog( 'isOpen' );
13219
13222
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
13220
13223
  if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
13221
13224
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
@@ -13302,7 +13305,7 @@ class Dialog {
13302
13305
 
13303
13306
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
13304
13307
  }
13305
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13308
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_ligplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13306
13309
  let oriWidth =(status.bTwoddgmInit2 || status.bSetsInit2) ?(me.htmlCls.WIDTH - twoddgmWidth)/2 : me.htmlCls.WIDTH / 2;
13307
13310
  let ratio = $("#" + id).width() / oriWidth;
13308
13311
 
@@ -13314,6 +13317,14 @@ class Dialog {
13314
13317
  let width = ic.scatterplotWidth * ratio;
13315
13318
  $("#" + me.scatterplotid).attr("width", width);
13316
13319
  }
13320
+ else if(id == me.pre + 'dl_ligplot') {
13321
+ let width = ic.ligplotWidth * ratio;
13322
+ $("#" + me.ligplotid).attr("width", width);
13323
+ }
13324
+ else if(id == me.pre + 'dl_ligplot') {
13325
+ let width = ic.ligplotWidth * ratio;
13326
+ $("#" + me.ligplotid).attr("width", width);
13327
+ }
13317
13328
  else if(id == me.pre + 'dl_contactmap') {
13318
13329
  let width = ic.contactmapWidth * ratio;
13319
13330
  $("#" + me.contactmapid).attr("width", width);
@@ -13367,7 +13378,7 @@ class Dialog {
13367
13378
  close: function(e) {
13368
13379
  let status = thisClass.getDialogStatus().status;
13369
13380
 
13370
- if((!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bTable2) &&(!status.bAlignmentInit2) ) {
13381
+ if((!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bTable2) &&(!status.bAlignmentInit2) ) {
13371
13382
  //ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH, me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT, true);
13372
13383
  ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH, me.htmlCls.HEIGHT, true);
13373
13384
  }
@@ -13396,7 +13407,7 @@ class Dialog {
13396
13407
 
13397
13408
  let status = this.getDialogStatus().status;
13398
13409
 
13399
- 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_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13410
+ 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_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13400
13411
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
13401
13412
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
13402
13413
 
@@ -13432,14 +13443,15 @@ class Dialog {
13432
13443
  modal: false,
13433
13444
  position: position,
13434
13445
  close: function(e) {
13435
- if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13436
- ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13437
- ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13438
- ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13439
- ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13440
- ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13441
- ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bAlignerrormap2))
13442
- ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
13446
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13447
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13448
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13449
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13450
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13451
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13452
+ ||(id === me.pre + 'dl_ligplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13453
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bAlignerrormap2))
13454
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2))
13443
13455
  ) {
13444
13456
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
13445
13457
  let canvasWidth = me.utilsCls.isMobile() ? me.htmlCls.WIDTH : me.htmlCls.WIDTH - twoddgmWidth;
@@ -13465,7 +13477,7 @@ class Dialog {
13465
13477
 
13466
13478
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
13467
13479
  }
13468
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13480
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_ligplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13469
13481
  let oriWidth =(status.bTwoddgmInit2 || status.bSetsInit2) ?(me.htmlCls.WIDTH - twoddgmWidth)/2 : me.htmlCls.WIDTH / 2;
13470
13482
  let ratio = $("#" + id).width() / oriWidth;
13471
13483
 
@@ -13477,6 +13489,10 @@ class Dialog {
13477
13489
  let width = ic.scatterplotWidth * ratio;
13478
13490
  $("#" + me.scatterplotid).attr("width", width);
13479
13491
  }
13492
+ else if(id == me.pre + 'dl_ligplot') {
13493
+ let width = ic.ligplotWidth * ratio;
13494
+ $("#" + me.ligplotid).attr("width", width);
13495
+ }
13480
13496
  else if(id == me.pre + 'dl_contactmap') {
13481
13497
  let width = ic.contactmapWidth * ratio;
13482
13498
  $("#" + me.contactmapid).attr("width", width);
@@ -13498,7 +13514,7 @@ class Dialog {
13498
13514
 
13499
13515
  //if(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH >= me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT) {
13500
13516
  if(me.htmlCls.WIDTH >= me.htmlCls.HEIGHT) {
13501
- if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bTable2 || status.bAlignmentInit2) {
13517
+ if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bLigplot2 || status.bTable2 || status.bAlignmentInit2) {
13502
13518
  //tmpWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
13503
13519
  tmpWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
13504
13520
  }
@@ -13537,7 +13553,7 @@ class Dialog {
13537
13553
 
13538
13554
  //if(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH >= me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT) {
13539
13555
  if(me.htmlCls.WIDTH >= me.htmlCls.HEIGHT) {
13540
- if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bTable2 || status.bAlignmentInit2) {
13556
+ if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bLigplot2 || status.bTable2 || status.bAlignmentInit2) {
13541
13557
  //tmpWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
13542
13558
  tmpWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
13543
13559
  }
@@ -13617,7 +13633,7 @@ class Dialog {
13617
13633
  let width = 400, height = 150;
13618
13634
  let twoddgmWidth = me.htmlCls.width2d + 20;
13619
13635
 
13620
- 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_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13636
+ 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_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13621
13637
  $( "#" + id ).show();
13622
13638
  $( "#" + id + "_nb").show();
13623
13639
  $( "#" + id + "_title").html(title);
@@ -13652,6 +13668,11 @@ class Dialog {
13652
13668
 
13653
13669
  $("#" + me.scatterplotid).attr("width", width);
13654
13670
  }
13671
+ else if(id == me.pre + 'dl_ligplot') {
13672
+ let width = ic.ligplotWidth * ratio;
13673
+
13674
+ $("#" + me.ligplotid).attr("width", width);
13675
+ }
13655
13676
  else if(id == me.pre + 'dl_contactmap') {
13656
13677
  let width = ic.contactmapWidth * ratio;
13657
13678
 
@@ -14350,6 +14371,8 @@ class SetDialog {
14350
14371
 
14351
14372
  html += "<div style='text-indent:1.1em'>" + me.htmlCls.buttonStr + "hbondScatterplot'>2D Interaction Map</button> " + me.htmlCls.buttonStr + "hbondScatterplot2' style='margin-left:12px'>2D Map with Reference Numbers</button> to show map</div><br>";
14352
14373
 
14374
+ html += "<div style='text-indent:1.1em'>" + me.htmlCls.buttonStr + "hbondLigplot'>2D Interaction for One Ligand/Residue</button> with atom details</div><br>";
14375
+
14353
14376
  tmpStr = ': </td><td><input style="margin-left:-12px" type="text" id="';
14354
14377
 
14355
14378
  html += "<div style='text-indent:1.1em'>" + me.htmlCls.buttonStr + "hbondGraph'>2D Graph(Force-Directed)</button> to show interactions with strength parameters in 0-200:</div>";
@@ -14516,6 +14539,40 @@ class SetDialog {
14516
14539
 
14517
14540
  html += "</div>";
14518
14541
 
14542
+
14543
+ html += me.htmlCls.divStr + "dl_ligplot' sty2D Interaction for One Ligand/Residule='background-color:white' class='" + dialogClass + "'>";
14544
+ html += this.addNotebookTitle('dl_ligplot', 'e with Atom Details');
14545
+
14546
+ html += me.htmlCls.divNowrapStr + "<b>Note</b>: Nodes can be dragged or clicked. Hold Ctrl key to select multiple nodes. " + me.htmlCls.space3;
14547
+
14548
+ html += '<div style="width:20px; margin-top:6px; display:inline-block;"><span id="'
14549
+ + me.pre + 'dl_ligplotcolor_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="display:none; width:15px;" title="Expand"></span><span id="'
14550
+ + me.pre + 'dl_ligplotcolor_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="width:15px;" title="Shrink"></span></div></div>';
14551
+
14552
+ html += me.htmlCls.divStr + "dl_ligplotcolor' style='inline-block;'>";
14553
+
14554
+ // html += "The real interaction distances are not in scale, and are about twice the distances of dashed line segments.<br>Some \"Contact\" lines are only shown partially to simplify the view.<br>";
14555
+ html += "Color legend for interactions (dashed lines): <br>";
14556
+
14557
+ html += me.htmlCls.setHtmlCls.setColorHints();
14558
+
14559
+ html += "<br></div>";
14560
+
14561
+ me.ligplotid = me.pre + 'ligplot';
14562
+ html += me.htmlCls.divNowrapStr + buttonStrTmp + me.ligplotid + '_svg">SVG</button>' + me.htmlCls.space2;
14563
+ html += buttonStrTmp + me.ligplotid + '_png">PNG</button>' + me.htmlCls.space2;
14564
+ // html += buttonStrTmp + me.ligplotid + '_json">JSON</button>' + me.htmlCls.space4;
14565
+ html += "<b>Scale</b>: <select id='" + me.ligplotid + "_scale'>";
14566
+
14567
+ html += me.htmlCls.setHtmlCls.getOptionHtml(optArray4, 5);
14568
+
14569
+ html += "</select></div><br>";
14570
+ html += '<div id="' + me.pre + 'ligplotDiv"></div>';
14571
+
14572
+ html += "</div>";
14573
+
14574
+
14575
+
14519
14576
  html += me.htmlCls.divStr + "dl_contactmap' style='background-color:white' class='" + dialogClass + "'>";
14520
14577
  html += this.addNotebookTitle('dl_contactmap', 'Contact Map');
14521
14578
 
@@ -15570,6 +15627,7 @@ class Events {
15570
15627
 
15571
15628
  ic.diagram2dCls.click2Ddgm();
15572
15629
  ic.cartoon2dCls.click2Dcartoon();
15630
+ ic.ligplotCls.clickLigplot();
15573
15631
  ic.addTrackCls.clickAddTrackButton();
15574
15632
  ic.resizeCanvasCls.windowResize();
15575
15633
  ic.annotationCls.setTabs();
@@ -17191,6 +17249,13 @@ class Events {
17191
17249
  thisClass.setLogCmd("show ref number", true);
17192
17250
  await ic.showInterCls.showInteractions('scatterplot');
17193
17251
  });
17252
+ me.myEventCls.onIds("#" + me.pre + "hbondLigplot", "click", async function(e) { let ic = me.icn3d;
17253
+ e.preventDefault();
17254
+
17255
+ ic.bShownRefnum = false;
17256
+ thisClass.setLogCmd("hide ref number", true);
17257
+ await ic.showInterCls.showInteractions('ligplot');
17258
+ });
17194
17259
  // select residues
17195
17260
  $(document).on("click", "#" + me.svgid + " circle.selected", function(e) { let ic = me.icn3d;
17196
17261
  e.stopImmediatePropagation();
@@ -17301,6 +17366,33 @@ class Events {
17301
17366
  thisClass.setLogCmd("scatterplot scale " + scale, true);
17302
17367
  });
17303
17368
 
17369
+ me.myEventCls.onIds("#" + me.ligplotid + "_svg", "click", function(e) { let ic = me.icn3d;
17370
+ e.preventDefault();
17371
+
17372
+ ic.saveFileCls.saveSvg(me.ligplotid, ic.inputid + "_ligplot.svg", undefined, true);
17373
+ });
17374
+ me.myEventCls.onIds("#" + me.ligplotid + "_png", "click", function(e) { let ic = me.icn3d;
17375
+ e.preventDefault();
17376
+
17377
+ ic.saveFileCls.savePng(me.ligplotid, ic.inputid + "_ligplot.png", undefined, true);
17378
+ });
17379
+ // me.myEventCls.onIds("#" + me.ligplotid + "_json", "click", function(e) { let ic = me.icn3d;
17380
+ // e.preventDefault();
17381
+
17382
+ // let graphStr2 = ic.ligplotStr.substr(0, ic.ligplotStr.lastIndexOf('}'));
17383
+
17384
+ // graphStr2 += me.htmlCls.setHtmlCls.getLinkColor();
17385
+
17386
+ // ic.saveFileCls.saveFile(ic.inputid + "_ligplot.json", "text", [graphStr2]);
17387
+ // });
17388
+ me.myEventCls.onIds("#" + me.ligplotid + "_scale", "change", function(e) { let ic = me.icn3d;
17389
+ e.preventDefault();
17390
+
17391
+ let scale = $("#" + me.ligplotid + "_scale").val();
17392
+ $("#" + me.ligplotid).attr("width",(ic.ligplotWidth * parseFloat(scale)).toString() + "px");
17393
+ thisClass.setLogCmd("ligplot scale " + scale, true);
17394
+ });
17395
+
17304
17396
  me.myEventCls.onIds("#" + me.contactmapid + "_svg", "click", function(e) { let ic = me.icn3d;
17305
17397
  e.preventDefault();
17306
17398
 
@@ -36758,7 +36850,8 @@ class Contact {
36758
36850
  if(oriCalpha === undefined) oriCalpha = oriAtom;
36759
36851
 
36760
36852
  if(bGetPairs) {
36761
- oriResidName = oriAtom.resn + ' $' + oriAtom.structure + '.' + oriAtom.chain + ':' + oriAtom.resi;
36853
+ let serialList = (oriAtom.name.indexOf('pi') == 0 && oriAtom.ring) ? oriAtom.ring.join(',') : oriAtom.serial;
36854
+ oriResidName = oriAtom.resn + ' $' + oriAtom.structure + '.' + oriAtom.chain + ':' + oriAtom.resi + ' ' + serialList;
36762
36855
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
36763
36856
  }
36764
36857
 
@@ -36803,13 +36896,14 @@ class Contact {
36803
36896
  if(bGetPairs) {
36804
36897
  let chain_resi2 = atom.structure + '_' + atom.chain + '_' + atom.resi;
36805
36898
 
36806
- residName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi;
36899
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
36900
+ residName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + ' ' + serialList;
36807
36901
  //var dist = Math.sqrt(atomDistSq).toFixed(1);
36808
36902
  let dist1 = atomDist.toFixed(1);
36809
36903
  let dist2 = calpha.coord.distanceTo(oriCalpha.coord).toFixed(1);
36810
36904
 
36811
36905
  let resids = chain_resi + '_' + oriAtom.resn + ',' + chain_resi2 + '_' + atom.resn;
36812
- let residNames = oriResidName + ',' + residName;
36906
+ let residNames = oriResidName + '|' + residName;
36813
36907
  if(ic.resids2interAll[resids] === undefined
36814
36908
  || ic.resids2interAll[resids]['contact'] === undefined
36815
36909
  || !ic.resids2interAll[resids]['contact'].hasOwnProperty(residNames)
@@ -36826,12 +36920,12 @@ class Contact {
36826
36920
  if(!bInternal) {
36827
36921
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
36828
36922
  if(ic.resids2inter[resids]['contact'] === undefined) ic.resids2inter[resids]['contact'] = {};
36829
- ic.resids2inter[resids]['contact'][oriResidName + ',' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36923
+ ic.resids2inter[resids]['contact'][oriResidName + '|' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36830
36924
  }
36831
36925
 
36832
36926
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
36833
36927
  if(ic.resids2interAll[resids]['contact'] === undefined) ic.resids2interAll[resids]['contact'] = {};
36834
- ic.resids2interAll[resids]['contact'][oriResidName + ',' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36928
+ ic.resids2interAll[resids]['contact'][oriResidName + '|' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36835
36929
  }
36836
36930
  }
36837
36931
  } // if(bGetPairs) {
@@ -37257,7 +37351,8 @@ class HBond {
37257
37351
  chain_resi_atom = chain_resi + "_" + atom.name;
37258
37352
 
37259
37353
  //var oriResidName = atom.resn + ' ' + chain_resi_atom;
37260
- let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name;
37354
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
37355
+ let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name + ' ' + serialList;
37261
37356
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
37262
37357
 
37263
37358
  for (let j in atomHbond) {
@@ -37382,24 +37477,25 @@ class HBond {
37382
37477
  residueHash[chain_resi2] = 1;
37383
37478
 
37384
37479
  //var residName = atomHbond[j].resn + " " + atomHbond[j].structure + "_" + atomHbond[j].chain + "_" + atomHbond[j].resi + '_' + atomHbond[j].name;
37385
- let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name;
37480
+ let serialList = (atomHbond[j].name.indexOf('pi') == 0 && atomHbond[j].ring) ? atomHbond[j].ring.join(',') : atomHbond[j].serial;
37481
+ let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name + ' ' + serialList;
37386
37482
 
37387
37483
  let resids = chain_resi + '_' + atom.resn + ',' + chain_resi2 + '_' + atomHbond[j].resn;
37388
37484
 
37389
37485
  if(ic.resids2interAll[resids] === undefined
37390
37486
  || ic.resids2interAll[resids]['ionic'] === undefined
37391
- || !ic.resids2interAll[resids]['ionic'].hasOwnProperty(oriResidName + ',' + residName) ) {
37487
+ || !ic.resids2interAll[resids]['ionic'].hasOwnProperty(oriResidName + '|' + residName) ) {
37392
37488
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
37393
37489
 
37394
37490
  if(!bInternal) {
37395
37491
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
37396
37492
  if(ic.resids2inter[resids]['hbond'] === undefined) ic.resids2inter[resids]['hbond'] = {};
37397
- ic.resids2inter[resids]['hbond'][oriResidName + ',' + residName] = dist.toFixed(1);
37493
+ ic.resids2inter[resids]['hbond'][oriResidName + '|' + residName] = dist.toFixed(1);
37398
37494
  }
37399
37495
 
37400
37496
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
37401
37497
  if(ic.resids2interAll[resids]['hbond'] === undefined) ic.resids2interAll[resids]['hbond'] = {};
37402
- ic.resids2interAll[resids]['hbond'][oriResidName + ',' + residName] = dist.toFixed(1);
37498
+ ic.resids2interAll[resids]['hbond'][oriResidName + '|' + residName] = dist.toFixed(1);
37403
37499
  }
37404
37500
  } // end of for (let j in atomHbond) {
37405
37501
  }
@@ -37552,7 +37648,8 @@ class PiHalogen {
37552
37648
 
37553
37649
  for (let i in atoms1a) {
37554
37650
  let atom1 = atoms1a[i];
37555
- let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name;
37651
+ let serialList = (atom1.name.indexOf('pi') == 0 && atom1.ring) ? atom1.ring.join(',') : atom1.serial;
37652
+ let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name + ' ' + serialList;
37556
37653
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
37557
37654
 
37558
37655
  for (let j in atoms1b) {
@@ -37596,7 +37693,8 @@ class PiHalogen {
37596
37693
 
37597
37694
  for (let i in atoms2a) {
37598
37695
  let atom1 = atoms2a[i];
37599
- let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name;
37696
+ let serialList = (atom1.name.indexOf('pi') == 0 && atom1.ring) ? atom1.ring.join(',') : atom1.serial;
37697
+ let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name + ' ' + serialList;
37600
37698
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
37601
37699
 
37602
37700
  // available in 1b and 2a
@@ -37761,7 +37859,8 @@ class PiHalogen {
37761
37859
  }
37762
37860
  }
37763
37861
 
37764
- let residName = atom2.resn + ' $' + atom2.structure + '.' + atom2.chain + ':' + atom2.resi + '@' + atom2.name;
37862
+ let serialList = (atom2.name.indexOf('pi') == 0 && atom2.ring) ? atom2.ring.join(',') : atom2.serial;
37863
+ let residName = atom2.resn + ' $' + atom2.structure + '.' + atom2.chain + ':' + atom2.resi + '@' + atom2.name + ' ' + serialList;
37765
37864
 
37766
37865
  //if(ic.resid2Residhash[oriResidName][residName] === undefined || ic.resid2Residhash[oriResidName][residName] > dist) {
37767
37866
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
@@ -37773,12 +37872,12 @@ class PiHalogen {
37773
37872
  if(!bInternal) {
37774
37873
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
37775
37874
  if(ic.resids2inter[resids][interactionType] === undefined) ic.resids2inter[resids][interactionType] = {};
37776
- ic.resids2inter[resids][interactionType][oriResidName + ',' + residName] = dist.toFixed(1);
37875
+ ic.resids2inter[resids][interactionType][oriResidName + '|' + residName] = dist.toFixed(1);
37777
37876
  }
37778
37877
 
37779
37878
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
37780
37879
  if(ic.resids2interAll[resids][interactionType] === undefined) ic.resids2interAll[resids][interactionType] = {};
37781
- ic.resids2interAll[resids][interactionType][oriResidName + ',' + residName] = dist.toFixed(1);
37880
+ ic.resids2interAll[resids][interactionType][oriResidName + '|' + residName] = dist.toFixed(1);
37782
37881
 
37783
37882
  return true;
37784
37883
  }
@@ -38025,12 +38124,13 @@ class PiHalogen {
38025
38124
  // Print the i-th cycle
38026
38125
  let coord = new THREE.Vector3();
38027
38126
  let cnt = 0, serial;
38028
- let coordArray = [];
38127
+ let coordArray = [], ringArray = [];
38029
38128
  if(cycles.hasOwnProperty(i)) {
38030
38129
  for (let j = 0, jl = cycles[i].length; j < jl; ++j) {
38031
38130
  serial = cycles[i][j];
38032
38131
  coord.add(ic.atoms[serial].coord);
38033
38132
  coordArray.push(ic.atoms[serial].coord);
38133
+ ringArray.push(serial);
38034
38134
  ++cnt;
38035
38135
  }
38036
38136
  }
@@ -38050,7 +38150,7 @@ class PiHalogen {
38050
38150
 
38051
38151
  let atom = ic.atoms[serial];
38052
38152
  name2atom[resid + '_pi' + serial] = {resn: atom.resn, name: 'pi' + serial, coord: coord, serial: atom.serial,
38053
- structure: atom.structure, chain: atom.chain, resi: atom.resi, normal: normal};
38153
+ structure: atom.structure, chain: atom.chain, resi: atom.resi, normal: normal, ring: ringArray};
38054
38154
  }
38055
38155
  }
38056
38156
  }
@@ -38148,7 +38248,8 @@ class Saltbridge {
38148
38248
  chain_resi = atom.structure + "_" + atom.chain + "_" + atom.resi;
38149
38249
  chain_resi_atom = chain_resi + "_" + atom.name;
38150
38250
 
38151
- let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name;
38251
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
38252
+ let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name + ' ' + serialList;
38152
38253
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
38153
38254
 
38154
38255
  let atomHbond = {};
@@ -38213,7 +38314,8 @@ class Saltbridge {
38213
38314
  residueHash[chain_resi] = 1;
38214
38315
  residueHash[chain_resi2] = 1;
38215
38316
 
38216
- let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name;
38317
+ let serialList = (atomHbond[j].name.indexOf('pi') == 0 && atomHbond[j].ring) ? atomHbond[j].ring.join(',') : atomHbond[j].serial;
38318
+ let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name + ' ' + serialList;
38217
38319
 
38218
38320
  //if(ic.resid2Residhash[oriResidName][residName] === undefined || ic.resid2Residhash[oriResidName][residName] > dist) {
38219
38321
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
@@ -38224,12 +38326,12 @@ class Saltbridge {
38224
38326
  if(!bInternal) {
38225
38327
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
38226
38328
  if(ic.resids2inter[resids]['ionic'] === undefined) ic.resids2inter[resids]['ionic'] = {};
38227
- ic.resids2inter[resids]['ionic'][oriResidName + ',' + residName] = dist.toFixed(1);
38329
+ ic.resids2inter[resids]['ionic'][oriResidName + '|' + residName] = dist.toFixed(1);
38228
38330
  }
38229
38331
 
38230
38332
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
38231
38333
  if(ic.resids2interAll[resids]['ionic'] === undefined) ic.resids2interAll[resids]['ionic'] = {};
38232
- ic.resids2interAll[resids]['ionic'][oriResidName + ',' + residName] = dist.toFixed(1);
38334
+ ic.resids2interAll[resids]['ionic'][oriResidName + '|' + residName] = dist.toFixed(1);
38233
38335
 
38234
38336
  } // end of for (let j in atomHbond) {
38235
38337
  }
@@ -49610,24 +49712,14 @@ class LineGraph {
49610
49712
  if(pos1 === undefined || pos2 === undefined) continue;
49611
49713
  let linestrokewidth;
49612
49714
  if(link.v == me.htmlCls.contactValue) {
49613
- linestrokewidth = (link.n == 1) ? 1 : 3;
49715
+ // linestrokewidth = (link.n == 1) ? 1 : 3;
49716
+ linestrokewidth = 1;
49614
49717
  } else {
49615
49718
  linestrokewidth = (link.n == 1) ? 2 : 4;
49616
49719
  }
49617
- let strokecolor;
49618
- if(link.v == me.htmlCls.hbondValue) {
49619
- strokecolor = "#" + me.htmlCls.hbondColor;
49620
- } else if(link.v == me.htmlCls.ionicValue) {
49621
- strokecolor = "#" + me.htmlCls.ionicColor;
49622
- } else if(link.v == me.htmlCls.halogenValue) {
49623
- strokecolor = "#" + me.htmlCls.halogenColor;
49624
- } else if(link.v == me.htmlCls.picationValue) {
49625
- strokecolor = "#" + me.htmlCls.picationColor;
49626
- } else if(link.v == me.htmlCls.pistackingValue) {
49627
- strokecolor = "#" + me.htmlCls.pistackingColor;
49628
- } else if(link.v == me.htmlCls.contactValue) {
49629
- strokecolor = "#" + me.htmlCls.contactColor;
49630
- }
49720
+
49721
+ let strokecolor = this.getStrokecolor(link.v);
49722
+
49631
49723
  html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
49632
49724
  let interactStr = (link.n == 1) ? 'Interaction' : link.n + ' interactions';
49633
49725
  if(link.n > 1) html += "<title>" + interactStr + " of residue " + node1.id + " with residue " + node2.id + "</title>";
@@ -49690,6 +49782,44 @@ class LineGraph {
49690
49782
  return html;
49691
49783
  }
49692
49784
 
49785
+ getStrokecolor(value, type) { let ic = this.icn3d, me = ic.icn3dui;
49786
+ let strokecolor = "#000";
49787
+
49788
+ if(value) {
49789
+ if(value == me.htmlCls.hbondValue) {
49790
+ strokecolor = "#" + me.htmlCls.hbondColor;
49791
+ } else if(value == me.htmlCls.ionicValue) {
49792
+ strokecolor = "#" + me.htmlCls.ionicColor;
49793
+ } else if(value == me.htmlCls.halogenValue) {
49794
+ strokecolor = "#" + me.htmlCls.halogenColor;
49795
+ } else if(value == me.htmlCls.picationValue) {
49796
+ strokecolor = "#" + me.htmlCls.picationColor;
49797
+ } else if(value == me.htmlCls.pistackingValue) {
49798
+ strokecolor = "#" + me.htmlCls.pistackingColor;
49799
+ } else if(value == me.htmlCls.contactValue) {
49800
+ strokecolor = "#" + me.htmlCls.contactColor;
49801
+ }
49802
+ }
49803
+
49804
+ if(type) {
49805
+ if(type == 'hbond') {
49806
+ strokecolor = "#" + me.htmlCls.hbondColor;
49807
+ } else if(type == 'ionic') {
49808
+ strokecolor = "#" + me.htmlCls.ionicColor;
49809
+ } else if(type == 'halogen') {
49810
+ strokecolor = "#" + me.htmlCls.halogenColor;
49811
+ } else if(type == 'pi-cation') {
49812
+ strokecolor = "#" + me.htmlCls.picationColor;
49813
+ } else if(type == 'pi-stacking') {
49814
+ strokecolor = "#" + me.htmlCls.pistackingColor;
49815
+ } else if(type == 'contact') {
49816
+ strokecolor = "#" + me.htmlCls.contactColor;
49817
+ }
49818
+ }
49819
+
49820
+ return strokecolor;
49821
+ }
49822
+
49693
49823
  drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap) { let ic = this.icn3d, me = ic.icn3dui;
49694
49824
  let html = '';
49695
49825
 
@@ -49705,26 +49835,14 @@ class LineGraph {
49705
49835
  let pos2 = node2posSet2[node2.id];
49706
49836
  if(pos1 === undefined || pos2 === undefined) return html;
49707
49837
 
49708
- let strokecolor;
49709
- if(link.v == me.htmlCls.hbondValue) {
49710
- strokecolor = "#" + me.htmlCls.hbondColor;
49711
- } else if(link.v == me.htmlCls.ionicValue) {
49712
- strokecolor = "#" + me.htmlCls.ionicColor;
49713
- } else if(link.v == me.htmlCls.halogenValue) {
49714
- strokecolor = "#" + me.htmlCls.halogenColor;
49715
- } else if(link.v == me.htmlCls.picationValue) {
49716
- strokecolor = "#" + me.htmlCls.picationColor;
49717
- } else if(link.v == me.htmlCls.pistackingValue) {
49718
- strokecolor = "#" + me.htmlCls.pistackingColor;
49719
- } else if(link.v == me.htmlCls.contactValue) {
49720
- strokecolor = "#" + me.htmlCls.contactColor;
49721
- }
49838
+ let strokecolor = this.getStrokecolor(link.v);
49722
49839
 
49723
49840
  if(bContactMap) strokecolor = "#" + link.c;
49724
49841
 
49725
49842
  let linestrokewidth;
49726
49843
  if(link.v == me.htmlCls.contactValue) {
49727
- linestrokewidth = (link.n == 1) ? 1 : 3;
49844
+ // linestrokewidth = (link.n == 1) ? 1 : 3;
49845
+ linestrokewidth = 1;
49728
49846
  } else {
49729
49847
  linestrokewidth = (link.n == 1) ? 2 : 4;
49730
49848
  }
@@ -50194,6 +50312,7 @@ class GetGraph {
50194
50312
  interStr += this.getContactLinks(ssAtomsArray[i], ssAtomsArray[j], labelType, true, bCartoon2d);
50195
50313
  }
50196
50314
  }
50315
+
50197
50316
  return interStr;
50198
50317
  }
50199
50318
  getContactLinks(atomlistTarget, otherAtoms, labelType, bInternal, bCartoon2d) { let ic = this.icn3d, me = ic.icn3dui;
@@ -50236,7 +50355,14 @@ class GetGraph {
50236
50355
  for(let resid1 in hash1) {
50237
50356
  //ASN $1KQ2.A:6@ND2
50238
50357
  //or ASN $1KQ2.A:6
50239
- resid1 = resid1.trim();
50358
+ // or ASN $1KQ2.A:6@ND2 2006
50359
+ let resid1Ori = resid1.trim();
50360
+
50361
+ let idArray1 = resid1Ori.split(' ');
50362
+ if(idArray1.length == 3) {
50363
+ resid1 = idArray1[0] + ' ' + idArray1[1];
50364
+ }
50365
+
50240
50366
  let pos1a = resid1.indexOf(' ');
50241
50367
  let pos1b = resid1.indexOf(':');
50242
50368
  let posTmp1 = resid1.indexOf('@');
@@ -50246,8 +50372,14 @@ class GetGraph {
50246
50372
  let resName1 = me.utilsCls.residueName2Abbr(resid1.substr(0, pos1a)) + resid1.substr(pos1b + 1, pos1c - pos1b - 1);
50247
50373
  if(labelType == 'chain' || labelType == 'structure') resName1 += '.' + resid1.substr(pos1d + 1, pos1b - pos1d - 1);
50248
50374
  if(labelType == 'structure') resName1 += '.' + resid1.substr(pos1e + 1, pos1d - pos1e - 1);
50249
- for(let resid2 in hash2[resid1]) {
50250
- resid2 = resid2.trim();
50375
+ for(let resid2 in hash2[resid1Ori]) {
50376
+ let resid2Ori = resid2.trim();
50377
+
50378
+ let idArray2 = resid2Ori.split(' ');
50379
+ if(idArray2.length == 3) {
50380
+ resid2 = idArray2[0] + ' ' + idArray2[1];
50381
+ }
50382
+
50251
50383
  let pos2a = resid2.indexOf(' ');
50252
50384
  let pos2b = resid2.indexOf(':');
50253
50385
  let posTmp2 = resid2.indexOf('@');
@@ -50263,16 +50395,6 @@ class GetGraph {
50263
50395
  resName1 = ic.resi2resirange[resName1];
50264
50396
  resName2 = ic.resi2resirange[resName2];
50265
50397
  }
50266
- /*
50267
- if(!sourceTargetHash.hasOwnProperty(resName1 + '_' + resName2) && resName1 !== undefined && resName2 !== undefined ) {
50268
- let linkStr = ', {"source": "' + resName1 + '", "target": "' + resName2 + '", "v": ' + value + ', "c": "' + color + '"}';
50269
- if(linkStr != prevLinkStr) hbondStr += linkStr;
50270
- prevLinkStr = linkStr;
50271
-
50272
- sourceTargetHash[resName1 + '_' + resName2] = 1;
50273
- sourceTargetHash[resName2 + '_' + resName1] = 1;
50274
- }
50275
- */
50276
50398
 
50277
50399
  if(resName1 !== undefined && resName2 !== undefined ) {
50278
50400
  let linkStr = '"source": "' + resName1 + '", "target": "' + resName2 + '", "v": ' + value + ', "c": "' + color + '"';
@@ -50298,6 +50420,10 @@ class GetGraph {
50298
50420
  convertLabel2Resid(residLabel) {var ic = this.icn3d; ic.icn3dui;
50299
50421
  //ASN $1KQ2.A:6@ND2
50300
50422
  //or ASN $1KQ2.A:6
50423
+ // or ASN $1KQ2.A:6@ND2 1234
50424
+ let idArray = residLabel.split(' ');
50425
+ residLabel = (idArray.length == 2) ? residLabel : residLabel.substr(0, residLabel.lastIndexOf(' '));
50426
+
50301
50427
  residLabel.indexOf(' ');
50302
50428
  let pos2Tmp = residLabel.indexOf('@');
50303
50429
  let pos2 =(pos2Tmp !== -1) ? pos2Tmp : residLabel.length;
@@ -50332,6 +50458,25 @@ class ShowInter {
50332
50458
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atoms);
50333
50459
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atoms2);
50334
50460
 
50461
+ if(type == 'ligplot') {
50462
+ let residueHash1 = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
50463
+ let residueHash2 = ic.firstAtomObjCls.getResiduesFromAtoms(atoms2);
50464
+
50465
+ if(Object.keys(residueHash1).length > 1 && Object.keys(residueHash2).length > 1) {
50466
+ var aaa = 1; //alert("Please select one ligand or residue as one of the interaction sets...");
50467
+ return;
50468
+ }
50469
+
50470
+ // switch the sets to make the first set as the ligand
50471
+ if(Object.keys(residueHash1).length < Object.keys(residueHash2).length) {
50472
+ nameArray2 = $("#" + ic.pre + "atomsCustomHbond").val();
50473
+ nameArray = $("#" + ic.pre + "atomsCustomHbond2").val();
50474
+
50475
+ atoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
50476
+ atoms2 = ic.definedSetsCls.getAtomsFromNameArray(nameArray2);
50477
+ }
50478
+ }
50479
+
50335
50480
  if(nameArray2.length == 0) {
50336
50481
  var aaa = 1; //alert("Please select the first set");
50337
50482
  }
@@ -50375,6 +50520,9 @@ class ShowInter {
50375
50520
  else if(type == 'scatterplot') {
50376
50521
  me.htmlCls.clickMenuCls.setLogCmd("scatterplot interaction pairs | " + tmpStr, true);
50377
50522
  }
50523
+ else if(type == 'ligplot') {
50524
+ me.htmlCls.clickMenuCls.setLogCmd("ligplot interaction pairs | " + tmpStr, true);
50525
+ }
50378
50526
  else if(type == 'graph') { // force-directed graph
50379
50527
  let dist_ss = parseInt($("#" + ic.pre + "dist_ss").val());
50380
50528
  let dist_coil = parseInt($("#" + ic.pre + "dist_coil").val());
@@ -51063,6 +51211,9 @@ class ViewInterPairs {
51063
51211
  let svgHtml = ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
51064
51212
  $("#" + ic.pre + "scatterplotDiv").html(svgHtml);
51065
51213
  }
51214
+ else if(type == 'ligplot') {
51215
+ await ic.ligplotCls.drawLigplot(atomSet1);
51216
+ }
51066
51217
  else if(bContactMapLocal) {
51067
51218
  me.htmlCls.dialogCls.openDlg('dl_contactmap', 'Show contact map');
51068
51219
  let bAnyAtom = true;
@@ -51152,7 +51303,9 @@ class ViewInterPairs {
51152
51303
  }
51153
51304
  }
51154
51305
 
51155
- getAllInteractionTable(type) { let ic = this.icn3d, me = ic.icn3dui;
51306
+ getAllInteractionTable(type, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d, me = ic.icn3dui;
51307
+ let svgHtmlNode = '', svgHtmlLine = '';
51308
+
51156
51309
  let bondCnt = [];
51157
51310
 
51158
51311
  let residsArray = Object.keys(ic.resids2inter);
@@ -51191,41 +51344,54 @@ class ViewInterPairs {
51191
51344
  }
51192
51345
  let labels2dist, result;
51193
51346
  labels2dist = ic.resids2inter[resids]['hbond'];
51194
- result = this.getInteractionPairDetails(labels2dist, type, 'hbond');
51347
+ result = this.getInteractionPairDetails(labels2dist, type, 'hbond', index2xy, xlen, ylen, xcenter, ycenter);
51195
51348
  strHbond += result.html;
51196
51349
  cntHbond += result.cnt;
51350
+ svgHtmlNode += result.svgHtmlNode;
51351
+ svgHtmlLine += result.svgHtmlLine;
51197
51352
  if(result.cnt > 0) residname2List += residname2 + ":hbond_" + result.cnt + " ";
51198
51353
 
51199
51354
  labels2dist = ic.resids2inter[resids]['ionic'];
51200
- result = this.getInteractionPairDetails(labels2dist, type, 'ionic');
51355
+ result = this.getInteractionPairDetails(labels2dist, type, 'ionic', index2xy, xlen, ylen, xcenter, ycenter);
51201
51356
  strIonic += result.html;
51202
51357
  cntIonic += result.cnt;
51358
+ svgHtmlNode += result.svgHtmlNode;
51359
+ svgHtmlLine += result.svgHtmlLine;
51203
51360
  if(result.cnt > 0) residname2List += residname2 + ":ionic_" + result.cnt + " ";
51204
51361
 
51205
- labels2dist = ic.resids2inter[resids]['contact'];
51206
- result = this.getContactPairDetails(labels2dist, type, 'contact');
51207
- strContact += result.html;
51208
- cntContact += result.cnt;
51209
- if(result.cnt > 0) residname2List += residname2 + ":contact_" + result.cnt + " ";
51210
-
51211
51362
  labels2dist = ic.resids2inter[resids]['halogen'];
51212
- result = this.getInteractionPairDetails(labels2dist, type, 'halogen');
51363
+ result = this.getInteractionPairDetails(labels2dist, type, 'halogen', index2xy, xlen, ylen, xcenter, ycenter);
51213
51364
  strHalegen += result.html;
51214
51365
  cntHalegen += result.cnt;
51366
+ svgHtmlNode += result.svgHtmlNode;
51367
+ svgHtmlLine += result.svgHtmlLine;
51215
51368
  if(result.cnt > 0) residname2List += residname2 + ":halogen_" + result.cnt + " ";
51216
51369
 
51217
51370
  labels2dist = ic.resids2inter[resids]['pi-cation'];
51218
- result = this.getInteractionPairDetails(labels2dist, type, 'pi-cation');
51371
+ result = this.getInteractionPairDetails(labels2dist, type, 'pi-cation', index2xy, xlen, ylen, xcenter, ycenter);
51219
51372
  strPication += result.html;
51220
51373
  cntPication += result.cnt;
51374
+ svgHtmlNode += result.svgHtmlNode;
51375
+ svgHtmlLine += result.svgHtmlLine;
51221
51376
  if(result.cnt > 0) residname2List += residname2 + ":pi-cation_" + result.cnt + " ";
51222
51377
 
51223
51378
  labels2dist = ic.resids2inter[resids]['pi-stacking'];
51224
- result = this.getInteractionPairDetails(labels2dist, type, 'pi-stacking');
51379
+ result = this.getInteractionPairDetails(labels2dist, type, 'pi-stacking', index2xy, xlen, ylen, xcenter, ycenter);
51225
51380
  strPistacking += result.html;
51226
51381
  cntPistacking += result.cnt;
51382
+ svgHtmlNode += result.svgHtmlNode;
51383
+ svgHtmlLine += result.svgHtmlLine;
51227
51384
  if(result.cnt > 0) residname2List += residname2 + ":pi-stacking_" + result.cnt + " ";
51228
51385
 
51386
+ // put contact as the last one since contact will use the same node as other interactions in ligand-protein interactoin
51387
+ labels2dist = ic.resids2inter[resids]['contact'];
51388
+ result = this.getContactPairDetails(labels2dist, type, 'contact', index2xy, xlen, ylen, xcenter, ycenter);
51389
+ strContact += result.html;
51390
+ cntContact += result.cnt;
51391
+ svgHtmlNode += result.svgHtmlNode;
51392
+ svgHtmlLine += result.svgHtmlLine;
51393
+ if(result.cnt > 0) residname2List += residname2 + ":contact_" + result.cnt + " ";
51394
+
51229
51395
  prevResidname1 = residname1;
51230
51396
  prevIds = ids;
51231
51397
  }
@@ -51253,7 +51419,7 @@ class ViewInterPairs {
51253
51419
  html += tmpText;
51254
51420
  html += '</tbody></table><br/>';
51255
51421
  }
51256
- return {html: html, bondCnt: bondCnt};
51422
+ return {html: html, bondCnt: bondCnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine};
51257
51423
  }
51258
51424
  getInteractionPerResidue(prevIds, strHbond, strIonic, strContact, strHalegen, strPication, strPistacking,
51259
51425
  cntHbond, cntIonic, cntContact, cntHalegen, cntPication, cntPistacking) { let ic = this.icn3d; ic.icn3dui;
@@ -51268,15 +51434,24 @@ class ViewInterPairs {
51268
51434
  tmpText += '</tr>';
51269
51435
  return tmpText;
51270
51436
  }
51271
- getInteractionPairDetails(labels2dist, type, interactionType) { let ic = this.icn3d; ic.icn3dui;
51272
- let tmpText = '', cnt = 0;
51437
+ getInteractionPairDetails(labels2dist, type, interactionType, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d; ic.icn3dui;
51438
+ let svgHtmlNode = '', svgHtmlLine = '', tmpText = '', cnt = 0;
51273
51439
  let colorText1 = ' <span style="background-color:#';
51274
51440
  let colorText2 = '">&nbsp;&nbsp;&nbsp;</span>';
51275
51441
  if(labels2dist !== undefined) {
51442
+ if(!ic.resid2cnt) ic.resid2cnt = {};
51443
+ if(!ic.resid2ToXy) ic.resid2ToXy = {};
51444
+ if(!ic.nodeid2lineid) ic.nodeid2lineid = {};
51276
51445
  for(let labels in labels2dist) {
51277
- let resid1_resid2 = labels.split(',');
51278
- let resid1 =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51279
- let resid2 =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51446
+ let resid1_resid2 = labels.split('|');
51447
+ let resid1Ori =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51448
+ let resid2Ori =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51449
+ //resid1: MET $3GVU.A:364@N 1234
51450
+ let pos1 = resid1Ori.lastIndexOf(' ');
51451
+ let pos2 = resid2Ori.lastIndexOf(' ');
51452
+ let resid1 = resid1Ori.substr(0, pos1);
51453
+ let resid2 = resid2Ori.substr(0, pos2);
51454
+
51280
51455
  let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
51281
51456
  let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
51282
51457
  let color1 = (atom1.color) ? atom1.color.getHexString() : '';
@@ -51288,38 +51463,125 @@ class ViewInterPairs {
51288
51463
  tmpText += '<td align="center"><button class="' + ic.pre + 'selres" resid="' + resid1 + '|' + resid2 + '">Highlight</button></td>';
51289
51464
  tmpText += '</tr>';
51290
51465
  ++cnt;
51466
+
51467
+ if(index2xy) {
51468
+ let serialArray1 = resid1Ori.substr(pos1 + 1).split(',');
51469
+
51470
+ let result = ic.ligplotCls.getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter);
51471
+ svgHtmlNode += result.node;
51472
+ svgHtmlLine += result.line;
51473
+ }
51291
51474
  }
51292
51475
  }
51293
- return {html: tmpText, cnt: cnt}
51476
+ return {html: tmpText, cnt: cnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine}
51294
51477
  }
51295
- getContactPairDetails(labels2dist, type) { let ic = this.icn3d; ic.icn3dui;
51296
- let tmpText = '', cnt = 0;
51478
+
51479
+ getContactPairDetails(labels2dist, type, interactionType, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d; ic.icn3dui;
51480
+ let svgHtmlNode = '', svgHtmlLine = '', tmpText = '', cnt = 0;
51297
51481
  let colorText1 = ' <span style="background-color:#';
51298
51482
  let colorText2 = '">&nbsp;&nbsp;&nbsp;</span>';
51299
51483
  if(labels2dist !== undefined) {
51484
+ let resids2distCnt = {};
51485
+ if(!ic.resid2cnt) ic.resid2cnt = {};
51486
+ if(!ic.resid2ToXy) ic.resid2ToXy = {};
51487
+ if(!ic.nodeid2lineid) ic.nodeid2lineid = {};
51300
51488
  for(let labels in labels2dist) {
51301
- let resid1_resid2 = labels.split(',');
51302
- let resid1 =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51303
- let resid2 =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51489
+ let resid1_resid2 = labels.split('|');
51490
+ let resid1Ori =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51491
+ let resid2Ori =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51492
+ //resid1: MET $3GVU.A:364 1234
51493
+ let pos1 = resid1Ori.lastIndexOf(' ');
51494
+ let pos2 = resid2Ori.lastIndexOf(' ');
51495
+
51496
+ let serialArray1 = resid1Ori.substr(pos1 + 1).split(',');
51497
+ let resid1 = resid1Ori.substr(0, pos1);
51498
+ if(index2xy) {
51499
+ // add atom name to resid1
51500
+ resid1 += '@' + ic.atoms[serialArray1[0]].name;
51501
+ }
51502
+
51503
+ let resid2 = resid2Ori.substr(0, pos2);
51504
+ let resids = resid1 + '|' + resid2;
51505
+
51506
+ let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
51507
+ ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
51508
+ // let color1 = (atom1.color) ? atom1.color.getHexString() : '';
51509
+ let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
51510
+ ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
51511
+ // let color2 = (atom2.color) ? atom2.color.getHexString() : '';
51512
+ let dist1_dist2_atom1_atom2 = labels2dist[labels].split('_');
51513
+ let dist1 = parseFloat(dist1_dist2_atom1_atom2[0]);
51514
+ // let dist2 = parseFloat(dist1_dist2_atom1_atom2[1]);
51515
+ // let atom1Name = dist1_dist2_atom1_atom2[2];
51516
+ // let atom2Name = dist1_dist2_atom1_atom2[3];
51517
+ let contactCnt = parseInt(dist1_dist2_atom1_atom2[4]);
51518
+ if(!resids2distCnt.hasOwnProperty(resids)) {
51519
+ resids2distCnt[resids] = {'dist1': dist1, 'dist1_dist2_atom1_atom2': dist1_dist2_atom1_atom2, 'cnt': contactCnt, 'serialArray1': serialArray1};
51520
+ }
51521
+ else {
51522
+ resids2distCnt[resids].cnt += contactCnt;
51523
+ if(dist1 < resids2distCnt[resids].dist1) {
51524
+ resids2distCnt[resids].dist1 = dist1;
51525
+ resids2distCnt[resids].dist1_dist2_atom1_atom2 = dist1_dist2_atom1_atom2;
51526
+ resids2distCnt[resids].serialArray1 = serialArray1;
51527
+ }
51528
+ }
51529
+ }
51530
+
51531
+ let resid2ToResid1 = {};
51532
+ for(let resids in resids2distCnt) {
51533
+ let resid1_resid2 = resids.split('|');
51534
+ let resid1 = resid1_resid2[0];
51535
+ let resid2 = resid1_resid2[1];
51536
+
51537
+ if(!resid2ToResid1.hasOwnProperty(resid2)) {
51538
+ resid2ToResid1[resid2] = [resid1];
51539
+ }
51540
+ else {
51541
+ resid2ToResid1[resid2].push(resid1);
51542
+ }
51543
+
51304
51544
  let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
51305
51545
  let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
51306
51546
  let color1 = (atom1.color) ? atom1.color.getHexString() : '';
51307
51547
  let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
51308
51548
  let atom2 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
51309
51549
  let color2 = (atom2.color) ? atom2.color.getHexString() : '';
51310
- let dist1_dist2_atom1_atom2 = labels2dist[labels].split('_');
51550
+ let dist1_dist2_atom1_atom2 = resids2distCnt[resids].dist1_dist2_atom1_atom2;
51311
51551
  let dist1 = dist1_dist2_atom1_atom2[0];
51312
51552
  let dist2 = dist1_dist2_atom1_atom2[1];
51313
51553
  let atom1Name = dist1_dist2_atom1_atom2[2];
51314
51554
  let atom2Name = dist1_dist2_atom1_atom2[3];
51315
- let contactCnt = dist1_dist2_atom1_atom2[4];
51555
+ let contactCnt = 1; //resids2distCnt[resids].cnt;
51556
+
51316
51557
  tmpText += '<tr><td><span style="white-space:nowrap"><input type="checkbox" class="' + ic.pre + 'seloneres" id="' + ic.pre + 'inter2_' + cnt + 'a" resid="' + resid1 + '"/> ' + resid1 + '@' + atom1Name + colorText1 + color1 + colorText2 + '</span></td><td><span style="white-space:nowrap"><input type="checkbox" class="' + ic.pre + 'seloneres" id="' + ic.pre + 'inter2_' + cnt + 'b" resid="' + resid2 + '"/> ' + resid2 + '@' + atom2Name + colorText1 + color2 + colorText2 + '</span></td><td align="center">' + contactCnt + '</td><td align="center">' + dist1 + '</td><td align="center">' + dist2 + '</td>';
51317
51558
  tmpText += '<td align="center"><button class="' + ic.pre + 'selres" resid="' + resid1 + '|' + resid2 + '">Highlight</button></td>';
51318
51559
  tmpText += '</tr>';
51319
51560
  cnt += parseInt(contactCnt);
51320
51561
  }
51562
+
51563
+ if(index2xy) {
51564
+ for(let resid2 in resid2ToResid1) {
51565
+ let resid1Array = resid2ToResid1[resid2];
51566
+ let prevX2, prevY2;
51567
+ for(let i = 0, il = resid1Array.length; i < il; ++i) {
51568
+ let resid1 = resid1Array[i];
51569
+ let resids = resid1 + '|' + resid2;
51570
+
51571
+ let serialArray1 = resids2distCnt[resids].serialArray1;
51572
+
51573
+ let bNotDrawNode = (i == 0) ? false : true;
51574
+ let result = ic.ligplotCls.getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter, bNotDrawNode, prevX2, prevY2);
51575
+ svgHtmlNode += result.node;
51576
+ svgHtmlLine += result.line;
51577
+ prevX2 = result.x2;
51578
+ prevY2 = result.y2;
51579
+ }
51580
+ }
51581
+ }
51321
51582
  }
51322
- return {html: tmpText, cnt: cnt}
51583
+
51584
+ return {html: tmpText, cnt: cnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine};
51323
51585
  }
51324
51586
 
51325
51587
  //Export the list of residues in some chain interacting with residues in another chain.
@@ -52727,8 +52989,8 @@ class ChainalignParser {
52727
52989
  let chain_t = idArray[3];
52728
52990
  let chainid_t = mmdbid_t + '_' + chain_t;
52729
52991
 
52730
- let atomSet_t = (me.cfg.resrange) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[0].split(','), chainid_t).hAtoms : ic.chains[chainid_t];
52731
- let atomSet_q = (me.cfg.resrange) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[index].split(','), chainid_q).hAtoms : ic.chains[chainid_q];
52992
+ let atomSet_t = (resRangeArray[0]) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[0].split(','), chainid_t).hAtoms : ic.chains[chainid_t];
52993
+ let atomSet_q = (resRangeArray[index]) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[index].split(','), chainid_q).hAtoms : ic.chains[chainid_q];
52732
52994
  // end of original version =============
52733
52995
 
52734
52996
  /*
@@ -55386,6 +55648,22 @@ class MmdbParser {
55386
55648
  hAtoms = ic.loadAtomDataCls.loadAtomDataIn(data, pdbid, 'mmdbid', undefined, type, chainid, chainIndex, bLastQuery, bNoTransformNoSeqalign);
55387
55649
  }
55388
55650
 
55651
+ // show ligand-protein interaction
55652
+ if(me.cfg.ligand) { // sid123059722
55653
+ for(let chainid in ic.chainid2sid) {
55654
+ if(ic.chainid2sid[chainid] == me.cfg.ligand.substr(3)) {
55655
+ // save a set named me.cfg.ligand
55656
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(ic.chains[chainid]);
55657
+ let idArray = Object.keys(residueHash)[0].split('_');
55658
+ let select = '.' + idArray[1] + ':' + idArray[2];
55659
+
55660
+ await ic.selByCommCls.selectByCommand(select, me.cfg.ligand, me.cfg.ligand);
55661
+ break;
55662
+ }
55663
+ }
55664
+ }
55665
+ ic.hAtoms = hAtoms;
55666
+
55389
55667
  // set 3d domains
55390
55668
  let structure = data.pdbId;
55391
55669
 
@@ -65973,6 +66251,7 @@ class ApplyCommand {
65973
66251
  || commandOri.indexOf('save2 interaction pairs') == 0
65974
66252
  || commandOri.indexOf('line graph interaction pairs') == 0
65975
66253
  || commandOri.indexOf('scatterplot interaction pairs') == 0
66254
+ || commandOri.indexOf('ligplot interaction pairs') == 0
65976
66255
  ) {
65977
66256
  let paraArray = commandOri.split(' | ');
65978
66257
  if(paraArray.length >= 3) {
@@ -66030,6 +66309,9 @@ class ApplyCommand {
66030
66309
  else if(commandOri.indexOf('scatterplot interaction pairs') == 0) {
66031
66310
  type = 'scatterplot';
66032
66311
  }
66312
+ else if(commandOri.indexOf('ligplot interaction pairs') == 0) {
66313
+ type = 'ligplot';
66314
+ }
66033
66315
 
66034
66316
  await ic.viewInterPairsCls.viewInteractionPairs(nameArray2, nameArray, bHbondCalc, type, bHbond, bSaltbridge, bInteraction, bHalogen, bPication, bPistacking);
66035
66317
  }
@@ -66089,6 +66371,14 @@ class ApplyCommand {
66089
66371
 
66090
66372
  $("#" + me.scatterplotid).attr("width",(ic.scatterplotWidth * parseFloat(scale)).toString() + "px");
66091
66373
  }
66374
+ else if(command.indexOf('ligplot scale') == 0) {
66375
+ let pos = command.lastIndexOf(' ');
66376
+ let scale = command.substr(pos + 1);
66377
+
66378
+ $("#" + me.ligplotid + "_scale").val(scale);
66379
+
66380
+ $("#" + me.ligplotid).attr("width",(ic.ligplotWidth * parseFloat(scale)).toString() + "px");
66381
+ }
66092
66382
  else if(command.indexOf('contactmap scale') == 0) {
66093
66383
  let pos = command.lastIndexOf(' ');
66094
66384
  let scale = command.substr(pos + 1);
@@ -66742,6 +67032,7 @@ class ApplyCommand {
66742
67032
  else if(cmd.indexOf('save2 interaction pairs') == 0) return hbondIntStr + ': "Set 2" button';
66743
67033
  else if(cmd.indexOf('line graph interaction pairs') == 0) return hbondIntStr + ': "2D Interaction Network" button';
66744
67034
  else if(cmd.indexOf('scatterplot interaction pairs') == 0) return hbondIntStr + ': "2D Interaction Map" button';
67035
+ else if(cmd.indexOf('ligplot interaction pairs') == 0) return hbondIntStr + ': "2D Interaction for One Ligand/Residue" button';
66745
67036
  else if(cmd.indexOf('graph label') == 0) return forceStr + ': "Label Size" menu';
66746
67037
  else if(cmd.indexOf('graph force') == 0) return forceStr + ': "Force on Nodes" menu';
66747
67038
  else if(cmd.indexOf('hide edges') == 0) return forceStr + ': "Internal Edges" menu';
@@ -75299,6 +75590,12 @@ class Diagram2d {
75299
75590
  thisClass.clickNode(this);
75300
75591
  });
75301
75592
 
75593
+ $(document).on("click", "#" + ic.pre + "dl_ligplot .icn3d-node", function(e) { thisClass.icn3d;
75594
+ e.stopImmediatePropagation();
75595
+
75596
+ thisClass.clickNode(this);
75597
+ });
75598
+
75302
75599
  //$("#" + ic.pre + "dl_linegraph .icn3d-interaction", "click", function(e) { let ic = this.icn3d, me = ic.icn3dui;
75303
75600
  $(document).on("click", "#" + ic.pre + "dl_linegraph .icn3d-interaction", function(e) { let ic = thisClass.icn3d;
75304
75601
  e.stopImmediatePropagation();
@@ -75381,6 +75678,8 @@ class Diagram2d {
75381
75678
  let strokeWidth = 2;
75382
75679
  $(node).find('circle').attr('stroke', me.htmlCls.ORANGE);
75383
75680
  $(node).find('circle').attr('stroke-width', strokeWidth);
75681
+ $(node).find('rect').attr('stroke', me.htmlCls.ORANGE);
75682
+ $(node).find('rect').attr('stroke-width', strokeWidth);
75384
75683
 
75385
75684
  ic.hAtoms = me.hashUtilsCls.unionHash(ic.hAtoms, ic.residues[resid]);
75386
75685
 
@@ -76498,6 +76797,364 @@ class Cartoon2d {
76498
76797
  }
76499
76798
  }
76500
76799
 
76800
+ /**
76801
+ * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
76802
+ */
76803
+
76804
+ class Ligplot {
76805
+ constructor(icn3d) {
76806
+ this.icn3d = icn3d;
76807
+ }
76808
+
76809
+ async drawLigplot(atomSet1) { let ic = this.icn3d, me = ic.icn3dui;
76810
+ me.htmlCls.dialogCls.openDlg('dl_ligplot', 'Show ligand interactions with atom details');
76811
+
76812
+ let widthOri, heightOri, width = 100, height = 100;
76813
+ ic.len4ang = 80;
76814
+
76815
+ // get SVG from backend
76816
+ let pdbStr = ic.saveFileCls.getAtomPDB(atomSet1);
76817
+ pdbStr = pdbStr.trim();
76818
+ pdbStr = pdbStr.replace(/\n\n/g, '\n'); // remove empty lines
76819
+
76820
+ let dataObj = {'pdb2svg': pdbStr};
76821
+ let url = me.htmlCls.baseUrl + "openbabel/openbabel.cgi";
76822
+ let dataStr = await me.getAjaxPostPromise(url, dataObj, undefined, undefined, undefined, undefined, 'text');
76823
+
76824
+ let lineArray = dataStr.split('\n');
76825
+ let lineSvg = '', nodeSvg = '', index2xy = {};
76826
+ let xsum = 0, ysum = 0, cnt = 0;
76827
+ ic.svgGridSize = ic.len4ang; // make the scg into many grids to tell whether the grid is empty, 30 is about bond length (1.5 angstrom)
76828
+ ic.gridXY2used = {};
76829
+ for(let i = 0, il = lineArray.length; i < il; ++i) {
76830
+ let line = lineArray[i];
76831
+ if(line.indexOf('<svg width') == 0) {
76832
+ //<svg width="100" height="100" x="0" y="0" viewBox="0 0 634.256 380"
76833
+ // get real width and height
76834
+ let start = line.indexOf('viewBox="') + 9;
76835
+ let linePart = line.substr(start);
76836
+ let viewbox = linePart.substr(0, linePart.indexOf('"'));
76837
+ let viewboxArray = viewbox.split(' ');
76838
+ widthOri = parseFloat(viewboxArray[2]);
76839
+ heightOri = parseFloat(viewboxArray[3]);
76840
+ width = widthOri + 2*ic.len4ang;
76841
+ height = heightOri + 2*ic.len4ang;
76842
+ }
76843
+ else if(line.indexOf('<line') == 0) {
76844
+ lineSvg += line + '\n';
76845
+ }
76846
+ else if(line.indexOf('<text') == 0) {
76847
+ if(line.indexOf('font-size="12"') != -1) {
76848
+ // index node
76849
+ //<text x="40.000000" y="120.000000" fill="rgb(255,0,0)" stroke-width="0" font-weight="bold" font-size="12" >1</text>
76850
+ let start = line.indexOf('>') + 1;
76851
+ let indexPart = line.substr(start);
76852
+ let index = parseInt(indexPart.substr(0, indexPart.indexOf('<')));
76853
+
76854
+ start = line.indexOf('x="') + 3;
76855
+ let xPart = line.substr(start);
76856
+ let x = parseFloat(xPart.substr(0, xPart.indexOf('"')));
76857
+
76858
+ start = line.indexOf('y="') + 3;
76859
+ let yPart = line.substr(start);
76860
+ let y = parseFloat(yPart.substr(0, yPart.indexOf('"')));
76861
+
76862
+ index2xy[index] = {"x": x, "y": y};
76863
+ let xGrid = parseInt(x / ic.svgGridSize);
76864
+ let yGrid = parseInt(y / ic.svgGridSize);
76865
+ ic.gridXY2used[xGrid + '_' + yGrid] = 1;
76866
+
76867
+ xsum += x;
76868
+ ysum += y;
76869
+ ++cnt;
76870
+ }
76871
+ else { // font-size > 12
76872
+ nodeSvg += line + '\n';
76873
+ }
76874
+ }
76875
+ else if(line.indexOf('</svg>') == 0) {
76876
+ break;
76877
+ }
76878
+ }
76879
+
76880
+ let xcenter = xsum / cnt, ycenter = ysum / cnt;
76881
+
76882
+ let id = me.ligplotid;
76883
+ ic.ligplotWidth = width;
76884
+ let graphWidth = ic.ligplotWidth;
76885
+
76886
+ let textHeight = 30;
76887
+ let heightAll = height + textHeight;
76888
+
76889
+ let offset = - ic.len4ang;
76890
+ let svgHtml = "<svg id='" + id + "' viewBox='" + offset + "," + offset + "," + width + "," + heightAll + "' width='" + graphWidth + "px' font-family='sans-serif' stroke='rgb(0,0,0)' stroke-width='2' stroke-linecap='round'>";
76891
+
76892
+ let xlen = parseInt(widthOri / ic.svgGridSize), ylen = parseInt(heightOri / ic.svgGridSize);
76893
+ let result = ic.viewInterPairsCls.getAllInteractionTable("save1", index2xy, xlen, ylen, xcenter, ycenter); // sort on the ligand/set1
76894
+ ic.bLigplot = true;
76895
+
76896
+ svgHtml += lineSvg + result.svgHtmlLine;
76897
+
76898
+ svgHtml += nodeSvg + result.svgHtmlNode;
76899
+
76900
+ svgHtml += "</svg>";
76901
+
76902
+ $("#" + ic.pre + "ligplotDiv").html(svgHtml);
76903
+
76904
+ this.setEventsForLigplot();
76905
+ }
76906
+
76907
+
76908
+ getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter, bNotDrawNode, prevX2, prevY2) { let ic = this.icn3d, me = ic.icn3dui;
76909
+ let xOffset = 1, yOffset = -1;
76910
+ let bondLen = (interactionType == 'hbond' || interactionType == 'contact' || interactionType == 'halogen') ? ic.len4ang : ic.len4ang * 1.5; // real distance should be bout 120, not 80
76911
+ let shortBondLen = ic.len4ang / 2;
76912
+ let strokeWidth = (interactionType == 'contact') ? 1 : 2;
76913
+
76914
+ let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
76915
+ let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
76916
+ let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
76917
+ let atom2 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
76918
+
76919
+ let xSum = 0, ySum = 0, cntPoint = 0;
76920
+ let baseSerial = atom1.serial;
76921
+ for(let i = 0, il = serialArray1.length; i < il; ++i) {
76922
+ let index = serialArray1[i] - baseSerial + 1;
76923
+ xSum += index2xy[index].x;
76924
+ ySum += index2xy[index].y;
76925
+ ++cntPoint;
76926
+ }
76927
+
76928
+ let x1 = xSum / cntPoint - xOffset;
76929
+ let y1 = ySum / cntPoint - yOffset;
76930
+
76931
+ if(!ic.resid2cnt.hasOwnProperty(resid1)) {
76932
+ ic.resid2cnt[resid1] = 0;
76933
+ }
76934
+ else {
76935
+ ++ic.resid2cnt[resid1];
76936
+ }
76937
+
76938
+ let x2, y2, angle;
76939
+ if(!bNotDrawNode && !ic.resid2ToXy.hasOwnProperty(resid2Real)) {
76940
+ // 1st and ideal way to find a position. If failed, use the 2nd way
76941
+ let xGrid = parseInt(x1 / ic.svgGridSize);
76942
+ let yGrid = parseInt(y1 / ic.svgGridSize);
76943
+ let gridArray = [];
76944
+ for(let i = 1; i >= -1; --i) { // try right-bottom first
76945
+ for(let j = 1; j >= -1; --j) {
76946
+ if(!(i == 0 && j == 0)) {
76947
+ if(xGrid + i >= 0 && xGrid + i <= xlen && yGrid + j >= 0 && yGrid + j <= ylen) gridArray.push((xGrid + i) + '_' + (yGrid + j));
76948
+ }
76949
+ }
76950
+ }
76951
+ for(let i = 2; i >= -2; --i) { // try right-bottom first
76952
+ for(let j = 2; j >= -2; --j) {
76953
+ if(!(i >= -1 && i <= 1 && j >= -1 && j <= 1 )) {
76954
+ if(xGrid + i >= 0 && xGrid + i <= xlen && yGrid + j >= 0 && yGrid + j <= ylen) gridArray.push((xGrid + i) + '_' + (yGrid + j));
76955
+ }
76956
+ }
76957
+ }
76958
+
76959
+ let bFound = false, xyGrids;
76960
+ for(let i = 0, il = gridArray.length; i < il; ++i) {
76961
+ if(!ic.gridXY2used[gridArray[i]]) { // found a spot to put the residue
76962
+ xyGrids = gridArray[i].split('_');
76963
+ x2 = (parseInt(xyGrids[0]) + 0.5) * ic.svgGridSize;
76964
+ y2 = (parseInt(xyGrids[1]) + 0.5) * ic.svgGridSize;
76965
+
76966
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
76967
+ let x2b = bondLen / dist * (x2 - x1) + x1;
76968
+ let y2b = bondLen / dist * (y2 - y1) + y1;
76969
+ x2 = x2b;
76970
+ y2 = y2b;
76971
+
76972
+ ic.gridXY2used[gridArray[i]] = 1;
76973
+ bFound = true;
76974
+ break;
76975
+ }
76976
+ }
76977
+
76978
+ if(!bFound) {
76979
+ // 2nd way to find a position from the center to the outside
76980
+ let dx = x1 - xcenter;
76981
+ let dy = y1 - ycenter;
76982
+
76983
+ let baseAngle = 0;
76984
+ if(Math.abs(dx) > Math.abs(dy)) { // extend along x-axis
76985
+ if(dx > 0) { // +x direction
76986
+ baseAngle = 0;
76987
+ }
76988
+ else { // -x direction
76989
+ baseAngle = 180;
76990
+ }
76991
+ }
76992
+ else { // extend along y-axis
76993
+ if(dy > 0) { // +y direction
76994
+ baseAngle = 90;
76995
+ }
76996
+ else { // -y direction
76997
+ baseAngle = 270;
76998
+ }
76999
+ }
77000
+ angle = baseAngle - 10 + ic.resid2cnt[resid1] * 30;
77001
+
77002
+ x2 = x1 + bondLen * Math.cos(angle * Math.PI/180);
77003
+ y2 = y1 + bondLen * Math.sin(angle * Math.PI/180);
77004
+ }
77005
+ }
77006
+
77007
+ let oneLetterRes = me.utilsCls.residueName2Abbr(atom2.resn.substr(0, 3));
77008
+ let resName2 = oneLetterRes + atom2.resi;
77009
+ let textColor2 = (atom2.color) ? atom2.color.getHexString() : '000';
77010
+ let lineColor = ic.lineGraphCls.getStrokecolor(undefined, interactionType);
77011
+
77012
+ // let node = '<circle cx="' + x2 + '" cy="' + y2 + '" r="8" fill="#' + textColor2 + '" stroke-width="1" stroke="' + textColor2 + '" resid="' + resid2 + '"></circle>\n<text x="' + x2 + '" y="' + y2 + '" stroke="#000" stroke-width="1px" text-anchor="middle" alignment-baseline="central" font-size="8px">' + resName2 + '</text>';
77013
+
77014
+ let node = '', line = '';
77015
+
77016
+ // id can't contain comma and thus use '-'
77017
+ // sometimes the same ligand atom is used in both Hbond and contact. THus we add "interactionType"
77018
+ let idpair = resid2Real + '--' + serialArray1.join('-') + interactionType;
77019
+
77020
+ let id = resid2Real;
77021
+ if(bNotDrawNode || ic.resid2ToXy.hasOwnProperty(id)) {
77022
+ x2 = (ic.resid2ToXy.hasOwnProperty(id)) ? ic.resid2ToXy[id].x2 : prevX2;
77023
+ y2 = (ic.resid2ToXy.hasOwnProperty(id)) ? ic.resid2ToXy[id].y2 : prevY2;
77024
+
77025
+ // draw a short line from x2, y2 to x1, y1 with the distance shortBondLen
77026
+ let x1b = x1, y1b = y1, bShort = 0;
77027
+ if(interactionType == 'contact') {
77028
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
77029
+ if(shortBondLen < dist) {
77030
+ x1b = shortBondLen / dist * (x1 - x2) + x2;
77031
+ y1b = shortBondLen / dist * (y1 - y2) + y2;
77032
+ bShort = 1;
77033
+ }
77034
+ }
77035
+
77036
+ line += '<line id="' + idpair + '" x1="' + x1b.toFixed(2) + '" y1="' + y1b.toFixed(2) + '" x2="' + x2.toFixed(2) + '" y2="' + y2.toFixed(2) + '" x0="' + x1.toFixed(2) + '" y0="' + y1.toFixed(2) + '" short="' + bShort + '" opacity="1.0" stroke="' + lineColor + '" stroke-width="' + strokeWidth + '" stroke-dasharray="5,5"/>\n';
77037
+ }
77038
+ else {
77039
+ node +='<g>';
77040
+ node += '<title>' + resName2 + '</title>';
77041
+ // node += '<circle class='icn3d-ctnode' cx="' + x2.toFixed(2) + '" cy="' + y2.toFixed(2) + '" r="10" fill="#' + textColor2 + '" stroke-width="1" stroke="' + textColor2 + '" resid="' + resid2Real + '"/>';
77042
+ let boxWidth = 28, boxHeight = 14;
77043
+ node += '<rect id="' + id + '_node" x="' + (x2 - boxWidth*0.5).toFixed(2) + '" y="' + (y2 - boxHeight*0.5).toFixed(2) + '" width="' + boxWidth + '" height="' + boxHeight + '" rx="2" ry="2" fill="#' + textColor2 + '" stroke-width="1" stroke="' + textColor2 + '" resid="' + resid2Real + '"/>';
77044
+
77045
+ node += '<text class="icn3d-ctnode" resid="' + id + '" id="' + id + '" x="' + x2.toFixed(2) + '" y="' + y2.toFixed(2) + '" fill="#000" stroke="none" text-anchor="middle" alignment-baseline="central" style="font-size:10px">' + resName2 + '</text>';
77046
+ node += '</g>\n';
77047
+
77048
+ line += '<line id="' + idpair + '" x1="' + x1.toFixed(2) + '" y1="' + y1.toFixed(2) + '" x2="' + x2.toFixed(2) + '" y2="' + y2.toFixed(2) + '" opacity="1.0" stroke="' + lineColor + '" stroke-width="' + strokeWidth + '" stroke-dasharray="5,5"/>\n';
77049
+
77050
+ if(interactionType != 'contact') {
77051
+ if(!ic.resid2ToXy.hasOwnProperty(resid2Real)) ic.resid2ToXy[resid2Real] = {x2: x2, y2: y2};
77052
+ }
77053
+ }
77054
+
77055
+ if(!ic.nodeid2lineid.hasOwnProperty(id)) ic.nodeid2lineid[id] = [];
77056
+ ic.nodeid2lineid[id].push(idpair);
77057
+
77058
+ return {node: node, line: line, x2: x2, y2: y2};
77059
+ }
77060
+
77061
+ setEventsForLigplot() { let ic = this.icn3d, me = ic.icn3dui;
77062
+ //https://stackoverflow.com/questions/1108480/svg-draggable-using-jquery-and-jquery-svg
77063
+ $("#" + me.ligplotid + " .icn3d-ctnode")
77064
+ .draggable({
77065
+ start: function( e, ui ) {
77066
+ let oriX= parseFloat(e.target.getAttribute('x'));
77067
+ let oriY = parseFloat(e.target.getAttribute('y'));
77068
+
77069
+ e.target.setAttribute('x', oriX);
77070
+ e.target.setAttribute('y', oriY);
77071
+ },
77072
+ drag: function( e, ui ) {
77073
+ let offsetX = $("#" + me.ligplotid).offset().left + ic.len4ang; // ic.len4ang was defined in svg viewbox
77074
+ let offsetY = $("#" + me.ligplotid).offset().top + ic.len4ang;
77075
+
77076
+ let id = e.target.getAttribute('resid');
77077
+ let x = (e.clientX - offsetX);
77078
+ let y = (e.clientY - offsetY);
77079
+
77080
+ let oriX = parseFloat(e.target.getAttribute('x'));
77081
+ let oriY = parseFloat(e.target.getAttribute('y'));
77082
+
77083
+ // change for each step
77084
+ let dx = (x - oriX) / ic.resizeRatioX;
77085
+ let dy = (y - oriY) / ic.resizeRatioY;
77086
+
77087
+ // move the text label
77088
+ oriX = parseFloat($("#" + id + "_node").attr('x'));
77089
+ oriY = parseFloat($("#" + id + "_node").attr('y'));
77090
+
77091
+ $("#" + id + "_node").attr('x', oriX + dx);
77092
+ $("#" + id + "_node").attr('y', oriY + dy);
77093
+
77094
+ // update the center
77095
+ e.target.setAttribute('x', x);
77096
+ e.target.setAttribute('y', y);
77097
+
77098
+ // update the edges
77099
+ if(ic.nodeid2lineid[id]) {
77100
+ for(let i = 0, il = ic.nodeid2lineid[id].length; i < il; ++i) {
77101
+ let idpair = ic.nodeid2lineid[id][i];
77102
+
77103
+ updateEdges(idpair, id);
77104
+ }
77105
+ }
77106
+
77107
+ function updateEdges(idpair, id) {
77108
+ if(idpair && idpair.indexOf(id) != -1) {
77109
+ let idArray = idpair.split('--');
77110
+ if(idArray.length == 2) {
77111
+ let id2;
77112
+ id2 = idArray[0];
77113
+
77114
+ let x2 = parseFloat($("#" + id2).attr('x'));
77115
+ let y2 = parseFloat($("#" + id2).attr('y'));
77116
+
77117
+ $("#" + idpair).attr('x2', x2);
77118
+ $("#" + idpair).attr('y2', y2);
77119
+
77120
+ let x1 = $("#" + idpair).attr('x1');
77121
+ let y1 = $("#" + idpair).attr('y1');
77122
+ let x1b = x1, y1b = y1;
77123
+
77124
+ let bShort = parseInt($("#" + idpair).attr('short'));
77125
+ if(bShort) { // adjust x1,y1
77126
+ x1 = $("#" + idpair).attr('x0');
77127
+ y1 = $("#" + idpair).attr('y0');
77128
+
77129
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
77130
+ let shortBondLen = ic.len4ang / 2;
77131
+
77132
+ if(shortBondLen < dist) {
77133
+ x1b = shortBondLen / dist * (x1 - x2) + x2;
77134
+ y1b = shortBondLen / dist * (y1 - y2) + y2;
77135
+ }
77136
+ }
77137
+
77138
+ $("#" + idpair).attr('x1', x1b);
77139
+ $("#" + idpair).attr('y1', y1b);
77140
+ }
77141
+ } // if
77142
+ } // function
77143
+ }
77144
+ });
77145
+ }
77146
+
77147
+ clickLigplot() { let ic = this.icn3d; ic.icn3dui;
77148
+ let thisClass = this;
77149
+
77150
+ $(document).on("click", "#" + ic.pre + "dl_ligplot .icn3d-ctnode", function(e) { let ic = thisClass.icn3d;
77151
+ e.stopImmediatePropagation();
77152
+
77153
+ ic.diagram2dCls.clickNode(this);
77154
+ });
77155
+ }
77156
+ }
77157
+
76501
77158
  /**
76502
77159
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
76503
77160
  */
@@ -77181,7 +77838,7 @@ class SaveFile {
77181
77838
  }
77182
77839
  }
77183
77840
 
77184
- saveSvg(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
77841
+ saveSvg(id, filename, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
77185
77842
  if(me.bNode) return '';
77186
77843
 
77187
77844
  let width = $("#" + id).width();
@@ -77189,19 +77846,26 @@ class SaveFile {
77189
77846
 
77190
77847
  if(bContactmap) height = width;
77191
77848
 
77192
- let svgXml = this.getSvgXml(id, width, height, bContactmap);
77849
+ if(bLigplot) {
77850
+ width += ic.len4ang;
77851
+ height += ic.len4ang;
77852
+ }
77853
+
77854
+ let svgXml = this.getSvgXml(id, width, height, bContactmap, bLigplot);
77193
77855
 
77194
77856
  let blob = new Blob([svgXml], {type: "image/svg+xml"});
77195
77857
  saveAs(blob, filename);
77196
77858
  }
77197
77859
 
77198
- getSvgXml(id, width, height, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
77860
+ getSvgXml(id, width, height, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
77199
77861
  if(me.bNode) return '';
77200
77862
 
77201
77863
  // font is not good
77202
77864
  let svg_data = document.getElementById(id).innerHTML; //put id of your svg element here
77203
77865
 
77204
- let viewbox = (width && height) ? "<svg viewBox=\"0 0 " + width + " " + height + "\"" : "<svg";
77866
+ let startX = (bLigplot) ? -30 : 0;
77867
+ let startY = (bLigplot) ? -30 : 0;
77868
+ let viewbox = (width && height) ? "<svg viewBox=\"" + startX + " " + startY + " " + width + " " + height + "\"" : "<svg";
77205
77869
  //let head = viewbox + " title=\"graph\" version=\"1.1\" xmlns:xl=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
77206
77870
  let head = viewbox + " title=\"graph\" xmlns:xl=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
77207
77871
 
@@ -77213,7 +77877,7 @@ class SaveFile {
77213
77877
  return full_svg;
77214
77878
  }
77215
77879
 
77216
- savePng(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
77880
+ savePng(id, filename, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
77217
77881
  if(me.bNode) return '';
77218
77882
 
77219
77883
  let width = $("#" + id).width();
@@ -77226,7 +77890,7 @@ class SaveFile {
77226
77890
  let bbox = svg.getBBox();
77227
77891
 
77228
77892
  let copy = svg.cloneNode(true);
77229
- ic.lineGraphCls.copyStylesInline(copy, svg);
77893
+ if(!bLigplot) ic.lineGraphCls.copyStylesInline(copy, svg);
77230
77894
  let canvas = document.createElement("CANVAS");
77231
77895
  canvas.width = width;
77232
77896
  canvas.height = height;
@@ -81019,6 +81683,7 @@ class iCn3D {
81019
81683
  this.shareLinkCls = new ShareLink(this);
81020
81684
  this.diagram2dCls = new Diagram2d(this);
81021
81685
  this.cartoon2dCls = new Cartoon2d(this);
81686
+ this.ligplotCls = new Ligplot(this);
81022
81687
 
81023
81688
  this.rayCls = new Ray(this);
81024
81689
  this.controlCls = new Control(this);
@@ -81245,7 +81910,7 @@ class iCn3DUI {
81245
81910
  //even when multiple iCn3D viewers are shown together.
81246
81911
  this.pre = this.cfg.divid + "_";
81247
81912
 
81248
- this.REVISION = '3.33.3';
81913
+ this.REVISION = '3.34.0';
81249
81914
 
81250
81915
  // In nodejs, iCn3D defines "window = {navigator: {}}"
81251
81916
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -81688,7 +82353,8 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
81688
82353
 
81689
82354
  ic.bChainAlign = true;
81690
82355
  ic.inputid = me.cfg.chainalign;
81691
- ic.loadCmd = 'load chainalignment ' + me.cfg.chainalign + ' | resnum ' + me.cfg.resnum + ' | resdef ' + me.cfg.resdef + ' | aligntool ' + me.cfg.aligntool + ' | parameters ' + me.cfg.inpara + ' | resrange ' + me.cfg.resrange;
82356
+ let resrangeStr = (me.cfg.resrange) ? ' | resrange ' + me.cfg.resrange : '';
82357
+ ic.loadCmd = 'load chainalignment ' + me.cfg.chainalign + ' | resnum ' + me.cfg.resnum + ' | resdef ' + me.cfg.resdef + ' | aligntool ' + me.cfg.aligntool + ' | parameters ' + me.cfg.inpara + resrangeStr;
81692
82358
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
81693
82359
  await ic.chainalignParserCls.downloadChainalignment(me.cfg.chainalign);
81694
82360
  }