icn3d 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/icn3d.js +315 -135
  2. package/package.json +1 -1
package/icn3d.js CHANGED
@@ -4484,6 +4484,16 @@ class UtilsCls {
4484
4484
  if(viewer_width && me.htmlCls.WIDTH > viewer_width) me.htmlCls.WIDTH = viewer_width;
4485
4485
  if(viewer_height && me.htmlCls.HEIGHT > viewer_height) me.htmlCls.HEIGHT = viewer_height;
4486
4486
  }
4487
+
4488
+ sumArray(numArray) {
4489
+ let sum = 0;
4490
+
4491
+ for(let i = 0, il = numArray.length; i < il; ++i) {
4492
+ sum += numArray[i];
4493
+ }
4494
+
4495
+ return sum;
4496
+ }
4487
4497
  }
4488
4498
 
4489
4499
  /**
@@ -15497,23 +15507,31 @@ class GetGraph {
15497
15507
  html += "</g>";
15498
15508
  return html;
15499
15509
  }
15500
- getNodeTopBottom(nameHash, name2node, bReverseNode) { let ic = this.icn3d; ic.icn3dui;
15510
+ getNodeTopBottom(nameHash, name2node, bReverseNode, bCommon, nameHashCommon) { let ic = this.icn3d, me = ic.icn3dui;
15501
15511
  let thisClass = this;
15502
- let nodeArray1 = [], nodeArray2 = [];
15512
+ let nodeArray1 = [], nodeArray2 = [], name2nodeCommon = {};
15503
15513
  for(let name in nameHash) {
15504
15514
  let node = name2node[name];
15505
15515
  if(!node) continue;
15506
15516
 
15517
+ if(bCommon) {
15518
+ node = me.hashUtilsCls.cloneHash(node);
15519
+
15520
+ let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : '-';
15521
+ node.id += ">" + mapping;
15522
+ name2nodeCommon[node.id] = node;
15523
+ }
15524
+
15507
15525
  if(node.s == 'a') {
15508
15526
  nodeArray1.push(node);
15509
15527
  }
15510
15528
  else if(node.s == 'b') {
15511
15529
  nodeArray2.push(node);
15512
15530
  }
15513
- else if(node.s == 'ab') {
15514
- nodeArray1.push(node);
15515
- nodeArray2.push(node);
15516
- }
15531
+ //else if(node.s == 'ab') {
15532
+ // nodeArray1.push(node);
15533
+ // nodeArray2.push(node);
15534
+ //}
15517
15535
  }
15518
15536
  // sort array
15519
15537
  nodeArray1.sort(function(a,b) {
@@ -15522,7 +15540,7 @@ class GetGraph {
15522
15540
  nodeArray2.sort(function(a,b) {
15523
15541
  return thisClass.compNode(a, b, bReverseNode);
15524
15542
  });
15525
- return {"nodeArray1": nodeArray1, "nodeArray2": nodeArray2}
15543
+ return {"nodeArray1": nodeArray1, "nodeArray2": nodeArray2, "name2node": name2nodeCommon};
15526
15544
  }
15527
15545
  updateGraphJson(struc, index, nodeArray1, nodeArray2, linkArray) { let ic = this.icn3d, me = ic.icn3dui;
15528
15546
  let lineGraphStr = '';
@@ -15845,22 +15863,31 @@ class LineGraph {
15845
15863
  let structureArray = ic.resid2specCls.atoms2structureArray(ic.hAtoms);
15846
15864
  //if(Object.keys(ic.structures).length > 1) {
15847
15865
  if(structureArray.length > 1) {
15848
- let nodeArray1a = [],
15849
- nodeArray1b = [],
15850
- nodeArray2a = [],
15851
- nodeArray2b = [],
15852
- nodeArray3a = [],
15853
- nodeArray3b = [];
15854
- //let struc1 = Object.keys(ic.structures)[0],
15855
- // struc2 = Object.keys(ic.structures)[1];
15856
- let struc1 = structureArray[0],
15857
- struc2 = structureArray[1];
15858
- let linkArrayA = [],
15859
- linkArrayB = [],
15860
- linkArrayAB = [];
15861
- let nameHashA = {},
15862
- nameHashB = {},
15863
- nameHashAB = {};
15866
+
15867
+ let struc2index= {};
15868
+ let nodeArray1Split = [], nodeArray2Split = [], linkArraySplit = [], nameHashSplit = [];
15869
+
15870
+ // show common interactions: nodes will be the same. The links/interactins are different.
15871
+ // The mapped residue name and number are attached to "id".
15872
+ // Original node: {id : "Q24.A.2AJF", r : "1_1_2AJF_A_24", s: "a", ...}
15873
+ // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
15874
+ let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
15875
+ let linkedNodeCnt = {};
15876
+
15877
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15878
+ nodeArray1Split[i] = [];
15879
+ nodeArray2Split[i] = [];
15880
+ linkArraySplit[i] = [];
15881
+ nameHashSplit[i] = {};
15882
+
15883
+ nodeArray1SplitCommon[i] = [];
15884
+ nodeArray2SplitCommon[i] = [];
15885
+ linkArraySplitCommon[i] = [];
15886
+ nameHashSplitCommon[i] = {};
15887
+
15888
+ struc2index[structureArray[i]] = i;
15889
+ }
15890
+
15864
15891
  for(let i = 0, il = linkArray.length; i < il; ++i) {
15865
15892
  let link = linkArray[i];
15866
15893
  let nodeA = name2node[link.source];
@@ -15870,70 +15897,131 @@ class LineGraph {
15870
15897
  continue;
15871
15898
  }
15872
15899
 
15873
- //var idArrayA = nodeA.r.split('_'); // 1_1_1KQ2_A_1
15874
- let idArrayA = [];
15875
- idArrayA.push('');
15876
- idArrayA.push('');
15900
+ let idArrayA = this.getIdArrayFromNode(nodeA);
15901
+ let idArrayB = this.getIdArrayFromNode(nodeB);
15877
15902
 
15878
- let tmpStr = nodeA.r.substr(4);
15879
- idArrayA = idArrayA.concat(me.utilsCls.getIdArray(tmpStr));
15903
+ let index = struc2index[idArrayA[2]];
15880
15904
 
15881
- //var idArrayB = nodeB.r.split('_'); // 1_1_1KQ2_A_1
15882
- let idArrayB = [];
15883
- idArrayB.push('');
15884
- idArrayB.push('');
15905
+ if(idArrayA[2] == structureArray[index] && idArrayB[2] == structureArray[index]) {
15906
+ linkArraySplit[index].push(link);
15907
+ nameHashSplit[index][link.source] = 1;
15908
+ nameHashSplit[index][link.target] = 1;
15885
15909
 
15886
- tmpStr = nodeB.r.substr(4);
15887
- idArrayB = idArrayB.concat(me.utilsCls.getIdArray(tmpStr));
15910
+ let chainid1 = idArrayA[2] + '_' + idArrayA[3];
15911
+ let chainid2 = idArrayB[2] + '_' + idArrayB[3];
15912
+ let resid1 = chainid1 + '_' + idArrayA[4];
15913
+ let resid2 = chainid2 + '_' + idArrayB[4];
15888
15914
 
15889
- if(idArrayA[2] == struc1 && idArrayB[2] == struc1) {
15890
- linkArrayA.push(link);
15891
- nameHashA[link.source] = 1;
15892
- nameHashA[link.target] = 1;
15893
- } else if(idArrayA[2] == struc2 && idArrayB[2] == struc2) {
15894
- linkArrayB.push(link);
15895
- nameHashB[link.source] = 1;
15896
- nameHashB[link.target] = 1;
15897
- } else {
15898
- linkArrayAB.push(link);
15899
- nameHashAB[link.source] = 1;
15900
- nameHashAB[link.target] = 1;
15901
- }
15902
- }
15903
- let nodeArraysA = ic.getGraphCls.getNodeTopBottom(nameHashA, name2node);
15904
- nodeArray1a = nodeArraysA.nodeArray1;
15905
- nodeArray1b = nodeArraysA.nodeArray2;
15906
- let nodeArraysB = ic.getGraphCls.getNodeTopBottom(nameHashB, name2node);
15907
- nodeArray2a = nodeArraysB.nodeArray1;
15908
- nodeArray2b = nodeArraysB.nodeArray2;
15909
- let nodeArraysAB = ic.getGraphCls.getNodeTopBottom(nameHashAB, name2node, true);
15910
- nodeArray3a = nodeArraysAB.nodeArray1;
15911
- nodeArray3b = nodeArraysAB.nodeArray2;
15912
- let len1a = nodeArray1a.length,
15913
- len1b = nodeArray1b.length;
15914
- let len2a = nodeArray2a.length,
15915
- len2b = nodeArray2b.length;
15916
- let len3a = nodeArray3a.length,
15917
- len3b = nodeArray3b.length;
15918
- let maxLen = Math.max(len1a, len1b, len2a, len2b, len3a, len3b);
15915
+ let mapping1, mapping2;
15916
+
15917
+ if(ic.chainsMapping[chainid1] && ic.chainsMapping[chainid1][resid1]
15918
+ && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
15919
+ mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
15920
+ mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
15921
+
15922
+ let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15923
+ if(!linkedNodeCnt.hasOwnProperty(mappingid)) {
15924
+ linkedNodeCnt[mappingid] = 1;
15925
+ }
15926
+ else {
15927
+ ++linkedNodeCnt[mappingid];
15928
+ }
15929
+ }
15930
+ }
15931
+ }
15932
+
15933
+ // set linkArraySplitCommon and nameHashSplitCommon
15934
+ for(let i = 0, il = linkArray.length; i < il; ++i) {
15935
+ let link = linkArray[i];
15936
+ let nodeA = name2node[link.source];
15937
+ let nodeB = name2node[link.target];
15938
+
15939
+ if(!nodeA || !nodeB || !nodeA.r || !nodeB.r) {
15940
+ continue;
15941
+ }
15942
+
15943
+ let idArrayA = this.getIdArrayFromNode(nodeA);
15944
+ let idArrayB = this.getIdArrayFromNode(nodeB);
15945
+
15946
+ let index = struc2index[idArrayA[2]];
15947
+
15948
+ if(idArrayA[2] == structureArray[index] && idArrayB[2] == structureArray[index]) {
15949
+ let chainid1 = idArrayA[2] + '_' + idArrayA[3];
15950
+ let chainid2 = idArrayB[2] + '_' + idArrayB[3];
15951
+ let resid1 = chainid1 + '_' + idArrayA[4];
15952
+ let resid2 = chainid2 + '_' + idArrayB[4];
15953
+
15954
+ let mapping1, mapping2;
15955
+
15956
+ if(ic.chainsMapping[chainid1] && ic.chainsMapping[chainid1][resid1]
15957
+ && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
15958
+ mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
15959
+ mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
15960
+
15961
+ let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15962
+
15963
+ if(linkedNodeCnt[mappingid] == structureArray.length) {
15964
+ let linkCommon = me.hashUtilsCls.cloneHash(link);
15965
+ linkCommon.source += '>' + ic.chainsMapping[chainid1][resid1];
15966
+ linkCommon.target += '>' + ic.chainsMapping[chainid2][resid2];
15967
+
15968
+ linkArraySplitCommon[index].push(linkCommon);
15969
+ }
15970
+
15971
+ nameHashSplitCommon[index][link.source] = ic.chainsMapping[chainid1][resid1];
15972
+ nameHashSplitCommon[index][link.target] = ic.chainsMapping[chainid2][resid2];
15973
+ }
15974
+ }
15975
+ }
15976
+
15977
+ let len1Split = [], len2Split = [], maxWidth = 0;
15919
15978
  let strucArray = [];
15920
- if(linkArrayA.length > 0) strucArray.push(struc1);
15921
- if(linkArrayB.length > 0) strucArray.push(struc2);
15922
- if(linkArrayAB.length > 0) strucArray.push(struc1 + '_' + struc2);
15979
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15980
+ let nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node);
15981
+ nodeArray1Split[i] = nodeArraysTmp.nodeArray1;
15982
+ nodeArray2Split[i] = nodeArraysTmp.nodeArray2;
15983
+
15984
+ let bCommon = true;
15985
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommon, nameHashSplitCommon[i]);
15986
+ nodeArray1SplitCommon[i] = nodeArraysTmp.nodeArray1;
15987
+ nodeArray2SplitCommon[i] = nodeArraysTmp.nodeArray2;
15988
+ name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
15989
+
15990
+ len1Split[i] = nodeArray1Split[i].length;
15991
+ len2Split[i] = nodeArray2Split[i].length;
15992
+
15993
+ maxWidth = Math.max(maxWidth, len2Split[i]);
15994
+
15995
+ //if(linkArraySplit[i].length > 0) strucArray.push(structureArray[i]);
15996
+ strucArray.push(structureArray[i]);
15997
+ }
15998
+
15923
15999
  let factor = 1;
15924
16000
  let r = 3 * factor;
15925
16001
  let gap = 7 * factor;
15926
16002
  let height, width, heightAll;
15927
16003
  let marginX = 10,
15928
16004
  marginY = 10,
15929
- legendWidth = 30;
16005
+ legendWidth = 30,
16006
+ textHeight = 20;
16007
+
15930
16008
  if(bScatterplot) {
15931
- heightAll =(len1a + 2 + len2a + 2) *(r + gap) + 4 * marginY + 2 * legendWidth;
15932
- width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16009
+ //heightAll =(len1a + 2 + len2a + 2) *(r + gap) + 4 * marginY + 2 * legendWidth;
16010
+ //width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16011
+ heightAll =(me.utilsCls.sumArray(len1Split) + 2*strucArray.length) *(r + gap) + 4 * marginY
16012
+ + 2 * legendWidth + textHeight*strucArray.length;
16013
+ // show common interaction as well
16014
+ heightAll *= 2;
16015
+
16016
+ width = (maxWidth + 2) * (r + gap) + 2 * marginX + legendWidth;
16017
+
15933
16018
  } else {
15934
- height = 110;
16019
+ height = 110 + textHeight;
15935
16020
  heightAll = height * strucArray.length;
15936
- width = maxLen *(r + gap) + 2 * marginX;
16021
+ // show common interaction as well
16022
+ heightAll *= 2;
16023
+
16024
+ width = (maxWidth + 2) * (r + gap) + 2 * marginX;
15937
16025
  }
15938
16026
  let id, graphWidth;
15939
16027
  if(bScatterplot) {
@@ -15946,43 +16034,42 @@ class LineGraph {
15946
16034
  id = me.linegraphid;
15947
16035
  }
15948
16036
  html =(strucArray.length == 0) ? "No interactions found for each structure<br><br>" :
15949
- "2D integration graph for structure(s) <b>" + strucArray + "</b><br><br>";
16037
+ "2D integration graph for " + strucArray.length + " structure(s) <b>" + strucArray + "</b>. Common interactions are shown in the last " + strucArray.length + " graphs.<br><br>";
15950
16038
  html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
15951
- let heightFinal = 0;
15952
- if(linkArrayA.length > 0) {
16039
+
16040
+ let heightFinal = 0;
16041
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15953
16042
  if(bScatterplot) {
15954
- heightFinal -= 15;
15955
- html += this.drawScatterplot_base(nodeArray1a, nodeArray1b, linkArrayA, name2node, heightFinal);
15956
- heightFinal = 15;
15957
- height =(len1a + 1) *(r + gap) + 2 * marginY;
16043
+ //heightFinal -= 15;
16044
+ html += this.drawScatterplot_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, undefined, "Interactions in structure " + strucArray[i], textHeight);
16045
+ //heightFinal = 15;
16046
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
15958
16047
  } else {
15959
- html += this.drawLineGraph_base(nodeArray1a, nodeArray1b, linkArrayA, name2node, heightFinal);
16048
+ html += this.drawLineGraph_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, "Interactions in structure " + strucArray[i], textHeight);
15960
16049
  }
15961
16050
  heightFinal += height;
15962
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(struc1, 1, nodeArray1a, nodeArray1b, linkArrayA);
16051
+
16052
+ if(i > 0) ic.lineGraphStr += ', \n';
16053
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i, nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i]);
15963
16054
  }
15964
- if(linkArrayB.length > 0) {
16055
+
16056
+ // draw common interaction
16057
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15965
16058
  if(bScatterplot) {
15966
- html += this.drawScatterplot_base(nodeArray2a, nodeArray2b, linkArrayB, name2node, heightFinal);
15967
- height =(len2a + 1) *(r + gap) + 2 * marginY;
16059
+ //heightFinal -= 15;
16060
+ html += this.drawScatterplot_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, undefined, "Common interactions in structure " + strucArray[i], textHeight);
16061
+ //heightFinal = 15;
16062
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
15968
16063
  } else {
15969
- html += this.drawLineGraph_base(nodeArray2a, nodeArray2b, linkArrayB, name2node, heightFinal);
16064
+ html += this.drawLineGraph_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, "Common interactions in structure " + strucArray[i], textHeight);
15970
16065
  }
15971
16066
  heightFinal += height;
15972
- if(linkArrayA.length > 0) ic.lineGraphStr += ', \n';
15973
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(struc2, 2, nodeArray2a, nodeArray2b, linkArrayB);
15974
- }
15975
- if(linkArrayAB.length > 0 && !bScatterplot) {
15976
- html += this.drawLineGraph_base(nodeArray3a, nodeArray3b, linkArrayAB, name2node, heightFinal);
15977
- if(linkArrayA.length > 0 || linkArrayB.length > 0) ic.lineGraphStr += ', \n';
15978
- ic.lineGraphStr += '"structure1_2": {"id1": "' + struc1 + '", "id2": "' + struc2 + '", "nodes1":[';
15979
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(nodeArray3a);
15980
- ic.lineGraphStr += '], \n"nodes2":[';
15981
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(nodeArray3b);
15982
- ic.lineGraphStr += '], \n"links":[';
15983
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(linkArrayAB);
15984
- ic.lineGraphStr += ']}';
16067
+
16068
+ //if(i > 0) ic.lineGraphStr += ', \n';
16069
+ ic.lineGraphStr += ', \n';
16070
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i + '_common', nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i]);
15985
16071
  }
16072
+
15986
16073
  html += "</svg>";
15987
16074
  } else {
15988
16075
  if(!bScatterplot) {
@@ -16040,7 +16127,18 @@ class LineGraph {
16040
16127
  return html;
16041
16128
  }
16042
16129
 
16043
- drawLineGraph_base(nodeArray1, nodeArray2, linkArray, name2node, height) { let ic = this.icn3d, me = ic.icn3dui;
16130
+ getIdArrayFromNode(node) { let ic = this.icn3d, me = ic.icn3dui;
16131
+ let idArray = []; // 1_1_1KQ2_A_1
16132
+ idArray.push('');
16133
+ idArray.push('');
16134
+
16135
+ let tmpStr = node.r.substr(4);
16136
+ idArray = idArray.concat(me.utilsCls.getIdArray(tmpStr));
16137
+
16138
+ return idArray;
16139
+ }
16140
+
16141
+ drawLineGraph_base(nodeArray1, nodeArray2, linkArray, name2node, height, label, textHeight) { let ic = this.icn3d, me = ic.icn3dui;
16044
16142
  let html = '';
16045
16143
  let len1 = nodeArray1.length,
16046
16144
  len2 = nodeArray2.length;
@@ -16057,6 +16155,11 @@ class LineGraph {
16057
16155
  margin2 = margin;
16058
16156
  margin1 = Math.abs(len1 - len2) *(r + gap) * 0.5 + margin;
16059
16157
  }
16158
+
16159
+ // draw label
16160
+ height += textHeight;
16161
+ html += "<text x='" + margin1 + "' y='" + height + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16162
+
16060
16163
  let h1 = 30 + height,
16061
16164
  h2 = 80 + height;
16062
16165
  let nodeHtml = '';
@@ -16112,7 +16215,7 @@ class LineGraph {
16112
16215
  return html;
16113
16216
  }
16114
16217
 
16115
- drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap) { let ic = this.icn3d; ic.icn3dui;
16218
+ drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight) { let ic = this.icn3d; ic.icn3dui;
16116
16219
  let html = '';
16117
16220
  let len1 = nodeArray1.length,
16118
16221
  len2 = nodeArray2.length;
@@ -16123,12 +16226,19 @@ class LineGraph {
16123
16226
  let marginX = 10,
16124
16227
  marginY = 20;
16125
16228
  let heightTotal =(len1 + 1) *(r + gap) + legendWidth + 2 * marginY;
16229
+
16230
+ // draw label
16231
+ height += textHeight;
16232
+
16233
+ html += "<text x='" + marginX + "' y='" + (height + 15).toString() + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16234
+
16126
16235
  let margin1 = height + heightTotal -(legendWidth + marginY +(r + gap)); // y-axis
16127
16236
  let margin2 = legendWidth + marginX +(r + gap); // x-axis
16128
- let x = legendWidth + marginX;
16237
+
16129
16238
  let nodeHtml = '';
16130
16239
  let node2posSet1 = {},
16131
16240
  node2posSet2 = {};
16241
+ let x = legendWidth + marginX;
16132
16242
  for(let i = 0; i < len1; ++i) {
16133
16243
  nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true);
16134
16244
  node2posSet1[nodeArray1[i].id] = { x: x, y: margin1 - i *(r + gap) };
@@ -16500,8 +16610,9 @@ class ViewInterPairs {
16500
16610
  tmpText = 'Set 2';
16501
16611
  }
16502
16612
  html += '<div style="text-align:center"><br><b>Interactions Sorted on ' + tmpText + '</b>: <button class="' + ic.pre + 'showintercntonly" style="margin-left:20px">Show Count Only</button><button class="' + ic.pre + 'showinterdetails" style="margin-left:20px">Show Details</button></div>';
16503
- html += this.getAllInteractionTable(type).html;
16504
- bondCnt = this.getAllInteractionTable(type).bondCnt;
16613
+ let result = this.getAllInteractionTable(type);
16614
+ html += result.html;
16615
+ bondCnt = result.bondCnt;
16505
16616
 
16506
16617
  $("#" + ic.pre + "dl_interactionsorted").html(html);
16507
16618
  me.htmlCls.dialogCls.openDlg('dl_interactionsorted', 'Show sorted interactions');
@@ -20810,6 +20921,7 @@ class LoadAtomData {
20810
20921
  let refinedStr =(me.cfg.inpara && me.cfg.inpara.indexOf('atype=1') !== -1) ? 'Invariant Core ' : '';
20811
20922
  ic.molTitle = refinedStr + 'Structure Alignment of ';
20812
20923
 
20924
+ let bTitle = false;
20813
20925
  for(let i = 0, il = data.alignedStructures[0].length; i < il; ++i) {
20814
20926
  let structure = data.alignedStructures[0][i];
20815
20927
 
@@ -20847,10 +20959,13 @@ class LoadAtomData {
20847
20959
  ic.molTitle += " and ";
20848
20960
  if(structure.descr !== undefined) ic.pmid += "_";
20849
20961
  }
20962
+
20963
+ bTitle = true;
20850
20964
  }
20851
20965
 
20852
20966
  ic.molTitle += ' from VAST+';
20853
20967
 
20968
+ if(!bTitle) ic.molTitle = '';
20854
20969
  }
20855
20970
  else { // mmdbid or mmcifid
20856
20971
  if(data.descr !== undefined) ic.molTitle += data.descr.name;
@@ -22350,7 +22465,7 @@ class PdbParser {
22350
22465
  let url, dataType;
22351
22466
 
22352
22467
  if(bAf) {
22353
- url = "https://alphafold.ebi.ac.uk/files/AF-" + pdbid + "-F1-model_v1.pdb";
22468
+ url = "https://alphafold.ebi.ac.uk/files/AF-" + pdbid + "-F1-model_v2.pdb";
22354
22469
  ic.ParserUtilsCls.setYourNote(pdbid.toUpperCase() + '(AlphaFold) in iCn3D');
22355
22470
  }
22356
22471
  else {
@@ -23155,11 +23270,11 @@ class AlignParser {
23155
23270
  ic.alignmolid2color.push(tmpHash);
23156
23271
  }
23157
23272
 
23158
- //var url3 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&atomonly=1&uid=' + ic.mmdbidArray[0];
23159
- //var url4 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&atomonly=1&uid=' + ic.mmdbidArray[1];
23273
+ //var url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[0];
23274
+ //var url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[1];
23160
23275
  // need the parameter moleculeInfor
23161
- let url3 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=' + ic.mmdbidArray[0];
23162
- let url4 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=' + ic.mmdbidArray[1];
23276
+ let url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[0];
23277
+ let url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[1];
23163
23278
 
23164
23279
  let d3 = $.ajax({
23165
23280
  url: url3,
@@ -23694,10 +23809,10 @@ class MmdbParser {
23694
23809
  // b: b-factor, s: water, ft: pdbsite
23695
23810
  //&ft=1
23696
23811
  if(bGi) {
23697
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&simple=1&gi=" + mmdbid;
23812
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&gi=" + mmdbid;
23698
23813
  }
23699
23814
  else {
23700
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&simple=1&uid=" + mmdbid;
23815
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&uid=" + mmdbid;
23701
23816
  }
23702
23817
 
23703
23818
  // use asymmetric unit for BLAST search, e.g., https://www.ncbi.nlm.nih.gov/Structure/icn3d/full.html?from=blast&blast_rep_id=5XZC_B&query_id=1TUP_A&command=view+annotations;set+annotation+cdd;set+annotation+site;set+view+detailed+view;select+chain+5XZC_B;show+selection&log$=align&blast_rank=1&RID=EPUCYNVV014&buidx=0
@@ -24583,7 +24698,7 @@ class ChainalignParser {
24583
24698
  let pos1 = alignArray[0].indexOf('_');
24584
24699
  ic.mmdbid_t = alignArray[0].substr(0, pos1).toUpperCase();
24585
24700
  ic.chain_t = alignArray[0].substr(pos1+1);
24586
- let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=" + ic.mmdbid_t;
24701
+ let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_t;
24587
24702
  if(me.cfg.inpara !== undefined) url_t += me.cfg.inpara;
24588
24703
 
24589
24704
  let ajaxArray = [];
@@ -24609,7 +24724,7 @@ class ChainalignParser {
24609
24724
  let chainalignFinal = ic.mmdbid_q + "_" + ic.chain_q + "," + ic.mmdbid_t + "_" + ic.chain_t;
24610
24725
 
24611
24726
  let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi?chainpairs=" + chainalignFinal;
24612
- let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=" + ic.mmdbid_q;
24727
+ let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_q;
24613
24728
 
24614
24729
  if(me.cfg.inpara !== undefined) url_q += me.cfg.inpara;
24615
24730
 
@@ -26678,11 +26793,18 @@ class LoadScript {
26678
26793
  me.cfg.mmcifid = id;
26679
26794
  ic.mmcifParserCls.downloadMmcif(id);
26680
26795
  }
26681
- else if(command.indexOf('load mmdb') !== -1) {
26796
+ else if(command.indexOf('load mmdb') !== -1 || command.indexOf('load mmdb1') !== -1) {
26682
26797
  me.cfg.mmdbid = id;
26798
+ me.cfg.buidx = 1;
26683
26799
 
26684
26800
  ic.mmdbParserCls.downloadMmdb(id);
26685
26801
  }
26802
+ else if(command.indexOf('load mmdb0') !== -1) {
26803
+ me.cfg.mmdbid = id;
26804
+ me.cfg.buidx = 0;
26805
+
26806
+ ic.mmdbParserCls.downloadMmdb(id);
26807
+ }
26686
26808
  else if(command.indexOf('load gi') !== -1) {
26687
26809
  me.cfg.gi = id;
26688
26810
  ic.mmdbParserCls.downloadGi(id);
@@ -29585,7 +29707,7 @@ class Picking {
29585
29707
  let text =(ic.pk == 1) ? atom.resn + atom.resi + '@' + atom.name : atom.resn + atom.resi;
29586
29708
  if(ic.structures !== undefined && Object.keys(ic.structures).length > 1) {
29587
29709
  text = atom.structure + '_' + atom.chain + ' ' + text;
29588
- $("#" + ic.pre + "popup").css("width", "140px");
29710
+ $("#" + ic.pre + "popup").css("width", "160px");
29589
29711
  }
29590
29712
  else {
29591
29713
  $("#" + ic.pre + "popup").css("width", "80px");
@@ -30420,6 +30542,9 @@ class ApplyCommand {
30420
30542
  $("#" + ic.pre + "titlelink").css("color", "black");
30421
30543
  }
30422
30544
  }
30545
+ else if(command.indexOf('set label color') == 0) {
30546
+ ic.labelcolor = command.substr(command.lastIndexOf(' ') + 1);
30547
+ }
30423
30548
  else if(commandOri.indexOf('set thickness') == 0) {
30424
30549
  let paraArray = command.split(' | ');
30425
30550
 
@@ -32251,6 +32376,8 @@ class SetSeqAlign {
32251
32376
  ic.alnChainsAnTtl[chainid1][6].push("");
32252
32377
 
32253
32378
  let alignIndex = 1;
32379
+ if(!ic.chainsMapping[chainid1]) ic.chainsMapping[chainid1] = {};
32380
+ if(!ic.chainsMapping[chainid2]) ic.chainsMapping[chainid2] = {};
32254
32381
  //for(let j = 0, jl = alignData.sseq.length; j < jl; ++j) {
32255
32382
  for(let j = start; j <= end; ++j) {
32256
32383
  // 0: internal resi id, 1: pdb resi id, 2: resn, 3: aligned or not
@@ -32282,6 +32409,10 @@ class SetSeqAlign {
32282
32409
  ic.nconsHash2[chainid2 + '_' + resi] = 1;
32283
32410
  }
32284
32411
 
32412
+ // mapping, use the firstsequence as the reference structure
32413
+ ic.chainsMapping[chainid1][chainid1 + '_' + id2aligninfo[j].resi] = id2aligninfo[j].resn + id2aligninfo[j].resi;
32414
+ ic.chainsMapping[chainid2][chainid2 + '_' + resi] = id2aligninfo[j].resn + id2aligninfo[j].resi;
32415
+
32285
32416
  color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(id2aligninfo[j].resn, resn);
32286
32417
 
32287
32418
  // expensive and thus remove
@@ -32466,6 +32597,8 @@ class SetSeqAlign {
32466
32597
  if(ic.qt_start_end[chainIndex] === undefined) return;
32467
32598
 
32468
32599
  let alignIndex = 1;
32600
+ if(!ic.chainsMapping[chainid1]) ic.chainsMapping[chainid1] = {};
32601
+ if(!ic.chainsMapping[chainid2]) ic.chainsMapping[chainid2] = {};
32469
32602
  for(let i = 0, il = ic.qt_start_end[chainIndex].length; i < il; ++i) {
32470
32603
  //var start1 = ic.qt_start_end[chainIndex][i].q_start - 1;
32471
32604
  //var start2 = ic.qt_start_end[chainIndex][i].t_start - 1;
@@ -32559,6 +32692,10 @@ class SetSeqAlign {
32559
32692
  ic.nconsHash2[chainid2 + '_' + resi2] = 1;
32560
32693
  }
32561
32694
 
32695
+ // mapping, use the firstsequence as the reference structure
32696
+ ic.chainsMapping[chainid1][chainid1 + '_' + resi1] = resn1 + resi1;
32697
+ ic.chainsMapping[chainid2][chainid2 + '_' + resi2] = resn1 + resi1;
32698
+
32562
32699
  color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(resn1, resn2);
32563
32700
 
32564
32701
  let bFirstResi =(i === 0 && j === 0) ? true : false;
@@ -32608,6 +32745,8 @@ class SetSeqAlign {
32608
32745
  // let prevChainid1 = '', prevChainid2 = '', cnt1 = 0, cnt2 = 0;
32609
32746
 
32610
32747
  let residuesHash = {};
32748
+ if(!ic.chainsMapping[chainid_t]) ic.chainsMapping[chainid_t] = {};
32749
+ if(!ic.chainsMapping[chainid]) ic.chainsMapping[chainid] = {};
32611
32750
 
32612
32751
  for(let i = 0, il = ic.realignResid[structure1].length; i < il; ++i) {
32613
32752
  let resObject1 = ic.realignResid[structure1][i];
@@ -32634,6 +32773,11 @@ class SetSeqAlign {
32634
32773
  else {
32635
32774
  color = "#0000FF";
32636
32775
  }
32776
+
32777
+ // mapping, use the firstsequence as the reference structure
32778
+ ic.chainsMapping[chainid_t][chainid_t + '_' + resObject1.resi] = resObject1.resn + resObject1.resi;
32779
+ ic.chainsMapping[chainid][chainid + '_' + resObject2.resi] = resObject1.resn + resObject1.resi;
32780
+
32637
32781
  let color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(resObject1.resn, resObject2.resn);
32638
32782
 
32639
32783
  resObject1.color = color;
@@ -38422,9 +38566,12 @@ class Selection {
38422
38566
  ic.graphStr = this.getGraphDataForDisplayed();
38423
38567
  }
38424
38568
 
38569
+ // don not redraw graphs after the selection changes
38570
+ /*
38425
38571
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
38426
38572
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
38427
38573
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
38574
+ */
38428
38575
  }
