@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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/helm",
3
3
  "friendlyName": "Helm",
4
- "version": "2.0.9",
4
+ "version": "2.1.0",
5
5
  "author": {
6
6
  "name": "Oleksandra Serhiienko",
7
7
  "email": "oserhiienko@datagrok.ai"
@@ -9,7 +9,7 @@
9
9
  "description": "",
10
10
  "dependencies": {
11
11
  "@datagrok-libraries/utils": "^1.11.1",
12
- "@datagrok-libraries/bio": "^5.9.2",
12
+ "@datagrok-libraries/bio": "^5.9.14",
13
13
  "cash-dom": "^8.1.1",
14
14
  "datagrok-api": "^1.7.2",
15
15
  "dayjs": "^1.10.6",
@@ -0,0 +1,110 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import {findMonomers, parseHelm, getParts} from './utils';
6
+ import {printLeftOrCentered} from '@datagrok-libraries/bio';
7
+
8
+
9
+ export class HelmCellRenderer extends DG.GridCellRenderer {
10
+ get name() { return 'helm'; }
11
+
12
+ get cellType() { return 'helm'; }
13
+
14
+ get defaultWidth(): number | null { return 400; }
15
+
16
+ get defaultHeight(): number | null { return 100; }
17
+
18
+ onMouseMove(gridCell: DG.GridCell, e: MouseEvent): void {
19
+ const maxLengthWordsSum = gridCell.cell.column.temp['helm-sum-maxLengthWords'];
20
+ const maxIndex = Object.values(gridCell.cell.column.temp['helm-maxLengthWords']).length - 1;
21
+ const argsX = e.offsetX - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCell.bounds.x);
22
+ let left = 0;
23
+ let right = maxIndex;
24
+ let found = false;
25
+ maxLengthWordsSum[maxIndex + 1] = argsX + 1;
26
+ let mid = 0;
27
+ if (argsX > maxLengthWordsSum[0]) {
28
+ while (!found) {
29
+ mid = Math.floor((right + left) / 2);
30
+ if (argsX >= maxLengthWordsSum[mid] && argsX <= maxLengthWordsSum[mid + 1]) {
31
+ left = mid;
32
+ found = true;
33
+ } else if (argsX < maxLengthWordsSum[mid]) {
34
+ right = mid - 1;
35
+ } else if (argsX > maxLengthWordsSum[mid + 1]) {
36
+ left = mid + 1;
37
+ }
38
+ if (left == right) {
39
+ found = true;
40
+ }
41
+ }
42
+ }
43
+ left = (argsX >= maxLengthWordsSum[left]) ? left + 1 : left;
44
+ const monomers = findMonomers(gridCell.cell.value);
45
+ let s: string = gridCell.cell.value ?? '';
46
+ let subParts: string[] = parseHelm(s);
47
+ let allParts: string[] = getParts(subParts, s);
48
+ let tooltipMessage: HTMLElement[] = [];
49
+ for (let i = 0; i < allParts.length; ++i) {
50
+ if (monomers.has(allParts[i]))
51
+ tooltipMessage[i] = ui.divV([
52
+ ui.divText(`Monomer ${allParts[i]} not found.`),
53
+ ui.divText('Open the Property Panel, then expand Manage Libraries')
54
+ ]);
55
+ }
56
+ (((tooltipMessage[left]?.childNodes.length ?? 0) > 0))
57
+ ? ui.tooltip.show(ui.div(tooltipMessage[left]), e.x + 16, e.y + 16)
58
+ : ui.tooltip.hide();
59
+ }
60
+
61
+ render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
62
+ gridCell: DG.GridCell, cellStyle: DG.GridCellStyle
63
+ ) {
64
+ const grid = gridCell.gridRow !== -1 ? gridCell.grid : undefined;
65
+ const undefinedColor = 'rgb(100,100,100)';
66
+ const grayColor = '#808080';
67
+ const monomers = findMonomers(gridCell.cell.value);
68
+ let s: string = gridCell.cell.value ?? '';
69
+ let subParts: string[] = parseHelm(s);
70
+ if (monomers.size == 0) {
71
+ const host = ui.div([], {style: {width: `${w}px`, height: `${h}px`}});
72
+ host.setAttribute('dataformat', 'helm');
73
+ host.setAttribute('data', gridCell.cell.value);
74
+ gridCell.element = host;
75
+ //@ts-ignore
76
+ const canvas = new JSDraw2.Editor(host, {width: w, height: h, skin: 'w8', viewonly: true});
77
+ return;
78
+ }
79
+ if (monomers.size > 0) {
80
+ w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
81
+ g.save();
82
+ g.beginPath();
83
+ g.rect(x, y, w, h);
84
+ g.clip();
85
+ g.font = '12px monospace';
86
+ g.textBaseline = 'top';
87
+ let x1 = x;
88
+ let maxLengthWords: any = {};
89
+ let maxLengthWordSum: any = {};
90
+ let allParts: string[] = getParts(subParts, s);
91
+ for (let i = 0; i < allParts.length; ++i) {
92
+ maxLengthWords[i] = allParts[i].length * 7;
93
+ let color = monomers.has(allParts[i]) ? 'red' : grayColor;
94
+ g.fillStyle = undefinedColor;
95
+ x1 = printLeftOrCentered(x1, y, w, h, g, allParts[i], color, 0, true, 1.0);
96
+ }
97
+
98
+ maxLengthWordSum[0] = maxLengthWords[0];
99
+ for (let i = 1; i < allParts.length; i++) {
100
+ maxLengthWordSum[i] = maxLengthWordSum[i - 1] + maxLengthWords[i];
101
+ }
102
+ gridCell.cell.column.temp = {
103
+ 'helm-sum-maxLengthWords': maxLengthWordSum,
104
+ 'helm-maxLengthWords': maxLengthWords
105
+ };
106
+ g.restore();
107
+ return;
108
+ }
109
+ }
110
+ }
package/src/constants.ts CHANGED
@@ -12,14 +12,16 @@ export const jsonSdfMonomerLibDict = {
12
12
  "symbol": "MonomerCode"
13
13
  }
14
14
 
15
- export const MONOMER_MANAGER_MAP = {
16
- 'id': 'symbol',
17
- 'n': 'name',
18
- 'na': 'naturalAnalog',
19
- 'type': 'polymerType',
20
- 'mt': 'monomerType',
21
- 'm': 'molfile',
22
- }
15
+ export type WebEditorMonomer = {
16
+ id: string, //symbol
17
+ n: string, //name
18
+ na: string, //natural analog
19
+ type: string, //polymer type
20
+ mt: string, //monomer type
21
+ m: string, //molfile
22
+ at: {[group: string]: string}, //substituents
23
+ rs: number //number of substituents
24
+ };
23
25
 
24
26
  export const SMILES = 'smiles';
25
27
  export const RGROUPS = "rgroups";