@datagrok/helm 2.3.3 → 2.4.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/CHANGELOG.md +28 -0
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +8 -7
- package/src/cell-renderer.ts +9 -8
- package/src/helm-helper.ts +232 -40
- package/src/helm-monomer-placer.ts +1 -1
- package/src/helm-web-editor.ts +24 -34
- package/src/package-utils.ts +92 -117
- package/src/package.ts +13 -22
- package/src/tests/findMonomers-tests.ts +3 -3
- package/src/tests/get-molfiles-tests.ts +2 -2
- package/src/tests/get-monomer-tests.ts +19 -16
- package/src/tests/helm-input-tests.ts +34 -23
- package/src/tests/helm-service-tests.ts +3 -3
- package/src/tests/helm-tests.ts +1 -2
- package/src/tests/helm-web-editor-tests.ts +2 -2
- package/src/tests/parse-helm-tests.ts +9 -8
- package/src/tests/properties-widget-tests.ts +2 -2
- package/src/tests/renderers-tests.ts +2 -2
- package/src/types/index.ts +1 -1
- package/src/utils/get-hovered.ts +8 -10
- package/src/utils/get-monomer.ts +3 -4
- package/src/utils/helm-grid-cell-renderer.ts +16 -29
- package/src/utils/helm-service.ts +4 -6
- package/src/widgets/helm-input.ts +135 -72
- package/src/widgets/properties-widget.ts +4 -4
- package/tsconfig.json +3 -3
- package/webpack.config.js +4 -4
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/helm",
|
|
3
3
|
"friendlyName": "Helm",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Oleksandra Serhiienko",
|
|
7
7
|
"email": "oserhiienko@datagrok.ai"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"css/helm.css"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@datagrok-libraries/bio": "^5.42.
|
|
19
|
+
"@datagrok-libraries/bio": "^5.42.9",
|
|
20
20
|
"@datagrok-libraries/chem-meta": "^1.2.5",
|
|
21
21
|
"@datagrok-libraries/utils": "^4.2.19",
|
|
22
22
|
"cash-dom": "^8.1.1",
|
|
@@ -26,17 +26,18 @@
|
|
|
26
26
|
"wu": "latest"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@datagrok-libraries/helm-web-editor": "^1.1.
|
|
30
|
-
"@datagrok-libraries/js-draw-lite": "^0.0.
|
|
31
|
-
"@datagrok/bio": "^2.
|
|
29
|
+
"@datagrok-libraries/helm-web-editor": "^1.1.8",
|
|
30
|
+
"@datagrok-libraries/js-draw-lite": "^0.0.6",
|
|
31
|
+
"@datagrok/bio": "^2.14.1",
|
|
32
32
|
"@datagrok/chem": "^1.9.2",
|
|
33
33
|
"@types/node": "17.0.45",
|
|
34
34
|
"@types/wu": "latest",
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
36
|
-
"@typescript-eslint/parser": "^
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^7.16.0",
|
|
36
|
+
"@typescript-eslint/parser": "^7.16.0",
|
|
37
37
|
"datagrok-tools": "latest",
|
|
38
38
|
"eslint": "^8.18.0",
|
|
39
39
|
"eslint-config-google": "^0.14.0",
|
|
40
|
+
"eslint-plugin-rxjs": "^5.0.3",
|
|
40
41
|
"path": "^0.12.7",
|
|
41
42
|
"source-map-loader": "^4.0.1",
|
|
42
43
|
"ts-loader": "^9.2.6",
|
package/src/cell-renderer.ts
CHANGED
|
@@ -4,19 +4,19 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import wu from 'wu';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {HelmMol, ISeqMonomer} from '@datagrok-libraries/bio/src/helm/types';
|
|
8
8
|
|
|
9
9
|
import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
|
|
10
10
|
import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
11
11
|
|
|
12
12
|
import {findMonomers, parseHelm, removeGapsFromHelm} from './utils';
|
|
13
13
|
import {HelmMonomerPlacer} from './helm-monomer-placer';
|
|
14
|
-
import {getHoveredMonomerFallback, getHoveredMonomerFromEditorMol} from './utils/get-hovered';
|
|
15
|
-
import {
|
|
14
|
+
import {getHoveredMonomerFallback, getHoveredMonomerFromEditorMol, getSeqMonomerFromHelmAtom} from './utils/get-hovered';
|
|
15
|
+
import {JSDraw2Module} from './types';
|
|
16
16
|
|
|
17
17
|
import {_package} from './package';
|
|
18
18
|
|
|
19
|
-
declare const JSDraw2:
|
|
19
|
+
declare const JSDraw2: JSDraw2Module;
|
|
20
20
|
|
|
21
21
|
const enum tempTAGS {
|
|
22
22
|
helmSumMaxLengthWords = 'helm-sum-maxLengthWords',
|
|
@@ -50,12 +50,13 @@ export class HelmCellRenderer extends DG.GridCellRenderer {
|
|
|
50
50
|
const argsY = e.offsetY - gcb.y;
|
|
51
51
|
|
|
52
52
|
const monomerLib = _package.monomerLib;
|
|
53
|
-
const editorMol:
|
|
53
|
+
const editorMol: HelmMol | null = helmPlacer.getEditorMol(gridCell.tableRowIndex!);
|
|
54
54
|
let seqMonomer: ISeqMonomer | null;
|
|
55
55
|
let missedMonomers: Set<string> = new Set<string>(); // of .size = 0
|
|
56
|
-
if (editorMol)
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if (editorMol) {
|
|
57
|
+
const hoveredAtom = getHoveredMonomerFromEditorMol(argsX, argsY, editorMol, gridCell.bounds.height);
|
|
58
|
+
seqMonomer = hoveredAtom ? getSeqMonomerFromHelmAtom(hoveredAtom) : null;
|
|
59
|
+
} else {
|
|
59
60
|
const seq: string = !gridCell.cell.value ? '' : removeGapsFromHelm(gridCell.cell.value as string);
|
|
60
61
|
const monomerList = parseHelm(seq);
|
|
61
62
|
missedMonomers = findMonomers(monomerList, monomerLib);
|
package/src/helm-helper.ts
CHANGED
|
@@ -3,23 +3,26 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
-
App, Atom, HelmType, GetMonomerFunc, GetMonomerResType, HelmString, HelmMol
|
|
6
|
+
App, Atom, HelmType, GetMonomerFunc, GetMonomerResType, HelmString, HelmMol,
|
|
7
|
+
MonomerExplorer, TabDescType, MonomersFuncs, MonomerSetType, HelmAtom, ISeqMonomer, PolymerType, MonomerType, type DojoType
|
|
7
8
|
} from '@datagrok-libraries/bio/src/helm/types';
|
|
8
|
-
|
|
9
|
+
import {HelmTypes, MonomerTypes, PolymerTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
9
10
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
10
11
|
import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
|
|
11
|
-
import {IHelmHelper,
|
|
12
|
+
import {HelmInputBase, IHelmHelper, IHelmInputInitOptions} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
12
13
|
import {IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
|
|
13
|
-
import {IMonomerLib} from '@datagrok-libraries/bio/src/types/index';
|
|
14
|
+
import {IMonomerLib, IMonomerLinkData, IMonomerSetPlaceholder} from '@datagrok-libraries/bio/src/types/index';
|
|
15
|
+
import {HelmTabKeys, IHelmDrawOptions} from '@datagrok-libraries/helm-web-editor/src/types/org-helm';
|
|
14
16
|
|
|
15
17
|
import {HelmWebEditor} from './helm-web-editor';
|
|
16
18
|
import {OrgHelmModule, ScilModule} from './types';
|
|
17
19
|
import {getWebEditorMonomer} from './utils/get-monomer';
|
|
18
20
|
import {HelmInput} from './widgets/helm-input';
|
|
21
|
+
import {getHoveredMonomerFromEditorMol} from './utils/get-hovered';
|
|
19
22
|
|
|
20
23
|
import {_package} from './package';
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
declare const dojo: DojoType;
|
|
23
26
|
declare const scil: ScilModule;
|
|
24
27
|
declare const org: OrgHelmModule;
|
|
25
28
|
|
|
@@ -34,9 +37,9 @@ export class HelmHelper implements IHelmHelper {
|
|
|
34
37
|
throw new Error(`HelmHelper must be a single.`);
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
createHelmInput(name?: string, options?:
|
|
40
|
+
createHelmInput(name?: string, options?: IHelmInputInitOptions): HelmInputBase {
|
|
38
41
|
try {
|
|
39
|
-
const monomerLib: IMonomerLib = _package.libHelper
|
|
42
|
+
const monomerLib: IMonomerLib = _package.libHelper!.getMonomerLib();
|
|
40
43
|
return HelmInput.create(this, monomerLib, name, options);
|
|
41
44
|
} catch (err: any) {
|
|
42
45
|
const [errMsg, errStack] = errInfo(err);
|
|
@@ -45,8 +48,8 @@ export class HelmHelper implements IHelmHelper {
|
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
createHelmWebEditor(host?: HTMLDivElement): IHelmWebEditor {
|
|
49
|
-
return new HelmWebEditor(host);
|
|
51
|
+
createHelmWebEditor(host?: HTMLDivElement, drawOptions?: Partial<IHelmDrawOptions>): IHelmWebEditor {
|
|
52
|
+
return new HelmWebEditor(host, drawOptions);
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
createWebEditorApp(host: HTMLDivElement, helm: string): App {
|
|
@@ -59,7 +62,36 @@ export class HelmHelper implements IHelmHelper {
|
|
|
59
62
|
mexmonomerstab: true,
|
|
60
63
|
sequenceviewonly: false,
|
|
61
64
|
mexfavoritefirst: true,
|
|
62
|
-
mexfilter: true
|
|
65
|
+
mexfilter: true,
|
|
66
|
+
// currentTabKey: HelmTabKeys.Helm,
|
|
67
|
+
overrideTabs: (tabs: Partial<TabDescType>[]): Partial<TabDescType>[] => {
|
|
68
|
+
const res: Partial<TabDescType>[] = [...tabs,
|
|
69
|
+
{caption: 'Placeholders', tabkey: 'placeholders'},
|
|
70
|
+
];
|
|
71
|
+
return res;
|
|
72
|
+
},
|
|
73
|
+
onShowTab: (mex: MonomerExplorer, div: HTMLDivElement, key: string): void => {
|
|
74
|
+
switch (key) {
|
|
75
|
+
case 'placeholders': {
|
|
76
|
+
this.onShowTabPlaceholders(mex, div);
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 'placeholders-meta': {
|
|
80
|
+
this.onShowTabPlaceholdersMeta(mex, div);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case 'placeholders-sets': {
|
|
84
|
+
this.onShowTabPlaceholdersSets(mex, div);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
dojo.connect(div, 'onmousedown', function(e: MouseEvent) {
|
|
89
|
+
mex.select(e);
|
|
90
|
+
});
|
|
91
|
+
dojo.connect(div, 'ondblclick', function(e: MouseEvent) {
|
|
92
|
+
mex.dblclick(e);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
63
95
|
});
|
|
64
96
|
const sizes = webEditorApp.calculateSizes();
|
|
65
97
|
webEditorApp.canvas!.resize(sizes.rightwidth - 100, sizes.topheight - 210);
|
|
@@ -70,55 +102,215 @@ export class HelmHelper implements IHelmHelper {
|
|
|
70
102
|
scil.apply(webEditorApp.properties!.parent.style, s);
|
|
71
103
|
webEditorApp.structureview!.resize(sizes.rightwidth, sizes.bottomheight + webEditorApp.toolbarheight);
|
|
72
104
|
webEditorApp.mex!.resize(sizes.topheight - 80);
|
|
73
|
-
|
|
74
|
-
webEditorApp.canvas!.helm!.setSequence(helm, 'HELM');
|
|
75
|
-
}, 200);
|
|
105
|
+
webEditorApp.canvas?.setHelm(helm);
|
|
76
106
|
return webEditorApp;
|
|
77
107
|
}
|
|
78
108
|
|
|
109
|
+
// -- MonomerExplorer.onShowTab --
|
|
110
|
+
|
|
111
|
+
public onShowTabPlaceholders(mex: MonomerExplorer, div: HTMLDivElement): void {
|
|
112
|
+
const d = scil.Utils.createElement(div, 'div', null, {paddingTop: '5px'});
|
|
113
|
+
|
|
114
|
+
/* eslint-disable max-len*/
|
|
115
|
+
// if (this.options.canvastoolbar == false) {
|
|
116
|
+
// const b = scil.Utils.createElement(d, 'div', '<img src=\'' + scil.Utils.imgSrc('helm/arrow.png') + '\' style=\'vertical-align:middle\'>Mouse Pointer', {cursor: 'pointer', padding: '2px', border: 'solid 1px gray', margin: '5px'});
|
|
117
|
+
// scil.connect(b, 'onclick', function() {
|
|
118
|
+
// mex.plugin.jsd.doCmd('lasso');
|
|
119
|
+
// });
|
|
120
|
+
// }
|
|
121
|
+
/* eslint-enable max-len*/
|
|
122
|
+
|
|
123
|
+
const phTabs: Partial<TabDescType>[] = [];
|
|
124
|
+
phTabs.push({caption: 'Meta', tabkey: 'placeholders-meta'});
|
|
125
|
+
phTabs.push({caption: 'Sets', tabkey: 'placeholders-sets'});
|
|
126
|
+
const placeholdersTabs = new scil.Tabs(d, {
|
|
127
|
+
onShowTab(td: HTMLTableCellElement) {
|
|
128
|
+
mex.onShowTab(td);
|
|
129
|
+
},
|
|
130
|
+
tabpadding: '5px 2px 1px 2px',
|
|
131
|
+
tabs: phTabs,
|
|
132
|
+
marginBottom: `0`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
public onShowTabPlaceholdersMeta(mex: MonomerExplorer, div: HTMLDivElement): void {
|
|
137
|
+
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public onShowTabPlaceholdersSets(mex: MonomerExplorer, div: HTMLDivElement): void {
|
|
141
|
+
const monomerSets = _package.libHelper!.getMonomerSets();
|
|
142
|
+
|
|
143
|
+
const phSet: { [polymerType: string]: { [helmType: string]: IMonomerSetPlaceholder[] } } = {};
|
|
144
|
+
for (const ph of monomerSets.placeholders) {
|
|
145
|
+
let ofPolymerTypeSet = phSet[ph.polymerType];
|
|
146
|
+
if (!ofPolymerTypeSet) ofPolymerTypeSet = phSet[ph.polymerType] = {};
|
|
147
|
+
|
|
148
|
+
const phHelmType = this.toHelmType(ph.polymerType, ph.monomerType);
|
|
149
|
+
let phList = ofPolymerTypeSet[phHelmType];
|
|
150
|
+
if (!phList) phList = ofPolymerTypeSet[phHelmType] = [];
|
|
151
|
+
phList.push(ph);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const fillPlaceholders = (
|
|
155
|
+
parentDiv: HTMLDivElement, phList: IMonomerSetPlaceholder[], helmType: HelmType
|
|
156
|
+
): void => {
|
|
157
|
+
for (const ph of phList) {
|
|
158
|
+
const phDiv = mex.createMonomerDiv(parentDiv, ph.symbol, helmType);
|
|
159
|
+
ui.tooltip.bind(phDiv, () => {
|
|
160
|
+
const phTooltipDiv = ui.div([
|
|
161
|
+
ui.table(ph.monomerLinks, (ml: IMonomerLinkData, idx: number) => {
|
|
162
|
+
return [ml.symbol, ml.source];
|
|
163
|
+
}, ['Symbol', 'Library source'])
|
|
164
|
+
]);
|
|
165
|
+
return phTooltipDiv;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const polymerTypes: [string, PolymerType][] = [
|
|
171
|
+
['Chem', PolymerTypes.CHEM],
|
|
172
|
+
['Peptide', PolymerTypes.PEPTIDE],
|
|
173
|
+
['RNA', PolymerTypes.RNA],
|
|
174
|
+
['Blob', PolymerTypes.BLOB],
|
|
175
|
+
['G', PolymerTypes.G],
|
|
176
|
+
];
|
|
177
|
+
const polymerTypeAcc = ui.accordion();
|
|
178
|
+
for (const [name, polymerType] of polymerTypes) {
|
|
179
|
+
if (polymerType in phSet) {
|
|
180
|
+
polymerTypeAcc.addPane(name, () => {
|
|
181
|
+
const polymerTypeDiv = ui.div();
|
|
182
|
+
const ofPolymerTypeSet = phSet[polymerType];
|
|
183
|
+
if (Object.keys(ofPolymerTypeSet).length == 1) {
|
|
184
|
+
const [helmType, phList] = Object.entries(ofPolymerTypeSet)[0];
|
|
185
|
+
fillPlaceholders(polymerTypeDiv, phList, helmType as HelmType);
|
|
186
|
+
} else {
|
|
187
|
+
const helmTypeAcc = ui.accordion();
|
|
188
|
+
for (const [helmTypeName, helmType] of Object.entries(HelmTypes)) {
|
|
189
|
+
if (helmType in ofPolymerTypeSet) {
|
|
190
|
+
helmTypeAcc.addPane(helmTypeName, () => {
|
|
191
|
+
const helmTypeDiv = ui.div();
|
|
192
|
+
|
|
193
|
+
const phList = ofPolymerTypeSet[helmType];
|
|
194
|
+
fillPlaceholders(helmTypeDiv, phList, helmType as HelmType);
|
|
195
|
+
|
|
196
|
+
return helmTypeDiv;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
polymerTypeDiv.appendChild(helmTypeAcc.root);
|
|
201
|
+
}
|
|
202
|
+
return polymerTypeDiv;
|
|
203
|
+
}, true, undefined, false);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
div.appendChild(polymerTypeAcc.root);
|
|
207
|
+
}
|
|
208
|
+
|
|
79
209
|
// -- GetMonomer --
|
|
80
210
|
|
|
81
|
-
public
|
|
211
|
+
public originalMonomersFuncs: MonomersFuncs | null = null;
|
|
82
212
|
|
|
83
|
-
public
|
|
213
|
+
public revertOriginalMonomersFuncs(): MonomersFuncs {
|
|
84
214
|
const logPrefix = `Helm: revertOriginalGetMonomer()`;
|
|
85
|
-
if (this.
|
|
215
|
+
if (this.originalMonomersFuncs === null)
|
|
86
216
|
throw new Error('Unable to revert original getMonomer');
|
|
87
217
|
|
|
88
218
|
const monomers = org.helm.webeditor.Monomers;
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
219
|
+
const overriddenMonomersFuncs: MonomersFuncs = {
|
|
220
|
+
getMonomer: monomers.getMonomer,
|
|
221
|
+
getMonomerSet: monomers.getMonomerSet,
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
monomers.getMonomer = this.originalMonomersFuncs.getMonomer;
|
|
225
|
+
monomers.getMonomerSet = this.originalMonomersFuncs.getMonomerSet;
|
|
226
|
+
this.originalMonomersFuncs = null;
|
|
227
|
+
|
|
228
|
+
return overriddenMonomersFuncs;
|
|
92
229
|
}
|
|
93
230
|
|
|
94
|
-
public
|
|
95
|
-
const logPrefix = `Helm: overrideGetMonomer()`;
|
|
231
|
+
public overrideMonomersFuncs(monomersFuncs: MonomersFuncs): MonomersFuncs {
|
|
232
|
+
const logPrefix = `Helm: HelmHelper.overrideGetMonomer()`;
|
|
96
233
|
|
|
97
|
-
if (this.
|
|
98
|
-
throw new Error(
|
|
234
|
+
if (this.originalMonomersFuncs != null)
|
|
235
|
+
throw new Error(`${logPrefix}, originalGetMonomer is overridden already`);
|
|
99
236
|
|
|
100
237
|
const monomers = org.helm.webeditor.Monomers;
|
|
101
|
-
this.
|
|
102
|
-
|
|
103
|
-
|
|
238
|
+
this.originalMonomersFuncs = {
|
|
239
|
+
getMonomer: monomers.getMonomer.bind(monomers),
|
|
240
|
+
getMonomerSet: monomers.getMonomerSet.bind(monomers),
|
|
241
|
+
};
|
|
242
|
+
monomers.getMonomer = monomersFuncs.getMonomer;
|
|
243
|
+
monomers.getMonomerSet = monomersFuncs.getMonomerSet;
|
|
244
|
+
return this.originalMonomersFuncs!;
|
|
104
245
|
}
|
|
105
246
|
|
|
106
|
-
public
|
|
247
|
+
public buildMonomersFuncsFromLib(monomerLib: IMonomerLib): MonomersFuncs {
|
|
107
248
|
const logPrefix = `Helm: HelmHelper.buildGetMonomerFromLib()`;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
getMonomer: (a: HelmAtom | HelmType, name?: string): GetMonomerResType => {
|
|
252
|
+
const logPrefixInt = `${logPrefix}, org.helm.webeditor.Monomers.getMonomer()`;
|
|
253
|
+
try {
|
|
254
|
+
// logger.debug(`${logPrefixInt}, a: ${JSON.stringify(a, helmJsonReplacer)}, name: '${name}'`);
|
|
255
|
+
|
|
256
|
+
// Creates monomers in lib
|
|
257
|
+
const dgWem = getWebEditorMonomer(monomerLib, a, name);
|
|
258
|
+
|
|
259
|
+
return dgWem; //dgWem;
|
|
260
|
+
} catch (err) {
|
|
261
|
+
const [errMsg, errStack] = errInfo(err);
|
|
262
|
+
this.logger.error(`${logPrefixInt}, Error: ${errMsg}`, undefined, errStack);
|
|
263
|
+
throw err;
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
getMonomerSet: (a: HelmAtom | HelmType | null): MonomerSetType | null => {
|
|
267
|
+
// if (a == null)
|
|
268
|
+
// return null;
|
|
269
|
+
// const atom = a as HelmAtom;
|
|
270
|
+
// if (atom.T === 'ATOM')
|
|
271
|
+
// a = atom.biotype();
|
|
272
|
+
// return monomerLib.getMonomerSet(a as HelmType);
|
|
273
|
+
return this.originalMonomersFuncs!.getMonomerSet(a);
|
|
121
274
|
}
|
|
122
275
|
};
|
|
123
276
|
}
|
|
277
|
+
|
|
278
|
+
// helm2type(seqM: ISeqMonomer): HelmType {
|
|
279
|
+
// if (seqM.polymerType == "PEPTIDE")
|
|
280
|
+
// return org.helm.webeditor.HELM.AA;
|
|
281
|
+
// else if (seqM.polymerType == "CHEM")
|
|
282
|
+
// return org.helm.webeditor.HELM.CHEM;
|
|
283
|
+
// else if (seqM.polymerType == "RNA") {
|
|
284
|
+
// if (seqM.mt == "Branch")
|
|
285
|
+
// return org.helm.webeditor.HELM.BASE;
|
|
286
|
+
// if (seqM.mt == "Backbone") {
|
|
287
|
+
// if (seqM.na == "P" || seqM.na == "p")
|
|
288
|
+
// return org.helm.webeditor.HELM.LINKER;
|
|
289
|
+
// else
|
|
290
|
+
// return org.helm.webeditor.HELM.SUGAR;
|
|
291
|
+
// }
|
|
292
|
+
// }
|
|
293
|
+
// throw new Error(`Not supported seq monomer ${JSON.stringify(seqM)}.`);
|
|
294
|
+
// }
|
|
295
|
+
private toHelmType(polymerType: PolymerType, monomerType: MonomerType, naturalAnalog?: string) {
|
|
296
|
+
if (polymerType == PolymerTypes.PEPTIDE)
|
|
297
|
+
return org.helm.webeditor.HELM.AA;
|
|
298
|
+
else if (polymerType == PolymerTypes.CHEM)
|
|
299
|
+
return org.helm.webeditor.HELM.CHEM;
|
|
300
|
+
else if (polymerType == PolymerTypes.RNA) {
|
|
301
|
+
if (monomerType == MonomerTypes.BRANCH)
|
|
302
|
+
return org.helm.webeditor.HELM.BASE;
|
|
303
|
+
if (monomerType == MonomerTypes.BACKBONE) {
|
|
304
|
+
if (naturalAnalog == 'P' || naturalAnalog == 'p')
|
|
305
|
+
return org.helm.webeditor.HELM.LINKER;
|
|
306
|
+
else
|
|
307
|
+
return org.helm.webeditor.HELM.SUGAR;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
throw new Error(`Not supported monomer polymerType: '${polymerType}', monomerType: '${monomerType}'.`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
public getHoveredAtom(x: number, y: number, mol: HelmMol, height: number): HelmAtom | null {
|
|
314
|
+
return getHoveredMonomerFromEditorMol(x, y, mol, height);
|
|
315
|
+
}
|
|
124
316
|
}
|
package/src/helm-web-editor.ts
CHANGED
|
@@ -6,19 +6,19 @@ import {Unsubscribable} from 'rxjs';
|
|
|
6
6
|
|
|
7
7
|
import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
|
|
8
8
|
import {
|
|
9
|
-
App, Editor, HelmType, IHelmWebEditor
|
|
9
|
+
App, Editor, HelmType, IHelmWebEditor, HelmEditor, IHelmDrawOptions
|
|
10
10
|
} from '@datagrok-libraries/bio/src/helm/types';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import {JSDraw2Module, OrgHelmModule, ScilModule} from './types';
|
|
13
13
|
|
|
14
14
|
import {_package} from './package';
|
|
15
15
|
|
|
16
16
|
declare const scil: ScilModule;
|
|
17
|
-
declare const JSDraw2:
|
|
17
|
+
declare const JSDraw2: JSDraw2Module;
|
|
18
18
|
declare const org: OrgHelmModule;
|
|
19
19
|
|
|
20
20
|
export class HelmWebEditor implements IHelmWebEditor {
|
|
21
|
-
editor:
|
|
21
|
+
editor: HelmEditor;
|
|
22
22
|
host: HTMLDivElement;
|
|
23
23
|
|
|
24
24
|
w = 200;
|
|
@@ -27,10 +27,19 @@ export class HelmWebEditor implements IHelmWebEditor {
|
|
|
27
27
|
|
|
28
28
|
constructor(
|
|
29
29
|
host?: HTMLDivElement,
|
|
30
|
+
drawOptions?: Partial<IHelmDrawOptions>,
|
|
30
31
|
private logger: ILogger = _package.logger
|
|
31
32
|
) {
|
|
32
33
|
this.host = host ?? ui.div([], {style: {width: `${this.w}px`, height: `${this.h}px`}});
|
|
33
|
-
|
|
34
|
+
|
|
35
|
+
const styleBackup = {width: this.host.style.width, height: this.host.style.height, overflow: this.host.style.overflow};
|
|
36
|
+
this.editor = new JSDraw2.Editor(this.host, {
|
|
37
|
+
width: this.w, height: this.h, viewonly: true,
|
|
38
|
+
drawOptions: drawOptions
|
|
39
|
+
});
|
|
40
|
+
this.host.style.width = styleBackup.width;
|
|
41
|
+
this.host.style.height = styleBackup.height;
|
|
42
|
+
this.host.style.overflow = styleBackup.overflow;
|
|
34
43
|
|
|
35
44
|
this.subs = [];
|
|
36
45
|
this.subs.push(ui.onSizeChanged(this.host).subscribe(this.hostOnSizeChanged.bind(this)));
|
|
@@ -40,38 +49,19 @@ export class HelmWebEditor implements IHelmWebEditor {
|
|
|
40
49
|
return `Helm: HelmWebEditor<#>`;
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
private lastSize: { width: number, height: number } = {width: -1, height: -1};
|
|
53
|
+
|
|
54
|
+
private hostOnSizeChanged(value: any): void {
|
|
55
|
+
const size = {width: value.target.clientWidth, height: value.target.clientHeight};
|
|
56
|
+
if (this.lastSize.width != size.width || this.lastSize.height != size.height) {
|
|
57
|
+
const logPrefix = `${this.toLog()}.hostOnSizeChanged()`;
|
|
58
|
+
this.logger.debug(`${logPrefix}`);
|
|
59
|
+
this.editor.setSize(this.host.clientWidth, this.host.clientHeight);
|
|
60
|
+
}
|
|
61
|
+
this.lastSize = size;
|
|
47
62
|
}
|
|
48
63
|
|
|
49
64
|
resizeEditor(w: number, h: number) {
|
|
50
65
|
this.editor.setSize(w, h);
|
|
51
66
|
}
|
|
52
67
|
}
|
|
53
|
-
|
|
54
|
-
export function buildWebEditorApp(view: HTMLDivElement): App {
|
|
55
|
-
org.helm.webeditor.MolViewer.molscale = 0.8;
|
|
56
|
-
const app = new org.helm.webeditor.App(view, {
|
|
57
|
-
showabout: false,
|
|
58
|
-
mexfontsize: '90%',
|
|
59
|
-
mexrnapinontab: true,
|
|
60
|
-
topmargin: 20,
|
|
61
|
-
mexmonomerstab: true,
|
|
62
|
-
sequenceviewonly: false,
|
|
63
|
-
mexfavoritefirst: true,
|
|
64
|
-
mexfilter: true
|
|
65
|
-
});
|
|
66
|
-
const sizes = app.calculateSizes();
|
|
67
|
-
app.canvas!.resize(sizes.rightwidth - 100, sizes.topheight - 210);
|
|
68
|
-
let s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
|
|
69
|
-
scil.apply(app.sequence.style, s);
|
|
70
|
-
scil.apply(app.notation!.style, s);
|
|
71
|
-
s = {width: sizes.rightwidth + 'px', height: (sizes.bottomheight + app.toolbarheight) + 'px'};
|
|
72
|
-
scil.apply(app.properties!.parent.style, s);
|
|
73
|
-
app.structureview!.resize(sizes.rightwidth, sizes.bottomheight + app.toolbarheight);
|
|
74
|
-
app.mex!.resize(sizes.topheight - 80);
|
|
75
|
-
|
|
76
|
-
return app;
|
|
77
|
-
}
|