@datagrok/bio 2.26.4 → 2.26.5

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,7 +3,8 @@ import * as DG from 'datagrok-api/dg';
3
3
  import {GridCell} from 'datagrok-api/dg';
4
4
  import * as ui from 'datagrok-api/ui';
5
5
  import {ALPHABET, monomerToShort} from '@datagrok-libraries/bio/src/utils/macromolecule';
6
- import {BioTags, GAP_SYMBOL, MONOMER_MOTIF_SPLITTER, TAGS as bioTAGS,} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
6
+ import {BioTags, GAP_SYMBOL, MONOMER_CANONICALIZER_FUNC_TAG, MONOMER_CANONICALIZER_TEMP, MONOMER_MOTIF_SPLITTER, TAGS as bioTAGS,} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
7
+ import {IMonomerCanonicalizer} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
7
8
  import {MONOMER_RENDERER_TAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer';
8
9
  import {getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
9
10
 
@@ -24,6 +25,34 @@ export class MonomerCellRendererBack extends CellRendererWithMonomerLibBackBase
24
25
  super(gridCol, tableCol);
25
26
  }
26
27
 
28
+ private static readonly _canonLoadingKey = MONOMER_CANONICALIZER_TEMP + '.loading';
29
+
30
+ /** Lazily resolves and caches the IMonomerCanonicalizer from the column tag/temp.
31
+ * Uses async apply() so the plugin package doesn't need to be loaded yet.
32
+ * Returns null while loading; the resolved instance is cached for subsequent calls. */
33
+ private getCanonicalizer(col: DG.Column): IMonomerCanonicalizer | null {
34
+ const cached: IMonomerCanonicalizer | null = col.temp[MONOMER_CANONICALIZER_TEMP] ?? null;
35
+ if (cached) return cached;
36
+ // Already loading — don't fire another request
37
+ if (col.temp[MonomerCellRendererBack._canonLoadingKey]) return null;
38
+ const funcName = col.getTag(MONOMER_CANONICALIZER_FUNC_TAG);
39
+ if (!funcName) return null;
40
+ const parts = funcName.includes(':') ? funcName.split(':') : [undefined, funcName];
41
+ const funcs = DG.Func.find({name: parts[1], package: parts[0]});
42
+ if (funcs.length === 0) return null;
43
+ col.temp[MonomerCellRendererBack._canonLoadingKey] = true;
44
+ funcs[0].apply({}).then((canon: IMonomerCanonicalizer) => {
45
+ col.temp[MONOMER_CANONICALIZER_TEMP] = canon;
46
+ col.temp[MonomerCellRendererBack._canonLoadingKey] = false;
47
+ // Invalidate the grid so cells re-render with the canonicalizer
48
+ if (this.gridCol?.grid?.invalidate)
49
+ this.gridCol.grid.invalidate();
50
+ }).catch(() => {
51
+ col.temp[MonomerCellRendererBack._canonLoadingKey] = false;
52
+ });
53
+ return null;
54
+ }
55
+
27
56
  render(g: CanvasRenderingContext2D,
28
57
  x: number, y: number, w: number, h: number, gridCell: DG.GridCell, cellStyle: DG.GridCellStyle
29
58
  ): void {
@@ -41,6 +70,10 @@ export class MonomerCellRendererBack extends CellRendererWithMonomerLibBackBase
41
70
  g.textAlign = 'left';
42
71
 
43
72
  let value: string = gridCell.cell.value;
73
+ // render original value
74
+ // const canonicalizer = this.getCanonicalizer(gridCell.cell.column);
75
+ // if (canonicalizer && value)
76
+ // value = canonicalizer.canonicalize(value);
44
77
  if (!value || value === GAP_SYMBOL)
45
78
  value = DASH_GAP_SYMBOL;
46
79
  const symbols = value.split(MONOMER_MOTIF_SPLITTER).map((s) => !s || s === GAP_SYMBOL ? DASH_GAP_SYMBOL : s.trim());
@@ -88,12 +121,16 @@ export class MonomerCellRendererBack extends CellRendererWithMonomerLibBackBase
88
121
  ) return false;
89
122
 
90
123
  const alphabet = tableCol.getTag(bioTAGS.alphabet) as ALPHABET;
91
- const monomerName: string = gridCell.cell.value;
124
+ const rawMonomerName: string = gridCell.cell.value;
125
+ const canonicalizer = this.getCanonicalizer(tableCol);
126
+ const monomerName = canonicalizer && rawMonomerName ? canonicalizer.canonicalize(rawMonomerName) : rawMonomerName;
92
127
  const canvasClientRect = gridCell.grid.canvas.getBoundingClientRect();
93
128
  const x1 = gridCell.bounds.right + canvasClientRect.left - 4;
94
129
  const y1 = gridCell.bounds.bottom + canvasClientRect.top - 4;
95
130
 
96
- if (!monomerName || monomerName == GAP_SYMBOL || monomerName == DASH_GAP_SYMBOL) {
131
+ const isGap = !rawMonomerName || rawMonomerName == GAP_SYMBOL || rawMonomerName == DASH_GAP_SYMBOL ||
132
+ (canonicalizer != null && canonicalizer.isGap(rawMonomerName));
133
+ if (isGap) {
97
134
  ui.tooltip.show(ui.divText('gap'), x1, y1);
98
135
  return true;
99
136
  }