@datagrok/bio 2.4.53 → 2.5.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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Leonid Stolbov",
|
|
6
6
|
"email": "lstolbov@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.5.0",
|
|
9
9
|
"description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@biowasm/aioli": "^3.1.0",
|
|
25
|
-
"@datagrok-libraries/bio": "^5.
|
|
25
|
+
"@datagrok-libraries/bio": "^5.33.0",
|
|
26
26
|
"@datagrok-libraries/chem-meta": "^1.0.1",
|
|
27
27
|
"@datagrok-libraries/ml": "^6.3.39",
|
|
28
28
|
"@datagrok-libraries/tutorials": "^1.3.2",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"eslint-config-google": "latest",
|
|
47
47
|
"source-map-loader": "^4.0.1",
|
|
48
48
|
"ts-loader": "^9.2.5",
|
|
49
|
-
"typescript": "^
|
|
49
|
+
"typescript": "^4.8.4",
|
|
50
50
|
"webpack": "^5.76.0",
|
|
51
51
|
"webpack-bundle-analyzer": "latest",
|
|
52
52
|
"webpack-cli": "^4.6.0",
|
|
@@ -313,7 +313,7 @@ export function drawMoleculeDifferenceOnCanvas(
|
|
|
313
313
|
w = textWidth + subParts1.length * 4;
|
|
314
314
|
g.canvas.width = textWidth + subParts1.length * 4;
|
|
315
315
|
}
|
|
316
|
-
let updatedX = Math.max(x, x + (w - (textWidth + subParts1.length * 4)) / 2);
|
|
316
|
+
let updatedX = Math.max(x, x + (w - (textWidth + subParts1.length * 4)) / 2) + 5;
|
|
317
317
|
// 28 is the height of the two substitutions on top of each other + space
|
|
318
318
|
const updatedY = Math.max(y, y + (h - 28) / 2);
|
|
319
319
|
|
|
@@ -3,7 +3,7 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
5
|
import wu from 'wu';
|
|
6
|
-
import {fromEvent, Unsubscribable} from 'rxjs';
|
|
6
|
+
import {fromEvent, Observable, Subject, Unsubscribable} from 'rxjs';
|
|
7
7
|
|
|
8
8
|
import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
|
|
9
9
|
import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
FilterSources,
|
|
18
18
|
HorizontalAlignments,
|
|
19
|
+
IWebLogoViewer,
|
|
19
20
|
PositionHeight,
|
|
20
21
|
PositionMarginStates,
|
|
21
22
|
positionSeparator,
|
|
@@ -67,6 +68,9 @@ export class PositionInfo {
|
|
|
67
68
|
/** Position name from column tag*/
|
|
68
69
|
public readonly name: string;
|
|
69
70
|
|
|
71
|
+
private readonly _label: string | undefined;
|
|
72
|
+
public get label(): string { return !!this._label ? this._label : this.name; }
|
|
73
|
+
|
|
70
74
|
private readonly _freqs: { [m: string]: PositionMonomerInfo };
|
|
71
75
|
|
|
72
76
|
rowCount: number;
|
|
@@ -79,14 +83,16 @@ export class PositionInfo {
|
|
|
79
83
|
* @param {number} rowCount Count of elements in column
|
|
80
84
|
* @param {number} sumForHeightCalc Sum of all monomer counts for height calculation
|
|
81
85
|
*/
|
|
82
|
-
constructor(pos: number, name: string,
|
|
83
|
-
|
|
86
|
+
constructor(pos: number, name: string, freqs?: { [m: string]: PositionMonomerInfo },
|
|
87
|
+
options?: { rowCount?: number, sumForHeightCalc?: number, label?: string }
|
|
84
88
|
) {
|
|
85
89
|
this.pos = pos;
|
|
86
90
|
this.name = name;
|
|
87
|
-
this._freqs = freqs;
|
|
88
|
-
|
|
89
|
-
this.
|
|
91
|
+
this._freqs = freqs ?? {};
|
|
92
|
+
|
|
93
|
+
if (options?.rowCount) this.rowCount = options.rowCount;
|
|
94
|
+
if (options?.sumForHeightCalc) this.sumForHeightCalc = options.sumForHeightCalc;
|
|
95
|
+
if (options?.label) this._label = options.label;
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
public getMonomers(): string[] {
|
|
@@ -277,7 +283,7 @@ enum RecalcLevel {
|
|
|
277
283
|
Freqs = 2,
|
|
278
284
|
}
|
|
279
285
|
|
|
280
|
-
export class WebLogoViewer extends DG.JsViewer {
|
|
286
|
+
export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
281
287
|
public static residuesSet = 'nucleotides';
|
|
282
288
|
private static viewerCount: number = -1;
|
|
283
289
|
|
|
@@ -319,13 +325,13 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
319
325
|
public minHeight: number;
|
|
320
326
|
public backgroundColor: number = 0xFFFFFFFF;
|
|
321
327
|
public maxHeight: number;
|
|
322
|
-
public positionMarginState:
|
|
328
|
+
public positionMarginState: PositionMarginStates;
|
|
323
329
|
public positionMargin: number = 0;
|
|
324
330
|
public startPositionName: string | null;
|
|
325
331
|
public endPositionName: string | null;
|
|
326
332
|
public fixWidth: boolean;
|
|
327
|
-
public verticalAlignment:
|
|
328
|
-
public horizontalAlignment:
|
|
333
|
+
public verticalAlignment: VerticalAlignments;
|
|
334
|
+
public horizontalAlignment: HorizontalAlignments;
|
|
329
335
|
public fitArea: boolean;
|
|
330
336
|
public shrinkEmptyTail: boolean;
|
|
331
337
|
public positionHeight: string;
|
|
@@ -334,6 +340,7 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
334
340
|
public filterSource: FilterSources;
|
|
335
341
|
|
|
336
342
|
private positionNames: string[] = [];
|
|
343
|
+
private positionLabels: string[] | undefined = undefined;
|
|
337
344
|
private startPosition: number = -1;
|
|
338
345
|
private endPosition: number = -1;
|
|
339
346
|
|
|
@@ -353,7 +360,7 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
353
360
|
}
|
|
354
361
|
|
|
355
362
|
/** For startPosition equals to endPosition Length is 1 */
|
|
356
|
-
|
|
363
|
+
public get Length(): number {
|
|
357
364
|
if (this.skipEmptyPositions)
|
|
358
365
|
return this.positions.length;
|
|
359
366
|
|
|
@@ -366,13 +373,13 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
366
373
|
}
|
|
367
374
|
|
|
368
375
|
private get positionMarginValue() {
|
|
369
|
-
if (
|
|
370
|
-
|
|
376
|
+
if (this.positionMarginState === PositionMarginStates.AUTO &&
|
|
377
|
+
this.unitsHandler?.getAlphabetIsMultichar() === true
|
|
378
|
+
) return this.positionMargin;
|
|
371
379
|
|
|
372
|
-
if (this.positionMarginState ===
|
|
380
|
+
if (this.positionMarginState === PositionMarginStates.ON)
|
|
373
381
|
return this.positionMargin;
|
|
374
382
|
|
|
375
|
-
|
|
376
383
|
return 0;
|
|
377
384
|
}
|
|
378
385
|
|
|
@@ -431,9 +438,9 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
431
438
|
|
|
432
439
|
// -- Layout --
|
|
433
440
|
this.verticalAlignment = this.string(PROPS.verticalAlignment, defaults.verticalAlignment,
|
|
434
|
-
{category: PROPS_CATS.LAYOUT, choices: Object.values(VerticalAlignments)});
|
|
441
|
+
{category: PROPS_CATS.LAYOUT, choices: Object.values(VerticalAlignments)}) as VerticalAlignments;
|
|
435
442
|
this.horizontalAlignment = this.string(PROPS.horizontalAlignment, defaults.horizontalAlignment,
|
|
436
|
-
{category: PROPS_CATS.LAYOUT, choices: Object.values(HorizontalAlignments)});
|
|
443
|
+
{category: PROPS_CATS.LAYOUT, choices: Object.values(HorizontalAlignments)}) as HorizontalAlignments;
|
|
437
444
|
this.fixWidth = this.bool(PROPS.fixWidth, defaults.fixWidth,
|
|
438
445
|
{category: PROPS_CATS.LAYOUT});
|
|
439
446
|
this.fitArea = this.bool(PROPS.fitArea, defaults.fitArea,
|
|
@@ -443,7 +450,7 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
443
450
|
this.maxHeight = this.float(PROPS.maxHeight, defaults.maxHeight,
|
|
444
451
|
{category: PROPS_CATS.LAYOUT/*, editor: 'slider', min: 25, max: 500, postfix: 'px'*/});
|
|
445
452
|
this.positionMarginState = this.string(PROPS.positionMarginState, defaults.positionMarginState,
|
|
446
|
-
{category: PROPS_CATS.LAYOUT, choices: Object.values(PositionMarginStates)});
|
|
453
|
+
{category: PROPS_CATS.LAYOUT, choices: Object.values(PositionMarginStates)}) as PositionMarginStates;
|
|
447
454
|
let defaultValueForPositionMargin = 0;
|
|
448
455
|
if (this.positionMarginState === 'auto') defaultValueForPositionMargin = 4;
|
|
449
456
|
this.positionMargin = this.int(PROPS.positionMargin, defaultValueForPositionMargin,
|
|
@@ -584,6 +591,7 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
584
591
|
if (!this.seqCol) {
|
|
585
592
|
this.unitsHandler = null;
|
|
586
593
|
this.positionNames = [];
|
|
594
|
+
this.positionLabels = [];
|
|
587
595
|
this.startPosition = -1;
|
|
588
596
|
this.endPosition = -1;
|
|
589
597
|
this.cp = null;
|
|
@@ -601,11 +609,13 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
601
609
|
const maxLength = wu(this.unitsHandler!.splitted).map((mList) => mList ? mList.length : 0)
|
|
602
610
|
.reduce((max, l) => Math.max(max, l), 0);
|
|
603
611
|
|
|
604
|
-
|
|
612
|
+
/** positionNames and positionLabel can be set up through the column's tags only */
|
|
605
613
|
const positionNamesTxt = this.seqCol.getTag(wlTAGS.positionNames);
|
|
606
|
-
|
|
607
|
-
this.positionNames = positionNamesTxt ? positionNamesTxt.split(positionSeparator).map((
|
|
608
|
-
[...Array(maxLength).keys()].map((jPos) => `${jPos + 1}`)
|
|
614
|
+
const positionLabelsTxt = this.seqCol.getTag(wlTAGS.positionLabels);
|
|
615
|
+
this.positionNames = !!positionNamesTxt ? positionNamesTxt.split(positionSeparator).map((v) => v.trim()) :
|
|
616
|
+
[...Array(maxLength).keys()].map((jPos) => `${jPos + 1}`)/* fallback if tag is not provided */;
|
|
617
|
+
this.positionLabels = !!positionLabelsTxt ? positionLabelsTxt.split(positionSeparator).map((v) => v.trim()) :
|
|
618
|
+
undefined;
|
|
609
619
|
|
|
610
620
|
this.startPosition = (this.startPositionName && this.positionNames &&
|
|
611
621
|
this.positionNames.includes(this.startPositionName)) ?
|
|
@@ -735,6 +745,10 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
735
745
|
}
|
|
736
746
|
}
|
|
737
747
|
|
|
748
|
+
private _onSizeChanged: Subject<void> = new Subject<void>();
|
|
749
|
+
|
|
750
|
+
public get onSizeChanged(): Observable<void> { return this._onSizeChanged; }
|
|
751
|
+
|
|
738
752
|
// -- Routines --
|
|
739
753
|
|
|
740
754
|
getMonomer(p: DG.Point): [number, string | null, PositionMonomerInfo | null] {
|
|
@@ -804,7 +818,9 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
804
818
|
this.positions = new Array(posCount);
|
|
805
819
|
for (let jPos = 0; jPos < length; jPos++) {
|
|
806
820
|
const posName: string = this.positionNames[this.startPosition + jPos];
|
|
807
|
-
|
|
821
|
+
const posLabel: string | undefined = this.positionLabels ?
|
|
822
|
+
this.positionLabels[this.startPosition + jPos] : undefined;
|
|
823
|
+
this.positions[jPos] = new PositionInfo(this.startPosition + jPos, posName, {}, {label: posLabel});
|
|
808
824
|
}
|
|
809
825
|
|
|
810
826
|
// 2022-05-05 askalkin instructed to show WebLogo based on filter (not selection)
|
|
@@ -900,7 +916,7 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
900
916
|
hScale, 0, 0, 1,
|
|
901
917
|
jPos * this.positionWidthWithMargin + this._positionWidth / 2 -
|
|
902
918
|
this.positionWidthWithMargin * firstVisibleIndex, 0);
|
|
903
|
-
g.fillText(pos.
|
|
919
|
+
g.fillText(pos.label, 0, 0);
|
|
904
920
|
}
|
|
905
921
|
//#endregion Plot positionNames
|
|
906
922
|
const fontStyle = '16px Roboto, Roboto Local, sans-serif';
|
|
@@ -1021,6 +1037,7 @@ export class WebLogoViewer extends DG.JsViewer {
|
|
|
1021
1037
|
this.host.style.setProperty('overflow-y', 'hidden', 'important');
|
|
1022
1038
|
}
|
|
1023
1039
|
}
|
|
1040
|
+
this._onSizeChanged.next();
|
|
1024
1041
|
}
|
|
1025
1042
|
|
|
1026
1043
|
public getAlphabetSize(): number {
|