@datagrok/peptides 1.17.12 → 1.17.14
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/CHANGELOG.md +10 -0
- package/dist/301.js +2 -2
- package/dist/997.js +2 -2
- package/dist/package-test.js +2 -2
- package/dist/package.js +2 -2
- package/package.json +2 -2
- package/src/model.ts +30 -5
- package/src/package.ts +8 -0
- package/src/utils/types.ts +1 -0
- package/src/viewers/cluster-max-activity-viewer.ts +228 -0
- package/src/viewers/logo-summary.ts +1 -1
- package/src/widgets/settings.ts +6 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/peptides",
|
|
3
3
|
"friendlyName": "Peptides",
|
|
4
|
-
"version": "1.17.
|
|
4
|
+
"version": "1.17.14",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Davit Rizhinashvili",
|
|
7
7
|
"email": "drizhinashvili@datagrok.ai"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@datagrok-libraries/bio": "^5.40.0",
|
|
17
|
-
"@datagrok-libraries/ml": "^6.4.
|
|
17
|
+
"@datagrok-libraries/ml": "^6.4.13",
|
|
18
18
|
"@datagrok-libraries/statistics": "^1.2.12",
|
|
19
19
|
"@datagrok-libraries/utils": "^4.1.45",
|
|
20
20
|
"@datagrok-libraries/tutorials": "^1.3.12",
|
package/src/model.ts
CHANGED
|
@@ -53,12 +53,14 @@ import {splitAlignedSequences} from '@datagrok-libraries/bio/src/utils/splitter'
|
|
|
53
53
|
import {getDbscanWorker} from '@datagrok-libraries/math';
|
|
54
54
|
import {markovCluster} from '@datagrok-libraries/ml/src/MCL/clustering-view';
|
|
55
55
|
import {DistanceAggregationMethods} from '@datagrok-libraries/ml/src/distance-matrix/types';
|
|
56
|
+
import {ClusterMaxActivityViewer, IClusterMaxActivity} from './viewers/cluster-max-activity-viewer';
|
|
56
57
|
|
|
57
58
|
export enum VIEWER_TYPE {
|
|
58
59
|
MONOMER_POSITION = 'Monomer-Position',
|
|
59
60
|
MOST_POTENT_RESIDUES = 'Most Potent Residues',
|
|
60
61
|
LOGO_SUMMARY_TABLE = 'Logo Summary Table',
|
|
61
62
|
DENDROGRAM = 'Dendrogram',
|
|
63
|
+
CLUSTER_MAX_ACTIVITY = 'Cluster Max Activity',
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
export type CachedWebLogoTooltip = { bar: string, tooltip: HTMLDivElement | null };
|
|
@@ -190,6 +192,9 @@ export class PeptidesModel {
|
|
|
190
192
|
case 'showDendrogram':
|
|
191
193
|
updateVars.add('dendrogram');
|
|
192
194
|
break;
|
|
195
|
+
case 'showClusterMaxActivity':
|
|
196
|
+
updateVars.add('clusterMaxActivity');
|
|
197
|
+
break;
|
|
193
198
|
case 'showSequenceSpace':
|
|
194
199
|
updateVars.add('showSequenceSpace');
|
|
195
200
|
break;
|
|
@@ -250,6 +255,10 @@ export class PeptidesModel {
|
|
|
250
255
|
case 'dendrogram':
|
|
251
256
|
this.settings!.showDendrogram ? this.addDendrogram() : this.closeViewer(VIEWER_TYPE.DENDROGRAM);
|
|
252
257
|
break;
|
|
258
|
+
case 'clusterMaxActivity':
|
|
259
|
+
this.settings!.showClusterMaxActivity ? this.addClusterMaxActivityViewer() :
|
|
260
|
+
this.closeViewer(VIEWER_TYPE.CLUSTER_MAX_ACTIVITY);
|
|
261
|
+
break;
|
|
253
262
|
case 'logoSummaryTable':
|
|
254
263
|
this.settings!.showLogoSummaryTable ? this.addLogoSummaryTable() :
|
|
255
264
|
this.closeViewer(VIEWER_TYPE.LOGO_SUMMARY_TABLE);
|
|
@@ -1115,6 +1124,22 @@ export class PeptidesModel {
|
|
|
1115
1124
|
logoSummaryTable.viewerGrid.invalidate();
|
|
1116
1125
|
}
|
|
1117
1126
|
|
|
1127
|
+
async addClusterMaxActivityViewer(viewerProperties?: IClusterMaxActivity): Promise<void> {
|
|
1128
|
+
const potentialClusterCol = this._mclCols?.find((colName) => colName.toLowerCase().startsWith('cluster (mcl)')) ??
|
|
1129
|
+
(this.findViewer(VIEWER_TYPE.LOGO_SUMMARY_TABLE) as LogoSummaryTable | null)?.clustersColumnName ??
|
|
1130
|
+
this._sequenceSpaceCols?.find((colName) => colName.toLowerCase().startsWith('cluster'));
|
|
1131
|
+
viewerProperties ??= {
|
|
1132
|
+
activityColumnName: this.settings!.activityColumnName,
|
|
1133
|
+
clusterColumnName: potentialClusterCol ?? wu(this.df.columns.categorical).next().value?.name,
|
|
1134
|
+
activityTarget: C.ACTIVITY_TARGET.HIGH,
|
|
1135
|
+
};
|
|
1136
|
+
const _clusterMaxActivity = await this.df.plot
|
|
1137
|
+
.fromType(VIEWER_TYPE.CLUSTER_MAX_ACTIVITY, viewerProperties) as ClusterMaxActivityViewer;
|
|
1138
|
+
const lstNode = this.findViewerNode(VIEWER_TYPE.LOGO_SUMMARY_TABLE) ?? null;
|
|
1139
|
+
this.analysisView.dockManager.dock(_clusterMaxActivity, lstNode ? DG.DOCK_TYPE.DOWN: DG.DOCK_TYPE.RIGHT,
|
|
1140
|
+
lstNode, VIEWER_TYPE.CLUSTER_MAX_ACTIVITY);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1118
1143
|
/**
|
|
1119
1144
|
* Adds Monomer-Position viewer to the analysis view
|
|
1120
1145
|
* @param {ISARViewer} [viewerProperties] - Viewer properties
|
|
@@ -1231,13 +1256,13 @@ export class PeptidesModel {
|
|
|
1231
1256
|
const seqCol = this.df.getCol(this.settings!.sequenceColumnName!);
|
|
1232
1257
|
this.settings!.mclSettings ??= new type.MCLSettings();
|
|
1233
1258
|
const mclParams = this.settings?.mclSettings;
|
|
1234
|
-
|
|
1235
1259
|
let counter = 0;
|
|
1236
|
-
const addedColCount =
|
|
1260
|
+
const addedColCount = 5; // embedx, embedy, cluster, cluster size and connectivity count
|
|
1237
1261
|
const columnAddedSub = this.df.onColumnsAdded.subscribe((colArgs: DG.ColumnsArgs) => {
|
|
1238
1262
|
for (const col of colArgs.columns) {
|
|
1239
|
-
if (col.name.toLowerCase().startsWith('embed') ||
|
|
1240
|
-
col.name.toLowerCase().startsWith('cluster')
|
|
1263
|
+
if ((col.name.toLowerCase().startsWith('embed') ||
|
|
1264
|
+
col.name.toLowerCase().startsWith('cluster') ||
|
|
1265
|
+
col.name.toLowerCase().startsWith('connectivity')) && col.name.toLowerCase().includes('mcl')) {
|
|
1241
1266
|
const gridCol = this.analysisView.grid.col(col.name);
|
|
1242
1267
|
if (gridCol == null || this._mclCols.includes(col.name))
|
|
1243
1268
|
continue;
|
|
@@ -1276,7 +1301,7 @@ export class PeptidesModel {
|
|
|
1276
1301
|
}], mclParams!.threshold, mclParams!.maxIterations,
|
|
1277
1302
|
);
|
|
1278
1303
|
mclAdditionSub.unsubscribe();
|
|
1279
|
-
this._mclViewer = mclViewer ?? null;
|
|
1304
|
+
this._mclViewer = mclViewer?.sc ?? null;
|
|
1280
1305
|
}
|
|
1281
1306
|
|
|
1282
1307
|
/**
|
package/src/package.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {MonomerWorks} from '@datagrok-libraries/bio/src/monomer-works/monomer-wo
|
|
|
13
13
|
import {PeptidesModel} from './model';
|
|
14
14
|
import {macromoleculeSarFastaDemoUI} from './demo/fasta';
|
|
15
15
|
import {u2} from '@datagrok-libraries/utils/src/u2';
|
|
16
|
+
import {ClusterMaxActivityViewer} from './viewers/cluster-max-activity-viewer';
|
|
16
17
|
|
|
17
18
|
let monomerWorks: MonomerWorks | null = null;
|
|
18
19
|
let treeHelper: ITreeHelper;
|
|
@@ -129,6 +130,13 @@ export function logoSummaryTable(): LogoSummaryTable {
|
|
|
129
130
|
return new LogoSummaryTable();
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
//name: Cluster Max Activity
|
|
134
|
+
//tags: viewer
|
|
135
|
+
//output: viewer result
|
|
136
|
+
export function clusterMaxActivity(): ClusterMaxActivityViewer {
|
|
137
|
+
return new ClusterMaxActivityViewer();
|
|
138
|
+
}
|
|
139
|
+
|
|
132
140
|
//name: Manual Alignment
|
|
133
141
|
//tags: panel, widgets
|
|
134
142
|
//input: string _monomer {semType: Monomer}
|
package/src/utils/types.ts
CHANGED
|
@@ -29,6 +29,7 @@ export interface PeptidesSettings {
|
|
|
29
29
|
showMostPotentResidues?: boolean,
|
|
30
30
|
showLogoSummaryTable?: boolean,
|
|
31
31
|
showDendrogram?: boolean,
|
|
32
|
+
showClusterMaxActivity?: boolean,
|
|
32
33
|
showSequenceSpace?: boolean,
|
|
33
34
|
columns?: AggregationColumns,
|
|
34
35
|
sequenceSpaceParams: SequenceSpaceParams,
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import * as ui from 'datagrok-api/ui';
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
import {PeptidesModel, VIEWER_TYPE} from '../model';
|
|
4
|
+
import {Options} from '@datagrok-libraries/utils/src/type-declarations';
|
|
5
|
+
import {ACTIVITY_TARGET, COLUMN_NAME, COLUMNS_NAMES} from '../utils/constants';
|
|
6
|
+
import wu from 'wu';
|
|
7
|
+
import $ from 'cash-dom';
|
|
8
|
+
export const enum ClusterMaxActivityProps {
|
|
9
|
+
CLUSTER_COLUMN = 'cluster',
|
|
10
|
+
ACTIVITY_COLUMN = 'activity',
|
|
11
|
+
COLOR_COLUMN = 'color',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IClusterMaxActivity {
|
|
15
|
+
clusterColumnName: string;
|
|
16
|
+
activityColumnName: string;
|
|
17
|
+
colorColumnName?: string;
|
|
18
|
+
activityTarget: ACTIVITY_TARGET;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export class ClusterMaxActivityViewer extends DG.JsViewer implements IClusterMaxActivity {
|
|
23
|
+
_titleHost = ui.divText(VIEWER_TYPE.CLUSTER_MAX_ACTIVITY, {id: 'pep-viewer-title'});
|
|
24
|
+
clusterColumnName: string;
|
|
25
|
+
activityColumnName: string;
|
|
26
|
+
colorColumnName: string;
|
|
27
|
+
activityTarget: ACTIVITY_TARGET = ACTIVITY_TARGET.HIGH;
|
|
28
|
+
_scViewer?: DG.ScatterPlotViewer | null;
|
|
29
|
+
viewerError: string = '';
|
|
30
|
+
renderTimeout: NodeJS.Timeout | number | null = null;
|
|
31
|
+
renderDebounceTime = 500;
|
|
32
|
+
static clusterSizeColName = '~cluster.size' as const;
|
|
33
|
+
static maxActivityInClusterSizeColName = '~max.activity.for.cluster.size' as const;
|
|
34
|
+
private scFilterQuery = `\$\{${ClusterMaxActivityViewer.maxActivityInClusterSizeColName}\} == 1` as const;
|
|
35
|
+
get scViewer(): DG.ScatterPlotViewer | null {
|
|
36
|
+
if (!this._scViewer)
|
|
37
|
+
this._scViewer = this.createSCViewer();
|
|
38
|
+
return this._scViewer;
|
|
39
|
+
}
|
|
40
|
+
constructor() {
|
|
41
|
+
super();
|
|
42
|
+
this.clusterColumnName = this.column(ClusterMaxActivityProps.CLUSTER_COLUMN, {nullable: false});
|
|
43
|
+
this.activityColumnName = this.column(ClusterMaxActivityProps.ACTIVITY_COLUMN, {nullable: false});
|
|
44
|
+
this.colorColumnName = this.column(ClusterMaxActivityProps.COLOR_COLUMN,
|
|
45
|
+
{nullable: true, defaultValue: null});
|
|
46
|
+
this.activityTarget = this.string(
|
|
47
|
+
'activityTarget', ACTIVITY_TARGET.HIGH, {choices: [ACTIVITY_TARGET.HIGH, ACTIVITY_TARGET.LOW]},
|
|
48
|
+
) as ACTIVITY_TARGET;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Returns PeptidesModel instance that belongs to the attached dataframe.
|
|
53
|
+
* @return - PeptidesModel instance.
|
|
54
|
+
*/
|
|
55
|
+
get model(): PeptidesModel {
|
|
56
|
+
return PeptidesModel.getInstance(this.dataFrame);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private createSCViewer(): DG.ScatterPlotViewer | null {
|
|
60
|
+
const scatterPlotProps: Partial<DG.IScatterPlotLookSettings> & Options = {
|
|
61
|
+
showXAxis: true,
|
|
62
|
+
showYAxis: true,
|
|
63
|
+
showXSelector: false,
|
|
64
|
+
showYSelector: false,
|
|
65
|
+
showColorSelector: false,
|
|
66
|
+
xAxisType: 'logarithmic',
|
|
67
|
+
yAxisType: 'logarithmic',
|
|
68
|
+
invertYAxis: this.activityTarget === ACTIVITY_TARGET.LOW,
|
|
69
|
+
xColumnName: ClusterMaxActivityViewer.clusterSizeColName,
|
|
70
|
+
markerType: 'circle',
|
|
71
|
+
markerDefaultSize: 10,
|
|
72
|
+
showSizeSelector: false,
|
|
73
|
+
};
|
|
74
|
+
if (this.clusterColumnName == null || this.activityColumnName == null ||
|
|
75
|
+
!this.dataFrame.columns.contains(this.clusterColumnName) ||
|
|
76
|
+
!this.dataFrame.columns.contains(this.activityColumnName)
|
|
77
|
+
) {
|
|
78
|
+
this.viewerError = 'Please set valid cluster and activity columns';
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const activityCol = this.dataFrame.columns.byName(this.activityColumnName);
|
|
82
|
+
const clusterCol = this.dataFrame.columns.byName(this.clusterColumnName);
|
|
83
|
+
const numericColTypes: DG.ColumnType[] =
|
|
84
|
+
[DG.COLUMN_TYPE.FLOAT, DG.COLUMN_TYPE.INT, DG.COLUMN_TYPE.BIG_INT, DG.COLUMN_TYPE.QNUM];
|
|
85
|
+
if (!numericColTypes.includes(activityCol.type)) {
|
|
86
|
+
this.viewerError = 'Activity column should be numeric';
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const clusterSizeCol = this.dataFrame.columns.getOrCreate(ClusterMaxActivityViewer.clusterSizeColName,
|
|
90
|
+
DG.TYPE.INT, this.dataFrame.rowCount);
|
|
91
|
+
const clusterSizeMap: {[key: number | string]: number} = {};
|
|
92
|
+
for (let i = 0; i < this.dataFrame.rowCount; i++) {
|
|
93
|
+
const cluster: string | number = clusterCol.get(i);
|
|
94
|
+
if (cluster == null)
|
|
95
|
+
continue;
|
|
96
|
+
clusterSizeMap[cluster] = (clusterSizeMap[cluster] ?? 0) + 1;
|
|
97
|
+
}
|
|
98
|
+
// for (let i = 0; i < this.dataFrame.rowCount; i++) {
|
|
99
|
+
// const cluster: string | number = clusterCol.get(i);
|
|
100
|
+
// if (clusterCol.isNone(i) || !clusterSizeMap[cluster])
|
|
101
|
+
// continue;
|
|
102
|
+
// clusterSizeCol.set(i, clusterSizeMap[cluster]);
|
|
103
|
+
// }
|
|
104
|
+
// clusterSizeCol.init((i) => {
|
|
105
|
+
// const cluster: string | number = clusterCol.get(i);
|
|
106
|
+
// if (clusterCol.isNone(i) || !clusterSizeMap[cluster])
|
|
107
|
+
// return null;
|
|
108
|
+
// return clusterSizeMap[cluster];
|
|
109
|
+
// });
|
|
110
|
+
clusterSizeCol.init((i) => clusterCol.isNone(i) ? null : clusterSizeMap[clusterCol.get(i)] ?? null);
|
|
111
|
+
|
|
112
|
+
if (activityCol.stats.min <= 0)
|
|
113
|
+
scatterPlotProps.yAxisType = 'linear';
|
|
114
|
+
|
|
115
|
+
// create a new column to store max activity for each cluster size
|
|
116
|
+
const maxActivityIndexPerClusterSizeMap: {[key: number]: number} = {};
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < this.dataFrame.rowCount; i++) {
|
|
119
|
+
const clusterSize: number | null = clusterSizeCol.get(i);
|
|
120
|
+
if (clusterSize == null || clusterSizeCol.isNone(i) || activityCol.isNone(i))
|
|
121
|
+
continue;
|
|
122
|
+
const activity: number = activityCol.get(i);
|
|
123
|
+
const prevMaxActivityIndex = maxActivityIndexPerClusterSizeMap[clusterSize];
|
|
124
|
+
if (prevMaxActivityIndex == null || prevMaxActivityIndex == undefined)
|
|
125
|
+
maxActivityIndexPerClusterSizeMap[clusterSize] = i;
|
|
126
|
+
else {
|
|
127
|
+
if (activity > activityCol.get(prevMaxActivityIndex) && this.activityTarget === ACTIVITY_TARGET.HIGH)
|
|
128
|
+
maxActivityIndexPerClusterSizeMap[clusterSize] = i;
|
|
129
|
+
else if (activity < activityCol.get(prevMaxActivityIndex) && this.activityTarget === ACTIVITY_TARGET.LOW)
|
|
130
|
+
maxActivityIndexPerClusterSizeMap[clusterSize] = i;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const maxAtivityInClusterSizeCol = this.dataFrame.columns.getOrCreate(
|
|
135
|
+
ClusterMaxActivityViewer.maxActivityInClusterSizeColName, DG.COLUMN_TYPE.INT, this.dataFrame.rowCount);
|
|
136
|
+
maxAtivityInClusterSizeCol.init((i) => {
|
|
137
|
+
if (clusterSizeCol.isNone(i))
|
|
138
|
+
return 0;
|
|
139
|
+
return i === maxActivityIndexPerClusterSizeMap[clusterSizeCol.get(i)] ? 1 : 0;
|
|
140
|
+
});
|
|
141
|
+
scatterPlotProps.xColumnName = ClusterMaxActivityViewer.clusterSizeColName;
|
|
142
|
+
scatterPlotProps.yColumnName = this.activityColumnName;
|
|
143
|
+
scatterPlotProps.filter = this.scFilterQuery;
|
|
144
|
+
this.viewerError = '';
|
|
145
|
+
const sc = DG.Viewer.scatterPlot(this.dataFrame, scatterPlotProps);
|
|
146
|
+
|
|
147
|
+
return sc;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
onTableAttached(): void {
|
|
151
|
+
super.onTableAttached();
|
|
152
|
+
const activityCol: DG.Column | null = this.dataFrame?.col(COLUMNS_NAMES.ACTIVITY) ??
|
|
153
|
+
wu(this.dataFrame?.columns.numerical).next()?.value;
|
|
154
|
+
if (activityCol != null)
|
|
155
|
+
this.getProperty(`${ClusterMaxActivityProps.ACTIVITY_COLUMN}${COLUMN_NAME}`)?.set(this, activityCol.name);
|
|
156
|
+
|
|
157
|
+
const clusterCol: DG.Column | null = wu(this.dataFrame?.columns.categorical).next()?.value;
|
|
158
|
+
if (clusterCol != null)
|
|
159
|
+
this.getProperty(`${ClusterMaxActivityProps.CLUSTER_COLUMN}${COLUMN_NAME}`)?.set(this, clusterCol.name);
|
|
160
|
+
|
|
161
|
+
this.render();
|
|
162
|
+
|
|
163
|
+
this.dataFrame.onDataChanged.subscribe(() => {
|
|
164
|
+
// this._scViewer = null;
|
|
165
|
+
// this.render();
|
|
166
|
+
|
|
167
|
+
this.render();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
render(): void {
|
|
172
|
+
if (this.renderTimeout)
|
|
173
|
+
clearTimeout(this.renderTimeout);
|
|
174
|
+
this.renderTimeout = setTimeout(() => {
|
|
175
|
+
$(this.root).empty();
|
|
176
|
+
const scViewer = this.scViewer;
|
|
177
|
+
if (scViewer == null) {
|
|
178
|
+
this.root.appendChild(ui.divText(this.viewerError ?? 'Error creating scatter plot'));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const clusterSizeLabel = ui.div('Cluster Size', {style: {
|
|
182
|
+
alignSelf: 'center',
|
|
183
|
+
color: 'var(--grey-6)',
|
|
184
|
+
marginBottom: '5px'},
|
|
185
|
+
});
|
|
186
|
+
const maxActivityLabel = ui.div(
|
|
187
|
+
this.activityTarget === ACTIVITY_TARGET.HIGH ? 'Maximum Activity' : 'Minimum Activity', {style: {
|
|
188
|
+
color: 'var(--grey-6)',
|
|
189
|
+
alignSelf: 'center',
|
|
190
|
+
textOrientation: 'mixed',
|
|
191
|
+
writingMode: 'tb',
|
|
192
|
+
transform: 'rotate(180deg)',
|
|
193
|
+
marginLeft: '5px',
|
|
194
|
+
}});
|
|
195
|
+
scViewer.props.colorColumnName = this.colorColumnName ?? null;
|
|
196
|
+
this.root.appendChild(
|
|
197
|
+
ui.divH([
|
|
198
|
+
maxActivityLabel,
|
|
199
|
+
ui.divV([
|
|
200
|
+
ui.divH([this._titleHost], {
|
|
201
|
+
style: {
|
|
202
|
+
alignSelf: 'center',
|
|
203
|
+
lineHeight: 'normal',
|
|
204
|
+
},
|
|
205
|
+
}),
|
|
206
|
+
scViewer.root,
|
|
207
|
+
clusterSizeLabel,
|
|
208
|
+
], {style: {flexGrow: '1'},
|
|
209
|
+
}),
|
|
210
|
+
]),
|
|
211
|
+
);
|
|
212
|
+
scViewer.root.style.width = '100%';
|
|
213
|
+
//this.root.appendChild(scViewer.root);
|
|
214
|
+
setTimeout(() => {
|
|
215
|
+
scViewer.props.filter = this.scFilterQuery;
|
|
216
|
+
scViewer.invalidateCanvas();
|
|
217
|
+
}, 100);
|
|
218
|
+
}, this.renderDebounceTime);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
onPropertyChanged(property: DG.Property | null): void {
|
|
222
|
+
super.onPropertyChanged(property);
|
|
223
|
+
if (property?.name !== `${ClusterMaxActivityProps.COLOR_COLUMN}${COLUMN_NAME}`)
|
|
224
|
+
this._scViewer = null;
|
|
225
|
+
this.render();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
@@ -580,7 +580,7 @@ export class LogoSummaryTable extends DG.JsViewer implements ILogoSummaryTable {
|
|
|
580
580
|
grid.onCellRender.subscribe(async (gridCellArgs) => {
|
|
581
581
|
const gridCell = gridCellArgs.cell;
|
|
582
582
|
const currentRowIdx = gridCell.tableRowIndex;
|
|
583
|
-
if (!gridCell.isTableCell || currentRowIdx
|
|
583
|
+
if (!gridCell.isTableCell || currentRowIdx == null || currentRowIdx === -1)
|
|
584
584
|
return;
|
|
585
585
|
|
|
586
586
|
|
package/src/widgets/settings.ts
CHANGED
|
@@ -113,6 +113,9 @@ export function getSettingsDialog(model: PeptidesModel): SettingsElements {
|
|
|
113
113
|
const isDendrogramEnabled = wu(model.analysisView.viewers).some((v) => v.type === VIEWER_TYPE.DENDROGRAM);
|
|
114
114
|
const dendrogram = ui.boolInput(VIEWER_TYPE.DENDROGRAM, isDendrogramEnabled ?? false,
|
|
115
115
|
() => result.showDendrogram = dendrogram.value) as DG.InputBase<boolean>;
|
|
116
|
+
const clusterMaxActivity = ui.boolInput(VIEWER_TYPE.CLUSTER_MAX_ACTIVITY, !!settings?.showClusterMaxActivity, () => {
|
|
117
|
+
result.showClusterMaxActivity = clusterMaxActivity.value ?? undefined;
|
|
118
|
+
});
|
|
116
119
|
const showSeqSpace = ui.boolInput('Sequence space', !!settings?.showSequenceSpace, () => {
|
|
117
120
|
result.showSequenceSpace = showSeqSpace.value ?? undefined;
|
|
118
121
|
if (showSeqSpace.value) {
|
|
@@ -126,11 +129,12 @@ export function getSettingsDialog(model: PeptidesModel): SettingsElements {
|
|
|
126
129
|
if (result.showSequenceSpace === settings?.showSequenceSpace)
|
|
127
130
|
delete result.showSequenceSpace;
|
|
128
131
|
});
|
|
132
|
+
clusterMaxActivity.setTooltip('Show cluster max activity viewer');
|
|
129
133
|
dendrogram.setTooltip('Show dendrogram viewer');
|
|
130
134
|
dendrogram.enabled = getTreeHelperInstance() !== null;
|
|
131
135
|
|
|
132
|
-
accordion.addPane(SETTINGS_PANES.VIEWERS, () => ui.inputs([dendrogram, showSeqSpace]), true);
|
|
133
|
-
inputs[SETTINGS_PANES.VIEWERS] = [dendrogram];
|
|
136
|
+
accordion.addPane(SETTINGS_PANES.VIEWERS, () => ui.inputs([dendrogram, showSeqSpace, clusterMaxActivity]), true);
|
|
137
|
+
inputs[SETTINGS_PANES.VIEWERS] = [dendrogram, showSeqSpace, clusterMaxActivity];
|
|
134
138
|
|
|
135
139
|
// Columns to include pane options
|
|
136
140
|
const inputsRows: HTMLElement[] = [];
|