@datagrok/peptides 0.8.9 → 0.8.13
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 +2 -1
- package/dist/package-test.js +22626 -0
- package/dist/package.js +21429 -0
- package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +8840 -0
- package/jest.config.js +33 -0
- package/package.json +75 -62
- package/src/__jest__/remote.test.ts +50 -0
- package/src/__jest__/test-node.ts +96 -0
- package/src/model.ts +950 -86
- package/src/monomer-library.ts +8 -0
- package/src/package-test.ts +3 -2
- package/src/package.ts +57 -22
- package/src/peptides.ts +165 -119
- package/src/styles.css +8 -0
- package/src/tests/peptides-tests.ts +17 -78
- package/src/tests/utils.ts +1 -7
- package/src/utils/SAR-multiple-filter.ts +439 -0
- package/src/utils/SAR-multiple-selection.ts +177 -0
- package/src/utils/cell-renderer.ts +49 -50
- package/src/utils/chem-palette.ts +61 -163
- package/src/utils/constants.ts +56 -0
- package/src/utils/filtering-statistics.ts +62 -0
- package/src/utils/multiple-sequence-alignment.ts +33 -2
- package/src/utils/multivariate-analysis.ts +79 -0
- package/src/utils/peptide-similarity-space.ts +12 -31
- package/src/utils/types.ts +10 -0
- package/src/viewers/logo-viewer.ts +2 -1
- package/src/viewers/peptide-space-viewer.ts +121 -0
- package/src/viewers/sar-viewer.ts +111 -313
- package/src/viewers/stacked-barchart-viewer.ts +126 -173
- package/src/widgets/analyze-peptides.ts +39 -18
- package/src/widgets/distribution.ts +61 -0
- package/src/widgets/manual-alignment.ts +3 -3
- package/src/widgets/peptide-molecule.ts +4 -4
- package/src/widgets/subst-table.ts +30 -22
- package/test-Peptides-f8114def7953-4bf59d70.html +256 -0
- package/src/describe.ts +0 -534
- package/src/utils/split-aligned.ts +0 -72
- package/src/viewers/subst-viewer.ts +0 -320
|
@@ -3,372 +3,170 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
5
|
import $ from 'cash-dom';
|
|
6
|
-
import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
|
|
7
6
|
import {PeptidesController} from '../peptides';
|
|
8
|
-
|
|
7
|
+
import * as C from '../utils/constants';
|
|
8
|
+
|
|
9
|
+
let IS_PROPERTY_CHANGING = false;
|
|
10
|
+
|
|
11
|
+
export class SARViewerBase extends DG.JsViewer {
|
|
12
|
+
tempName!: string;
|
|
13
|
+
viewerGrid!: DG.Grid;
|
|
14
|
+
sourceGrid!: DG.Grid;
|
|
15
|
+
controller!: PeptidesController;
|
|
16
|
+
scaling: string;
|
|
17
|
+
// filterMode: boolean;
|
|
18
|
+
bidirectionalAnalysis: boolean;
|
|
19
|
+
// grouping: boolean;
|
|
20
|
+
showSubstitution: boolean;
|
|
21
|
+
maxSubstitutions: number;
|
|
22
|
+
activityLimit: number;
|
|
23
|
+
_titleHost = ui.divText('SAR Viewer', {id: 'pep-viewer-title'});
|
|
24
|
+
initialized = false;
|
|
25
|
+
isPropertyChanging: boolean = false;
|
|
9
26
|
|
|
10
|
-
/**
|
|
11
|
-
* Structure-activity relationship viewer.
|
|
12
|
-
*
|
|
13
|
-
* @export
|
|
14
|
-
* @class SARViewer
|
|
15
|
-
* @extends {DG.JsViewer}
|
|
16
|
-
*/
|
|
17
|
-
export class SARViewer extends DG.JsViewer {
|
|
18
|
-
protected viewerGrid: DG.Grid | null;
|
|
19
|
-
protected sourceGrid: DG.Grid | null;
|
|
20
|
-
protected activityColumnName: string;
|
|
21
|
-
protected scaling: string;
|
|
22
|
-
protected bidirectionalAnalysis: boolean;
|
|
23
|
-
protected filterMode: boolean;
|
|
24
|
-
protected statsDf: DG.DataFrame | null;
|
|
25
|
-
protected initialized: boolean;
|
|
26
|
-
protected viewGridInitialized: boolean;
|
|
27
|
-
protected aminoAcidResidue;
|
|
28
|
-
protected _initialBitset: DG.BitSet | null;
|
|
29
|
-
protected viewerVGrid: DG.Grid | null;
|
|
30
|
-
protected currentBitset: DG.BitSet | null;
|
|
31
|
-
protected grouping: boolean;
|
|
32
|
-
protected groupMapping: StringDictionary | null;
|
|
33
|
-
// model: PeptidesModel | null;
|
|
34
|
-
protected _name: string = 'Monomer-Positions';
|
|
35
|
-
protected controller: PeptidesController | null;
|
|
36
|
-
// protected pValueThreshold: number;
|
|
37
|
-
// protected amountOfBestAARs: number;
|
|
38
|
-
// duplicatesHandingMethod: string;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Creates an instance of SARViewer.
|
|
42
|
-
*
|
|
43
|
-
* @memberof SARViewer
|
|
44
|
-
*/
|
|
45
27
|
constructor() {
|
|
46
28
|
super();
|
|
47
29
|
|
|
48
|
-
this.viewerGrid = null;
|
|
49
|
-
this.viewerVGrid = null;
|
|
50
|
-
this.statsDf = null;
|
|
51
|
-
this.groupMapping = null;
|
|
52
|
-
this.initialized = false;
|
|
53
|
-
this.aminoAcidResidue = 'AAR';
|
|
54
|
-
this._initialBitset = null;
|
|
55
|
-
this.viewGridInitialized = false;
|
|
56
|
-
this.currentBitset = null;
|
|
57
|
-
// this.model = null;
|
|
58
|
-
this.controller = null;
|
|
59
|
-
|
|
60
|
-
//TODO: find a way to restrict activityColumnName to accept only numerical columns (double even better)
|
|
61
|
-
this.activityColumnName = this.string('activityColumnName');
|
|
62
30
|
this.scaling = this.string('scaling', 'none', {choices: ['none', 'lg', '-lg']});
|
|
63
|
-
this.filterMode = this.bool('filterMode', false);
|
|
31
|
+
// this.filterMode = this.bool('filterMode', false);
|
|
64
32
|
this.bidirectionalAnalysis = this.bool('bidirectionalAnalysis', false);
|
|
65
|
-
this.grouping = this.bool('grouping', false);
|
|
66
|
-
|
|
67
|
-
this.sourceGrid = null;
|
|
68
|
-
}
|
|
33
|
+
// this.grouping = this.bool('grouping', false);
|
|
69
34
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
init() {
|
|
75
|
-
this._initialBitset = this.dataFrame!.filter.clone();
|
|
76
|
-
this.currentBitset = this._initialBitset.clone();
|
|
77
|
-
this.initialized = true;
|
|
35
|
+
this.showSubstitution = this.bool('showSubstitution', false);
|
|
36
|
+
this.maxSubstitutions = this.int('maxSubstitutions', 1);
|
|
37
|
+
this.activityLimit = this.float('activityLimit', 2);
|
|
78
38
|
}
|
|
79
39
|
|
|
80
40
|
async onTableAttached() {
|
|
41
|
+
super.onTableAttached();
|
|
42
|
+
this.dataFrame.temp[this.tempName] ??= this;
|
|
81
43
|
this.sourceGrid = this.view?.grid ?? (grok.shell.v as DG.TableView).grid;
|
|
82
|
-
this.dataFrame
|
|
83
|
-
this.controller
|
|
84
|
-
|
|
85
|
-
// this.model = this.controller.getOrInitModel();
|
|
44
|
+
this.controller = await PeptidesController.getInstance(this.dataFrame);
|
|
45
|
+
this.controller.init(this.dataFrame);
|
|
46
|
+
await this.requestDataUpdate();
|
|
86
47
|
|
|
87
|
-
this.subs.push(this.controller.
|
|
88
|
-
|
|
89
|
-
this.viewerGrid = data;
|
|
90
|
-
this.render(false);
|
|
91
|
-
}));
|
|
92
|
-
this.subs.push(this.controller.onSARVGridChanged.subscribe((data) => this.viewerVGrid = data));
|
|
93
|
-
this.subs.push(this.controller.onGroupMappingChanged.subscribe((data) => this.groupMapping = data));
|
|
48
|
+
// this.subs.push(this.controller.onGroupMappingChanged.subscribe(() => {this.render(true);}));
|
|
49
|
+
}
|
|
94
50
|
|
|
95
|
-
|
|
51
|
+
detach() {this.subs.forEach((sub) => sub.unsubscribe());}
|
|
52
|
+
|
|
53
|
+
render(refreshOnly = false) {
|
|
54
|
+
if (!this.initialized)
|
|
55
|
+
return;
|
|
56
|
+
if (!refreshOnly) {
|
|
57
|
+
$(this.root).empty();
|
|
58
|
+
const viewerRoot = this.viewerGrid.root;
|
|
59
|
+
viewerRoot.style.width = 'auto';
|
|
60
|
+
this.root.appendChild(ui.divV([this._titleHost, viewerRoot]));
|
|
61
|
+
}
|
|
62
|
+
this.viewerGrid?.invalidate();
|
|
96
63
|
}
|
|
97
64
|
|
|
98
|
-
|
|
99
|
-
this.
|
|
65
|
+
async requestDataUpdate() {
|
|
66
|
+
await this.controller.updateData(this.scaling, this.sourceGrid, this.bidirectionalAnalysis,
|
|
67
|
+
this.activityLimit, this.maxSubstitutions, this.showSubstitution);
|
|
100
68
|
}
|
|
101
69
|
|
|
102
|
-
/**
|
|
103
|
-
* Function that is executed when the property is changed.
|
|
104
|
-
*
|
|
105
|
-
* @param {DG.Property} property New property.
|
|
106
|
-
* @memberof SARViewer
|
|
107
|
-
*/
|
|
108
70
|
async onPropertyChanged(property: DG.Property) {
|
|
109
71
|
super.onPropertyChanged(property);
|
|
110
|
-
|
|
111
|
-
if (!this.initialized)
|
|
112
|
-
this.init();
|
|
72
|
+
this.dataFrame.tags[property.name] = `${property.get(this)}`;
|
|
73
|
+
if (!this.initialized || IS_PROPERTY_CHANGING)
|
|
113
74
|
return;
|
|
114
|
-
|
|
75
|
+
|
|
76
|
+
const propName = property.name;
|
|
115
77
|
|
|
116
|
-
if (
|
|
117
|
-
const minActivity =
|
|
118
|
-
this.dataFrame!.col(this.activityColumnName)!,
|
|
119
|
-
this._initialBitset,
|
|
120
|
-
).min;
|
|
78
|
+
if (propName === 'scaling' && typeof this.dataFrame !== 'undefined') {
|
|
79
|
+
const minActivity = this.dataFrame.getCol(C.COLUMNS_NAMES.ACTIVITY).stats.min;
|
|
121
80
|
if (minActivity && minActivity <= 0 && this.scaling !== 'none') {
|
|
122
81
|
grok.shell.warning(`Could not apply ${this.scaling}: ` +
|
|
123
|
-
`activity column ${
|
|
82
|
+
`activity column ${C.COLUMNS_NAMES.ACTIVITY} contains zero or negative values, falling back to 'none'.`);
|
|
124
83
|
property.set(this, 'none');
|
|
125
84
|
return;
|
|
126
85
|
}
|
|
127
86
|
}
|
|
128
87
|
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Viewer render function.
|
|
134
|
-
*
|
|
135
|
-
* @param {boolean} [computeData=true] Recalculate data.
|
|
136
|
-
* @memberof SARViewer
|
|
137
|
-
*/
|
|
138
|
-
async render(computeData = true) {
|
|
139
|
-
if (!this.initialized)
|
|
88
|
+
if (!this.showSubstitution && ['maxSubstitutions', 'activityLimit'].includes(propName))
|
|
140
89
|
return;
|
|
141
90
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (computeData) {
|
|
145
|
-
await this.controller!.updateData(this.dataFrame, this.activityColumnName, this.scaling, this.sourceGrid,
|
|
146
|
-
this.bidirectionalAnalysis, this._initialBitset, this.grouping);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (this.viewerGrid !== null && this.viewerVGrid !== null) {
|
|
150
|
-
$(this.root).empty();
|
|
151
|
-
const title = ui.h1(this._name, {style: {'align-self': 'center'}});
|
|
152
|
-
const gridRoot = this.viewerGrid.root;
|
|
153
|
-
gridRoot.style.width = 'auto';
|
|
154
|
-
this.root.appendChild(ui.divV([title, gridRoot]));
|
|
155
|
-
this.viewerGrid.dataFrame!.onCurrentCellChanged.subscribe((_) => {
|
|
156
|
-
this.currentBitset = applyBitset(
|
|
157
|
-
this.dataFrame!, this.viewerGrid!, this.aminoAcidResidue,
|
|
158
|
-
this.groupMapping!, this._initialBitset!, this.filterMode,
|
|
159
|
-
) ?? this.currentBitset;
|
|
160
|
-
syncGridsFunc(false, this.viewerGrid!, this.viewerVGrid!, this.aminoAcidResidue);
|
|
161
|
-
});
|
|
162
|
-
this.viewerVGrid.dataFrame!.onCurrentCellChanged.subscribe((_) => {
|
|
163
|
-
syncGridsFunc(true, this.viewerGrid!, this.viewerVGrid!, this.aminoAcidResidue);
|
|
164
|
-
});
|
|
165
|
-
this.dataFrame.onRowsFiltering.subscribe((_) => {
|
|
166
|
-
sourceFilteringFunc(this.filterMode, this.dataFrame!, this.currentBitset!, this._initialBitset!);
|
|
167
|
-
});
|
|
168
|
-
grok.events.onAccordionConstructed.subscribe((accordion: DG.Accordion) => {
|
|
169
|
-
accordionFunc(
|
|
170
|
-
accordion, this.viewerGrid!, this.aminoAcidResidue,
|
|
171
|
-
this._initialBitset!, this.activityColumnName, this.statsDf!,
|
|
172
|
-
);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
//fixes viewers not rendering immediately after analyze.
|
|
177
|
-
this.viewerGrid?.invalidate();
|
|
91
|
+
await this.requestDataUpdate();
|
|
92
|
+
this.render(true);
|
|
178
93
|
}
|
|
179
94
|
}
|
|
180
95
|
|
|
181
96
|
/**
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
* @export
|
|
185
|
-
* @class SARViewerVertical
|
|
186
|
-
* @extends {DG.JsViewer}
|
|
97
|
+
* Structure-activity relationship viewer.
|
|
187
98
|
*/
|
|
188
|
-
export class
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
controller: PeptidesController | null;
|
|
99
|
+
export class SARViewer extends SARViewerBase {
|
|
100
|
+
_titleHost = ui.divText('Monomer-Positions', {id: 'pep-viewer-title'});
|
|
101
|
+
_name = 'Structure-Activity Relationship';
|
|
102
|
+
tempName = 'sarViewer';
|
|
193
103
|
|
|
194
|
-
constructor() {
|
|
195
|
-
super();
|
|
104
|
+
constructor() { super(); }
|
|
196
105
|
|
|
197
|
-
|
|
198
|
-
this.controller = null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
get name() {
|
|
202
|
-
return this._name;
|
|
203
|
-
}
|
|
106
|
+
get name() {return this._name;}
|
|
204
107
|
|
|
205
|
-
onTableAttached()
|
|
206
|
-
|
|
207
|
-
this.
|
|
108
|
+
async onTableAttached() {
|
|
109
|
+
await super.onTableAttached();
|
|
110
|
+
this.viewerGrid = this.controller.sarGrid;
|
|
208
111
|
|
|
209
|
-
this.subs.push(this.controller.
|
|
210
|
-
this.
|
|
112
|
+
this.subs.push(this.controller.onSARGridChanged.subscribe((data) => {
|
|
113
|
+
this.viewerGrid = data;
|
|
211
114
|
this.render();
|
|
212
115
|
}));
|
|
213
|
-
}
|
|
214
116
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
$(this.root).empty();
|
|
218
|
-
this.root.appendChild(this.viewerVGrid.root);
|
|
219
|
-
}
|
|
220
|
-
this.viewerVGrid?.invalidate();
|
|
117
|
+
this.initialized = true;
|
|
118
|
+
this.render();
|
|
221
119
|
}
|
|
222
|
-
}
|
|
223
120
|
|
|
224
|
-
|
|
225
|
-
function syncGridsFunc(sourceVertical: boolean, viewerGrid: DG.Grid, viewerVGrid: DG.Grid, aminoAcidResidue: string) {
|
|
226
|
-
if (viewerGrid && viewerGrid.dataFrame && viewerVGrid && viewerVGrid.dataFrame) {
|
|
227
|
-
if (sourceVertical) {
|
|
228
|
-
const dfCell = viewerVGrid.dataFrame.currentCell;
|
|
229
|
-
if (dfCell.column === null || dfCell.column.name !== 'Diff')
|
|
230
|
-
return;
|
|
121
|
+
isInitialized() { return this.controller?.sarGrid ?? false; }
|
|
231
122
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
for (let i = 0; i < viewerGrid.dataFrame.rowCount; i++) {
|
|
236
|
-
if (viewerGrid.dataFrame.get(aminoAcidResidue, i) === otherRowName) {
|
|
237
|
-
otherRowIndex = i;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (otherRowIndex !== -1)
|
|
242
|
-
viewerGrid.dataFrame.currentCell = viewerGrid.dataFrame.cell(otherRowIndex, otherColName);
|
|
243
|
-
} else {
|
|
244
|
-
const otherPos: string = viewerGrid.dataFrame.currentCol?.name;
|
|
245
|
-
if (typeof otherPos === 'undefined' && otherPos !== aminoAcidResidue)
|
|
246
|
-
return;
|
|
123
|
+
async onPropertyChanged(property: DG.Property): Promise<void> {
|
|
124
|
+
if (!this.isInitialized() || IS_PROPERTY_CHANGING)
|
|
125
|
+
return;
|
|
247
126
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (
|
|
253
|
-
viewerVGrid.dataFrame.get(aminoAcidResidue, i) === otherAAR &&
|
|
254
|
-
viewerVGrid.dataFrame.get('Pos', i) === otherPos
|
|
255
|
-
) {
|
|
256
|
-
otherRowIndex = i;
|
|
257
|
-
break;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
if (otherRowIndex !== -1)
|
|
261
|
-
viewerVGrid.dataFrame.currentCell = viewerVGrid.dataFrame.cell(otherRowIndex, 'Diff');
|
|
262
|
-
}
|
|
127
|
+
await super.onPropertyChanged(property);
|
|
128
|
+
IS_PROPERTY_CHANGING = true;
|
|
129
|
+
this.controller.syncProperties(true);
|
|
130
|
+
IS_PROPERTY_CHANGING = false;
|
|
263
131
|
}
|
|
264
132
|
}
|
|
265
133
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Vertical structure activity relationship viewer.
|
|
136
|
+
*/
|
|
137
|
+
export class SARViewerVertical extends SARViewerBase {
|
|
138
|
+
_name = 'Sequence-Activity relationship';
|
|
139
|
+
_titleHost = ui.divText('Most Potent Residues', {id: 'pep-viewer-title'});
|
|
140
|
+
tempName = 'sarViewerVertical';
|
|
141
|
+
|
|
142
|
+
constructor() {
|
|
143
|
+
super();
|
|
274
144
|
}
|
|
275
|
-
}
|
|
276
145
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
const splitColName = '~splitCol';
|
|
291
|
-
const otherLabel = 'Other';
|
|
292
|
-
const aarLabel = `${currentAAR === '-' ? 'Empty' : currentAAR} - ${currentPosition}`;
|
|
293
|
-
|
|
294
|
-
let splitCol = dataFrame.col(splitColName);
|
|
295
|
-
if (!splitCol)
|
|
296
|
-
splitCol = dataFrame.columns.addNew(splitColName, 'string');
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const isChosen = (i: number) => groupMapping[dataFrame!.get(currentPosition, i)] === currentAAR;
|
|
300
|
-
splitCol!.init((i) => isChosen(i) ? aarLabel : otherLabel);
|
|
301
|
-
|
|
302
|
-
//TODO: use column.compact
|
|
303
|
-
currentBitset = DG.BitSet.create(dataFrame.rowCount, isChosen).and(initialBitset);
|
|
304
|
-
sourceFilteringFunc(filterMode, dataFrame, currentBitset, initialBitset);
|
|
305
|
-
|
|
306
|
-
const colorMap: {[index: string]: string | number} = {};
|
|
307
|
-
colorMap[otherLabel] = DG.Color.blue;
|
|
308
|
-
colorMap[aarLabel] = DG.Color.orange;
|
|
309
|
-
// colorMap[currentAAR] = cp.getColor(currentAAR);
|
|
310
|
-
dataFrame.getCol(splitColName).colors.setCategorical(colorMap);
|
|
146
|
+
get name() {return this._name;}
|
|
147
|
+
|
|
148
|
+
async onTableAttached() {
|
|
149
|
+
await super.onTableAttached();
|
|
150
|
+
this.viewerGrid = this.controller.sarVGrid;
|
|
151
|
+
|
|
152
|
+
this.subs.push(this.controller.onSARVGridChanged.subscribe((data) => {
|
|
153
|
+
this.viewerGrid = data;
|
|
154
|
+
this.render();
|
|
155
|
+
}));
|
|
156
|
+
|
|
157
|
+
this.initialized = true;
|
|
158
|
+
this.render();
|
|
311
159
|
}
|
|
312
|
-
return currentBitset;
|
|
313
|
-
}
|
|
314
160
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
viewerDf &&
|
|
326
|
-
viewerDf.currentCol !== null
|
|
327
|
-
) {
|
|
328
|
-
const currentAAR: string = viewerDf.get(
|
|
329
|
-
aminoAcidResidue,
|
|
330
|
-
viewerDf.currentRowIdx,
|
|
331
|
-
);
|
|
332
|
-
const currentPosition = viewerDf.currentCol.name;
|
|
333
|
-
|
|
334
|
-
const labelStr = `${currentAAR === '-' ? 'Empty' : currentAAR} - ${currentPosition}`;
|
|
335
|
-
const currentColor = DG.Color.toHtml(DG.Color.orange);
|
|
336
|
-
const otherColor = DG.Color.toHtml(DG.Color.blue);
|
|
337
|
-
const currentLabel = ui.label(labelStr, {style: {color: currentColor}});
|
|
338
|
-
const otherLabel = ui.label('Other', {style: {color: otherColor}});
|
|
339
|
-
|
|
340
|
-
const elements: (HTMLLabelElement | HTMLElement)[] = [currentLabel, otherLabel];
|
|
341
|
-
|
|
342
|
-
const distPane = accordion.getPane('Distribution');
|
|
343
|
-
if (distPane)
|
|
344
|
-
accordion.removePane(distPane);
|
|
345
|
-
|
|
346
|
-
accordion.addPane('Distribution', () => {
|
|
347
|
-
const hist = originalDf.clone(initialBitset).plot.histogram({
|
|
348
|
-
// const hist = originalDf.plot.histogram({
|
|
349
|
-
filteringEnabled: false,
|
|
350
|
-
valueColumnName: `${activityColumnName}Scaled`,
|
|
351
|
-
splitColumnName: '~splitCol',
|
|
352
|
-
legendVisibility: 'Never',
|
|
353
|
-
showXAxis: true,
|
|
354
|
-
showColumnSelector: false,
|
|
355
|
-
showRangeSlider: false,
|
|
356
|
-
}).root;
|
|
357
|
-
hist.style.width = 'auto';
|
|
358
|
-
elements.push(hist);
|
|
359
|
-
|
|
360
|
-
const tableMap: StringDictionary = {'Statistics:': ''};
|
|
361
|
-
for (const colName of new Set(['Count', 'pValue', 'Mean difference'])) {
|
|
362
|
-
const query = `${aminoAcidResidue} = ${currentAAR} and Pos = ${currentPosition}`;
|
|
363
|
-
const textNum = statsDf.groupBy([colName]).where(query).aggregate().get(colName, 0);
|
|
364
|
-
// const text = textNum === 0 ? '<0.01' : `${colName === 'Count' ? textNum : textNum.toFixed(2)}`;
|
|
365
|
-
const text = colName === 'Count' ? `${textNum}` : textNum < 0.01 ? '<0.01' : textNum.toFixed(2);
|
|
366
|
-
tableMap[colName === 'pValue' ? 'p-value' : colName] = text;
|
|
367
|
-
}
|
|
368
|
-
elements.push(ui.tableFromMap(tableMap));
|
|
369
|
-
|
|
370
|
-
return ui.divV(elements);
|
|
371
|
-
}, true);
|
|
372
|
-
}
|
|
161
|
+
isInitialized() { return this.controller?.sarVGrid ?? false; }
|
|
162
|
+
|
|
163
|
+
async onPropertyChanged(property: DG.Property): Promise<void> {
|
|
164
|
+
if (!this.isInitialized() || IS_PROPERTY_CHANGING)
|
|
165
|
+
return;
|
|
166
|
+
|
|
167
|
+
await super.onPropertyChanged(property);
|
|
168
|
+
IS_PROPERTY_CHANGING = true;
|
|
169
|
+
this.controller.syncProperties(false);
|
|
170
|
+
IS_PROPERTY_CHANGING = false;
|
|
373
171
|
}
|
|
374
172
|
}
|