@datagrok/helm 2.0.9 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/package.ts CHANGED
@@ -2,32 +2,68 @@
2
2
  import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
- import * as bio from '@datagrok-libraries/bio';
6
5
 
7
- import {createJsonMonomerLibFromSdf} from './utils';
8
- import {MONOMER_MANAGER_MAP, RGROUPS, RGROUP_CAP_GROUP_NAME, RGROUP_LABEL, SMILES} from './constants';
6
+ import {WebEditorMonomer, RGROUP_CAP_GROUP_NAME, RGROUP_LABEL, SMILES} from './constants';
9
7
  import {HelmWebEditor} from './helm-web-editor';
10
- import {Observable, Subject} from 'rxjs';
8
+ import {NotationConverter, IMonomerLib, Monomer} from '@datagrok-libraries/bio';
9
+ import {HelmCellRenderer} from './cell-renderer';
11
10
 
12
11
  export const _package = new DG.Package();
13
-
14
- const STORAGE_NAME = 'Libraries';
15
- const LIB_PATH = 'libraries/';
12
+ let monomerLib: IMonomerLib | null = null;
16
13
 
17
14
  //tags: init
18
15
  export async function initHelm(): Promise<void> {
19
- return new Promise(async (resolve, reject) => {
16
+ return Promise.all([new Promise((resolve, reject) => {
20
17
  // @ts-ignore
21
18
  dojo.ready(function() { resolve(null); });
22
- await loadLibraries();
19
+ }), await grok.functions.call('Bio:getBioLib')]).then(([_, lib]: [void, IMonomerLib]) => {
20
+ monomerLib = lib;
21
+ rewriteLibraries();
22
+ monomerLib.onChanged.subscribe((_) => {
23
+ rewriteLibraries();
24
+ })
23
25
  });
24
26
  }
25
27
 
28
+ function rewriteLibraries() {
29
+ org.helm.webeditor.Monomers.clear();
30
+ monomerLib.getTypes().forEach(type => {
31
+ const mms = monomerLib.getMonomerNamesByType(type);
32
+ mms.forEach(symbol => {
33
+ let isBroken = false;
34
+ const monomer: Monomer = monomerLib.getMonomer(type, symbol);
35
+ const webEditorMonomer: WebEditorMonomer = {
36
+ id: symbol,
37
+ m: monomer.molfile,
38
+ n: monomer.name,
39
+ na: monomer.naturalAnalog,
40
+ rs: monomer.rgroups.length,
41
+ type: monomer.polymerType,
42
+ mt: monomer.monomerType,
43
+ at: {}
44
+ };
45
+
46
+ if(monomer.rgroups.length > 0) {
47
+ webEditorMonomer.rs = monomer.rgroups.length;
48
+ const at = {};
49
+ monomer.rgroups.forEach(it => {
50
+ at[it[RGROUP_LABEL]] = it[RGROUP_CAP_GROUP_NAME];
51
+ });
52
+ webEditorMonomer.at = at;
53
+ } else if (monomer.data[SMILES] != null){
54
+ webEditorMonomer.rs = Object.keys(getRS(monomer.data[SMILES].toString())).length;
55
+ webEditorMonomer.at = getRS(monomer.data[SMILES].toString());
56
+ } else
57
+ isBroken = true;
58
+
59
+ if(!isBroken)
60
+ org.helm.webeditor.Monomers.addOneMonomer(webEditorMonomer);
61
+ });
62
+ });
26
63
 
27
- async function loadLibraries() {
28
- let uploadedLibraries: string[] = Object.values(await grok.dapi.userDataStorage.get(STORAGE_NAME, true));
29
- for (let i = 0; i < uploadedLibraries.length; ++i)
30
- await monomerManager(uploadedLibraries[i]);
64
+ // Obsolete
65
+ let grid: DG.Grid = grok.shell.tv.grid;
66
+ grid.invalidate();
31
67
  }
32
68
 
33
69
  //name: helmCellRenderer
@@ -39,57 +75,12 @@ export function helmCellRenderer(): HelmCellRenderer {
39
75
  return new HelmCellRenderer();
40
76
  }
41
77
 
42
-
43
- function webEditor(cell?: DG.GridCell, value?: string) {
44
- let view = ui.div();
45
- org.helm.webeditor.MolViewer.molscale = 0.8;
46
- let app = new scil.helm.App(view, {
47
- showabout: false,
48
- mexfontsize: '90%',
49
- mexrnapinontab: true,
50
- topmargin: 20,
51
- mexmonomerstab: true,
52
- sequenceviewonly: false,
53
- mexfavoritefirst: true,
54
- mexfilter: true
55
- });
56
- var sizes = app.calculateSizes();
57
- app.canvas.resize(sizes.rightwidth - 100, sizes.topheight - 210);
58
- var s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
59
- //@ts-ignore
60
- scil.apply(app.sequence.style, s);
61
- //@ts-ignore
62
- scil.apply(app.notation.style, s);
63
- s = {width: sizes.rightwidth + 'px', height: (sizes.bottomheight + app.toolbarheight) + 'px'};
64
- //@ts-ignore
65
- scil.apply(app.properties.parent.style, s);
66
- app.structureview.resize(sizes.rightwidth, sizes.bottomheight + app.toolbarheight);
67
- app.mex.resize(sizes.topheight - 80);
68
- setTimeout(function() {
69
- if (typeof cell !== 'undefined') {
70
- app.canvas.helm.setSequence(cell.cell.value, 'HELM');
71
- } else {
72
- app.canvas.helm.setSequence(value, 'HELM');
73
- }
74
- }, 200);
75
- //@ts-ignore
76
- ui.dialog({showHeader: false, showFooter: true})
77
- .add(view)
78
- .onOK(() => {
79
- if (typeof cell !== 'undefined') {
80
- cell.cell.value = app.canvas.getHelm(true).replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
81
- }
82
- }).show({modal: true, fullScreen: true});
83
- }
84
-
85
-
86
78
  //tags: cellEditor
87
79
  //description: Macromolecule
88
80
  //input: grid_cell cell
89
81
  export function editMoleculeCell(cell: DG.GridCell): void {
90
- if (cell.gridColumn.column.tags[DG.TAGS.UNITS] === 'helm') {
82
+ if (cell.gridColumn.column.tags[DG.TAGS.UNITS] === 'helm')
91
83
  webEditor(cell);
92
- }
93
84
  }
94
85
 
95
86
  //name: Open Helm Web Editor
@@ -98,7 +89,7 @@ export function editMoleculeCell(cell: DG.GridCell): void {
98
89
  //input: string mol { semType: Macromolecule }
99
90
  export function openEditor(mol: string): void {
100
91
  let df = grok.shell.tv.grid.dataFrame;
101
- let converter = new bio.NotationConverter(df.columns.bySemType('Macromolecule'));
92
+ let converter = new NotationConverter(df.columns.bySemType('Macromolecule'));
102
93
  const resStr = converter.convertStringToHelm(mol, '/');
103
94
  webEditor(undefined, resStr);
104
95
  }
@@ -129,50 +120,48 @@ export async function propertiesPanel(helmString: string) {
129
120
  );
130
121
  }
131
122
 
132
-
133
- //name: Manage Libraries
134
- //tags: panel, widgets
135
- //input: column helmColumn {semType: Macromolecule}
136
- //output: widget result
137
- export async function libraryPanel(helmColumn: DG.Column): Promise<DG.Widget> {
123
+ function webEditor(cell?: DG.GridCell, value?: string) {
124
+ let view = ui.div();
125
+ org.helm.webeditor.MolViewer.molscale = 0.8;
126
+ let app = new scil.helm.App(view, {
127
+ showabout: false,
128
+ mexfontsize: '90%',
129
+ mexrnapinontab: true,
130
+ topmargin: 20,
131
+ mexmonomerstab: true,
132
+ sequenceviewonly: false,
133
+ mexfavoritefirst: true,
134
+ mexfilter: true
135
+ });
136
+ var sizes = app.calculateSizes();
137
+ app.canvas.resize(sizes.rightwidth - 100, sizes.topheight - 210);
138
+ var s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
138
139
  //@ts-ignore
139
- let filesButton: HTMLButtonElement = ui.button('Manage', manageFiles);
140
- let divInputs: HTMLDivElement = ui.div();
141
- let librariesList: string[] = (await _package.files.list(`${LIB_PATH}`, false, '')).map(it => it.fileName);
142
- let uploadedLibraries: string[] = Object.values(await grok.dapi.userDataStorage.get(STORAGE_NAME, true));
143
- for (let i = 0; i < uploadedLibraries.length; ++i) {
144
- let libraryName: string = uploadedLibraries[i];
145
- divInputs.append(ui.boolInput(libraryName, true, async v => {
146
- org.helm.webeditor.Monomers.clear();
147
- grok.dapi.userDataStorage.remove(STORAGE_NAME, libraryName, true);
148
- await loadLibraries();
149
- grok.shell.tv.grid.invalidate();
150
- }).root);
151
- }
152
- let unusedLibraries: string[] = librariesList.filter(x => !uploadedLibraries.includes(x));
153
- for (let i = 0; i < unusedLibraries.length; ++i) {
154
- let libraryName: string = unusedLibraries[i];
155
- divInputs.append(ui.boolInput(libraryName, false, v => {
156
- monomerManager(libraryName);
157
- grok.dapi.userDataStorage.postValue(STORAGE_NAME, libraryName, libraryName, true);
158
- }).root);
159
- }
160
- return new DG.Widget(ui.splitV([
161
- divInputs,
162
- ui.divV([filesButton])
163
- ]));
164
- }
165
-
166
- //name: manageFiles
167
- export async function manageFiles() {
168
- const a = ui.dialog({title: 'Manage files'})
169
- //@ts-ignore
170
- .add(ui.fileBrowser({path: 'System:AppData/Helm/libraries'}).root)
171
- .addButton('OK', () => a.close())
172
- .show();
140
+ scil.apply(app.sequence.style, s);
141
+ //@ts-ignore
142
+ scil.apply(app.notation.style, s);
143
+ s = {width: sizes.rightwidth + 'px', height: (sizes.bottomheight + app.toolbarheight) + 'px'};
144
+ //@ts-ignore
145
+ scil.apply(app.properties.parent.style, s);
146
+ app.structureview.resize(sizes.rightwidth, sizes.bottomheight + app.toolbarheight);
147
+ app.mex.resize(sizes.topheight - 80);
148
+ setTimeout(function() {
149
+ if (typeof cell !== 'undefined') {
150
+ app.canvas.helm.setSequence(cell.cell.value, 'HELM');
151
+ } else {
152
+ app.canvas.helm.setSequence(value, 'HELM');
153
+ }
154
+ }, 200);
155
+ //@ts-ignore
156
+ ui.dialog({showHeader: false, showFooter: true})
157
+ .add(view)
158
+ .onOK(() => {
159
+ if (typeof cell !== 'undefined') {
160
+ cell.cell.value = app.canvas.getHelm(true).replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
161
+ }
162
+ }).show({modal: true, fullScreen: true});
173
163
  }
174
164
 
175
-
176
165
  async function accessServer(url: string, key: string) {
177
166
  const params: RequestInit = {
178
167
  method: 'GET',
@@ -185,7 +174,6 @@ async function accessServer(url: string, key: string) {
185
174
  return json[key];
186
175
  }
187
176
 
188
-
189
177
  //name: helmToFasta
190
178
  //input: string helmString {semType: Macromolecule}
191
179
  //output: string res
@@ -203,7 +191,6 @@ export async function helmToRNA(helmString: string) {
203
191
  return await accessServer(url, 'Sequence');
204
192
  }
205
193
 
206
-
207
194
  //name: helmToPeptide
208
195
  //description: converts to peptide analogue sequence
209
196
  //input: string helmString {semType: Macromolecule}
@@ -244,262 +231,6 @@ function getRS(smiles: string) {
244
231
  return res;
245
232
  }
246
233
 
247
- //name: monomerManager
248
- //input: string value
249
- export async function monomerManager(value: string) {
250
- let df: any[];
251
- let file;
252
- let dfSdf;
253
- if (value.endsWith('.sdf')) {
254
- const funcList: DG.Func[] = DG.Func.find({package: 'Chem', name: 'importSdf'});
255
- console.debug(`Helm: initHelm() funcList.length = ${funcList.length}`);
256
- if (funcList.length === 1) {
257
- file = await _package.files.readAsBytes(`${LIB_PATH}${value}`);
258
- dfSdf = await grok.functions.call('Chem:importSdf', {bytes: file});
259
- df = createJsonMonomerLibFromSdf(dfSdf[0]);
260
- } else {
261
- grok.shell.warning('Chem package is not installed');
262
- }
263
- } else {
264
- const file = await _package.files.readAsText(`${LIB_PATH}${value}`);
265
- df = JSON.parse(file);
266
- }
267
-
268
- df.forEach(monomer => {
269
- const m = {};
270
- Object.keys(MONOMER_MANAGER_MAP).forEach(field => {
271
- m[field] = monomer[MONOMER_MANAGER_MAP[field]] ?? '';
272
- });
273
- if (monomer[RGROUPS]) {
274
- m['rs'] = monomer[RGROUPS].length;
275
- const at = {};
276
- monomer[RGROUPS].forEach(it => {
277
- at[it[RGROUP_LABEL]] = it[RGROUP_CAP_GROUP_NAME];
278
- });
279
- m['at'] = at;
280
- } else {
281
- m['rs'] = Object.keys(getRS(df[SMILES].toString())).length;
282
- m['at'] = getRS(df[SMILES].toString());
283
- }
284
- org.helm.webeditor.Monomers.addOneMonomer(m);
285
- });
286
-
287
- // Now after updating org.helm.webeditor.Monomers we update MonomerLib window singleton (fires onChanged event)
288
- (getMonomerLibObj() as MonomerLib).update(getAllLibsData());
289
- //grok.events.fireCustomEvent('monomersLibChanged', null);
290
-
291
- // Obsolete
292
- let grid: DG.Grid = grok.shell.tv.grid;
293
- grid.invalidate();
294
- }
295
-
296
- //name: helmColumnToSmiles
297
- //input: column helmColumn {semType: Macromolecule}
298
- export function helmColumnToSmiles(helmColumn: DG.Column) {
299
- //todo: add column with smiles to col.dataFrame.
300
- }
301
-
302
-
303
- function split(s: string, sep: string) {
304
- var ret = [];
305
- var frag = '';
306
- var parentheses = 0;
307
- var bracket = 0;
308
- var braces = 0;
309
- var quote = 0;
310
- for (var i = 0; i < s.length; ++i) {
311
- var c = s.substring(i, i + 1);
312
- if (c == sep && bracket == 0 && parentheses == 0 && braces == 0 && quote == 0) {
313
- ret.push(frag);
314
- frag = '';
315
- } else {
316
- frag += c;
317
- if (quote > 0) {
318
- if (c == '\\' && i + 1 < s.length) {
319
- ++i;
320
- var c2 = s.substring(i, i + 1);
321
- frag += c2;
322
- c += c2;
323
- }
324
- }
325
- if (c == '\"') {
326
- if (!(i > 0 && s.substring(i - 1, i) == '\\'))
327
- quote = quote == 0 ? 1 : 0;
328
- } else if (c == '[')
329
- ++bracket;
330
- else if (c == ']')
331
- --bracket;
332
- else if (c == '(')
333
- ++parentheses;
334
- else if (c == ')')
335
- --parentheses;
336
- else if (c == '{')
337
- ++braces;
338
- else if (c == '}')
339
- --braces;
340
- }
341
- }
342
- ret.push(frag);
343
- return ret;
344
- }
345
-
346
- function detachAnnotation(s: string) {
347
- var ret = _detachAppendix(s, '\"');
348
- if (ret.tag != null)
349
- return ret;
350
-
351
- var r = _detachAppendix(s, '\'');
352
- return {tag: ret.tag, repeat: r.tag, str: r.str};
353
- }
354
-
355
- function _detachAppendix(s: string, c: string) {
356
- var tag = null;
357
- //@ts-ignore
358
- if (scil.Utils.endswith(s, c)) {
359
- var p = s.length - 1;
360
- while (p > 0) {
361
- p = s.lastIndexOf(c, p - 1);
362
- if (p <= 0 || s.substring(p - 1, p) != '\\')
363
- break;
364
- }
365
-
366
- if (p > 0 && p < s.length - 1) {
367
- tag = s.substring(p + 1, s.length - 1);
368
- s = s.substring(0, p);
369
- }
370
- }
371
- if (tag != null)
372
- tag = tag.replace(new RegExp('\\' + c, 'g'), c);
373
- return {tag: unescape(tag), str: s};
374
- }
375
-
376
- function unescape(s: string) {
377
- //@ts-ignore
378
- if (scil.Utils.isNullOrEmpty(s))
379
- return s;
380
-
381
- return s.replace(/[\\]./g, function(m) {
382
- switch (m) {
383
- case '\\r':
384
- return '\r';
385
- case '\\n':
386
- return '\n';
387
- case '\\t':
388
- return '\t';
389
- default:
390
- return m.substring(1);
391
- }
392
- });
393
- }
394
-
395
- //name: parseHelm
396
- //input: string s
397
- export function parseHelm(s: string) {
398
- var sections = split(s, '$');
399
- s = sections[0];
400
- var monomers = [];
401
- //@ts-ignore
402
- if (!scil.Utils.isNullOrEmpty(s)) {
403
- var seqs = split(s, '|');
404
- for (var i = 0; i < seqs.length; ++i) {
405
- var e = detachAnnotation(seqs[i]);
406
- s = e.str;
407
-
408
- var p = s.indexOf('{');
409
-
410
- s = s.substring(p + 1);
411
- p = s.indexOf('}');
412
- s = s.substring(0, p);
413
-
414
- var ss = split(s, '.');
415
- for (var monomer of ss) {
416
- if (monomer.includes('(') && monomer.includes(')')) {
417
- var elements = monomer.replace(/[()]/g, '').split('');
418
- for (var el of elements) {
419
- monomers.push(el);
420
- }
421
- } else if (monomer.includes('[') && monomer.includes(']')) {
422
- var element = monomer.match(/(?<=\[).*?(?=\])/g, '');
423
- monomers.push(element[0]);
424
- } else {
425
- monomers.push(monomer);
426
- }
427
- }
428
- }
429
- }
430
- return monomers;
431
- }
432
-
433
- //name: findMonomers
434
- //input: string helmString
435
- export function findMonomers(helmString: string) {
436
- //@ts-ignore
437
- const types = Object.keys(org.helm.webeditor.monomerTypeList());
438
- const monomers: any = [];
439
- const monomer_names: any = [];
440
- for (var i = 0; i < types.length; i++) {
441
- //@ts-ignore
442
- monomers.push(new scil.helm.Monomers.getMonomerSet(types[i]));
443
- Object.keys(monomers[i]).forEach(k => {
444
- monomer_names.push(monomers[i][k].id);
445
- });
446
- }
447
- const split_string = parseHelm(helmString);
448
- return new Set(split_string.filter(val => !monomer_names.includes(val)));
449
- }
450
-
451
-
452
- class MonomerLib implements bio.IMonomerLib {
453
- private _monomers: { [type: string]: { [name: string]: bio.Monomer } };
454
- private _onChanged = new Subject<any>();
455
-
456
- get(monomerType: string, monomerName: string): bio.Monomer | null {
457
- if (monomerType in this._monomers && monomerName in this._monomers[monomerType])
458
- return this._monomers[monomerType][monomerName];
459
- else
460
- return null;
461
- }
462
-
463
- get onChanged(): Observable<any> {
464
- return this._onChanged;
465
- }
466
-
467
- get types(): bio.MonomerType[] {
468
- return Object.keys(this._monomers) as bio.MonomerType[];
469
- }
470
-
471
- public update(monomers: { [type: string]: { [name: string]: bio.Monomer } }): void {
472
- this._monomers = monomers;
473
- this._onChanged.next();
474
- }
475
- }
476
-
477
- function getAllLibsData(): { [type: string]: { [name: string]: bio.Monomer } } {
478
- //@ts-ignore
479
- const types = Object.keys(org.helm.webeditor.monomerTypeList());
480
- //const monomers: any = [];
481
- const monomers: { [type: string]: { [name: string]: bio.Monomer } } = {};
482
- for (let i = 0; i < types.length; i++) {
483
- monomers[types[i]] = new scil.helm.Monomers.getMonomerSet(types[i]);
484
- //@ts-ignore
485
- //monomers.push(new scil.helm.Monomers.getMonomerSet(types[i]));
486
- }
487
-
488
- return monomers;
489
- }
490
-
491
- //name: getMonomerLibObj
492
- //description: Get object of IMonomerLib interface (singleton)
493
- //output: object result
494
- export function getMonomerLibObj(): bio.IMonomerLib {
495
- if (!('monomerLib' in window)) {
496
- window['monomerLib'] = new MonomerLib();
497
- window['monomerLib'].update(getAllLibsData()); // TODO: refactor
498
- }
499
-
500
- return window['monomerLib'];
501
- }
502
-
503
234
  //name: getMolfiles
504
235
  //input: column col {semType: Macromolecule}
505
236
  //output: column res
@@ -521,132 +252,6 @@ export function getMolfiles(col: DG.Column): DG.Column {
521
252
  return res;
522
253
  }
523
254
 
524
- function getParts(subParts: string[], s: string): string[] {
525
- let j = 0;
526
- let allParts: string[] = [];
527
- for (let k = 0; k < subParts.length; ++k) {
528
- let indexOfMonomer = s.indexOf(subParts[k]);
529
- let helmBeforeMonomer = s.slice(j, indexOfMonomer);
530
- allParts.push(helmBeforeMonomer);
531
- allParts.push(subParts[k]);
532
- s = s.substring(indexOfMonomer + subParts[k].length);
533
- }
534
- allParts.push(s);
535
- return allParts;
536
- }
537
-
538
- class HelmCellRenderer extends DG.GridCellRenderer {
539
- get name() { return 'helm'; }
540
-
541
- get cellType() { return 'helm'; }
542
-
543
- get defaultWidth(): number | null { return 400; }
544
-
545
- get defaultHeight(): number | null { return 100; }
546
-
547
- onMouseMove(gridCell: DG.GridCell, e: MouseEvent): void {
548
- const maxLengthWordsSum = gridCell.cell.column.temp['helm-sum-maxLengthWords'];
549
- const maxIndex = Object.values(gridCell.cell.column.temp['helm-maxLengthWords']).length - 1;
550
- const argsX = e.offsetX - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCell.bounds.x);
551
- let left = 0;
552
- let right = maxIndex;
553
- let found = false;
554
- maxLengthWordsSum[maxIndex + 1] = argsX + 1;
555
- let mid = 0;
556
- if (argsX > maxLengthWordsSum[0]) {
557
- while (!found) {
558
- mid = Math.floor((right + left) / 2);
559
- if (argsX >= maxLengthWordsSum[mid] && argsX <= maxLengthWordsSum[mid + 1]) {
560
- left = mid;
561
- found = true;
562
- } else if (argsX < maxLengthWordsSum[mid]) {
563
- right = mid - 1;
564
- } else if (argsX > maxLengthWordsSum[mid + 1]) {
565
- left = mid + 1;
566
- }
567
- if (left == right) {
568
- found = true;
569
- }
570
- }
571
- }
572
- left = (argsX >= maxLengthWordsSum[left]) ? left + 1 : left;
573
- const monomers = findMonomers(gridCell.cell.value);
574
- let s: string = gridCell.cell.value ?? '';
575
- let subParts: string[] = parseHelm(s);
576
- let allParts: string[] = getParts(subParts, s);
577
- let tooltipMessage: HTMLElement[] = [];
578
- for (let i = 0; i < allParts.length; ++i) {
579
- if (monomers.has(allParts[i]))
580
- tooltipMessage[i] = ui.divV([
581
- ui.divText(`Monomer ${allParts[i]} not found.`),
582
- ui.divText('Open the Property Panel, then expand Manage Libraries')
583
- ]);
584
- }
585
- (((tooltipMessage[left]?.childNodes.length ?? 0) > 0))
586
- ? ui.tooltip.show(ui.div(tooltipMessage[left]), e.x + 16, e.y + 16)
587
- : ui.tooltip.hide();
588
- }
589
-
590
- render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
591
- gridCell: DG.GridCell, cellStyle: DG.GridCellStyle
592
- ) {
593
- const grid = gridCell.gridRow !== -1 ? gridCell.grid : undefined;
594
- const undefinedColor = 'rgb(100,100,100)';
595
- const grayColor = '#808080';
596
- const monomers = findMonomers(gridCell.cell.value);
597
- let s: string = gridCell.cell.value ?? '';
598
- let subParts: string[] = parseHelm(s);
599
- if (monomers.size == 0) {
600
- const host = ui.div([], {style: {width: `${w}px`, height: `${h}px`}});
601
- host.setAttribute('dataformat', 'helm');
602
- host.setAttribute('data', gridCell.cell.value);
603
- gridCell.element = host;
604
- //@ts-ignore
605
- const canvas = new JSDraw2.Editor(host, {width: w, height: h, skin: 'w8', viewonly: true});
606
- return;
607
- }
608
- if (monomers.size > 0) {
609
- w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
610
- g.save();
611
- g.beginPath();
612
- g.rect(x, y, w, h);
613
- g.clip();
614
- g.font = '12px monospace';
615
- g.textBaseline = 'top';
616
- let x1 = x;
617
- let maxLengthWords: any = {};
618
- let maxLengthWordSum: any = {};
619
- let allParts: string[] = getParts(subParts, s);
620
- for (let i = 0; i < allParts.length; ++i) {
621
- maxLengthWords[i] = allParts[i].length * 7;
622
- let color = monomers.has(allParts[i]) ? 'red' : grayColor;
623
- g.fillStyle = undefinedColor;
624
- x1 = bio.printLeftOrCentered(x1, y, w, h, g, allParts[i], color, 0, true, 1.0);
625
- }
626
-
627
- maxLengthWordSum[0] = maxLengthWords[0];
628
- for (let i = 1; i < allParts.length; i++) {
629
- maxLengthWordSum[i] = maxLengthWordSum[i - 1] + maxLengthWords[i];
630
- }
631
- gridCell.cell.column.temp = {
632
- 'helm-sum-maxLengthWords': maxLengthWordSum,
633
- 'helm-maxLengthWords': maxLengthWords
634
- };
635
- g.restore();
636
- return;
637
- }
638
- }
639
- }
640
-
641
- //name: getMonomerLib
642
- //input: string type
643
- //output: string monomerSetJSON
644
- export function getMonomerLib(type: string): string {
645
- // TODO: deprecate
646
- return JSON.stringify(scil.helm.Monomers.getMonomerSet(type));
647
- }
648
-
649
-
650
255
  //name: helmWebEditor
651
256
  //output: object
652
257
  export function helmWebEditor(): HelmWebEditor {
@@ -1,7 +1,7 @@
1
1
  import {after, before, category, delay, expect, test} from '@datagrok-libraries/utils/src/test';
2
2
  //import {findMonomers, helmToFasta, helmToPeptide, helmToRNA, initHelm} from '../package';
3
3
  import {_package} from '../package-test';
4
- import {manageFiles, parseHelm} from '../package';
4
+ import {parseHelm} from '../utils';
5
5
  import * as DG from 'datagrok-api/dg';
6
6
  import * as grok from 'datagrok-api/grok';
7
7
 
@@ -46,31 +46,6 @@ category('Helm', () => {
46
46
  // expect(col.tags[DG.TAGS.UNITS], 'HELM');
47
47
  // });
48
48
 
49
- test('manageFiles', async () => {
50
- return await manageFiles();
51
- });
52
-
53
-
54
- test('monomerManager', async() => {
55
- const df: DG.DataFrame = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/test.csv'));
56
- grok.shell.addTableView(df);
57
- await grok.functions.call('Helm:monomerManager', {value: 'HELMCoreLibrary.json'});
58
- const checkName = '2-Chloroadenine';
59
- let flag = false;
60
- const types = Object.keys(org.helm.webeditor.monomerTypeList());
61
- const monomers: any = [];
62
- for (var i = 0; i < types.length; i++) {
63
- //@ts-ignore
64
- monomers.push(new scil.helm.Monomers.getMonomerSet(types[i]));
65
- Object.keys(monomers[i]).forEach(k => {
66
- if (monomers[i][k].n == checkName){
67
- flag = true;
68
- }
69
- });
70
- }
71
- expect(flag, true);
72
- });
73
-
74
49
  test('parseHelm', async() => {
75
50
  const expectedResults = [
76
51
  ['meI', 'hHis', 'Aca', 'N', 'T', 'dK', 'Thr_PO3H2', 'D-Tyr_Et', 'Aze', 'dV', 'E', 'Phe_4Me'],
@@ -90,5 +65,4 @@ category('Helm', () => {
90
65
  expect(JSON.stringify(monomerArray), JSON.stringify(expectedResults[idx]));
91
66
  }
92
67
  });
93
-
94
68
  });