@datagrok/bio 1.11.0 → 1.11.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/README.md +1 -1
- package/dist/package-test.js +194 -149
- package/dist/package.js +174 -149
- package/package.json +8 -3
- package/src/package.ts +4 -3
- package/src/tests/renderers-test.ts +17 -0
- package/src/tests/test-sequnces-generators.ts +16 -21
- package/src/utils/cell-renderer.ts +16 -16
- package/src/utils/sequence-activity-cliffs.ts +120 -8
- package/test-Bio-f1ac5a5eade4-e2085bf5.html +261 -0
- package/test-Bio-eb4783c07294-8e35df79.html +0 -359
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Leonid Stolbov",
|
|
6
6
|
"email": "lstolbov@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.11.
|
|
8
|
+
"version": "1.11.1",
|
|
9
9
|
"description": "Bio is a [package](https://datagrok.ai/help/develop/develop#packages) for the [Datagrok](https://datagrok.ai) platform",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@biowasm/aioli": ">=2.4.0",
|
|
17
17
|
"@datagrok-libraries/bio": "^4.2.0",
|
|
18
18
|
"@datagrok-libraries/chem-meta": "1.0.0",
|
|
19
|
-
"@datagrok-libraries/ml": "^
|
|
19
|
+
"@datagrok-libraries/ml": "^6.0.0",
|
|
20
20
|
"@datagrok-libraries/utils": "^1.6.2",
|
|
21
21
|
"cash-dom": "latest",
|
|
22
22
|
"datagrok-api": "^1.6.6",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"link-api": "npm link datagrok-api",
|
|
49
49
|
"link-bio": "npm link @datagrok-libraries/bio",
|
|
50
50
|
"link-ml": "npm link @datagrok-libraries/ml",
|
|
51
|
+
"link-utils": "npm link @datagrok-libraries/utils",
|
|
51
52
|
"link-all": "npm link datagrok-api @datagrok-libraries/utils @datagrok-libraries/bio @datagrok-libraries/ml",
|
|
52
53
|
"debug-sequences1": "grok publish",
|
|
53
54
|
"release-sequences1": "grok publish --release",
|
|
@@ -69,7 +70,11 @@
|
|
|
69
70
|
"Developers"
|
|
70
71
|
],
|
|
71
72
|
"sources": [
|
|
72
|
-
"css/helm.css"
|
|
73
|
+
"css/helm.css",
|
|
74
|
+
"https://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js",
|
|
75
|
+
"helm/JSDraw/Scilligence.JSDraw2.Lite.js",
|
|
76
|
+
"helm/JSDraw/Scilligence.JSDraw2.Resources.js",
|
|
77
|
+
"helm/JSDraw/Pistoia.HELM-uncompressed.js"
|
|
73
78
|
],
|
|
74
79
|
"category": "Bioinformatics"
|
|
75
80
|
}
|
package/src/package.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {Aminoacids} from '@datagrok-libraries/bio/src/aminoacids';
|
|
|
15
15
|
import {getEmbeddingColsNames, sequenceSpace} from './utils/sequence-space';
|
|
16
16
|
import {AvailableMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
17
17
|
import {getActivityCliffs} from '@datagrok-libraries/ml/src/viewers/activity-cliffs';
|
|
18
|
-
import {
|
|
18
|
+
import {createPropPanelElement, createTooltipElement, getSimilaritiesMarix} from './utils/sequence-activity-cliffs';
|
|
19
19
|
import {createJsonMonomerLibFromSdf, encodeMonomers, getMolfilesFromSeq, HELM_CORE_LIB_FILENAME} from './utils/utils';
|
|
20
20
|
import {getMacroMol} from './utils/atomic-works';
|
|
21
21
|
import {MacromoleculeSequenceCellRenderer} from './utils/cell-renderer';
|
|
@@ -180,8 +180,9 @@ export async function activityCliffs(df: DG.DataFrame, macroMolecule: DG.Column,
|
|
|
180
180
|
DG.SEMTYPE.MACROMOLECULE,
|
|
181
181
|
tags,
|
|
182
182
|
sequenceSpace,
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
getSimilaritiesMarix,
|
|
184
|
+
createTooltipElement,
|
|
185
|
+
createPropPanelElement,
|
|
185
186
|
(options as any)[methodName]);
|
|
186
187
|
return sp;
|
|
187
188
|
}
|
|
@@ -6,6 +6,7 @@ import {importFasta, multipleSequenceAlignmentAny} from '../package';
|
|
|
6
6
|
import {readDataframe} from './utils';
|
|
7
7
|
import {convertDo} from '../utils/convert';
|
|
8
8
|
import {ALPHABET, NOTATION, UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
|
|
9
|
+
import { SEM_TYPES, TAGS } from '../utils/constants';
|
|
9
10
|
|
|
10
11
|
category('renderers', () => {
|
|
11
12
|
let tvList: DG.TableView[];
|
|
@@ -30,6 +31,10 @@ category('renderers', () => {
|
|
|
30
31
|
await _testAfterConvert();
|
|
31
32
|
});
|
|
32
33
|
|
|
34
|
+
test('setRenderer', async () => {
|
|
35
|
+
await _setRendererManually();
|
|
36
|
+
});
|
|
37
|
+
|
|
33
38
|
async function _testAfterMsa() {
|
|
34
39
|
const fastaTxt: string = await grok.dapi.files.readAsText('System:AppData/Bio/samples/sample_FASTA.fasta');
|
|
35
40
|
const df: DG.DataFrame = importFasta(fastaTxt)[0];
|
|
@@ -75,4 +80,16 @@ category('renderers', () => {
|
|
|
75
80
|
tvList.push(tv);
|
|
76
81
|
dfList.push(df);
|
|
77
82
|
};
|
|
83
|
+
|
|
84
|
+
async function _setRendererManually() {
|
|
85
|
+
const df = DG.DataFrame.fromColumns([DG.Column.fromStrings('SequencesDiff', ['meI/hHis/Aca/N/T/dK/Thr_PO3H2/Aca#D-Tyr_Et/Tyr_ab-dehydroMe/meN/E/N/dV'])]);
|
|
86
|
+
df.col('SequencesDiff')!.tags[DG.TAGS.UNITS] = 'separator';
|
|
87
|
+
df.col('SequencesDiff')!.tags[TAGS.SEPARATOR] = '/';
|
|
88
|
+
df.col('SequencesDiff')!.semType = SEM_TYPES.MACROMOLECULE_DIFFERENCE;
|
|
89
|
+
const tw = grok.shell.addTableView(df);
|
|
90
|
+
await delay(100);
|
|
91
|
+
const renderer = tw.dataFrame.col('SequencesDiff')?.getTag(DG.TAGS.CELL_RENDERER);
|
|
92
|
+
if (renderer !== 'MacromoleculeDifferenceCR')
|
|
93
|
+
throw new Error(`Units 'separator', separator '/' and semType 'MacromoleculeDifference' have been manually set on column but after df aws added as table view renderer has been reset to '${renderer}'`)
|
|
94
|
+
};
|
|
78
95
|
});
|
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import {DataFrame} from 'datagrok-api/dg';
|
|
3
4
|
|
|
4
|
-
export function generateManySequences():
|
|
5
|
-
let
|
|
6
|
-
meI/hHis/Aca/N/T/dE/Thr_PO3H2/Aca/D-Tyr_Et/Tyr_ab-dehydroMe/dV/E/N/D-Orn/D-aThr//Phe_4Me
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
return csvData;
|
|
5
|
+
export function generateManySequences(): DG.Column[] {
|
|
6
|
+
let columns: DG.Column[] = [];
|
|
7
|
+
columns.push(DG.Column.fromList('string', 'MSA', new Array(10 ** 6).fill('meI/hHis/Aca/N/T/dE/Thr_PO3H2/Aca/D-Tyr_Et/Tyr_ab-dehydroMe/dV/E/N/D-Orn/D-aThr//Phe_4Me')));
|
|
8
|
+
columns.push(DG.Column.fromList('string', 'Activity', new Array(10 ** 6).fill('5.30751')));
|
|
9
|
+
return columns;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
export function generateLongSequence():
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
let csvData = `MSA,Activity `;
|
|
20
|
-
for (let i = 0; i <= 10 ** 1 * 4; i++) {
|
|
21
|
-
csvData += `\n ${longSequence}`;
|
|
22
|
-
}
|
|
23
|
-
return csvData;
|
|
12
|
+
export function generateLongSequence(): DG.Column[] {
|
|
13
|
+
let columns: DG.Column[] = [];
|
|
14
|
+
const longSequence = `meI/hHis/Aca/N/T/dE/Thr_PO3H2/Aca/D-Tyr_Et/Tyr_ab-dehydroMe/dV/E/N/D-Orn/D-aThr`.repeat(10 ** 5);
|
|
15
|
+
columns.push(DG.Column.fromList('string', 'MSA', new Array(10 ** 2).fill(longSequence)));
|
|
16
|
+
columns.push(DG.Column.fromList('string', 'Activity', new Array(10 ** 2).fill('7.30751')));
|
|
17
|
+
return columns;
|
|
24
18
|
}
|
|
19
|
+
|
|
25
20
|
export function setTagsMacromolecule(col: DG.Column) {
|
|
26
21
|
col.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
27
22
|
col.setTag('units', 'separator');
|
|
@@ -31,10 +26,10 @@ export function setTagsMacromolecule(col: DG.Column) {
|
|
|
31
26
|
return col;
|
|
32
27
|
}
|
|
33
28
|
|
|
34
|
-
export function performanceTest(generateFunc: () =>
|
|
29
|
+
export function performanceTest(generateFunc: () => DG.Column[], testName: string) {
|
|
30
|
+
const columns = generateFunc();
|
|
31
|
+
const df: DG.DataFrame = DG.DataFrame.fromColumns(columns);
|
|
35
32
|
const startTime: number = Date.now();
|
|
36
|
-
const csv = generateFunc();
|
|
37
|
-
const df: DG.DataFrame = DG.DataFrame.fromCsv(csv);
|
|
38
33
|
const col: DG.Column = df.columns.byName('MSA');
|
|
39
34
|
setTagsMacromolecule(col);
|
|
40
35
|
grok.shell.addTableView(df);
|
|
@@ -2,7 +2,7 @@ import * as C from './constants';
|
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
import {AminoacidsPalettes} from '@datagrok-libraries/bio/src/aminoacids';
|
|
4
4
|
import {NucleotidesPalettes} from '@datagrok-libraries/bio/src/nucleotides';
|
|
5
|
-
import {
|
|
5
|
+
import {UnknownSeqPalettes} from '@datagrok-libraries/bio/src/unknown';
|
|
6
6
|
import {SplitterFunc, WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
|
|
7
7
|
import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
|
|
8
8
|
import * as ui from 'datagrok-api/ui';
|
|
@@ -14,7 +14,7 @@ const monomerToShortFunction: (amino: string, maxLengthOfMonomer: number) => str
|
|
|
14
14
|
const gapRenderer = 5;
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
function
|
|
17
|
+
function getPaletteByType(paletteType: string): SeqPalette {
|
|
18
18
|
switch (paletteType) {
|
|
19
19
|
case 'PT':
|
|
20
20
|
return AminoacidsPalettes.GrokGroups;
|
|
@@ -30,6 +30,10 @@ function getPalleteByType(paletteType: string): SeqPalette {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
function getUpdatedWidth(grid: DG.Grid | null, g: CanvasRenderingContext2D, x: number, w: number): number {
|
|
34
|
+
return grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
|
|
35
|
+
}
|
|
36
|
+
|
|
33
37
|
export function processSequence(subParts: string[]): [string[], boolean] {
|
|
34
38
|
const simplified = !subParts.some((amino, index) =>
|
|
35
39
|
amino.length > 1 &&
|
|
@@ -63,8 +67,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
63
67
|
}
|
|
64
68
|
const maxLengthWordsSum = gridCell.cell.column.temp['bio-sum-maxLengthWords'];
|
|
65
69
|
const maxIndex = gridCell.cell.column.temp['bio-maxIndex'];
|
|
66
|
-
|
|
67
|
-
const argsX = e.layerX - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCell.bounds.x);
|
|
70
|
+
const argsX = e.offsetX - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCell.bounds.x);
|
|
68
71
|
let left = 0;
|
|
69
72
|
let right = maxIndex;
|
|
70
73
|
let found = false;
|
|
@@ -109,23 +112,22 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
109
112
|
g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
110
113
|
cellStyle: DG.GridCellStyle
|
|
111
114
|
): void {
|
|
112
|
-
const grid = gridCell.gridRow !== -1 ? gridCell.grid :
|
|
115
|
+
const grid = gridCell.gridRow !== -1 ? gridCell.grid : null;
|
|
113
116
|
const cell = gridCell.cell;
|
|
114
|
-
const
|
|
117
|
+
const paletteType = gridCell.cell.column.getTag(C.TAGS.ALPHABET);
|
|
115
118
|
const minDistanceRenderer = 50;
|
|
116
|
-
w =
|
|
119
|
+
w = getUpdatedWidth(grid, g, x, w);
|
|
117
120
|
g.save();
|
|
118
121
|
g.beginPath();
|
|
119
122
|
g.rect(x, y, w, h);
|
|
120
123
|
g.clip();
|
|
121
124
|
g.font = '12px monospace';
|
|
122
125
|
g.textBaseline = 'top';
|
|
123
|
-
const s: string = cell.value ?? '';
|
|
124
126
|
|
|
125
127
|
//TODO: can this be replaced/merged with splitSequence?
|
|
126
128
|
const units = gridCell.cell.column.getTag(DG.TAGS.UNITS);
|
|
127
129
|
|
|
128
|
-
const palette =
|
|
130
|
+
const palette = getPaletteByType(paletteType);
|
|
129
131
|
|
|
130
132
|
const separator = gridCell.cell.column.getTag('separator') ?? '';
|
|
131
133
|
const splitLimit = gridCell.bounds.width / 5;
|
|
@@ -184,10 +186,8 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
184
186
|
g.fillStyle = undefinedColor;
|
|
185
187
|
let last = index === subParts.length - 1;
|
|
186
188
|
x1 = printLeftOrCentered(x1, y, w, h, g, monomerToShortFunction(amino, maxLengthOfMonomer), color, 0, true, 1.0, separator, last, drawStyle, maxLengthWords, index, gridCell);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
return true;
|
|
189
|
+
return x1 - minDistanceRenderer - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCell.bounds.x) <= gridCell.bounds.width;
|
|
190
|
+
|
|
191
191
|
});
|
|
192
192
|
|
|
193
193
|
g.restore();
|
|
@@ -226,7 +226,7 @@ export class MonomerCellRenderer extends DG.GridCellRenderer {
|
|
|
226
226
|
g.font = `12px monospace`;
|
|
227
227
|
g.textBaseline = 'top';
|
|
228
228
|
|
|
229
|
-
const palette =
|
|
229
|
+
const palette = getPaletteByType(gridCell.tableColumn!.tags[C.TAGS.ALPHABET]);
|
|
230
230
|
const s: string = gridCell.cell.value ? gridCell.cell.value : '-';
|
|
231
231
|
const color = palette.get(s);
|
|
232
232
|
|
|
@@ -262,7 +262,7 @@ export class MacromoleculeDifferenceCellRenderer extends DG.GridCellRenderer {
|
|
|
262
262
|
const grid = gridCell.grid;
|
|
263
263
|
const cell = gridCell.cell;
|
|
264
264
|
|
|
265
|
-
w =
|
|
265
|
+
w = getUpdatedWidth(grid, g, w, x);
|
|
266
266
|
g.save();
|
|
267
267
|
g.beginPath();
|
|
268
268
|
g.rect(x, y, w, h);
|
|
@@ -286,7 +286,7 @@ export class MacromoleculeDifferenceCellRenderer extends DG.GridCellRenderer {
|
|
|
286
286
|
|
|
287
287
|
let palette: SeqPalette = UnknownSeqPalettes.Color;
|
|
288
288
|
if (units != 'HELM')
|
|
289
|
-
palette =
|
|
289
|
+
palette = getPaletteByType(units.substring(units.length - 2));
|
|
290
290
|
|
|
291
291
|
const vShift = 7;
|
|
292
292
|
for (let i = 0; i < subParts1.length; i++) {
|
|
@@ -3,18 +3,130 @@ import * as DG from 'datagrok-api/dg';
|
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
4
|
import {getSimilarityFromDistance} from '@datagrok-libraries/utils/src/similarity-metrics';
|
|
5
5
|
import {AvailableMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
6
|
+
import * as grok from 'datagrok-api/grok';
|
|
6
7
|
|
|
7
|
-
export async function
|
|
8
|
+
export async function getDistances(col: DG.Column, seq: string): Promise<Array<number>> {
|
|
8
9
|
const stringArray = col.toList();
|
|
9
|
-
const distances = new Array(stringArray.length).fill(0
|
|
10
|
+
const distances = new Array(stringArray.length).fill(0);
|
|
10
11
|
for (let i = 0; i < stringArray.length; ++i)
|
|
11
|
-
distances[i] = stringArray[i] ?
|
|
12
|
-
return
|
|
12
|
+
distances[i] = stringArray[i] ? AvailableMetrics['String']['Levenshtein'](stringArray[i], seq) : null;
|
|
13
|
+
return distances;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
export function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
export async function getSimilaritiesMarix(dim: number, seqCol: DG.Column, df: DG.DataFrame, colName: string, simArr: DG.Column[])
|
|
17
|
+
: Promise<DG.Column[]> {
|
|
18
|
+
|
|
19
|
+
function arrayMin(arr: number[]) {
|
|
20
|
+
return arr.reduce(function (p, v) {
|
|
21
|
+
return (p < v ? p : v);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function arrayMax(arr: number[]) {
|
|
26
|
+
return arr.reduce(function (p, v) {
|
|
27
|
+
return (p > v ? p : v);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const distances = new Array(simArr.length).fill(null);
|
|
31
|
+
let min = Infinity;
|
|
32
|
+
let max = -Infinity;
|
|
33
|
+
for (let i = 0; i != dim - 1; ++i) {
|
|
34
|
+
const seq = seqCol.get(i);
|
|
35
|
+
df.rows.removeAt(0, 1, false);
|
|
36
|
+
distances[i] = (await getDistances(df.col(colName)!, seq))!;
|
|
37
|
+
const newMin = arrayMin(distances[i]);
|
|
38
|
+
const newMax = arrayMax(distances[i]);
|
|
39
|
+
if (newMin < min)
|
|
40
|
+
min = newMin;
|
|
41
|
+
if (newMax > max)
|
|
42
|
+
max = newMax;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (let i = 0; i < distances.length; i++) {
|
|
46
|
+
for (let j = 0; j < distances[i].length; j++) {
|
|
47
|
+
distances[i][j] = getSimilarityFromDistance((distances[i][j] - min)/(max - min));
|
|
48
|
+
}
|
|
49
|
+
simArr[i] = DG.Column.fromList(DG.COLUMN_TYPE.FLOAT, 'distances', distances[i]);
|
|
50
|
+
}
|
|
51
|
+
return simArr;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function createTooltipElement(params: ITooltipAndPanelParams): HTMLDivElement {
|
|
55
|
+
const tooltipElement = ui.divH([]);
|
|
56
|
+
const columnNames = ui.divV([
|
|
57
|
+
ui.divText(params.seqCol.name),
|
|
58
|
+
ui.divText(params.activityCol.name),
|
|
59
|
+
]);
|
|
60
|
+
columnNames.style.fontWeight = 'bold';
|
|
61
|
+
columnNames.style.display = 'flex';
|
|
62
|
+
columnNames.style.justifyContent = 'space-between';
|
|
63
|
+
tooltipElement.append(columnNames);
|
|
64
|
+
params.line.mols.forEach((molIdx: number, idx: number) => {
|
|
65
|
+
const activity = ui.divText(params.activityCol.get(molIdx).toFixed(2));
|
|
66
|
+
activity.style.display = 'flex';
|
|
67
|
+
activity.style.justifyContent = 'left';
|
|
68
|
+
activity.style.paddingLeft = '30px';
|
|
69
|
+
tooltipElement.append(ui.divV([
|
|
70
|
+
ui.divText(params.seqCol.get(molIdx)),
|
|
71
|
+
activity,
|
|
72
|
+
]));
|
|
19
73
|
});
|
|
74
|
+
return tooltipElement;
|
|
20
75
|
}
|
|
76
|
+
|
|
77
|
+
function moleculeInfo(df: DG.DataFrame, idx: number, seqColName: string): HTMLElement {
|
|
78
|
+
let dict: {[key: string]: string} = {};
|
|
79
|
+
for (let col of df.columns) {
|
|
80
|
+
if(col.name !== seqColName) {
|
|
81
|
+
dict[col.name] = df.get(col.name, idx);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return ui.tableFromMap(dict);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
export function createPropPanelElement(params: ITooltipAndPanelParams): HTMLDivElement {
|
|
89
|
+
const propPanel = ui.divV([]);
|
|
90
|
+
const columnNames = ui.divH([
|
|
91
|
+
ui.divText(params.seqCol.name),
|
|
92
|
+
ui.divText(params.activityCol.name),
|
|
93
|
+
]);
|
|
94
|
+
columnNames.style.fontWeight = 'bold';
|
|
95
|
+
columnNames.style.justifyContent = 'space-between';
|
|
96
|
+
propPanel.append(columnNames);
|
|
97
|
+
const hosts: HTMLDivElement[] = [];
|
|
98
|
+
params.line.mols.forEach((molIdx: number, hostIdx: number) => {
|
|
99
|
+
const activity = ui.divText(params.activityCol.get(molIdx).toFixed(2));
|
|
100
|
+
activity.style.paddingLeft = '15px';
|
|
101
|
+
activity.style.paddingLeft = '10px';
|
|
102
|
+
const molHost = ui.divText(params.seqCol.get(molIdx));
|
|
103
|
+
if (params.df.currentRowIdx === molIdx) {
|
|
104
|
+
molHost.style.border = 'solid 1px lightgrey';
|
|
105
|
+
}
|
|
106
|
+
//@ts-ignore
|
|
107
|
+
ui.tooltip.bind(molHost, () => moleculeInfo(params.df, molIdx, params.seqCol.name));
|
|
108
|
+
molHost.onclick = () => {
|
|
109
|
+
const obj = grok.shell.o;
|
|
110
|
+
molHost.style.border = 'solid 1px lightgrey';
|
|
111
|
+
params.df.currentRowIdx = molIdx;
|
|
112
|
+
hosts.forEach((h, i) => {
|
|
113
|
+
if (i !== hostIdx) {
|
|
114
|
+
h.style.border = '';
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
grok.shell.o = obj
|
|
119
|
+
}, 1000);
|
|
120
|
+
};
|
|
121
|
+
propPanel.append(ui.divH([
|
|
122
|
+
molHost,
|
|
123
|
+
activity,
|
|
124
|
+
]));
|
|
125
|
+
hosts.push(molHost);
|
|
126
|
+
});
|
|
127
|
+
propPanel.append(ui.divH([
|
|
128
|
+
ui.divText(`Cliff: `, {style: {fontWeight: 'bold', paddingRight: '5px'}}),
|
|
129
|
+
ui.divText(params.sali!.toFixed(2))
|
|
130
|
+
]));
|
|
131
|
+
return propPanel;
|
|
132
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
<html><head><meta charset="utf-8"/><title>Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=f1ac5a5eade4. Commit e2085bf5.</title><style type="text/css">html,
|
|
2
|
+
body {
|
|
3
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
4
|
+
font-size: 1rem;
|
|
5
|
+
margin: 0;
|
|
6
|
+
padding: 0;
|
|
7
|
+
color: #333;
|
|
8
|
+
}
|
|
9
|
+
body {
|
|
10
|
+
padding: 2rem 1rem;
|
|
11
|
+
font-size: 0.85rem;
|
|
12
|
+
}
|
|
13
|
+
#jesthtml-content {
|
|
14
|
+
margin: 0 auto;
|
|
15
|
+
max-width: 70rem;
|
|
16
|
+
}
|
|
17
|
+
header {
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
}
|
|
21
|
+
#title {
|
|
22
|
+
margin: 0;
|
|
23
|
+
flex-grow: 1;
|
|
24
|
+
}
|
|
25
|
+
#logo {
|
|
26
|
+
height: 4rem;
|
|
27
|
+
}
|
|
28
|
+
#timestamp {
|
|
29
|
+
color: #777;
|
|
30
|
+
margin-top: 0.5rem;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** SUMMARY */
|
|
34
|
+
#summary {
|
|
35
|
+
color: #333;
|
|
36
|
+
margin: 2rem 0;
|
|
37
|
+
display: flex;
|
|
38
|
+
font-family: monospace;
|
|
39
|
+
font-size: 1rem;
|
|
40
|
+
}
|
|
41
|
+
#summary > div {
|
|
42
|
+
margin-right: 2rem;
|
|
43
|
+
background: #eee;
|
|
44
|
+
padding: 1rem;
|
|
45
|
+
min-width: 15rem;
|
|
46
|
+
}
|
|
47
|
+
#summary > div:last-child {
|
|
48
|
+
margin-right: 0;
|
|
49
|
+
}
|
|
50
|
+
@media only screen and (max-width: 720px) {
|
|
51
|
+
#summary {
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
}
|
|
54
|
+
#summary > div {
|
|
55
|
+
margin-right: 0;
|
|
56
|
+
margin-top: 2rem;
|
|
57
|
+
}
|
|
58
|
+
#summary > div:first-child {
|
|
59
|
+
margin-top: 0;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.summary-total {
|
|
64
|
+
font-weight: bold;
|
|
65
|
+
margin-bottom: 0.5rem;
|
|
66
|
+
}
|
|
67
|
+
.summary-passed {
|
|
68
|
+
color: #4f8a10;
|
|
69
|
+
border-left: 0.4rem solid #4f8a10;
|
|
70
|
+
padding-left: 0.5rem;
|
|
71
|
+
}
|
|
72
|
+
.summary-failed,
|
|
73
|
+
.summary-obsolete-snapshots {
|
|
74
|
+
color: #d8000c;
|
|
75
|
+
border-left: 0.4rem solid #d8000c;
|
|
76
|
+
padding-left: 0.5rem;
|
|
77
|
+
}
|
|
78
|
+
.summary-pending {
|
|
79
|
+
color: #9f6000;
|
|
80
|
+
border-left: 0.4rem solid #9f6000;
|
|
81
|
+
padding-left: 0.5rem;
|
|
82
|
+
}
|
|
83
|
+
.summary-empty {
|
|
84
|
+
color: #999;
|
|
85
|
+
border-left: 0.4rem solid #999;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.test-result {
|
|
89
|
+
padding: 1rem;
|
|
90
|
+
margin-bottom: 0.25rem;
|
|
91
|
+
}
|
|
92
|
+
.test-result:last-child {
|
|
93
|
+
border: 0;
|
|
94
|
+
}
|
|
95
|
+
.test-result.passed {
|
|
96
|
+
background-color: #dff2bf;
|
|
97
|
+
color: #4f8a10;
|
|
98
|
+
}
|
|
99
|
+
.test-result.failed {
|
|
100
|
+
background-color: #ffbaba;
|
|
101
|
+
color: #d8000c;
|
|
102
|
+
}
|
|
103
|
+
.test-result.pending {
|
|
104
|
+
background-color: #ffdf61;
|
|
105
|
+
color: #9f6000;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.test-info {
|
|
109
|
+
display: flex;
|
|
110
|
+
justify-content: space-between;
|
|
111
|
+
}
|
|
112
|
+
.test-suitename {
|
|
113
|
+
width: 20%;
|
|
114
|
+
text-align: left;
|
|
115
|
+
font-weight: bold;
|
|
116
|
+
word-break: break-word;
|
|
117
|
+
}
|
|
118
|
+
.test-title {
|
|
119
|
+
width: 40%;
|
|
120
|
+
text-align: left;
|
|
121
|
+
font-style: italic;
|
|
122
|
+
}
|
|
123
|
+
.test-status {
|
|
124
|
+
width: 20%;
|
|
125
|
+
text-align: right;
|
|
126
|
+
}
|
|
127
|
+
.test-duration {
|
|
128
|
+
width: 10%;
|
|
129
|
+
text-align: right;
|
|
130
|
+
font-size: 0.75rem;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.failureMessages {
|
|
134
|
+
padding: 0 1rem;
|
|
135
|
+
margin-top: 1rem;
|
|
136
|
+
border-top: 1px dashed #d8000c;
|
|
137
|
+
}
|
|
138
|
+
.failureMessages.suiteFailure {
|
|
139
|
+
border-top: none;
|
|
140
|
+
}
|
|
141
|
+
.failureMsg {
|
|
142
|
+
white-space: pre-wrap;
|
|
143
|
+
white-space: -moz-pre-wrap;
|
|
144
|
+
white-space: -pre-wrap;
|
|
145
|
+
white-space: -o-pre-wrap;
|
|
146
|
+
word-wrap: break-word;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.suite-container {
|
|
150
|
+
margin-bottom: 2rem;
|
|
151
|
+
}
|
|
152
|
+
.suite-info {
|
|
153
|
+
padding: 1rem;
|
|
154
|
+
background-color: #eee;
|
|
155
|
+
color: #777;
|
|
156
|
+
display: flex;
|
|
157
|
+
align-items: center;
|
|
158
|
+
margin-bottom: 0.25rem;
|
|
159
|
+
}
|
|
160
|
+
.suite-info .suite-path {
|
|
161
|
+
word-break: break-all;
|
|
162
|
+
flex-grow: 1;
|
|
163
|
+
font-family: monospace;
|
|
164
|
+
font-size: 1rem;
|
|
165
|
+
}
|
|
166
|
+
.suite-info .suite-time {
|
|
167
|
+
margin-left: 0.5rem;
|
|
168
|
+
padding: 0.2rem 0.3rem;
|
|
169
|
+
font-size: 0.75rem;
|
|
170
|
+
}
|
|
171
|
+
.suite-info .suite-time.warn {
|
|
172
|
+
background-color: #d8000c;
|
|
173
|
+
color: #fff;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* CONSOLE LOGS */
|
|
177
|
+
.suite-consolelog {
|
|
178
|
+
margin-bottom: 0.25rem;
|
|
179
|
+
padding: 1rem;
|
|
180
|
+
background-color: #efefef;
|
|
181
|
+
}
|
|
182
|
+
.suite-consolelog-header {
|
|
183
|
+
font-weight: bold;
|
|
184
|
+
}
|
|
185
|
+
.suite-consolelog-item {
|
|
186
|
+
padding: 0.5rem;
|
|
187
|
+
}
|
|
188
|
+
.suite-consolelog-item pre {
|
|
189
|
+
margin: 0.5rem 0;
|
|
190
|
+
white-space: pre-wrap;
|
|
191
|
+
white-space: -moz-pre-wrap;
|
|
192
|
+
white-space: -pre-wrap;
|
|
193
|
+
white-space: -o-pre-wrap;
|
|
194
|
+
word-wrap: break-word;
|
|
195
|
+
}
|
|
196
|
+
.suite-consolelog-item-origin {
|
|
197
|
+
color: #777;
|
|
198
|
+
font-weight: bold;
|
|
199
|
+
}
|
|
200
|
+
.suite-consolelog-item-message {
|
|
201
|
+
color: #000;
|
|
202
|
+
font-size: 1rem;
|
|
203
|
+
padding: 0 0.5rem;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* OBSOLETE SNAPSHOTS */
|
|
207
|
+
.suite-obsolete-snapshots {
|
|
208
|
+
margin-bottom: 0.25rem;
|
|
209
|
+
padding: 1rem;
|
|
210
|
+
background-color: #ffbaba;
|
|
211
|
+
color: #d8000c;
|
|
212
|
+
}
|
|
213
|
+
.suite-obsolete-snapshots-header {
|
|
214
|
+
font-weight: bold;
|
|
215
|
+
}
|
|
216
|
+
.suite-obsolete-snapshots-item {
|
|
217
|
+
padding: 0.5rem;
|
|
218
|
+
}
|
|
219
|
+
.suite-obsolete-snapshots-item pre {
|
|
220
|
+
margin: 0.5rem 0;
|
|
221
|
+
white-space: pre-wrap;
|
|
222
|
+
white-space: -moz-pre-wrap;
|
|
223
|
+
white-space: -pre-wrap;
|
|
224
|
+
white-space: -o-pre-wrap;
|
|
225
|
+
word-wrap: break-word;
|
|
226
|
+
}
|
|
227
|
+
.suite-obsolete-snapshots-item-message {
|
|
228
|
+
color: #000;
|
|
229
|
+
font-size: 1rem;
|
|
230
|
+
padding: 0 0.5rem;
|
|
231
|
+
}
|
|
232
|
+
</style></head><body><div id="jesthtml-content"><header><h1 id="title">Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=f1ac5a5eade4. Commit e2085bf5.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-09-08 09:07:23</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts</div><div class="suite-time warn">10.876s</div></div><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">failed</div><div class="test-duration">0s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: Unknown server alias. Please add it to /home/runner/.grok/config.yaml
|
|
233
|
+
at getDevKey (/home/runner/work/public/public/packages/Bio/src/__jest__/test-node.ts:48:13)
|
|
234
|
+
at Object.<anonymous> (/home/runner/work/public/public/packages/Bio/src/__jest__/test-node.ts:57:15)
|
|
235
|
+
at Generator.next (<anonymous>)
|
|
236
|
+
at /home/runner/work/public/public/packages/Bio/src/__jest__/test-node.ts:31:71
|
|
237
|
+
at new Promise (<anonymous>)
|
|
238
|
+
at Object.<anonymous>.__awaiter (/home/runner/work/public/public/packages/Bio/src/__jest__/test-node.ts:27:12)
|
|
239
|
+
at Object.getBrowserPage (/home/runner/work/public/public/packages/Bio/src/__jest__/test-node.ts:94:12)
|
|
240
|
+
at /home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts:13:27
|
|
241
|
+
at Generator.next (<anonymous>)
|
|
242
|
+
at /home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts:34:71
|
|
243
|
+
at new Promise (<anonymous>)
|
|
244
|
+
at Object.<anonymous>.__awaiter (/home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts:30:12)
|
|
245
|
+
at /home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts:12:22
|
|
246
|
+
at Promise.then.completed (/home/runner/work/public/public/packages/Bio/node_modules/jest-circus/build/utils.js:391:28)
|
|
247
|
+
at new Promise (<anonymous>)
|
|
248
|
+
at callAsyncCircusFn (/home/runner/work/public/public/packages/Bio/node_modules/jest-circus/build/utils.js:316:10)
|
|
249
|
+
at _callCircusHook (/home/runner/work/public/public/packages/Bio/node_modules/jest-circus/build/run.js:181:40)
|
|
250
|
+
at _runTestsForDescribeBlock (/home/runner/work/public/public/packages/Bio/node_modules/jest-circus/build/run.js:47:7)
|
|
251
|
+
at run (/home/runner/work/public/public/packages/Bio/node_modules/jest-circus/build/run.js:25:3)
|
|
252
|
+
at runAndTransformResultsToJestFormat (/home/runner/work/public/public/packages/Bio/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:170:21)
|
|
253
|
+
at jestAdapter (/home/runner/work/public/public/packages/Bio/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:82:19)
|
|
254
|
+
at runTestInternal (/home/runner/work/public/public/packages/Bio/node_modules/jest-runner/build/runTest.js:389:16)
|
|
255
|
+
at runTest (/home/runner/work/public/public/packages/Bio/node_modules/jest-runner/build/runTest.js:475:34)
|
|
256
|
+
at TestRunner.runTests (/home/runner/work/public/public/packages/Bio/node_modules/jest-runner/build/index.js:101:12)
|
|
257
|
+
at TestScheduler.scheduleTests (/home/runner/work/public/public/packages/Bio/node_modules/@jest/core/build/TestScheduler.js:333:13)
|
|
258
|
+
at runJest (/home/runner/work/public/public/packages/Bio/node_modules/@jest/core/build/runJest.js:404:19)
|
|
259
|
+
at _run10000 (/home/runner/work/public/public/packages/Bio/node_modules/@jest/core/build/cli/index.js:320:7)
|
|
260
|
+
at runCLI (/home/runner/work/public/public/packages/Bio/node_modules/@jest/core/build/cli/index.js:173:3)
|
|
261
|
+
at Object.run (/home/runner/work/public/public/packages/Bio/node_modules/jest-cli/build/cli/index.js:155:37)</pre></div></div></div></div></div></body></html>
|