@datagrok/helm 2.5.3 → 2.5.5
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/.eslintrc.json +27 -6
- package/CHANGELOG.md +15 -1
- package/dist/455.js.map +1 -1
- 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 +16 -14
- package/src/helm-helper.ts +11 -9
- package/src/helm-web-editor.ts +8 -7
- package/src/package-test.ts +1 -1
- package/src/package-utils.ts +41 -18
- package/src/package.ts +15 -13
- package/src/tests/get-monomer-tests.ts +5 -10
- package/src/tests/helm-helper-tests.ts +6 -4
- package/src/tests/helm-service-tests.ts +2 -1
- package/src/tests/parse-helm-tests.ts +6 -6
- package/src/tests/properties-widget-tests.ts +17 -15
- package/src/utils/get-hovered.ts +1 -2
- package/src/utils/helm-grid-cell-renderer.ts +46 -26
- package/src/utils/helm-service.ts +32 -13
- package/src/widgets/helm-input.ts +2 -2
- package/src/widgets/properties-widget.ts +5 -3
|
@@ -8,22 +8,24 @@ import {HelmType, ISeqMonomer, Mol} from '@datagrok-libraries/bio/src/helm/types
|
|
|
8
8
|
import {
|
|
9
9
|
CellRendererBackAsyncBase, RenderServiceBase
|
|
10
10
|
} from '@datagrok-libraries/bio/src/utils/cell-renderer-async-base';
|
|
11
|
-
import {HelmAux, HelmProps} from '@datagrok-libraries/bio/src/viewers/helm-service';
|
|
12
|
-
import {_getHelmService} from '../package-utils';
|
|
11
|
+
import {HelmAux, HelmProps, HelmServiceBase} from '@datagrok-libraries/bio/src/viewers/helm-service';
|
|
13
12
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
14
13
|
import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
|
|
15
14
|
import {getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
16
|
-
import {
|
|
15
|
+
import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
16
|
+
import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
|
|
17
17
|
import {execMonomerHoverLinks} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
|
|
18
|
+
import {MmcrTemps} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
18
19
|
|
|
19
20
|
import {getHoveredMonomerFromEditorMol, getSeqMonomerFromHelmAtom} from './get-hovered';
|
|
20
21
|
|
|
21
|
-
import {_package} from '../package';
|
|
22
|
+
import {_package, getHelmService} from '../package';
|
|
22
23
|
|
|
23
24
|
export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProps, HelmAux> {
|
|
24
25
|
private _auxList: (HelmAux | null)[];
|
|
25
26
|
|
|
26
|
-
private
|
|
27
|
+
private sysMonomerLib: IMonomerLibBase | null = null;
|
|
28
|
+
private helmRenderService: HelmServiceBase | null = null;
|
|
27
29
|
|
|
28
30
|
// eslint-disable-next-line max-len
|
|
29
31
|
private readonly uuid: string = wu.repeat(1).map(() => Math.floor((Math.random() * 36)).toString(36)).take(4).toArray().join('');
|
|
@@ -35,23 +37,48 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
35
37
|
super(gridCol, tableCol, _package.logger, true);
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
public async init(): Promise<void> {
|
|
41
|
+
await Promise.all([
|
|
42
|
+
(async () => {
|
|
43
|
+
const libHelper = await getMonomerLibHelper();
|
|
44
|
+
this.sysMonomerLib = libHelper.getMonomerLib();
|
|
45
|
+
})(),
|
|
46
|
+
(async () => {
|
|
47
|
+
this.helmRenderService = await getHelmService();
|
|
48
|
+
})(),
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
this.subs.push(this.sysMonomerLib!.onChanged.subscribe(() => {
|
|
52
|
+
this.dirty = true;
|
|
53
|
+
this.invalidateGrid();
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
this.dirty = true;
|
|
57
|
+
this.invalidateGrid();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
protected getMonomerLib(): IMonomerLibBase {
|
|
61
|
+
return this.tableCol.temp[MmcrTemps.overriddenLibrary] ?? this.sysMonomerLib;
|
|
62
|
+
}
|
|
63
|
+
|
|
38
64
|
protected override reset(): void {
|
|
39
65
|
const logPrefix = `${this.toLog()}.reset()`;
|
|
40
66
|
this.logger.debug(`${logPrefix}, start`);
|
|
41
67
|
super.reset();
|
|
42
68
|
this._auxList = new Array<HelmAux | null>(this.tableCol.length).fill(null);
|
|
43
|
-
|
|
69
|
+
this.invalidateGrid();
|
|
44
70
|
this.logger.debug(`${logPrefix}, end`);
|
|
45
71
|
}
|
|
46
72
|
|
|
47
|
-
protected override getRenderService(): RenderServiceBase<HelmProps, HelmAux> {
|
|
48
|
-
return
|
|
73
|
+
protected override getRenderService(): RenderServiceBase<HelmProps, HelmAux> | null {
|
|
74
|
+
return this.helmRenderService;
|
|
49
75
|
}
|
|
50
76
|
|
|
51
77
|
protected override getRenderTaskProps(
|
|
52
78
|
gridCell: DG.GridCell, backColor: number, width: number, height: number,
|
|
53
79
|
): HelmProps {
|
|
54
|
-
|
|
80
|
+
const monomerLib = this.getMonomerLib();
|
|
81
|
+
return new HelmProps(gridCell.cell.value, monomerLib, backColor, width, height);
|
|
55
82
|
}
|
|
56
83
|
|
|
57
84
|
protected override storeAux(gridCell: DG.GridCell, aux: HelmAux): void {
|
|
@@ -133,7 +160,7 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
133
160
|
let seqMonomer: ISeqMonomer | null = null;
|
|
134
161
|
if (hoveredAtom) {
|
|
135
162
|
seqMonomer = getSeqMonomerFromHelmAtom(hoveredAtom);
|
|
136
|
-
const monomerLib = _package.monomerLib;
|
|
163
|
+
const monomerLib = this.tableCol.temp[MmcrTemps.overriddenLibrary] ?? _package.monomerLib;
|
|
137
164
|
const tooltipEl = monomerLib ? monomerLib.getTooltip(seqMonomer.biotype, seqMonomer.symbol) :
|
|
138
165
|
ui.divText('Monomer library is not available');
|
|
139
166
|
ui.tooltip.show(tooltipEl, e.x + 16, e.y + 16);
|
|
@@ -149,30 +176,23 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
149
176
|
execMonomerHoverLinks(gridCell, null);
|
|
150
177
|
}
|
|
151
178
|
|
|
152
|
-
public override render(g: CanvasRenderingContext2D,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (this.monomerLib)
|
|
158
|
-
this.subs.push(this.monomerLib.onChanged.subscribe(this.monomerLibOnChanged.bind(this)));
|
|
159
|
-
}
|
|
160
|
-
super.render(g, x, y, w, h, gridCell, cellStyle);
|
|
161
|
-
}
|
|
179
|
+
// public override render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
|
|
180
|
+
// gridCell: DG.GridCell, cellStyle: DG.GridCellStyle
|
|
181
|
+
// ) {
|
|
182
|
+
// super.render(g, x, y, w, h, gridCell, cellStyle);
|
|
183
|
+
// }
|
|
162
184
|
|
|
163
185
|
// -- Handle events --
|
|
164
186
|
|
|
165
|
-
private monomerLibOnChanged(_value: any): void {
|
|
166
|
-
this.dirty = true;
|
|
167
|
-
this.invalidateGrid();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
187
|
static getOrCreate(gridCell: DG.GridCell): HelmGridCellRendererBack {
|
|
171
188
|
const [gridCol, tableCol, temp] =
|
|
172
189
|
getGridCellColTemp<string, HelmGridCellRendererBack>(gridCell);
|
|
173
190
|
|
|
174
191
|
let res: HelmGridCellRendererBack = temp.rendererBack;
|
|
175
|
-
if (!res)
|
|
192
|
+
if (!res) {
|
|
193
|
+
res = temp.rendererBack = new HelmGridCellRendererBack(gridCol, tableCol);
|
|
194
|
+
res.init().then(() => {});
|
|
195
|
+
}
|
|
176
196
|
return res;
|
|
177
197
|
}
|
|
178
198
|
}
|
|
@@ -4,8 +4,9 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import $ from 'cash-dom';
|
|
6
6
|
import {Subject, Unsubscribable} from 'rxjs';
|
|
7
|
+
import {LRUCache} from 'lru-cache';
|
|
7
8
|
|
|
8
|
-
import {HelmEditor, HelmType,
|
|
9
|
+
import {HelmEditor, HelmType, IHelmEditorOptions} from '@datagrok-libraries/bio/src/helm/types';
|
|
9
10
|
import {RenderTask} from '@datagrok-libraries/bio/src/utils/cell-renderer-async-base';
|
|
10
11
|
import {HelmAux, HelmProps, HelmServiceBase} from '@datagrok-libraries/bio/src/viewers/helm-service';
|
|
11
12
|
import {svgToImage} from '@datagrok-libraries/utils/src/svg';
|
|
@@ -19,7 +20,9 @@ declare const JSDraw2: JSDraw2Module;
|
|
|
19
20
|
export class HelmService extends HelmServiceBase {
|
|
20
21
|
private readonly hostDiv: HTMLDivElement;
|
|
21
22
|
|
|
22
|
-
private
|
|
23
|
+
private readonly editorLruCache: LRUCache<string, HelmEditor>;
|
|
24
|
+
|
|
25
|
+
// private editor!: HelmEditor;
|
|
23
26
|
private image: HTMLImageElement | null = null;
|
|
24
27
|
|
|
25
28
|
constructor() {
|
|
@@ -34,27 +37,43 @@ export class HelmService extends HelmServiceBase {
|
|
|
34
37
|
this.hostDiv.style.height = '0px';
|
|
35
38
|
this.hostDiv.style.visibility = 'hidden';
|
|
36
39
|
document.body.appendChild(this.hostDiv);
|
|
40
|
+
|
|
41
|
+
this.editorLruCache = new LRUCache<string, HelmEditor>({max: 20});
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
protected override toLog(): string {
|
|
40
45
|
return `Helm: ${super.toLog()}`;
|
|
41
46
|
}
|
|
42
47
|
|
|
48
|
+
private getEditor(props: HelmProps): HelmEditor {
|
|
49
|
+
const editorKey = props.monomerLib.source;
|
|
50
|
+
|
|
51
|
+
let resEditor: HelmEditor | undefined = this.editorLruCache.get(editorKey);
|
|
52
|
+
if (!resEditor) {
|
|
53
|
+
const getMonomerFuncs = _package.helmHelper.buildMonomersFuncsFromLib(props.monomerLib);
|
|
54
|
+
resEditor = new JSDraw2.Editor<HelmType, IHelmEditorOptions>(this.hostDiv, {
|
|
55
|
+
width: props.width, height: props.height, skin: 'w8', viewonly: true,
|
|
56
|
+
drawOptions: {getMonomer: getMonomerFuncs.getMonomer},
|
|
57
|
+
});
|
|
58
|
+
this.editorLruCache.set(editorKey, resEditor);
|
|
59
|
+
}
|
|
60
|
+
return resEditor;
|
|
61
|
+
}
|
|
62
|
+
|
|
43
63
|
protected override async requestRender(
|
|
44
64
|
key: keyof any | undefined, task: RenderTask<HelmProps, HelmAux>, renderHandler: (aux: HelmAux) => void
|
|
45
65
|
): Promise<[Unsubscribable, number, () => void]> {
|
|
46
66
|
const logPrefix = `${this.toLog()}.requestRender()`;
|
|
47
67
|
this.logger.debug(`${logPrefix}, start, ` + `key: ${key?.toString()}`);
|
|
48
68
|
const emptyCanvasHash: number = 0;
|
|
69
|
+
const monomerLib = task.props.monomerLib;
|
|
70
|
+
|
|
71
|
+
const editor = this.getEditor(task.props);
|
|
49
72
|
|
|
50
|
-
if (!this.editor) {
|
|
51
|
-
this.editor = new JSDraw2.Editor<HelmType, IHelmDrawOptions>(this.hostDiv,
|
|
52
|
-
{width: task.props.width, height: task.props.height, skin: 'w8', viewonly: true});
|
|
53
|
-
}
|
|
54
73
|
const lST = window.performance.now();
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
editor.options.width = task.props.width;
|
|
75
|
+
editor.options.height = task.props.height;
|
|
76
|
+
editor.resize(task.props.width, task.props.height);
|
|
58
77
|
const helmStr = task.props.helm;
|
|
59
78
|
if (helmStr) {
|
|
60
79
|
// getMonomerOverrideAndLogAlert(
|
|
@@ -65,14 +84,14 @@ export class HelmService extends HelmServiceBase {
|
|
|
65
84
|
// this.editor.setData(helmStr, 'helm');
|
|
66
85
|
// }, this.logger);
|
|
67
86
|
this.logger.debug(`${logPrefix}, editor.setData( '${helmStr}' )`);
|
|
68
|
-
|
|
87
|
+
editor.setData(helmStr, 'helm');
|
|
69
88
|
}
|
|
70
89
|
if (!helmStr)
|
|
71
|
-
|
|
90
|
+
editor.reset();
|
|
72
91
|
|
|
73
|
-
const bBox = (
|
|
92
|
+
const bBox = (editor.div.children[0] as SVGSVGElement).getBBox();
|
|
74
93
|
const aux: HelmAux = {
|
|
75
|
-
mol:
|
|
94
|
+
mol: editor.m.clone(false),
|
|
76
95
|
bBox: new DG.Rect(bBox.x, bBox.y, bBox.width + 2, bBox.height + 2) /* adjust for clipping right/bottom */,
|
|
77
96
|
cBox: new DG.Rect(0, 0, task.props.width, task.props.height),
|
|
78
97
|
};
|
|
@@ -7,7 +7,7 @@ import {fromEvent, Observable, Unsubscribable} from 'rxjs';
|
|
|
7
7
|
|
|
8
8
|
import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
|
|
9
9
|
import {HelmInputBase, IHelmHelper, IHelmInputInitOptions} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
10
|
-
import {HelmAtom, HelmMol, HelmString, IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
|
|
10
|
+
import {HelmAtom, HelmMol, HelmString, IHelmEditorOptions, IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
|
|
11
11
|
|
|
12
12
|
import {defaultErrorHandler} from '../utils/err-info';
|
|
13
13
|
import {getHoveredMonomerFromEditorMol, getSeqMonomerFromHelmAtom} from '../utils/get-hovered';
|
|
@@ -86,7 +86,7 @@ export class HelmInput extends HelmInputBase {
|
|
|
86
86
|
style: {width: '100%', height: '100%', overflow: 'hidden'},
|
|
87
87
|
});
|
|
88
88
|
this.viewer = this.helmHelper.createHelmWebEditor(this.viewerHost, {
|
|
89
|
-
monomerNumbering: MonomerNumberingTypes.continuous
|
|
89
|
+
drawOptions: {monomerNumbering: MonomerNumberingTypes.continuous},
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
this.editHintDiv = ui.divH([
|
|
@@ -4,12 +4,14 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import $ from 'cash-dom';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
8
8
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
9
9
|
|
|
10
10
|
import {JSDraw2Module} from '../types';
|
|
11
11
|
import {removeGapsFromHelm} from '../utils';
|
|
12
12
|
|
|
13
|
+
import {_package} from '../package';
|
|
14
|
+
|
|
13
15
|
declare const JSDraw2: JSDraw2Module;
|
|
14
16
|
|
|
15
17
|
export class SeqPropertiesError extends Error {
|
|
@@ -18,7 +20,7 @@ export class SeqPropertiesError extends Error {
|
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
export function getPropertiesDict(seq: string, sh:
|
|
23
|
+
export function getPropertiesDict(seq: string, sh: ISeqHandler): {} {
|
|
22
24
|
const host = ui.div([], {style: {width: '0', height: '0'}});
|
|
23
25
|
document.documentElement.appendChild(host);
|
|
24
26
|
try {
|
|
@@ -48,7 +50,7 @@ export function getPropertiesDict(seq: string, sh: SeqHandler): {} {
|
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
export function getPropertiesWidget(value: DG.SemanticValue<string>): DG.Widget {
|
|
51
|
-
const sh =
|
|
53
|
+
const sh = _package.seqHelper.getSeqHandler(value.cell.column as DG.Column<string>);
|
|
52
54
|
try {
|
|
53
55
|
const propDict = getPropertiesDict(value.value, sh);
|
|
54
56
|
return new DG.Widget(
|