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.module.js CHANGED
@@ -14089,6 +14089,7 @@ class Dialog {
14089
14089
  let bGraph = $('#' + me.pre + 'dl_graph').hasClass('ui-dialog-content'); // initialized
14090
14090
  let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
14091
14091
  let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
14092
+ let bLigplot = $('#' + me.pre + 'dl_ligplot').hasClass('ui-dialog-content'); // initialized
14092
14093
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
14093
14094
  let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
14094
14095
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
@@ -14098,13 +14099,14 @@ class Dialog {
14098
14099
  let bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
14099
14100
 
14100
14101
  status.bSelectannotationsInit2 = false, status.bGraph2 = false, status.bLineGraph2 = false;
14101
- status.bScatterplot2 = false, status.bTable2 = false, status.bAlignmentInit2 = false;
14102
+ status.bScatterplot2 = false, status.bLigplot2 = false, status.bTable2 = false, status.bAlignmentInit2 = false;
14102
14103
  status.bTwoddgmInit2 = false, status.bTwodctnInit2 = false, status.bSetsInit2 = false;
14103
14104
 
14104
14105
  id2flag.dl_selectannotations = 'bSelectannotationsInit2';
14105
14106
  id2flag.dl_graph = 'bGraph2';
14106
14107
  id2flag.dl_linegraph = 'bLineGraph2';
14107
- id2flag.dl_scatterplot = 'bScatterplot2';
14108
+ id2flag.dl_scatterplot = 'bScatterplot2';
14109
+ id2flag.dl_ligplot = 'bLigplot2';
14108
14110
  id2flag.dl_contactmap = 'bContactmap2';
14109
14111
  id2flag.dl_alignerrormap = 'bAlignerrormap2';
14110
14112
  id2flag.dl_interactionsorted = 'bTable2';
@@ -14117,6 +14119,7 @@ class Dialog {
14117
14119
  if(bGraph) status.bGraph2 = $('#' + me.pre + 'dl_graph').dialog( 'isOpen' );
14118
14120
  if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
14119
14121
  if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
14122
+ if(bLigplot) status.bLigplot2 = $('#' + me.pre + 'dl_ligplot').dialog( 'isOpen' );
14120
14123
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
14121
14124
  if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
14122
14125
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
@@ -14203,7 +14206,7 @@ class Dialog {
14203
14206
 
14204
14207
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
14205
14208
  }
14206
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
14209
+ 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') {
14207
14210
  let oriWidth =(status.bTwoddgmInit2 || status.bSetsInit2) ?(me.htmlCls.WIDTH - twoddgmWidth)/2 : me.htmlCls.WIDTH / 2;
14208
14211
  let ratio = $("#" + id).width() / oriWidth;
14209
14212
 
@@ -14215,6 +14218,14 @@ class Dialog {
14215
14218
  let width = ic.scatterplotWidth * ratio;
14216
14219
  $("#" + me.scatterplotid).attr("width", width);
14217
14220
  }
14221
+ else if(id == me.pre + 'dl_ligplot') {
14222
+ let width = ic.ligplotWidth * ratio;
14223
+ $("#" + me.ligplotid).attr("width", width);
14224
+ }
14225
+ else if(id == me.pre + 'dl_ligplot') {
14226
+ let width = ic.ligplotWidth * ratio;
14227
+ $("#" + me.ligplotid).attr("width", width);
14228
+ }
14218
14229
  else if(id == me.pre + 'dl_contactmap') {
14219
14230
  let width = ic.contactmapWidth * ratio;
14220
14231
  $("#" + me.contactmapid).attr("width", width);
@@ -14268,7 +14279,7 @@ class Dialog {
14268
14279
  close: function(e) {
14269
14280
  let status = thisClass.getDialogStatus().status;
14270
14281
 
14271
- if((!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bTable2) &&(!status.bAlignmentInit2) ) {
14282
+ if((!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bTable2) &&(!status.bAlignmentInit2) ) {
14272
14283
  //ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH, me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT, true);
14273
14284
  ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH, me.htmlCls.HEIGHT, true);
14274
14285
  }
@@ -14297,7 +14308,7 @@ class Dialog {
14297
14308
 
14298
14309
  let status = this.getDialogStatus().status;
14299
14310
 
14300
- 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') {
14311
+ 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') {
14301
14312
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
14302
14313
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
14303
14314
 
@@ -14333,14 +14344,15 @@ class Dialog {
14333
14344
  modal: false,
14334
14345
  position: position,
14335
14346
  close: function(e) {
14336
- if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14337
- ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14338
- ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14339
- ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14340
- ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14341
- ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14342
- ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bAlignerrormap2))
14343
- ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
14347
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14348
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14349
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14350
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14351
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14352
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14353
+ ||(id === me.pre + 'dl_ligplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
14354
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bAlignerrormap2))
14355
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2))
14344
14356
  ) {
14345
14357
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
14346
14358
  let canvasWidth = me.utilsCls.isMobile() ? me.htmlCls.WIDTH : me.htmlCls.WIDTH - twoddgmWidth;
@@ -14366,7 +14378,7 @@ class Dialog {
14366
14378
 
14367
14379
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
14368
14380
  }
14369
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
14381
+ 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') {
14370
14382
  let oriWidth =(status.bTwoddgmInit2 || status.bSetsInit2) ?(me.htmlCls.WIDTH - twoddgmWidth)/2 : me.htmlCls.WIDTH / 2;
14371
14383
  let ratio = $("#" + id).width() / oriWidth;
14372
14384
 
@@ -14378,6 +14390,10 @@ class Dialog {
14378
14390
  let width = ic.scatterplotWidth * ratio;
14379
14391
  $("#" + me.scatterplotid).attr("width", width);
14380
14392
  }
14393
+ else if(id == me.pre + 'dl_ligplot') {
14394
+ let width = ic.ligplotWidth * ratio;
14395
+ $("#" + me.ligplotid).attr("width", width);
14396
+ }
14381
14397
  else if(id == me.pre + 'dl_contactmap') {
14382
14398
  let width = ic.contactmapWidth * ratio;
14383
14399
  $("#" + me.contactmapid).attr("width", width);
@@ -14399,7 +14415,7 @@ class Dialog {
14399
14415
 
14400
14416
  //if(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH >= me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT) {
14401
14417
  if(me.htmlCls.WIDTH >= me.htmlCls.HEIGHT) {
14402
- if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bTable2 || status.bAlignmentInit2) {
14418
+ if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bLigplot2 || status.bTable2 || status.bAlignmentInit2) {
14403
14419
  //tmpWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
14404
14420
  tmpWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
14405
14421
  }
@@ -14438,7 +14454,7 @@ class Dialog {
14438
14454
 
14439
14455
  //if(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH >= me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT) {
14440
14456
  if(me.htmlCls.WIDTH >= me.htmlCls.HEIGHT) {
14441
- if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bTable2 || status.bAlignmentInit2) {
14457
+ if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bLigplot2 || status.bTable2 || status.bAlignmentInit2) {
14442
14458
  //tmpWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
14443
14459
  tmpWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
14444
14460
  }
@@ -14518,7 +14534,7 @@ class Dialog {
14518
14534
  let width = 400, height = 150;
14519
14535
  let twoddgmWidth = me.htmlCls.width2d + 20;
14520
14536
 
14521
- 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') {
14537
+ 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') {
14522
14538
  $( "#" + id ).show();
14523
14539
  $( "#" + id + "_nb").show();
14524
14540
  $( "#" + id + "_title").html(title);
@@ -14553,6 +14569,11 @@ class Dialog {
14553
14569
 
14554
14570
  $("#" + me.scatterplotid).attr("width", width);
14555
14571
  }
14572
+ else if(id == me.pre + 'dl_ligplot') {
14573
+ let width = ic.ligplotWidth * ratio;
14574
+
14575
+ $("#" + me.ligplotid).attr("width", width);
14576
+ }
14556
14577
  else if(id == me.pre + 'dl_contactmap') {
14557
14578
  let width = ic.contactmapWidth * ratio;
14558
14579
 
@@ -15251,6 +15272,8 @@ class SetDialog {
15251
15272
 
15252
15273
  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>";
15253
15274
 
15275
+ html += "<div style='text-indent:1.1em'>" + me.htmlCls.buttonStr + "hbondLigplot'>2D Interaction for One Ligand/Residue</button> with atom details</div><br>";
15276
+
15254
15277
  tmpStr = ': </td><td><input style="margin-left:-12px" type="text" id="';
15255
15278
 
15256
15279
  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>";
@@ -15417,6 +15440,40 @@ class SetDialog {
15417
15440
 
15418
15441
  html += "</div>";
15419
15442
 
15443
+
15444
+ html += me.htmlCls.divStr + "dl_ligplot' sty2D Interaction for One Ligand/Residule='background-color:white' class='" + dialogClass + "'>";
15445
+ html += this.addNotebookTitle('dl_ligplot', 'e with Atom Details');
15446
+
15447
+ html += me.htmlCls.divNowrapStr + "<b>Note</b>: Nodes can be dragged or clicked. Hold Ctrl key to select multiple nodes. " + me.htmlCls.space3;
15448
+
15449
+ html += '<div style="width:20px; margin-top:6px; display:inline-block;"><span id="'
15450
+ + 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="'
15451
+ + me.pre + 'dl_ligplotcolor_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="width:15px;" title="Shrink"></span></div></div>';
15452
+
15453
+ html += me.htmlCls.divStr + "dl_ligplotcolor' style='inline-block;'>";
15454
+
15455
+ // 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>";
15456
+ html += "Color legend for interactions (dashed lines): <br>";
15457
+
15458
+ html += me.htmlCls.setHtmlCls.setColorHints();
15459
+
15460
+ html += "<br></div>";
15461
+
15462
+ me.ligplotid = me.pre + 'ligplot';
15463
+ html += me.htmlCls.divNowrapStr + buttonStrTmp + me.ligplotid + '_svg">SVG</button>' + me.htmlCls.space2;
15464
+ html += buttonStrTmp + me.ligplotid + '_png">PNG</button>' + me.htmlCls.space2;
15465
+ // html += buttonStrTmp + me.ligplotid + '_json">JSON</button>' + me.htmlCls.space4;
15466
+ html += "<b>Scale</b>: <select id='" + me.ligplotid + "_scale'>";
15467
+
15468
+ html += me.htmlCls.setHtmlCls.getOptionHtml(optArray4, 5);
15469
+
15470
+ html += "</select></div><br>";
15471
+ html += '<div id="' + me.pre + 'ligplotDiv"></div>';
15472
+
15473
+ html += "</div>";
15474
+
15475
+
15476
+
15420
15477
  html += me.htmlCls.divStr + "dl_contactmap' style='background-color:white' class='" + dialogClass + "'>";
15421
15478
  html += this.addNotebookTitle('dl_contactmap', 'Contact Map');
15422
15479
 
@@ -16471,6 +16528,7 @@ class Events {
16471
16528
 
16472
16529
  ic.diagram2dCls.click2Ddgm();
16473
16530
  ic.cartoon2dCls.click2Dcartoon();
16531
+ ic.ligplotCls.clickLigplot();
16474
16532
  ic.addTrackCls.clickAddTrackButton();
16475
16533
  ic.resizeCanvasCls.windowResize();
16476
16534
  ic.annotationCls.setTabs();
@@ -18092,6 +18150,13 @@ class Events {
18092
18150
  thisClass.setLogCmd("show ref number", true);
18093
18151
  await ic.showInterCls.showInteractions('scatterplot');
18094
18152
  });
18153
+ me.myEventCls.onIds("#" + me.pre + "hbondLigplot", "click", async function(e) { let ic = me.icn3d;
18154
+ e.preventDefault();
18155
+
18156
+ ic.bShownRefnum = false;
18157
+ thisClass.setLogCmd("hide ref number", true);
18158
+ await ic.showInterCls.showInteractions('ligplot');
18159
+ });
18095
18160
  // select residues
18096
18161
  $(document).on("click", "#" + me.svgid + " circle.selected", function(e) { let ic = me.icn3d;
18097
18162
  e.stopImmediatePropagation();
@@ -18202,6 +18267,33 @@ class Events {
18202
18267
  thisClass.setLogCmd("scatterplot scale " + scale, true);
18203
18268
  });
18204
18269
 
18270
+ me.myEventCls.onIds("#" + me.ligplotid + "_svg", "click", function(e) { let ic = me.icn3d;
18271
+ e.preventDefault();
18272
+
18273
+ ic.saveFileCls.saveSvg(me.ligplotid, ic.inputid + "_ligplot.svg", undefined, true);
18274
+ });
18275
+ me.myEventCls.onIds("#" + me.ligplotid + "_png", "click", function(e) { let ic = me.icn3d;
18276
+ e.preventDefault();
18277
+
18278
+ ic.saveFileCls.savePng(me.ligplotid, ic.inputid + "_ligplot.png", undefined, true);
18279
+ });
18280
+ // me.myEventCls.onIds("#" + me.ligplotid + "_json", "click", function(e) { let ic = me.icn3d;
18281
+ // e.preventDefault();
18282
+
18283
+ // let graphStr2 = ic.ligplotStr.substr(0, ic.ligplotStr.lastIndexOf('}'));
18284
+
18285
+ // graphStr2 += me.htmlCls.setHtmlCls.getLinkColor();
18286
+
18287
+ // ic.saveFileCls.saveFile(ic.inputid + "_ligplot.json", "text", [graphStr2]);
18288
+ // });
18289
+ me.myEventCls.onIds("#" + me.ligplotid + "_scale", "change", function(e) { let ic = me.icn3d;
18290
+ e.preventDefault();
18291
+
18292
+ let scale = $("#" + me.ligplotid + "_scale").val();
18293
+ $("#" + me.ligplotid).attr("width",(ic.ligplotWidth * parseFloat(scale)).toString() + "px");
18294
+ thisClass.setLogCmd("ligplot scale " + scale, true);
18295
+ });
18296
+
18205
18297
  me.myEventCls.onIds("#" + me.contactmapid + "_svg", "click", function(e) { let ic = me.icn3d;
18206
18298
  e.preventDefault();
18207
18299
 
@@ -37659,7 +37751,8 @@ class Contact {
37659
37751
  if(oriCalpha === undefined) oriCalpha = oriAtom;
37660
37752
 
37661
37753
  if(bGetPairs) {
37662
- oriResidName = oriAtom.resn + ' $' + oriAtom.structure + '.' + oriAtom.chain + ':' + oriAtom.resi;
37754
+ let serialList = (oriAtom.name.indexOf('pi') == 0 && oriAtom.ring) ? oriAtom.ring.join(',') : oriAtom.serial;
37755
+ oriResidName = oriAtom.resn + ' $' + oriAtom.structure + '.' + oriAtom.chain + ':' + oriAtom.resi + ' ' + serialList;
37663
37756
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
37664
37757
  }
37665
37758
 
@@ -37704,13 +37797,14 @@ class Contact {
37704
37797
  if(bGetPairs) {
37705
37798
  let chain_resi2 = atom.structure + '_' + atom.chain + '_' + atom.resi;
37706
37799
 
37707
- residName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi;
37800
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
37801
+ residName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + ' ' + serialList;
37708
37802
  //var dist = Math.sqrt(atomDistSq).toFixed(1);
37709
37803
  let dist1 = atomDist.toFixed(1);
37710
37804
  let dist2 = calpha.coord.distanceTo(oriCalpha.coord).toFixed(1);
37711
37805
 
37712
37806
  let resids = chain_resi + '_' + oriAtom.resn + ',' + chain_resi2 + '_' + atom.resn;
37713
- let residNames = oriResidName + ',' + residName;
37807
+ let residNames = oriResidName + '|' + residName;
37714
37808
  if(ic.resids2interAll[resids] === undefined
37715
37809
  || ic.resids2interAll[resids]['contact'] === undefined
37716
37810
  || !ic.resids2interAll[resids]['contact'].hasOwnProperty(residNames)
@@ -37727,12 +37821,12 @@ class Contact {
37727
37821
  if(!bInternal) {
37728
37822
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
37729
37823
  if(ic.resids2inter[resids]['contact'] === undefined) ic.resids2inter[resids]['contact'] = {};
37730
- ic.resids2inter[resids]['contact'][oriResidName + ',' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
37824
+ ic.resids2inter[resids]['contact'][oriResidName + '|' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
37731
37825
  }
37732
37826
 
37733
37827
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
37734
37828
  if(ic.resids2interAll[resids]['contact'] === undefined) ic.resids2interAll[resids]['contact'] = {};
37735
- ic.resids2interAll[resids]['contact'][oriResidName + ',' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
37829
+ ic.resids2interAll[resids]['contact'][oriResidName + '|' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
37736
37830
  }
37737
37831
  }
37738
37832
  } // if(bGetPairs) {
@@ -38158,7 +38252,8 @@ class HBond {
38158
38252
  chain_resi_atom = chain_resi + "_" + atom.name;
38159
38253
 
38160
38254
  //var oriResidName = atom.resn + ' ' + chain_resi_atom;
38161
- let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name;
38255
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
38256
+ let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name + ' ' + serialList;
38162
38257
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
38163
38258
 
38164
38259
  for (let j in atomHbond) {
@@ -38283,24 +38378,25 @@ class HBond {
38283
38378
  residueHash[chain_resi2] = 1;
38284
38379
 
38285
38380
  //var residName = atomHbond[j].resn + " " + atomHbond[j].structure + "_" + atomHbond[j].chain + "_" + atomHbond[j].resi + '_' + atomHbond[j].name;
38286
- let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name;
38381
+ let serialList = (atomHbond[j].name.indexOf('pi') == 0 && atomHbond[j].ring) ? atomHbond[j].ring.join(',') : atomHbond[j].serial;
38382
+ let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name + ' ' + serialList;
38287
38383
 
38288
38384
  let resids = chain_resi + '_' + atom.resn + ',' + chain_resi2 + '_' + atomHbond[j].resn;
38289
38385
 
38290
38386
  if(ic.resids2interAll[resids] === undefined
38291
38387
  || ic.resids2interAll[resids]['ionic'] === undefined
38292
- || !ic.resids2interAll[resids]['ionic'].hasOwnProperty(oriResidName + ',' + residName) ) {
38388
+ || !ic.resids2interAll[resids]['ionic'].hasOwnProperty(oriResidName + '|' + residName) ) {
38293
38389
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
38294
38390
 
38295
38391
  if(!bInternal) {
38296
38392
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
38297
38393
  if(ic.resids2inter[resids]['hbond'] === undefined) ic.resids2inter[resids]['hbond'] = {};
38298
- ic.resids2inter[resids]['hbond'][oriResidName + ',' + residName] = dist.toFixed(1);
38394
+ ic.resids2inter[resids]['hbond'][oriResidName + '|' + residName] = dist.toFixed(1);
38299
38395
  }
38300
38396
 
38301
38397
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
38302
38398
  if(ic.resids2interAll[resids]['hbond'] === undefined) ic.resids2interAll[resids]['hbond'] = {};
38303
- ic.resids2interAll[resids]['hbond'][oriResidName + ',' + residName] = dist.toFixed(1);
38399
+ ic.resids2interAll[resids]['hbond'][oriResidName + '|' + residName] = dist.toFixed(1);
38304
38400
  }
38305
38401
  } // end of for (let j in atomHbond) {
38306
38402
  }
@@ -38453,7 +38549,8 @@ class PiHalogen {
38453
38549
 
38454
38550
  for (let i in atoms1a) {
38455
38551
  let atom1 = atoms1a[i];
38456
- let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name;
38552
+ let serialList = (atom1.name.indexOf('pi') == 0 && atom1.ring) ? atom1.ring.join(',') : atom1.serial;
38553
+ let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name + ' ' + serialList;
38457
38554
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
38458
38555
 
38459
38556
  for (let j in atoms1b) {
@@ -38497,7 +38594,8 @@ class PiHalogen {
38497
38594
 
38498
38595
  for (let i in atoms2a) {
38499
38596
  let atom1 = atoms2a[i];
38500
- let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name;
38597
+ let serialList = (atom1.name.indexOf('pi') == 0 && atom1.ring) ? atom1.ring.join(',') : atom1.serial;
38598
+ let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name + ' ' + serialList;
38501
38599
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
38502
38600
 
38503
38601
  // available in 1b and 2a
@@ -38662,7 +38760,8 @@ class PiHalogen {
38662
38760
  }
38663
38761
  }
38664
38762
 
38665
- let residName = atom2.resn + ' $' + atom2.structure + '.' + atom2.chain + ':' + atom2.resi + '@' + atom2.name;
38763
+ let serialList = (atom2.name.indexOf('pi') == 0 && atom2.ring) ? atom2.ring.join(',') : atom2.serial;
38764
+ let residName = atom2.resn + ' $' + atom2.structure + '.' + atom2.chain + ':' + atom2.resi + '@' + atom2.name + ' ' + serialList;
38666
38765
 
38667
38766
  //if(ic.resid2Residhash[oriResidName][residName] === undefined || ic.resid2Residhash[oriResidName][residName] > dist) {
38668
38767
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
@@ -38674,12 +38773,12 @@ class PiHalogen {
38674
38773
  if(!bInternal) {
38675
38774
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
38676
38775
  if(ic.resids2inter[resids][interactionType] === undefined) ic.resids2inter[resids][interactionType] = {};
38677
- ic.resids2inter[resids][interactionType][oriResidName + ',' + residName] = dist.toFixed(1);
38776
+ ic.resids2inter[resids][interactionType][oriResidName + '|' + residName] = dist.toFixed(1);
38678
38777
  }
38679
38778
 
38680
38779
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
38681
38780
  if(ic.resids2interAll[resids][interactionType] === undefined) ic.resids2interAll[resids][interactionType] = {};
38682
- ic.resids2interAll[resids][interactionType][oriResidName + ',' + residName] = dist.toFixed(1);
38781
+ ic.resids2interAll[resids][interactionType][oriResidName + '|' + residName] = dist.toFixed(1);
38683
38782
 
38684
38783
  return true;
38685
38784
  }
@@ -38926,12 +39025,13 @@ class PiHalogen {
38926
39025
  // Print the i-th cycle
38927
39026
  let coord = new THREE.Vector3();
38928
39027
  let cnt = 0, serial;
38929
- let coordArray = [];
39028
+ let coordArray = [], ringArray = [];
38930
39029
  if(cycles.hasOwnProperty(i)) {
38931
39030
  for (let j = 0, jl = cycles[i].length; j < jl; ++j) {
38932
39031
  serial = cycles[i][j];
38933
39032
  coord.add(ic.atoms[serial].coord);
38934
39033
  coordArray.push(ic.atoms[serial].coord);
39034
+ ringArray.push(serial);
38935
39035
  ++cnt;
38936
39036
  }
38937
39037
  }
@@ -38951,7 +39051,7 @@ class PiHalogen {
38951
39051
 
38952
39052
  let atom = ic.atoms[serial];
38953
39053
  name2atom[resid + '_pi' + serial] = {resn: atom.resn, name: 'pi' + serial, coord: coord, serial: atom.serial,
38954
- structure: atom.structure, chain: atom.chain, resi: atom.resi, normal: normal};
39054
+ structure: atom.structure, chain: atom.chain, resi: atom.resi, normal: normal, ring: ringArray};
38955
39055
  }
38956
39056
  }
38957
39057
  }
@@ -39049,7 +39149,8 @@ class Saltbridge {
39049
39149
  chain_resi = atom.structure + "_" + atom.chain + "_" + atom.resi;
39050
39150
  chain_resi_atom = chain_resi + "_" + atom.name;
39051
39151
 
39052
- let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name;
39152
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
39153
+ let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name + ' ' + serialList;
39053
39154
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
39054
39155
 
39055
39156
  let atomHbond = {};
@@ -39114,7 +39215,8 @@ class Saltbridge {
39114
39215
  residueHash[chain_resi] = 1;
39115
39216
  residueHash[chain_resi2] = 1;
39116
39217
 
39117
- let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name;
39218
+ let serialList = (atomHbond[j].name.indexOf('pi') == 0 && atomHbond[j].ring) ? atomHbond[j].ring.join(',') : atomHbond[j].serial;
39219
+ let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name + ' ' + serialList;
39118
39220
 
39119
39221
  //if(ic.resid2Residhash[oriResidName][residName] === undefined || ic.resid2Residhash[oriResidName][residName] > dist) {
39120
39222
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
@@ -39125,12 +39227,12 @@ class Saltbridge {
39125
39227
  if(!bInternal) {
39126
39228
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
39127
39229
  if(ic.resids2inter[resids]['ionic'] === undefined) ic.resids2inter[resids]['ionic'] = {};
39128
- ic.resids2inter[resids]['ionic'][oriResidName + ',' + residName] = dist.toFixed(1);
39230
+ ic.resids2inter[resids]['ionic'][oriResidName + '|' + residName] = dist.toFixed(1);
39129
39231
  }
39130
39232
 
39131
39233
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
39132
39234
  if(ic.resids2interAll[resids]['ionic'] === undefined) ic.resids2interAll[resids]['ionic'] = {};
39133
- ic.resids2interAll[resids]['ionic'][oriResidName + ',' + residName] = dist.toFixed(1);
39235
+ ic.resids2interAll[resids]['ionic'][oriResidName + '|' + residName] = dist.toFixed(1);
39134
39236
 
39135
39237
  } // end of for (let j in atomHbond) {
39136
39238
  }
@@ -50511,24 +50613,14 @@ class LineGraph {
50511
50613
  if(pos1 === undefined || pos2 === undefined) continue;
50512
50614
  let linestrokewidth;
50513
50615
  if(link.v == me.htmlCls.contactValue) {
50514
- linestrokewidth = (link.n == 1) ? 1 : 3;
50616
+ // linestrokewidth = (link.n == 1) ? 1 : 3;
50617
+ linestrokewidth = 1;
50515
50618
  } else {
50516
50619
  linestrokewidth = (link.n == 1) ? 2 : 4;
50517
50620
  }
50518
- let strokecolor;
50519
- if(link.v == me.htmlCls.hbondValue) {
50520
- strokecolor = "#" + me.htmlCls.hbondColor;
50521
- } else if(link.v == me.htmlCls.ionicValue) {
50522
- strokecolor = "#" + me.htmlCls.ionicColor;
50523
- } else if(link.v == me.htmlCls.halogenValue) {
50524
- strokecolor = "#" + me.htmlCls.halogenColor;
50525
- } else if(link.v == me.htmlCls.picationValue) {
50526
- strokecolor = "#" + me.htmlCls.picationColor;
50527
- } else if(link.v == me.htmlCls.pistackingValue) {
50528
- strokecolor = "#" + me.htmlCls.pistackingColor;
50529
- } else if(link.v == me.htmlCls.contactValue) {
50530
- strokecolor = "#" + me.htmlCls.contactColor;
50531
- }
50621
+
50622
+ let strokecolor = this.getStrokecolor(link.v);
50623
+
50532
50624
  html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
50533
50625
  let interactStr = (link.n == 1) ? 'Interaction' : link.n + ' interactions';
50534
50626
  if(link.n > 1) html += "<title>" + interactStr + " of residue " + node1.id + " with residue " + node2.id + "</title>";
@@ -50591,6 +50683,44 @@ class LineGraph {
50591
50683
  return html;
50592
50684
  }
50593
50685
 
50686
+ getStrokecolor(value, type) { let ic = this.icn3d, me = ic.icn3dui;
50687
+ let strokecolor = "#000";
50688
+
50689
+ if(value) {
50690
+ if(value == me.htmlCls.hbondValue) {
50691
+ strokecolor = "#" + me.htmlCls.hbondColor;
50692
+ } else if(value == me.htmlCls.ionicValue) {
50693
+ strokecolor = "#" + me.htmlCls.ionicColor;
50694
+ } else if(value == me.htmlCls.halogenValue) {
50695
+ strokecolor = "#" + me.htmlCls.halogenColor;
50696
+ } else if(value == me.htmlCls.picationValue) {
50697
+ strokecolor = "#" + me.htmlCls.picationColor;
50698
+ } else if(value == me.htmlCls.pistackingValue) {
50699
+ strokecolor = "#" + me.htmlCls.pistackingColor;
50700
+ } else if(value == me.htmlCls.contactValue) {
50701
+ strokecolor = "#" + me.htmlCls.contactColor;
50702
+ }
50703
+ }
50704
+
50705
+ if(type) {
50706
+ if(type == 'hbond') {
50707
+ strokecolor = "#" + me.htmlCls.hbondColor;
50708
+ } else if(type == 'ionic') {
50709
+ strokecolor = "#" + me.htmlCls.ionicColor;
50710
+ } else if(type == 'halogen') {
50711
+ strokecolor = "#" + me.htmlCls.halogenColor;
50712
+ } else if(type == 'pi-cation') {
50713
+ strokecolor = "#" + me.htmlCls.picationColor;
50714
+ } else if(type == 'pi-stacking') {
50715
+ strokecolor = "#" + me.htmlCls.pistackingColor;
50716
+ } else if(type == 'contact') {
50717
+ strokecolor = "#" + me.htmlCls.contactColor;
50718
+ }
50719
+ }
50720
+
50721
+ return strokecolor;
50722
+ }
50723
+
50594
50724
  drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap) { let ic = this.icn3d, me = ic.icn3dui;
50595
50725
  let html = '';
50596
50726
 
@@ -50606,26 +50736,14 @@ class LineGraph {
50606
50736
  let pos2 = node2posSet2[node2.id];
50607
50737
  if(pos1 === undefined || pos2 === undefined) return html;
50608
50738
 
50609
- let strokecolor;
50610
- if(link.v == me.htmlCls.hbondValue) {
50611
- strokecolor = "#" + me.htmlCls.hbondColor;
50612
- } else if(link.v == me.htmlCls.ionicValue) {
50613
- strokecolor = "#" + me.htmlCls.ionicColor;
50614
- } else if(link.v == me.htmlCls.halogenValue) {
50615
- strokecolor = "#" + me.htmlCls.halogenColor;
50616
- } else if(link.v == me.htmlCls.picationValue) {
50617
- strokecolor = "#" + me.htmlCls.picationColor;
50618
- } else if(link.v == me.htmlCls.pistackingValue) {
50619
- strokecolor = "#" + me.htmlCls.pistackingColor;
50620
- } else if(link.v == me.htmlCls.contactValue) {
50621
- strokecolor = "#" + me.htmlCls.contactColor;
50622
- }
50739
+ let strokecolor = this.getStrokecolor(link.v);
50623
50740
 
50624
50741
  if(bContactMap) strokecolor = "#" + link.c;
50625
50742
 
50626
50743
  let linestrokewidth;
50627
50744
  if(link.v == me.htmlCls.contactValue) {
50628
- linestrokewidth = (link.n == 1) ? 1 : 3;
50745
+ // linestrokewidth = (link.n == 1) ? 1 : 3;
50746
+ linestrokewidth = 1;
50629
50747
  } else {
50630
50748
  linestrokewidth = (link.n == 1) ? 2 : 4;
50631
50749
  }
@@ -51095,6 +51213,7 @@ class GetGraph {
51095
51213
  interStr += this.getContactLinks(ssAtomsArray[i], ssAtomsArray[j], labelType, true, bCartoon2d);
51096
51214
  }
51097
51215
  }
51216
+
51098
51217
  return interStr;
51099
51218
  }
51100
51219
  getContactLinks(atomlistTarget, otherAtoms, labelType, bInternal, bCartoon2d) { let ic = this.icn3d, me = ic.icn3dui;
@@ -51137,7 +51256,14 @@ class GetGraph {
51137
51256
  for(let resid1 in hash1) {
51138
51257
  //ASN $1KQ2.A:6@ND2
51139
51258
  //or ASN $1KQ2.A:6
51140
- resid1 = resid1.trim();
51259
+ // or ASN $1KQ2.A:6@ND2 2006
51260
+ let resid1Ori = resid1.trim();
51261
+
51262
+ let idArray1 = resid1Ori.split(' ');
51263
+ if(idArray1.length == 3) {
51264
+ resid1 = idArray1[0] + ' ' + idArray1[1];
51265
+ }
51266
+
51141
51267
  let pos1a = resid1.indexOf(' ');
51142
51268
  let pos1b = resid1.indexOf(':');
51143
51269
  let posTmp1 = resid1.indexOf('@');
@@ -51147,8 +51273,14 @@ class GetGraph {
51147
51273
  let resName1 = me.utilsCls.residueName2Abbr(resid1.substr(0, pos1a)) + resid1.substr(pos1b + 1, pos1c - pos1b - 1);
51148
51274
  if(labelType == 'chain' || labelType == 'structure') resName1 += '.' + resid1.substr(pos1d + 1, pos1b - pos1d - 1);
51149
51275
  if(labelType == 'structure') resName1 += '.' + resid1.substr(pos1e + 1, pos1d - pos1e - 1);
51150
- for(let resid2 in hash2[resid1]) {
51151
- resid2 = resid2.trim();
51276
+ for(let resid2 in hash2[resid1Ori]) {
51277
+ let resid2Ori = resid2.trim();
51278
+
51279
+ let idArray2 = resid2Ori.split(' ');
51280
+ if(idArray2.length == 3) {
51281
+ resid2 = idArray2[0] + ' ' + idArray2[1];
51282
+ }
51283
+
51152
51284
  let pos2a = resid2.indexOf(' ');
51153
51285
  let pos2b = resid2.indexOf(':');
51154
51286
  let posTmp2 = resid2.indexOf('@');
@@ -51164,16 +51296,6 @@ class GetGraph {
51164
51296
  resName1 = ic.resi2resirange[resName1];
51165
51297
  resName2 = ic.resi2resirange[resName2];
51166
51298
  }
51167
- /*
51168
- if(!sourceTargetHash.hasOwnProperty(resName1 + '_' + resName2) && resName1 !== undefined && resName2 !== undefined ) {
51169
- let linkStr = ', {"source": "' + resName1 + '", "target": "' + resName2 + '", "v": ' + value + ', "c": "' + color + '"}';
51170
- if(linkStr != prevLinkStr) hbondStr += linkStr;
51171
- prevLinkStr = linkStr;
51172
-
51173
- sourceTargetHash[resName1 + '_' + resName2] = 1;
51174
- sourceTargetHash[resName2 + '_' + resName1] = 1;
51175
- }
51176
- */
51177
51299
 
51178
51300
  if(resName1 !== undefined && resName2 !== undefined ) {
51179
51301
  let linkStr = '"source": "' + resName1 + '", "target": "' + resName2 + '", "v": ' + value + ', "c": "' + color + '"';
@@ -51199,6 +51321,10 @@ class GetGraph {
51199
51321
  convertLabel2Resid(residLabel) {var ic = this.icn3d; ic.icn3dui;
51200
51322
  //ASN $1KQ2.A:6@ND2
51201
51323
  //or ASN $1KQ2.A:6
51324
+ // or ASN $1KQ2.A:6@ND2 1234
51325
+ let idArray = residLabel.split(' ');
51326
+ residLabel = (idArray.length == 2) ? residLabel : residLabel.substr(0, residLabel.lastIndexOf(' '));
51327
+
51202
51328
  residLabel.indexOf(' ');
51203
51329
  let pos2Tmp = residLabel.indexOf('@');
51204
51330
  let pos2 =(pos2Tmp !== -1) ? pos2Tmp : residLabel.length;
@@ -51233,6 +51359,25 @@ class ShowInter {
51233
51359
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atoms);
51234
51360
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atoms2);
51235
51361
 
51362
+ if(type == 'ligplot') {
51363
+ let residueHash1 = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
51364
+ let residueHash2 = ic.firstAtomObjCls.getResiduesFromAtoms(atoms2);
51365
+
51366
+ if(Object.keys(residueHash1).length > 1 && Object.keys(residueHash2).length > 1) {
51367
+ alert("Please select one ligand or residue as one of the interaction sets...");
51368
+ return;
51369
+ }
51370
+
51371
+ // switch the sets to make the first set as the ligand
51372
+ if(Object.keys(residueHash1).length < Object.keys(residueHash2).length) {
51373
+ nameArray2 = $("#" + ic.pre + "atomsCustomHbond").val();
51374
+ nameArray = $("#" + ic.pre + "atomsCustomHbond2").val();
51375
+
51376
+ atoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
51377
+ atoms2 = ic.definedSetsCls.getAtomsFromNameArray(nameArray2);
51378
+ }
51379
+ }
51380
+
51236
51381
  if(nameArray2.length == 0) {
51237
51382
  alert("Please select the first set");
51238
51383
  }
@@ -51276,6 +51421,9 @@ class ShowInter {
51276
51421
  else if(type == 'scatterplot') {
51277
51422
  me.htmlCls.clickMenuCls.setLogCmd("scatterplot interaction pairs | " + tmpStr, true);
51278
51423
  }
51424
+ else if(type == 'ligplot') {
51425
+ me.htmlCls.clickMenuCls.setLogCmd("ligplot interaction pairs | " + tmpStr, true);
51426
+ }
51279
51427
  else if(type == 'graph') { // force-directed graph
51280
51428
  let dist_ss = parseInt($("#" + ic.pre + "dist_ss").val());
51281
51429
  let dist_coil = parseInt($("#" + ic.pre + "dist_coil").val());
@@ -51964,6 +52112,9 @@ class ViewInterPairs {
51964
52112
  let svgHtml = ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
51965
52113
  $("#" + ic.pre + "scatterplotDiv").html(svgHtml);
51966
52114
  }
52115
+ else if(type == 'ligplot') {
52116
+ await ic.ligplotCls.drawLigplot(atomSet1);
52117
+ }
51967
52118
  else if(bContactMapLocal) {
51968
52119
  me.htmlCls.dialogCls.openDlg('dl_contactmap', 'Show contact map');
51969
52120
  let bAnyAtom = true;
@@ -52053,7 +52204,9 @@ class ViewInterPairs {
52053
52204
  }
52054
52205
  }
52055
52206
 
52056
- getAllInteractionTable(type) { let ic = this.icn3d, me = ic.icn3dui;
52207
+ getAllInteractionTable(type, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d, me = ic.icn3dui;
52208
+ let svgHtmlNode = '', svgHtmlLine = '';
52209
+
52057
52210
  let bondCnt = [];
52058
52211
 
52059
52212
  let residsArray = Object.keys(ic.resids2inter);
@@ -52092,41 +52245,54 @@ class ViewInterPairs {
52092
52245
  }
52093
52246
  let labels2dist, result;
52094
52247
  labels2dist = ic.resids2inter[resids]['hbond'];
52095
- result = this.getInteractionPairDetails(labels2dist, type, 'hbond');
52248
+ result = this.getInteractionPairDetails(labels2dist, type, 'hbond', index2xy, xlen, ylen, xcenter, ycenter);
52096
52249
  strHbond += result.html;
52097
52250
  cntHbond += result.cnt;
52251
+ svgHtmlNode += result.svgHtmlNode;
52252
+ svgHtmlLine += result.svgHtmlLine;
52098
52253
  if(result.cnt > 0) residname2List += residname2 + ":hbond_" + result.cnt + " ";
52099
52254
 
52100
52255
  labels2dist = ic.resids2inter[resids]['ionic'];
52101
- result = this.getInteractionPairDetails(labels2dist, type, 'ionic');
52256
+ result = this.getInteractionPairDetails(labels2dist, type, 'ionic', index2xy, xlen, ylen, xcenter, ycenter);
52102
52257
  strIonic += result.html;
52103
52258
  cntIonic += result.cnt;
52259
+ svgHtmlNode += result.svgHtmlNode;
52260
+ svgHtmlLine += result.svgHtmlLine;
52104
52261
  if(result.cnt > 0) residname2List += residname2 + ":ionic_" + result.cnt + " ";
52105
52262
 
52106
- labels2dist = ic.resids2inter[resids]['contact'];
52107
- result = this.getContactPairDetails(labels2dist, type, 'contact');
52108
- strContact += result.html;
52109
- cntContact += result.cnt;
52110
- if(result.cnt > 0) residname2List += residname2 + ":contact_" + result.cnt + " ";
52111
-
52112
52263
  labels2dist = ic.resids2inter[resids]['halogen'];
52113
- result = this.getInteractionPairDetails(labels2dist, type, 'halogen');
52264
+ result = this.getInteractionPairDetails(labels2dist, type, 'halogen', index2xy, xlen, ylen, xcenter, ycenter);
52114
52265
  strHalegen += result.html;
52115
52266
  cntHalegen += result.cnt;
52267
+ svgHtmlNode += result.svgHtmlNode;
52268
+ svgHtmlLine += result.svgHtmlLine;
52116
52269
  if(result.cnt > 0) residname2List += residname2 + ":halogen_" + result.cnt + " ";
52117
52270
 
52118
52271
  labels2dist = ic.resids2inter[resids]['pi-cation'];
52119
- result = this.getInteractionPairDetails(labels2dist, type, 'pi-cation');
52272
+ result = this.getInteractionPairDetails(labels2dist, type, 'pi-cation', index2xy, xlen, ylen, xcenter, ycenter);
52120
52273
  strPication += result.html;
52121
52274
  cntPication += result.cnt;
52275
+ svgHtmlNode += result.svgHtmlNode;
52276
+ svgHtmlLine += result.svgHtmlLine;
52122
52277
  if(result.cnt > 0) residname2List += residname2 + ":pi-cation_" + result.cnt + " ";
52123
52278
 
52124
52279
  labels2dist = ic.resids2inter[resids]['pi-stacking'];
52125
- result = this.getInteractionPairDetails(labels2dist, type, 'pi-stacking');
52280
+ result = this.getInteractionPairDetails(labels2dist, type, 'pi-stacking', index2xy, xlen, ylen, xcenter, ycenter);
52126
52281
  strPistacking += result.html;
52127
52282
  cntPistacking += result.cnt;
52283
+ svgHtmlNode += result.svgHtmlNode;
52284
+ svgHtmlLine += result.svgHtmlLine;
52128
52285
  if(result.cnt > 0) residname2List += residname2 + ":pi-stacking_" + result.cnt + " ";
52129
52286
 
52287
+ // put contact as the last one since contact will use the same node as other interactions in ligand-protein interactoin
52288
+ labels2dist = ic.resids2inter[resids]['contact'];
52289
+ result = this.getContactPairDetails(labels2dist, type, 'contact', index2xy, xlen, ylen, xcenter, ycenter);
52290
+ strContact += result.html;
52291
+ cntContact += result.cnt;
52292
+ svgHtmlNode += result.svgHtmlNode;
52293
+ svgHtmlLine += result.svgHtmlLine;
52294
+ if(result.cnt > 0) residname2List += residname2 + ":contact_" + result.cnt + " ";
52295
+
52130
52296
  prevResidname1 = residname1;
52131
52297
  prevIds = ids;
52132
52298
  }
@@ -52154,7 +52320,7 @@ class ViewInterPairs {
52154
52320
  html += tmpText;
52155
52321
  html += '</tbody></table><br/>';
52156
52322
  }
52157
- return {html: html, bondCnt: bondCnt};
52323
+ return {html: html, bondCnt: bondCnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine};
52158
52324
  }
52159
52325
  getInteractionPerResidue(prevIds, strHbond, strIonic, strContact, strHalegen, strPication, strPistacking,
52160
52326
  cntHbond, cntIonic, cntContact, cntHalegen, cntPication, cntPistacking) { let ic = this.icn3d; ic.icn3dui;
@@ -52169,15 +52335,24 @@ class ViewInterPairs {
52169
52335
  tmpText += '</tr>';
52170
52336
  return tmpText;
52171
52337
  }
52172
- getInteractionPairDetails(labels2dist, type, interactionType) { let ic = this.icn3d; ic.icn3dui;
52173
- let tmpText = '', cnt = 0;
52338
+ getInteractionPairDetails(labels2dist, type, interactionType, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d; ic.icn3dui;
52339
+ let svgHtmlNode = '', svgHtmlLine = '', tmpText = '', cnt = 0;
52174
52340
  let colorText1 = ' <span style="background-color:#';
52175
52341
  let colorText2 = '">&nbsp;&nbsp;&nbsp;</span>';
52176
52342
  if(labels2dist !== undefined) {
52343
+ if(!ic.resid2cnt) ic.resid2cnt = {};
52344
+ if(!ic.resid2ToXy) ic.resid2ToXy = {};
52345
+ if(!ic.nodeid2lineid) ic.nodeid2lineid = {};
52177
52346
  for(let labels in labels2dist) {
52178
- let resid1_resid2 = labels.split(',');
52179
- let resid1 =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
52180
- let resid2 =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
52347
+ let resid1_resid2 = labels.split('|');
52348
+ let resid1Ori =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
52349
+ let resid2Ori =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
52350
+ //resid1: MET $3GVU.A:364@N 1234
52351
+ let pos1 = resid1Ori.lastIndexOf(' ');
52352
+ let pos2 = resid2Ori.lastIndexOf(' ');
52353
+ let resid1 = resid1Ori.substr(0, pos1);
52354
+ let resid2 = resid2Ori.substr(0, pos2);
52355
+
52181
52356
  let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
52182
52357
  let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
52183
52358
  let color1 = (atom1.color) ? atom1.color.getHexString() : '';
@@ -52189,38 +52364,125 @@ class ViewInterPairs {
52189
52364
  tmpText += '<td align="center"><button class="' + ic.pre + 'selres" resid="' + resid1 + '|' + resid2 + '">Highlight</button></td>';
52190
52365
  tmpText += '</tr>';
52191
52366
  ++cnt;
52367
+
52368
+ if(index2xy) {
52369
+ let serialArray1 = resid1Ori.substr(pos1 + 1).split(',');
52370
+
52371
+ let result = ic.ligplotCls.getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter);
52372
+ svgHtmlNode += result.node;
52373
+ svgHtmlLine += result.line;
52374
+ }
52192
52375
  }
52193
52376
  }
52194
- return {html: tmpText, cnt: cnt}
52377
+ return {html: tmpText, cnt: cnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine}
52195
52378
  }
52196
- getContactPairDetails(labels2dist, type) { let ic = this.icn3d; ic.icn3dui;
52197
- let tmpText = '', cnt = 0;
52379
+
52380
+ getContactPairDetails(labels2dist, type, interactionType, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d; ic.icn3dui;
52381
+ let svgHtmlNode = '', svgHtmlLine = '', tmpText = '', cnt = 0;
52198
52382
  let colorText1 = ' <span style="background-color:#';
52199
52383
  let colorText2 = '">&nbsp;&nbsp;&nbsp;</span>';
52200
52384
  if(labels2dist !== undefined) {
52385
+ let resids2distCnt = {};
52386
+ if(!ic.resid2cnt) ic.resid2cnt = {};
52387
+ if(!ic.resid2ToXy) ic.resid2ToXy = {};
52388
+ if(!ic.nodeid2lineid) ic.nodeid2lineid = {};
52201
52389
  for(let labels in labels2dist) {
52202
- let resid1_resid2 = labels.split(',');
52203
- let resid1 =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
52204
- let resid2 =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
52390
+ let resid1_resid2 = labels.split('|');
52391
+ let resid1Ori =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
52392
+ let resid2Ori =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
52393
+ //resid1: MET $3GVU.A:364 1234
52394
+ let pos1 = resid1Ori.lastIndexOf(' ');
52395
+ let pos2 = resid2Ori.lastIndexOf(' ');
52396
+
52397
+ let serialArray1 = resid1Ori.substr(pos1 + 1).split(',');
52398
+ let resid1 = resid1Ori.substr(0, pos1);
52399
+ if(index2xy) {
52400
+ // add atom name to resid1
52401
+ resid1 += '@' + ic.atoms[serialArray1[0]].name;
52402
+ }
52403
+
52404
+ let resid2 = resid2Ori.substr(0, pos2);
52405
+ let resids = resid1 + '|' + resid2;
52406
+
52407
+ let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
52408
+ ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
52409
+ // let color1 = (atom1.color) ? atom1.color.getHexString() : '';
52410
+ let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
52411
+ ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
52412
+ // let color2 = (atom2.color) ? atom2.color.getHexString() : '';
52413
+ let dist1_dist2_atom1_atom2 = labels2dist[labels].split('_');
52414
+ let dist1 = parseFloat(dist1_dist2_atom1_atom2[0]);
52415
+ // let dist2 = parseFloat(dist1_dist2_atom1_atom2[1]);
52416
+ // let atom1Name = dist1_dist2_atom1_atom2[2];
52417
+ // let atom2Name = dist1_dist2_atom1_atom2[3];
52418
+ let contactCnt = parseInt(dist1_dist2_atom1_atom2[4]);
52419
+ if(!resids2distCnt.hasOwnProperty(resids)) {
52420
+ resids2distCnt[resids] = {'dist1': dist1, 'dist1_dist2_atom1_atom2': dist1_dist2_atom1_atom2, 'cnt': contactCnt, 'serialArray1': serialArray1};
52421
+ }
52422
+ else {
52423
+ resids2distCnt[resids].cnt += contactCnt;
52424
+ if(dist1 < resids2distCnt[resids].dist1) {
52425
+ resids2distCnt[resids].dist1 = dist1;
52426
+ resids2distCnt[resids].dist1_dist2_atom1_atom2 = dist1_dist2_atom1_atom2;
52427
+ resids2distCnt[resids].serialArray1 = serialArray1;
52428
+ }
52429
+ }
52430
+ }
52431
+
52432
+ let resid2ToResid1 = {};
52433
+ for(let resids in resids2distCnt) {
52434
+ let resid1_resid2 = resids.split('|');
52435
+ let resid1 = resid1_resid2[0];
52436
+ let resid2 = resid1_resid2[1];
52437
+
52438
+ if(!resid2ToResid1.hasOwnProperty(resid2)) {
52439
+ resid2ToResid1[resid2] = [resid1];
52440
+ }
52441
+ else {
52442
+ resid2ToResid1[resid2].push(resid1);
52443
+ }
52444
+
52205
52445
  let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
52206
52446
  let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
52207
52447
  let color1 = (atom1.color) ? atom1.color.getHexString() : '';
52208
52448
  let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
52209
52449
  let atom2 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
52210
52450
  let color2 = (atom2.color) ? atom2.color.getHexString() : '';
52211
- let dist1_dist2_atom1_atom2 = labels2dist[labels].split('_');
52451
+ let dist1_dist2_atom1_atom2 = resids2distCnt[resids].dist1_dist2_atom1_atom2;
52212
52452
  let dist1 = dist1_dist2_atom1_atom2[0];
52213
52453
  let dist2 = dist1_dist2_atom1_atom2[1];
52214
52454
  let atom1Name = dist1_dist2_atom1_atom2[2];
52215
52455
  let atom2Name = dist1_dist2_atom1_atom2[3];
52216
- let contactCnt = dist1_dist2_atom1_atom2[4];
52456
+ let contactCnt = 1; //resids2distCnt[resids].cnt;
52457
+
52217
52458
  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>';
52218
52459
  tmpText += '<td align="center"><button class="' + ic.pre + 'selres" resid="' + resid1 + '|' + resid2 + '">Highlight</button></td>';
52219
52460
  tmpText += '</tr>';
52220
52461
  cnt += parseInt(contactCnt);
52221
52462
  }
52463
+
52464
+ if(index2xy) {
52465
+ for(let resid2 in resid2ToResid1) {
52466
+ let resid1Array = resid2ToResid1[resid2];
52467
+ let prevX2, prevY2;
52468
+ for(let i = 0, il = resid1Array.length; i < il; ++i) {
52469
+ let resid1 = resid1Array[i];
52470
+ let resids = resid1 + '|' + resid2;
52471
+
52472
+ let serialArray1 = resids2distCnt[resids].serialArray1;
52473
+
52474
+ let bNotDrawNode = (i == 0) ? false : true;
52475
+ let result = ic.ligplotCls.getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter, bNotDrawNode, prevX2, prevY2);
52476
+ svgHtmlNode += result.node;
52477
+ svgHtmlLine += result.line;
52478
+ prevX2 = result.x2;
52479
+ prevY2 = result.y2;
52480
+ }
52481
+ }
52482
+ }
52222
52483
  }
52223
- return {html: tmpText, cnt: cnt}
52484
+
52485
+ return {html: tmpText, cnt: cnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine};
52224
52486
  }
52225
52487
 
52226
52488
  //Export the list of residues in some chain interacting with residues in another chain.
@@ -53628,8 +53890,8 @@ class ChainalignParser {
53628
53890
  let chain_t = idArray[3];
53629
53891
  let chainid_t = mmdbid_t + '_' + chain_t;
53630
53892
 
53631
- let atomSet_t = (me.cfg.resrange) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[0].split(','), chainid_t).hAtoms : ic.chains[chainid_t];
53632
- let atomSet_q = (me.cfg.resrange) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[index].split(','), chainid_q).hAtoms : ic.chains[chainid_q];
53893
+ let atomSet_t = (resRangeArray[0]) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[0].split(','), chainid_t).hAtoms : ic.chains[chainid_t];
53894
+ let atomSet_q = (resRangeArray[index]) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[index].split(','), chainid_q).hAtoms : ic.chains[chainid_q];
53633
53895
  // end of original version =============
53634
53896
 
53635
53897
  /*
@@ -56287,6 +56549,22 @@ class MmdbParser {
56287
56549
  hAtoms = ic.loadAtomDataCls.loadAtomDataIn(data, pdbid, 'mmdbid', undefined, type, chainid, chainIndex, bLastQuery, bNoTransformNoSeqalign);
56288
56550
  }
56289
56551
 
56552
+ // show ligand-protein interaction
56553
+ if(me.cfg.ligand) { // sid123059722
56554
+ for(let chainid in ic.chainid2sid) {
56555
+ if(ic.chainid2sid[chainid] == me.cfg.ligand.substr(3)) {
56556
+ // save a set named me.cfg.ligand
56557
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(ic.chains[chainid]);
56558
+ let idArray = Object.keys(residueHash)[0].split('_');
56559
+ let select = '.' + idArray[1] + ':' + idArray[2];
56560
+
56561
+ await ic.selByCommCls.selectByCommand(select, me.cfg.ligand, me.cfg.ligand);
56562
+ break;
56563
+ }
56564
+ }
56565
+ }
56566
+ ic.hAtoms = hAtoms;
56567
+
56290
56568
  // set 3d domains
56291
56569
  let structure = data.pdbId;
56292
56570
 
@@ -66874,6 +67152,7 @@ class ApplyCommand {
66874
67152
  || commandOri.indexOf('save2 interaction pairs') == 0
66875
67153
  || commandOri.indexOf('line graph interaction pairs') == 0
66876
67154
  || commandOri.indexOf('scatterplot interaction pairs') == 0
67155
+ || commandOri.indexOf('ligplot interaction pairs') == 0
66877
67156
  ) {
66878
67157
  let paraArray = commandOri.split(' | ');
66879
67158
  if(paraArray.length >= 3) {
@@ -66931,6 +67210,9 @@ class ApplyCommand {
66931
67210
  else if(commandOri.indexOf('scatterplot interaction pairs') == 0) {
66932
67211
  type = 'scatterplot';
66933
67212
  }
67213
+ else if(commandOri.indexOf('ligplot interaction pairs') == 0) {
67214
+ type = 'ligplot';
67215
+ }
66934
67216
 
66935
67217
  await ic.viewInterPairsCls.viewInteractionPairs(nameArray2, nameArray, bHbondCalc, type, bHbond, bSaltbridge, bInteraction, bHalogen, bPication, bPistacking);
66936
67218
  }
@@ -66990,6 +67272,14 @@ class ApplyCommand {
66990
67272
 
66991
67273
  $("#" + me.scatterplotid).attr("width",(ic.scatterplotWidth * parseFloat(scale)).toString() + "px");
66992
67274
  }
67275
+ else if(command.indexOf('ligplot scale') == 0) {
67276
+ let pos = command.lastIndexOf(' ');
67277
+ let scale = command.substr(pos + 1);
67278
+
67279
+ $("#" + me.ligplotid + "_scale").val(scale);
67280
+
67281
+ $("#" + me.ligplotid).attr("width",(ic.ligplotWidth * parseFloat(scale)).toString() + "px");
67282
+ }
66993
67283
  else if(command.indexOf('contactmap scale') == 0) {
66994
67284
  let pos = command.lastIndexOf(' ');
66995
67285
  let scale = command.substr(pos + 1);
@@ -67643,6 +67933,7 @@ class ApplyCommand {
67643
67933
  else if(cmd.indexOf('save2 interaction pairs') == 0) return hbondIntStr + ': "Set 2" button';
67644
67934
  else if(cmd.indexOf('line graph interaction pairs') == 0) return hbondIntStr + ': "2D Interaction Network" button';
67645
67935
  else if(cmd.indexOf('scatterplot interaction pairs') == 0) return hbondIntStr + ': "2D Interaction Map" button';
67936
+ else if(cmd.indexOf('ligplot interaction pairs') == 0) return hbondIntStr + ': "2D Interaction for One Ligand/Residue" button';
67646
67937
  else if(cmd.indexOf('graph label') == 0) return forceStr + ': "Label Size" menu';
67647
67938
  else if(cmd.indexOf('graph force') == 0) return forceStr + ': "Force on Nodes" menu';
67648
67939
  else if(cmd.indexOf('hide edges') == 0) return forceStr + ': "Internal Edges" menu';
@@ -76200,6 +76491,12 @@ class Diagram2d {
76200
76491
  thisClass.clickNode(this);
76201
76492
  });
76202
76493
 
76494
+ $(document).on("click", "#" + ic.pre + "dl_ligplot .icn3d-node", function(e) { thisClass.icn3d;
76495
+ e.stopImmediatePropagation();
76496
+
76497
+ thisClass.clickNode(this);
76498
+ });
76499
+
76203
76500
  //$("#" + ic.pre + "dl_linegraph .icn3d-interaction", "click", function(e) { let ic = this.icn3d, me = ic.icn3dui;
76204
76501
  $(document).on("click", "#" + ic.pre + "dl_linegraph .icn3d-interaction", function(e) { let ic = thisClass.icn3d;
76205
76502
  e.stopImmediatePropagation();
@@ -76282,6 +76579,8 @@ class Diagram2d {
76282
76579
  let strokeWidth = 2;
76283
76580
  $(node).find('circle').attr('stroke', me.htmlCls.ORANGE);
76284
76581
  $(node).find('circle').attr('stroke-width', strokeWidth);
76582
+ $(node).find('rect').attr('stroke', me.htmlCls.ORANGE);
76583
+ $(node).find('rect').attr('stroke-width', strokeWidth);
76285
76584
 
76286
76585
  ic.hAtoms = me.hashUtilsCls.unionHash(ic.hAtoms, ic.residues[resid]);
76287
76586
 
@@ -77399,6 +77698,364 @@ class Cartoon2d {
77399
77698
  }
77400
77699
  }
77401
77700
 
77701
+ /**
77702
+ * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
77703
+ */
77704
+
77705
+ class Ligplot {
77706
+ constructor(icn3d) {
77707
+ this.icn3d = icn3d;
77708
+ }
77709
+
77710
+ async drawLigplot(atomSet1) { let ic = this.icn3d, me = ic.icn3dui;
77711
+ me.htmlCls.dialogCls.openDlg('dl_ligplot', 'Show ligand interactions with atom details');
77712
+
77713
+ let widthOri, heightOri, width = 100, height = 100;
77714
+ ic.len4ang = 80;
77715
+
77716
+ // get SVG from backend
77717
+ let pdbStr = ic.saveFileCls.getAtomPDB(atomSet1);
77718
+ pdbStr = pdbStr.trim();
77719
+ pdbStr = pdbStr.replace(/\n\n/g, '\n'); // remove empty lines
77720
+
77721
+ let dataObj = {'pdb2svg': pdbStr};
77722
+ let url = me.htmlCls.baseUrl + "openbabel/openbabel.cgi";
77723
+ let dataStr = await me.getAjaxPostPromise(url, dataObj, undefined, undefined, undefined, undefined, 'text');
77724
+
77725
+ let lineArray = dataStr.split('\n');
77726
+ let lineSvg = '', nodeSvg = '', index2xy = {};
77727
+ let xsum = 0, ysum = 0, cnt = 0;
77728
+ 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)
77729
+ ic.gridXY2used = {};
77730
+ for(let i = 0, il = lineArray.length; i < il; ++i) {
77731
+ let line = lineArray[i];
77732
+ if(line.indexOf('<svg width') == 0) {
77733
+ //<svg width="100" height="100" x="0" y="0" viewBox="0 0 634.256 380"
77734
+ // get real width and height
77735
+ let start = line.indexOf('viewBox="') + 9;
77736
+ let linePart = line.substr(start);
77737
+ let viewbox = linePart.substr(0, linePart.indexOf('"'));
77738
+ let viewboxArray = viewbox.split(' ');
77739
+ widthOri = parseFloat(viewboxArray[2]);
77740
+ heightOri = parseFloat(viewboxArray[3]);
77741
+ width = widthOri + 2*ic.len4ang;
77742
+ height = heightOri + 2*ic.len4ang;
77743
+ }
77744
+ else if(line.indexOf('<line') == 0) {
77745
+ lineSvg += line + '\n';
77746
+ }
77747
+ else if(line.indexOf('<text') == 0) {
77748
+ if(line.indexOf('font-size="12"') != -1) {
77749
+ // index node
77750
+ //<text x="40.000000" y="120.000000" fill="rgb(255,0,0)" stroke-width="0" font-weight="bold" font-size="12" >1</text>
77751
+ let start = line.indexOf('>') + 1;
77752
+ let indexPart = line.substr(start);
77753
+ let index = parseInt(indexPart.substr(0, indexPart.indexOf('<')));
77754
+
77755
+ start = line.indexOf('x="') + 3;
77756
+ let xPart = line.substr(start);
77757
+ let x = parseFloat(xPart.substr(0, xPart.indexOf('"')));
77758
+
77759
+ start = line.indexOf('y="') + 3;
77760
+ let yPart = line.substr(start);
77761
+ let y = parseFloat(yPart.substr(0, yPart.indexOf('"')));
77762
+
77763
+ index2xy[index] = {"x": x, "y": y};
77764
+ let xGrid = parseInt(x / ic.svgGridSize);
77765
+ let yGrid = parseInt(y / ic.svgGridSize);
77766
+ ic.gridXY2used[xGrid + '_' + yGrid] = 1;
77767
+
77768
+ xsum += x;
77769
+ ysum += y;
77770
+ ++cnt;
77771
+ }
77772
+ else { // font-size > 12
77773
+ nodeSvg += line + '\n';
77774
+ }
77775
+ }
77776
+ else if(line.indexOf('</svg>') == 0) {
77777
+ break;
77778
+ }
77779
+ }
77780
+
77781
+ let xcenter = xsum / cnt, ycenter = ysum / cnt;
77782
+
77783
+ let id = me.ligplotid;
77784
+ ic.ligplotWidth = width;
77785
+ let graphWidth = ic.ligplotWidth;
77786
+
77787
+ let textHeight = 30;
77788
+ let heightAll = height + textHeight;
77789
+
77790
+ let offset = - ic.len4ang;
77791
+ 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'>";
77792
+
77793
+ let xlen = parseInt(widthOri / ic.svgGridSize), ylen = parseInt(heightOri / ic.svgGridSize);
77794
+ let result = ic.viewInterPairsCls.getAllInteractionTable("save1", index2xy, xlen, ylen, xcenter, ycenter); // sort on the ligand/set1
77795
+ ic.bLigplot = true;
77796
+
77797
+ svgHtml += lineSvg + result.svgHtmlLine;
77798
+
77799
+ svgHtml += nodeSvg + result.svgHtmlNode;
77800
+
77801
+ svgHtml += "</svg>";
77802
+
77803
+ $("#" + ic.pre + "ligplotDiv").html(svgHtml);
77804
+
77805
+ this.setEventsForLigplot();
77806
+ }
77807
+
77808
+
77809
+ getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter, bNotDrawNode, prevX2, prevY2) { let ic = this.icn3d, me = ic.icn3dui;
77810
+ let xOffset = 1, yOffset = -1;
77811
+ let bondLen = (interactionType == 'hbond' || interactionType == 'contact' || interactionType == 'halogen') ? ic.len4ang : ic.len4ang * 1.5; // real distance should be bout 120, not 80
77812
+ let shortBondLen = ic.len4ang / 2;
77813
+ let strokeWidth = (interactionType == 'contact') ? 1 : 2;
77814
+
77815
+ let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
77816
+ let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
77817
+ let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
77818
+ let atom2 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
77819
+
77820
+ let xSum = 0, ySum = 0, cntPoint = 0;
77821
+ let baseSerial = atom1.serial;
77822
+ for(let i = 0, il = serialArray1.length; i < il; ++i) {
77823
+ let index = serialArray1[i] - baseSerial + 1;
77824
+ xSum += index2xy[index].x;
77825
+ ySum += index2xy[index].y;
77826
+ ++cntPoint;
77827
+ }
77828
+
77829
+ let x1 = xSum / cntPoint - xOffset;
77830
+ let y1 = ySum / cntPoint - yOffset;
77831
+
77832
+ if(!ic.resid2cnt.hasOwnProperty(resid1)) {
77833
+ ic.resid2cnt[resid1] = 0;
77834
+ }
77835
+ else {
77836
+ ++ic.resid2cnt[resid1];
77837
+ }
77838
+
77839
+ let x2, y2, angle;
77840
+ if(!bNotDrawNode && !ic.resid2ToXy.hasOwnProperty(resid2Real)) {
77841
+ // 1st and ideal way to find a position. If failed, use the 2nd way
77842
+ let xGrid = parseInt(x1 / ic.svgGridSize);
77843
+ let yGrid = parseInt(y1 / ic.svgGridSize);
77844
+ let gridArray = [];
77845
+ for(let i = 1; i >= -1; --i) { // try right-bottom first
77846
+ for(let j = 1; j >= -1; --j) {
77847
+ if(!(i == 0 && j == 0)) {
77848
+ if(xGrid + i >= 0 && xGrid + i <= xlen && yGrid + j >= 0 && yGrid + j <= ylen) gridArray.push((xGrid + i) + '_' + (yGrid + j));
77849
+ }
77850
+ }
77851
+ }
77852
+ for(let i = 2; i >= -2; --i) { // try right-bottom first
77853
+ for(let j = 2; j >= -2; --j) {
77854
+ if(!(i >= -1 && i <= 1 && j >= -1 && j <= 1 )) {
77855
+ if(xGrid + i >= 0 && xGrid + i <= xlen && yGrid + j >= 0 && yGrid + j <= ylen) gridArray.push((xGrid + i) + '_' + (yGrid + j));
77856
+ }
77857
+ }
77858
+ }
77859
+
77860
+ let bFound = false, xyGrids;
77861
+ for(let i = 0, il = gridArray.length; i < il; ++i) {
77862
+ if(!ic.gridXY2used[gridArray[i]]) { // found a spot to put the residue
77863
+ xyGrids = gridArray[i].split('_');
77864
+ x2 = (parseInt(xyGrids[0]) + 0.5) * ic.svgGridSize;
77865
+ y2 = (parseInt(xyGrids[1]) + 0.5) * ic.svgGridSize;
77866
+
77867
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
77868
+ let x2b = bondLen / dist * (x2 - x1) + x1;
77869
+ let y2b = bondLen / dist * (y2 - y1) + y1;
77870
+ x2 = x2b;
77871
+ y2 = y2b;
77872
+
77873
+ ic.gridXY2used[gridArray[i]] = 1;
77874
+ bFound = true;
77875
+ break;
77876
+ }
77877
+ }
77878
+
77879
+ if(!bFound) {
77880
+ // 2nd way to find a position from the center to the outside
77881
+ let dx = x1 - xcenter;
77882
+ let dy = y1 - ycenter;
77883
+
77884
+ let baseAngle = 0;
77885
+ if(Math.abs(dx) > Math.abs(dy)) { // extend along x-axis
77886
+ if(dx > 0) { // +x direction
77887
+ baseAngle = 0;
77888
+ }
77889
+ else { // -x direction
77890
+ baseAngle = 180;
77891
+ }
77892
+ }
77893
+ else { // extend along y-axis
77894
+ if(dy > 0) { // +y direction
77895
+ baseAngle = 90;
77896
+ }
77897
+ else { // -y direction
77898
+ baseAngle = 270;
77899
+ }
77900
+ }
77901
+ angle = baseAngle - 10 + ic.resid2cnt[resid1] * 30;
77902
+
77903
+ x2 = x1 + bondLen * Math.cos(angle * Math.PI/180);
77904
+ y2 = y1 + bondLen * Math.sin(angle * Math.PI/180);
77905
+ }
77906
+ }
77907
+
77908
+ let oneLetterRes = me.utilsCls.residueName2Abbr(atom2.resn.substr(0, 3));
77909
+ let resName2 = oneLetterRes + atom2.resi;
77910
+ let textColor2 = (atom2.color) ? atom2.color.getHexString() : '000';
77911
+ let lineColor = ic.lineGraphCls.getStrokecolor(undefined, interactionType);
77912
+
77913
+ // 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>';
77914
+
77915
+ let node = '', line = '';
77916
+
77917
+ // id can't contain comma and thus use '-'
77918
+ // sometimes the same ligand atom is used in both Hbond and contact. THus we add "interactionType"
77919
+ let idpair = resid2Real + '--' + serialArray1.join('-') + interactionType;
77920
+
77921
+ let id = resid2Real;
77922
+ if(bNotDrawNode || ic.resid2ToXy.hasOwnProperty(id)) {
77923
+ x2 = (ic.resid2ToXy.hasOwnProperty(id)) ? ic.resid2ToXy[id].x2 : prevX2;
77924
+ y2 = (ic.resid2ToXy.hasOwnProperty(id)) ? ic.resid2ToXy[id].y2 : prevY2;
77925
+
77926
+ // draw a short line from x2, y2 to x1, y1 with the distance shortBondLen
77927
+ let x1b = x1, y1b = y1, bShort = 0;
77928
+ if(interactionType == 'contact') {
77929
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
77930
+ if(shortBondLen < dist) {
77931
+ x1b = shortBondLen / dist * (x1 - x2) + x2;
77932
+ y1b = shortBondLen / dist * (y1 - y2) + y2;
77933
+ bShort = 1;
77934
+ }
77935
+ }
77936
+
77937
+ 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';
77938
+ }
77939
+ else {
77940
+ node +='<g>';
77941
+ node += '<title>' + resName2 + '</title>';
77942
+ // node += '<circle class='icn3d-ctnode' cx="' + x2.toFixed(2) + '" cy="' + y2.toFixed(2) + '" r="10" fill="#' + textColor2 + '" stroke-width="1" stroke="' + textColor2 + '" resid="' + resid2Real + '"/>';
77943
+ let boxWidth = 28, boxHeight = 14;
77944
+ 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 + '"/>';
77945
+
77946
+ 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>';
77947
+ node += '</g>\n';
77948
+
77949
+ 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';
77950
+
77951
+ if(interactionType != 'contact') {
77952
+ if(!ic.resid2ToXy.hasOwnProperty(resid2Real)) ic.resid2ToXy[resid2Real] = {x2: x2, y2: y2};
77953
+ }
77954
+ }
77955
+
77956
+ if(!ic.nodeid2lineid.hasOwnProperty(id)) ic.nodeid2lineid[id] = [];
77957
+ ic.nodeid2lineid[id].push(idpair);
77958
+
77959
+ return {node: node, line: line, x2: x2, y2: y2};
77960
+ }
77961
+
77962
+ setEventsForLigplot() { let ic = this.icn3d, me = ic.icn3dui;
77963
+ //https://stackoverflow.com/questions/1108480/svg-draggable-using-jquery-and-jquery-svg
77964
+ $("#" + me.ligplotid + " .icn3d-ctnode")
77965
+ .draggable({
77966
+ start: function( e, ui ) {
77967
+ let oriX= parseFloat(e.target.getAttribute('x'));
77968
+ let oriY = parseFloat(e.target.getAttribute('y'));
77969
+
77970
+ e.target.setAttribute('x', oriX);
77971
+ e.target.setAttribute('y', oriY);
77972
+ },
77973
+ drag: function( e, ui ) {
77974
+ let offsetX = $("#" + me.ligplotid).offset().left + ic.len4ang; // ic.len4ang was defined in svg viewbox
77975
+ let offsetY = $("#" + me.ligplotid).offset().top + ic.len4ang;
77976
+
77977
+ let id = e.target.getAttribute('resid');
77978
+ let x = (e.clientX - offsetX);
77979
+ let y = (e.clientY - offsetY);
77980
+
77981
+ let oriX = parseFloat(e.target.getAttribute('x'));
77982
+ let oriY = parseFloat(e.target.getAttribute('y'));
77983
+
77984
+ // change for each step
77985
+ let dx = (x - oriX) / ic.resizeRatioX;
77986
+ let dy = (y - oriY) / ic.resizeRatioY;
77987
+
77988
+ // move the text label
77989
+ oriX = parseFloat($("#" + id + "_node").attr('x'));
77990
+ oriY = parseFloat($("#" + id + "_node").attr('y'));
77991
+
77992
+ $("#" + id + "_node").attr('x', oriX + dx);
77993
+ $("#" + id + "_node").attr('y', oriY + dy);
77994
+
77995
+ // update the center
77996
+ e.target.setAttribute('x', x);
77997
+ e.target.setAttribute('y', y);
77998
+
77999
+ // update the edges
78000
+ if(ic.nodeid2lineid[id]) {
78001
+ for(let i = 0, il = ic.nodeid2lineid[id].length; i < il; ++i) {
78002
+ let idpair = ic.nodeid2lineid[id][i];
78003
+
78004
+ updateEdges(idpair, id);
78005
+ }
78006
+ }
78007
+
78008
+ function updateEdges(idpair, id) {
78009
+ if(idpair && idpair.indexOf(id) != -1) {
78010
+ let idArray = idpair.split('--');
78011
+ if(idArray.length == 2) {
78012
+ let id2;
78013
+ id2 = idArray[0];
78014
+
78015
+ let x2 = parseFloat($("#" + id2).attr('x'));
78016
+ let y2 = parseFloat($("#" + id2).attr('y'));
78017
+
78018
+ $("#" + idpair).attr('x2', x2);
78019
+ $("#" + idpair).attr('y2', y2);
78020
+
78021
+ let x1 = $("#" + idpair).attr('x1');
78022
+ let y1 = $("#" + idpair).attr('y1');
78023
+ let x1b = x1, y1b = y1;
78024
+
78025
+ let bShort = parseInt($("#" + idpair).attr('short'));
78026
+ if(bShort) { // adjust x1,y1
78027
+ x1 = $("#" + idpair).attr('x0');
78028
+ y1 = $("#" + idpair).attr('y0');
78029
+
78030
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
78031
+ let shortBondLen = ic.len4ang / 2;
78032
+
78033
+ if(shortBondLen < dist) {
78034
+ x1b = shortBondLen / dist * (x1 - x2) + x2;
78035
+ y1b = shortBondLen / dist * (y1 - y2) + y2;
78036
+ }
78037
+ }
78038
+
78039
+ $("#" + idpair).attr('x1', x1b);
78040
+ $("#" + idpair).attr('y1', y1b);
78041
+ }
78042
+ } // if
78043
+ } // function
78044
+ }
78045
+ });
78046
+ }
78047
+
78048
+ clickLigplot() { let ic = this.icn3d; ic.icn3dui;
78049
+ let thisClass = this;
78050
+
78051
+ $(document).on("click", "#" + ic.pre + "dl_ligplot .icn3d-ctnode", function(e) { let ic = thisClass.icn3d;
78052
+ e.stopImmediatePropagation();
78053
+
78054
+ ic.diagram2dCls.clickNode(this);
78055
+ });
78056
+ }
78057
+ }
78058
+
77402
78059
  /**
77403
78060
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
77404
78061
  */
@@ -78082,7 +78739,7 @@ class SaveFile {
78082
78739
  }
78083
78740
  }
78084
78741
 
78085
- saveSvg(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
78742
+ saveSvg(id, filename, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
78086
78743
  if(me.bNode) return '';
78087
78744
 
78088
78745
  let width = $("#" + id).width();
@@ -78090,19 +78747,26 @@ class SaveFile {
78090
78747
 
78091
78748
  if(bContactmap) height = width;
78092
78749
 
78093
- let svgXml = this.getSvgXml(id, width, height, bContactmap);
78750
+ if(bLigplot) {
78751
+ width += ic.len4ang;
78752
+ height += ic.len4ang;
78753
+ }
78754
+
78755
+ let svgXml = this.getSvgXml(id, width, height, bContactmap, bLigplot);
78094
78756
 
78095
78757
  let blob = new Blob([svgXml], {type: "image/svg+xml"});
78096
78758
  saveAs(blob, filename);
78097
78759
  }
78098
78760
 
78099
- getSvgXml(id, width, height, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
78761
+ getSvgXml(id, width, height, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
78100
78762
  if(me.bNode) return '';
78101
78763
 
78102
78764
  // font is not good
78103
78765
  let svg_data = document.getElementById(id).innerHTML; //put id of your svg element here
78104
78766
 
78105
- let viewbox = (width && height) ? "<svg viewBox=\"0 0 " + width + " " + height + "\"" : "<svg";
78767
+ let startX = (bLigplot) ? -30 : 0;
78768
+ let startY = (bLigplot) ? -30 : 0;
78769
+ let viewbox = (width && height) ? "<svg viewBox=\"" + startX + " " + startY + " " + width + " " + height + "\"" : "<svg";
78106
78770
  //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/\">";
78107
78771
  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/\">";
78108
78772
 
@@ -78114,7 +78778,7 @@ class SaveFile {
78114
78778
  return full_svg;
78115
78779
  }
78116
78780
 
78117
- savePng(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
78781
+ savePng(id, filename, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
78118
78782
  if(me.bNode) return '';
78119
78783
 
78120
78784
  let width = $("#" + id).width();
@@ -78127,7 +78791,7 @@ class SaveFile {
78127
78791
  let bbox = svg.getBBox();
78128
78792
 
78129
78793
  let copy = svg.cloneNode(true);
78130
- ic.lineGraphCls.copyStylesInline(copy, svg);
78794
+ if(!bLigplot) ic.lineGraphCls.copyStylesInline(copy, svg);
78131
78795
  let canvas = document.createElement("CANVAS");
78132
78796
  canvas.width = width;
78133
78797
  canvas.height = height;
@@ -81920,6 +82584,7 @@ class iCn3D {
81920
82584
  this.shareLinkCls = new ShareLink(this);
81921
82585
  this.diagram2dCls = new Diagram2d(this);
81922
82586
  this.cartoon2dCls = new Cartoon2d(this);
82587
+ this.ligplotCls = new Ligplot(this);
81923
82588
 
81924
82589
  this.rayCls = new Ray(this);
81925
82590
  this.controlCls = new Control(this);
@@ -82146,7 +82811,7 @@ class iCn3DUI {
82146
82811
  //even when multiple iCn3D viewers are shown together.
82147
82812
  this.pre = this.cfg.divid + "_";
82148
82813
 
82149
- this.REVISION = '3.33.3';
82814
+ this.REVISION = '3.34.0';
82150
82815
 
82151
82816
  // In nodejs, iCn3D defines "window = {navigator: {}}"
82152
82817
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -82589,7 +83254,8 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
82589
83254
 
82590
83255
  ic.bChainAlign = true;
82591
83256
  ic.inputid = me.cfg.chainalign;
82592
- 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;
83257
+ let resrangeStr = (me.cfg.resrange) ? ' | resrange ' + me.cfg.resrange : '';
83258
+ ic.loadCmd = 'load chainalignment ' + me.cfg.chainalign + ' | resnum ' + me.cfg.resnum + ' | resdef ' + me.cfg.resdef + ' | aligntool ' + me.cfg.aligntool + ' | parameters ' + me.cfg.inpara + resrangeStr;
82593
83259
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
82594
83260
  await ic.chainalignParserCls.downloadChainalignment(me.cfg.chainalign);
82595
83261
  }