@datagrok/peptides 0.3.0 → 0.5.6

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.
@@ -3,13 +3,22 @@ import * as DG from 'datagrok-api/dg';
3
3
 
4
4
  const cp = new ChemPalette('grok');
5
5
 
6
- export function expandColumn(col:DG.Column,
7
- grid:DG.Grid,
8
- cellRenderSize: (celVal:string)=>number,
9
- textSizeMult = 10,
10
- minSize = 30,
11
- maxSize = 650,
12
- timeout = 500) {
6
+ /**
7
+ * A function to expand column size based on its contents.
8
+ *
9
+ * @export
10
+ * @param {DG.Column} col Column to expand.
11
+ * @param {DG.Grid} grid Grid containing colum for expansion.
12
+ * @param {(cellVal: string) => number} cellRenderSize An anonymous function that calculates cell value length.
13
+ * @param {number} [textSizeMult=10] Text size muliplier.
14
+ * @param {number} [minSize=30] Minimal column width.
15
+ * @param {number} [maxSize=650] Maximum column width.
16
+ * @param {number} [timeout=500] Timeout value.
17
+ */
18
+ export function expandColumn(
19
+ col: DG.Column, grid: DG.Grid, cellRenderSize: (cellVal: string) => number,
20
+ textSizeMult = 10, minSize = 30, maxSize = 650, timeout = 500,
21
+ ) {
13
22
  let maxLen = 0;
14
23
  col.categories.forEach((ent: string) => {
15
24
  const len = cellRenderSize(ent);
@@ -23,24 +32,57 @@ export function expandColumn(col:DG.Column,
23
32
  timeout);
24
33
  }
25
34
 
26
- export function setAARRenderer(col:DG.Column, grid:DG.Grid|null = null) {
35
+ /**
36
+ * A function that sets amino acid residue to the specified column.
37
+ *
38
+ * @export
39
+ * @param {DG.Column} col Column to set renderer for.
40
+ * @param {(DG.Grid | null)} [grid=null] Grid that contains the col column.
41
+ * @param {boolean} [grouping=false] Is grouping enabled.
42
+ */
43
+ export function setAARRenderer(col: DG.Column, grid: DG.Grid | null = null, grouping = false) {
27
44
  col.semType = 'aminoAcids';
28
45
  col.setTag('cell.renderer', 'aminoAcids');
29
- if (grid)
46
+ if (grouping) {
47
+ col.setTag('groups', `${grouping}`);
48
+ }
49
+ if (grid) {
30
50
  expandColumn(col, grid, (ent) => measureAAR(ent));
51
+ }
31
52
  }
32
-
53
+ /**
54
+ * A function to measure amino acid residue
55
+ *
56
+ * @export
57
+ * @param {string} s Amino acid residue string.
58
+ * @return {number} Amino acid residue size.
59
+ */
33
60
  export function measureAAR(s: string): number {
34
61
  const end = s.lastIndexOf(')');
35
62
  const beg = s.indexOf('(');
36
- return end == beg ? s.length:s.length - (end-beg)+1;
63
+ return end == beg ? s.length : s.length - (end - beg) + 1;
37
64
  }
38
65
 
39
- function printLeftCentered(
40
- x: number, y: number, w: number, h: number,
41
- g: CanvasRenderingContext2D, s: string, color = ChemPalette.undefinedColor,
42
- pivot: number = 0, left = false, hideMod = false) {
43
-
66
+ /**
67
+ * A function that prints a string aligned to left or centered.
68
+ *
69
+ * @param {number} x x coordinate.
70
+ * @param {number} y y coordinate.
71
+ * @param {number} w Width.
72
+ * @param {number} h Height.
73
+ * @param {CanvasRenderingContext2D} g Canvas rendering context.
74
+ * @param {string} s String to print.
75
+ * @param {string} [color=ChemPalette.undefinedColor] String color.
76
+ * @param {number} [pivot=0] Pirvot.
77
+ * @param {boolean} [left=false] Is left aligned.
78
+ * @param {boolean} [hideMod=false] Hide amino acid redidue modifications.
79
+ * @return {number} x coordinate to start printing at.
80
+ */
81
+ function printLeftOrCentered(
82
+ x: number, y: number, w: number, h: number,
83
+ g: CanvasRenderingContext2D, s: string, color = ChemPalette.undefinedColor,
84
+ pivot: number = 0, left = false, hideMod = false,
85
+ ) {
44
86
  g.textAlign = 'start';
45
87
  let colorPart = pivot == -1 ? s.substring(0) : s.substring(0, pivot);
46
88
  if (colorPart.length == 1) {
@@ -91,22 +133,66 @@ function printLeftCentered(
91
133
  if (left || textSize.width > w) {
92
134
  draw(indent, indent + colorTextSize.width);
93
135
  return x + colorTextSize.width + g.measureText(grayPart).width;
94
- }
95
- else {
136
+ } else {
96
137
  draw((w - textSize.width) / 2, (w - textSize.width) / 2 + colorTextSize.width);
97
138
  return x + (w - textSize.width) / 2 + colorTextSize.width;
98
139
  }
99
140
  }
100
141
 
101
-
142
+ /**
143
+ * Amino acid residue cell renderer.
144
+ *
145
+ * @export
146
+ * @class AminoAcidsCellRenderer
147
+ * @extends {DG.GridCellRenderer}
148
+ */
102
149
  export class AminoAcidsCellRenderer extends DG.GridCellRenderer {
150
+ chemPalette: ChemPalette | null;
103
151
 
104
- get name() { return 'aminoAcidsCR'; }
152
+ /**
153
+ * Renderer name.
154
+ *
155
+ * @readonly
156
+ * @memberof AminoAcidsCellRenderer
157
+ */
158
+ get name() {
159
+ return 'aminoAcidsCR';
160
+ }
105
161
 
106
- get cellType() { return 'aminoAcids'; }
162
+ /**
163
+ * Cell type.
164
+ *
165
+ * @readonly
166
+ * @memberof AminoAcidsCellRenderer
167
+ */
168
+ get cellType() {
169
+ return 'aminoAcids';
170
+ }
171
+
172
+ /**
173
+ * Constructor.
174
+ */
175
+ constructor() {
176
+ super();
177
+ this.chemPalette = null;
178
+ }
107
179
 
180
+ /**
181
+ * Cell renderer function.
182
+ *
183
+ * @param {CanvasRenderingContext2D} g Canvas rendering context.
184
+ * @param {number} x x coordinate on the canvas.
185
+ * @param {number} y y coordinate on the canvas.
186
+ * @param {number} w width of the cell.
187
+ * @param {number} h height of the cell.
188
+ * @param {DG.GridCell} gridCell Grid cell.
189
+ * @param {DG.GridCellStyle} cellStyle Cell style.
190
+ */
108
191
  render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
109
- gridCell: DG.GridCell, cellStyle: DG.GridCellStyle) {
192
+ gridCell: DG.GridCell, cellStyle: DG.GridCellStyle) {
193
+ if (this.chemPalette === null) {
194
+ this.chemPalette = new ChemPalette('grok', gridCell.tableColumn?.getTag('groups') ? true : false);
195
+ }
110
196
  g.save();
111
197
  g.beginPath();
112
198
  g.rect(x, y, w, h);
@@ -115,63 +201,102 @@ export class AminoAcidsCellRenderer extends DG.GridCellRenderer {
115
201
  g.textBaseline = 'top';
116
202
  const s: string = gridCell.cell.value ? gridCell.cell.value : '-';
117
203
  const [color, pivot] = cp.getColorPivot(s);
118
- printLeftCentered(x, y, w, h, g, s, color, pivot, false, true);
204
+ printLeftOrCentered(x, y, w, h, g, s, color, pivot, false, true);
119
205
  g.restore();
120
206
  }
121
207
  }
122
208
 
123
-
209
+ /**
210
+ * Aligned sequence cell renderer.
211
+ *
212
+ * @export
213
+ * @class AlignedSequenceCellRenderer
214
+ * @extends {DG.GridCellRenderer}
215
+ */
124
216
  export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
217
+ /**
218
+ * Renderer name.
219
+ *
220
+ * @readonly
221
+ * @memberof AlignedSequenceCellRenderer
222
+ */
223
+ get name() {
224
+ return 'alignedSequenceCR';
225
+ }
125
226
 
126
- get name() { return 'alignedSequenceCR'; }
127
-
128
- get cellType() { return 'alignedSequence'; }
227
+ /**
228
+ * Cell type.
229
+ *
230
+ * @readonly
231
+ * @memberof AlignedSequenceCellRenderer
232
+ */
233
+ get cellType() {
234
+ return 'alignedSequence';
235
+ }
129
236
 
130
- render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
131
- gridCell: DG.GridCell, cellStyle: DG.GridCellStyle ) {
132
- w = Math.min(gridCell.grid.canvas.width - x, w);
133
- g.save();
134
- g.beginPath();
135
- g.rect(x, y, w, h);
136
- g.clip();
137
- g.font = '14px monospace';
138
- g.textBaseline = 'top';
139
- const s: string = gridCell.cell.value ?? '';
140
-
141
- const subParts = s.split('-');
142
- const [text, simplified] = processSequence(subParts);
143
- const textSize = g.measureText(text.join(''));
144
- x = Math.max(x, x + (w - textSize.width) / 2);
145
-
146
- subParts.forEach((amino: string, index) => {
147
- const [color, pivot] = cp.getColorPivot(amino);
148
- g.fillStyle = ChemPalette.undefinedColor;
149
- if (index + 1 < subParts.length) {
150
- const gap = simplified?'':' ';
151
- amino += `${amino?'':'-'}${gap}`;
152
- }
153
- x = printLeftCentered(x, y, w, h, g, amino, color, pivot, true);
154
- });
237
+ /**
238
+ * Cell renderer function.
239
+ *
240
+ * @param {CanvasRenderingContext2D} g Canvas rendering context.
241
+ * @param {number} x x coordinate on the canvas.
242
+ * @param {number} y y coordinate on the canvas.
243
+ * @param {number} w width of the cell.
244
+ * @param {number} h height of the cell.
245
+ * @param {DG.GridCell} gridCell Grid cell.
246
+ * @param {DG.GridCellStyle} cellStyle Cell style.
247
+ * @memberof AlignedSequenceCellRenderer
248
+ */
249
+ render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
250
+ gridCell: DG.GridCell, cellStyle: DG.GridCellStyle ) {
251
+ w = Math.min(gridCell.grid.canvas.width - x, w);
252
+ g.save();
253
+ g.beginPath();
254
+ g.rect(x, y, w, h);
255
+ g.clip();
256
+ g.font = '14px monospace';
257
+ g.textBaseline = 'top';
258
+ const s: string = gridCell.cell.value ?? '';
155
259
 
156
- g.restore();
157
- }
158
- }
260
+ //TODO: can this be replaced/merged with splitSequence?
261
+ const subParts = s.split('-');
262
+ const [text, simplified] = processSequence(subParts);
263
+ const textSize = g.measureText(text.join(''));
264
+ x = Math.max(x, x + (w - textSize.width) / 2);
159
265
 
266
+ subParts.forEach((amino: string, index) => {
267
+ const [color, pivot] = cp.getColorPivot(amino);
268
+ g.fillStyle = ChemPalette.undefinedColor;
269
+ if (index + 1 < subParts.length) {
270
+ const gap = simplified?'':' ';
271
+ amino += `${amino?'':'-'}${gap}`;
272
+ }
273
+ x = printLeftOrCentered(x, y, w, h, g, amino, color, pivot, true);
274
+ });
160
275
 
161
- export function processSequence(subParts:string[]) : [string[], boolean] {
276
+ g.restore();
277
+ }
278
+ }
162
279
 
280
+ /**
281
+ * Function for sequence processing.
282
+ *
283
+ * @export
284
+ * @param {string[]} subParts Sequence subparts.
285
+ * @return {[string[], boolean]}
286
+ */
287
+ export function processSequence(subParts: string[]): [string[], boolean] {
163
288
  const simplified = !subParts.some((amino, index) =>
164
289
  amino.length > 1 &&
165
290
  index != 0 &&
166
291
  index != subParts.length - 1);
167
292
 
168
- const text:string[] = [];
293
+ const text: string[] = [];
294
+ const gap = simplified ? '' : ' ';
169
295
  subParts.forEach((amino: string, index) => {
170
296
  if (index < subParts.length) {
171
- const gap = simplified?'':' ';
172
- amino += `${amino?'':'-'}${gap}`;
297
+ amino += `${amino ? '' : '-'}${gap}`;
173
298
  }
174
299
  text.push(amino);
175
300
  });
176
301
  return [text, simplified];
177
- }
302
+ }