38429
38576
 
38430
38577
  hideSelection() { let ic = this.icn3d, me = ic.icn3dui;
@@ -39656,6 +39803,8 @@ class Label {
39656
39803
 
39657
39804
  let labelsize = (label.size !== undefined) ? label.size : ic.LABELSIZE;
39658
39805
  let labelcolor = (label.color !== undefined) ? label.color : defaultColor;
39806
+ if(ic.labelcolor) labelcolor = ic.labelcolor;
39807
+
39659
39808
  let labelbackground = (label.background !== undefined) ? label.background : '#cccccc';
39660
39809
  let labelalpha = (label.alpha !== undefined) ? label.alpha : 1.0;
39661
39810
 
@@ -39681,7 +39830,8 @@ class Label {
39681
39830
  }
39682
39831
  }
39683
39832
 
39684
- bb.position.set(label.position.x, label.position.y, label.position.z);
39833
+ let labelOffset = (name == 'schematic' || name == 'residue') ? 0 : ic.coilWidth; // 0.3
39834
+ bb.position.set(label.position.x + labelOffset, label.position.y + labelOffset, label.position.z + labelOffset);
39685
39835
  ic.mdl.add(bb);
39686
39836
  // do not add labels to objects for pk
39687
39837
  }
@@ -44905,6 +45055,10 @@ class ClickMenu {
44905
45055
  me.myEventCls.onIds("#" + me.pre + "mn6_addlabelSelection", "click", function(e) { me.icn3d;
44906
45056
  me.htmlCls.dialogCls.openDlg('dl_addlabelselection', 'Add custom labels by the selected');
44907
45057
  });
45058
+
45059
+ me.myEventCls.onIds("#" + me.pre + "mn6_labelColor", "click", function(e) { me.icn3d;
45060
+ me.htmlCls.dialogCls.openDlg('dl_labelColor', 'Change color for all labels');
45061
+ });
44908
45062
  // },
44909
45063
  // clkMn2_saveselection: function() {
44910
45064
  me.myEventCls.onIds("#" + me.pre + "mn2_saveselection", "click", function(e) { me.icn3d;
@@ -44913,7 +45067,8 @@ class ClickMenu {
44913
45067
  // },
44914
45068
  // clkMn6_addlabelNo: function() {
44915
45069
  me.myEventCls.onIds(["#" + me.pre + "mn6_addlabelNo", "#" + me.pre + "removeLabels"], "click", function(e) { let ic = me.icn3d;
44916
- ic.pickpair = false;
45070
+ ic.labelcolor = undefined;
45071
+ ic.pickpair = false;
44917
45072
  //ic.labels['residue'] = [];
44918
45073
  //ic.labels['custom'] = [];
44919
45074
  let select = "set labels off";
@@ -45838,6 +45993,7 @@ class SetMenu {
45838
45993
  let html = "";
45839
45994
 
45840
45995
  html += "<ul class='icn3d-mn-item'>";
45996
+ html += "<li><a href='https://www.ncbi.nlm.nih.gov/structure' target='_blank'>Search Structure " + me.htmlCls.wifiStr + "</a></li>";
45841
45997
  html += "<li><span>Retrieve by ID</span>";
45842
45998
  html += "<ul>";
45843
45999
  html += me.htmlCls.setHtmlCls.getLink('mn1_mmdbid', 'MMDB ID ' + me.htmlCls.wifiStr);
@@ -46912,6 +47068,8 @@ class SetMenu {
46912
47068
  html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini');
46913
47069
  }
46914
47070
 
47071
+ html += "<li>-</li>";
47072
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_labelColor', 'Change Label Color', true);
46915
47073
  html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_addlabelNo', 'Remove', true);
46916
47074
  html += "</ul>";
46917
47075
  html += "</li>";
@@ -46967,6 +47125,8 @@ class SetMenu {
46967
47125
  }
46968
47126
 
46969
47127
  let bOnePdb = me.cfg.mmtfid !== undefined || me.cfg.pdbid !== undefined || me.cfg.opmid !== undefined || me.cfg.mmcifid !== undefined || me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined;
47128
+ console.log("me.cfg.mmdbid: " + me.cfg.mmdbid + " bOnePdb: " + bOnePdb);
47129
+
46970
47130
  if(bOnePdb) {
46971
47131
  html += "<li id='" + me.pre + "assemblyWrapper'><span>Assembly</span>";
46972
47132
  html += "<ul>";
@@ -47882,7 +48042,7 @@ class SetDialog {
47882
48042
  html += "<b>Optional 1</b>, full chains are used for structure alignment<br/><br/>";
47883
48043
  html += "<b>Optional 2</b>, sequence alignment (followed by structure alignemnt) based on residue numbers in the First/Master chain: <br>" + me.htmlCls.inputTextStr + "id='" + me.pre + "resalignids' placeholder='1,5,10-50' size=50><br/><br/>";
47884
48044
  html += "<b>Optional 3</b>, predefined alignment with residue numbers in each chain specified (one chain per line): <br><textarea id='" + me.pre + "predefinedres' rows='5' style='width: 100%; height: " +(me.htmlCls.LOG_HEIGHT) + "px; padding: 0px; border: 0px;' placeholder='1,5,10-50\n1,5,10-50\n1,5,10-50'></textarea><br/><br/>";
47885
- html += me.htmlCls.buttonStr + "reload_chainalign'>Align Biological Unit</button>" + me.htmlCls.buttonStr + "reload_chainalign_asym' style='margin-left:30px'>Align Asymmetric Unit</button><br/><br/>";
48045
+ html += me.htmlCls.buttonStr + "reload_chainalign_asym'>Align Asymmetric Unit</button>" + me.htmlCls.buttonStr + "reload_chainalign' style='margin-left:30px'>Align Biological Unit</button><br/><br/>";
47886
48046
  html += "(Note: To align chains in custom PDB files, you could concatenate PDB files in a single PDB file with the separation line \"ENDMDL\". Then load it in \"Open File > PDB File\" in the \"File\" menu and click \"View Sequences & Annotations\" in the \"Window\" menu. Finally select multiple chains in the sequence window and click \"Realign Selection\" in the \"File\" menu.)<br><br>";
47887
48047
  html += "</div></div>";
47888
48048
 
@@ -47931,8 +48091,8 @@ class SetDialog {
47931
48091
  html += "</div>";
47932
48092
 
47933
48093
  html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "'>";
47934
- html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> ";
47935
- html += me.htmlCls.buttonStr + "reload_mmdb'>Load</button>";
48094
+ html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> <br><br>";
48095
+ html += me.htmlCls.buttonStr + "reload_mmdb_asym'>Load Asymmetric Unit (All Chains)</button>" + me.htmlCls.buttonStr + "reload_mmdb' style='margin-left:30px'>Load Biological Unit</button><br/><br/>";
47936
48096
  html += "</div>";
47937
48097
 
47938
48098
  html += me.htmlCls.divStr + "dl_blast_rep_id' style='max-width:500px;' class='" + dialogClass + "'>";
@@ -48323,23 +48483,28 @@ class SetDialog {
48323
48483
  html += me.htmlCls.divStr + "dl_addlabel' class='" + dialogClass + "'>";
48324
48484
  html += "1. Text: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labeltext' value='Text' size=4><br/>";
48325
48485
  html += "2. Size: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelsize' value='18' size=4 maxlength=2><br/>";
48326
- //html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor' value='" + defaultColor + "' size=4><br/>";
48486
+ html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor' value='" + defaultColor + "' size=4><br/>";
48327
48487
  //html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd' value='' size=4><br/>";
48328
48488
  if(me.utilsCls.isMobile()) {
48329
- html += me.htmlCls.spanNowrapStr + "3. Touch TWO atoms</span><br/>";
48489
+ html += me.htmlCls.spanNowrapStr + "4. Touch TWO atoms</span><br/>";
48330
48490
  }
48331
48491
  else {
48332
- html += me.htmlCls.spanNowrapStr + "3. Pick TWO atoms while holding \"Alt\" key</span><br/>";
48492
+ html += me.htmlCls.spanNowrapStr + "4. Pick TWO atoms while holding \"Alt\" key</span><br/>";
48333
48493
  }
48334
- html += me.htmlCls.spanNowrapStr + "4. " + me.htmlCls.buttonStr + "applypick_labels'>Display</button></span>";
48494
+ html += me.htmlCls.spanNowrapStr + "5. " + me.htmlCls.buttonStr + "applypick_labels'>Display</button></span>";
48335
48495
  html += "</div>";
48336
48496
 
48337
48497
  html += me.htmlCls.divStr + "dl_addlabelselection' class='" + dialogClass + "'>";
48338
48498
  html += "1. Text: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labeltext2' value='Text' size=4><br/>";
48339
48499
  html += "2. Size: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelsize2' value='18' size=4 maxlength=2><br/>";
48340
- //html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor2' value='" + defaultColor + "' size=4><br/>";
48500
+ html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor2' value='" + defaultColor + "' size=4><br/>";
48341
48501
  //html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd2' value='' size=4><br/>";
48342
- html += me.htmlCls.spanNowrapStr + "3. " + me.htmlCls.buttonStr + "applyselection_labels'>Display</button></span>";
48502
+ html += me.htmlCls.spanNowrapStr + "4. " + me.htmlCls.buttonStr + "applyselection_labels'>Display</button></span>";
48503
+ html += "</div>";
48504
+
48505
+ html += me.htmlCls.divStr + "dl_labelColor' class='" + dialogClass + "'>";
48506
+ html += "Color for all labels: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolorall' value='" + defaultColor + "' size=4><br/><br/>";
48507
+ html += me.htmlCls.spanNowrapStr + me.htmlCls.buttonStr + "applylabelcolor'>Display</button></span>";
48343
48508
  html += "</div>";
48344
48509
 
48345
48510
  html += me.htmlCls.divStr + "dl_distance' class='" + dialogClass + "'>";
@@ -49157,20 +49322,24 @@ class Events {
49157
49322
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb", "click", function(e) { me.icn3d;
49158
49323
  e.preventDefault();
49159
49324
  if(!me.cfg.notebook) dialog.dialog( "close" );
49160
- me.htmlCls.clickMenuCls.setLogCmd("load mmdb " + $("#" + me.pre + "mmdbid").val(), false);
49161
- //ic.mmdbParserCls.downloadMmdb($("#" + me.pre + "mmdbid").val());
49162
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
49163
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
49325
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb1 " + $("#" + me.pre + "mmdbid").val(), false);
49326
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=1', '_blank');
49164
49327
  });
49165
49328
 
49329
+ me.myEventCls.onIds("#" + me.pre + "reload_mmdb_asym", "click", function(e) { me.icn3d;
49330
+ e.preventDefault();
49331
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49332
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49333
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49334
+ });
49335
+
49166
49336
  me.myEventCls.onIds("#" + me.pre + "mmdbid", "keyup", function(e) { me.icn3d;
49167
49337
  if (e.keyCode === 13) {
49168
49338
  e.preventDefault();
49169
49339
  if(!me.cfg.notebook) dialog.dialog( "close" );
49170
- me.htmlCls.clickMenuCls.setLogCmd("load mmdb " + $("#" + me.pre + "mmdbid").val(), false);
49171
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
49172
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
49173
- }
49340
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49341
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49342
+ }
49174
49343
  });
49175
49344
 
49176
49345
  // },
@@ -50031,6 +50200,15 @@ class Events {
50031
50200
  me.htmlCls.clickMenuCls.setLogCmd('add label ' + text + ' | x ' + x.toPrecision(4) + ' y ' + y.toPrecision(4) + ' z ' + z.toPrecision(4) + sizeStr + colorStr + backgroundStr + ' | type custom', true);
50032
50201
  ic.drawCls.draw();
50033
50202
  });
50203
+
50204
+ me.myEventCls.onIds("#" + me.pre + "applylabelcolor", "click", function(e) { let ic = me.icn3d;
50205
+ e.preventDefault();
50206
+ if(!me.cfg.notebook) dialog.dialog( "close" );
50207
+ ic.labelcolor = $("#" + me.pre + "labelcolorall" ).val();
50208
+
50209
+ me.htmlCls.clickMenuCls.setLogCmd('set label color ' + ic.labelcolor, true);
50210
+ ic.drawCls.draw();
50211
+ });
50034
50212
  // },
50035
50213
  // clickApplypick_stabilizer: function() {
50036
50214
  me.myEventCls.onIds("#" + me.pre + "applypick_stabilizer", "click", function(e) { let ic = me.icn3d;
@@ -54805,6 +54983,8 @@ iCn3D.prototype.init_base = function (bKeepCmd) {
54805
54983
  this.chainsAn = {}; // structure_chain name -> array of annotations, such as residue number
54806
54984
  this.chainsAnTitle = {}; // structure_chain name -> array of annotation title
54807
54985
 
54986
+ this.chainsMapping = {}; // structure_chain name -> residue id hash such as {'structure_chain_resi1': 'reference residue such as K10', ...}
54987
+
54808
54988
  this.alnChainsSeq = {}; // structure_chain name -> array of residue object: {mmdbid, chain, resi, resn, aligned}
54809
54989
  this.alnChainsAnno = {}; // structure_chain name -> array of annotations, such as residue number
54810
54990
  this.alnChainsAnTtl = {}; // structure_chain name -> array of annotation title
@@ -54954,7 +55134,7 @@ class iCn3DUI {
54954
55134
  //even when multiple iCn3D viewers are shown together.
54955
55135
  this.pre = this.cfg.divid + "_";
54956
55136
 
54957
- this.REVISION = '3.6.0';
55137
+ this.REVISION = '3.7.0';
54958
55138
 
54959
55139
  // In nodejs, iCn3D defines "window = {navigator: {}}"
54960
55140
  this.bNode = (Object.keys(window).length < 2) ? true : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icn3d",
3
- "version": "3.6.0",
3
+ "version": "3.7.0",
4
4
  "main": "icn3d.js",
5
5
  "description": "iCn3D Structure Viewer",
6
6
  "repository": {