@datagrok/sequence-translator 1.3.2 → 1.3.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/sequence-translator",
3
3
  "friendlyName": "Sequence Translator",
4
- "version": "1.3.2",
4
+ "version": "1.3.3",
5
5
  "author": {
6
6
  "name": "Alexey Choposky",
7
7
  "email": "achopovsky@datagrok.ai"
@@ -1,5 +1,5 @@
1
1
  import {NUCLEOTIDES} from '../../../common/model/const';
2
- import {STRAND, STRANDS, TERMINUS} from '../../model/const';
2
+ import {STRAND, STRANDS, TERMINI, TERMINUS} from '../../model/const';
3
3
  import {PatternConfiguration} from '../../model/types';
4
4
  import {isOverhangNucleotide} from '../../model/utils';
5
5
  import {SVG_CIRCLE_SIZES, SVG_ELEMENT_COLORS, SVG_TEXT_FONT_SIZES} from './const';
@@ -19,6 +19,7 @@ const RIGHT_LABEL_WIDTH = 20;
19
19
  export class StrandsBlock extends SVGBlockBase {
20
20
  private strands: SVGBlockBase[];
21
21
  private labels: SVGBlockBase[];
22
+ private terminalModifications: SVGBlockBase[];
22
23
  constructor(
23
24
  svgElementFactory: SVGElementFactory,
24
25
  config: PatternConfiguration,
@@ -30,16 +31,22 @@ export class StrandsBlock extends SVGBlockBase {
30
31
  this.strands = strandTypes
31
32
  .map((strand) => new SingleStrandBlock(this.svgElementFactory, config, yShift, strand));
32
33
 
34
+
35
+ this.terminalModifications = strandTypes.map(
36
+ (strandType, idx) =>
37
+ new TerminalModificationLabels(this.svgElementFactory, config, yShift, strandType, this.strands[idx] as SingleStrandBlock)
38
+ );
33
39
  this.labels = strandTypes.map(
34
40
  (strandType, idx) =>
35
- new StrandLabel(this.svgElementFactory, config, yShift, strandType, this.strands[idx] as SingleStrandBlock)
41
+ new StrandLabel(this.svgElementFactory, config, yShift, strandType, this.terminalModifications[idx] as TerminalModificationLabels)
36
42
  );
37
43
  }
38
44
 
39
45
  get svgElements(): SVGElement[] {
40
46
  const elements = [
41
47
  ...this.strands,
42
- ...this.labels
48
+ ...this.terminalModifications,
49
+ ...this.labels,
43
50
  ].map((block) => block.svgElements).flat();
44
51
  return elements;
45
52
  }
@@ -255,11 +262,10 @@ class StrandLabel extends SVGBlockBase {
255
262
  protected config: PatternConfiguration,
256
263
  protected yShift: number,
257
264
  private strand: STRAND,
258
- private strandSvgWrapper: SingleStrandBlock
265
+ private terminalModifications: TerminalModificationLabels
259
266
  ) {
260
267
  super(svgElementFactory, config, yShift);
261
268
  this._svgElements = this.createSVGElements();
262
- // this.strandSvgWrapper.shiftElements({x: this.getLeftLabelWidth(), y: 0});
263
269
  }
264
270
 
265
271
  private createSVGElements(): SVGElement[] {
@@ -300,7 +306,7 @@ class StrandLabel extends SVGBlockBase {
300
306
  const text = ` ${terminus}`;
301
307
  const textDimensions = TextDimensionsCalculator.getTextDimensions(text, SVG_TEXT_FONT_SIZES.NUCLEOBASE);
302
308
  const position = {
303
- x: SENSE_STRAND_HORIZONTAL_SHIFT + this.strandSvgWrapper.getContentWidth() + 5,
309
+ x: SENSE_STRAND_HORIZONTAL_SHIFT + this.terminalModifications.getContentWidth() + 5,
304
310
  y: getStrandCircleYShift(this.strand, this.yShift) + textDimensions.height / 3
305
311
  };
306
312
 
@@ -317,7 +323,92 @@ class StrandLabel extends SVGBlockBase {
317
323
  }
318
324
 
319
325
  getContentWidth(): number {
320
- return this.strandSvgWrapper.getContentWidth() + this.getLeftLabelWidth() + this.getRightLabelWidth() + SENSE_STRAND_PADDING;
326
+ return this.terminalModifications.getContentWidth() + this.getLeftLabelWidth() +
327
+ this.getRightLabelWidth() + SENSE_STRAND_PADDING;
328
+ }
329
+
330
+ getContentHeight(): number {
331
+ return this.terminalModifications.getContentHeight();
332
+ }
333
+ }
334
+
335
+ class TerminalModificationLabels extends SVGBlockBase {
336
+ private _svgElements: SVGElement[];
337
+ constructor(
338
+ protected svgElementFactory: SVGElementFactory,
339
+ protected config: PatternConfiguration,
340
+ protected yShift: number,
341
+ private strand: STRAND,
342
+ private strandSvgWrapper: SingleStrandBlock
343
+ ) {
344
+ super(svgElementFactory, config, yShift);
345
+ this._svgElements = this.createSVGElements();
346
+ }
347
+
348
+ private createSVGElements(): SVGElement[] {
349
+ const elements = this.createTerminalModifications();
350
+ return elements;
351
+ }
352
+
353
+ private getTerminalModification(terminus: TERMINUS): string {
354
+ const terminalModification = this.config.strandTerminusModifications[this.strand][terminus];
355
+ return terminalModification;
356
+ }
357
+
358
+ private getTerminalModificationTextDimensions(terminus: TERMINUS): {width: number, height: number} {
359
+ const terminalModification = this.getTerminalModification(terminus);
360
+ const textDimensions = TextDimensionsCalculator
361
+ .getTextDimensions(terminalModification, SVG_TEXT_FONT_SIZES.NUCLEOBASE);
362
+ return textDimensions;
363
+ }
364
+
365
+ private getLeftTerminus(): TERMINUS {
366
+ return this.strand === STRAND.SENSE ? TERMINUS.FIVE_PRIME : TERMINUS.THREE_PRIME;
367
+ }
368
+
369
+ private createTerminalModification(terminus: TERMINUS): SVGTextElement {
370
+ const terminalModification = this.getTerminalModification(terminus);
371
+ const dimensions = this.getTerminalModificationTextDimensions(terminus);
372
+
373
+ const isLeft = terminus === this.getLeftTerminus();
374
+ const xShift = isLeft ? SENSE_STRAND_HORIZONTAL_SHIFT :
375
+ SENSE_STRAND_HORIZONTAL_SHIFT +
376
+ this.getTerminalModificationTextDimensions(this.getLeftTerminus()).width +
377
+ this.strandSvgWrapper.getContentWidth();
378
+ const position = {
379
+ x: xShift,
380
+ y: getStrandCircleYShift(this.strand, this.yShift) + dimensions.height / 3
381
+ };
382
+ if (isLeft) {
383
+ this.strandSvgWrapper.shiftElements({
384
+ x: dimensions.width,
385
+ y: 0
386
+ });
387
+ }
388
+
389
+ return this.svgElementFactory.createTextElement(
390
+ terminalModification,
391
+ position,
392
+ SVG_TEXT_FONT_SIZES.NUCLEOBASE,
393
+ SVG_ELEMENT_COLORS.MODIFICATION_TEXT
394
+ );
395
+ }
396
+
397
+ private createTerminalModifications(): SVGTextElement[] {
398
+ const termini = (this.strand === STRAND.ANTISENSE) ? TERMINI : Array.from(TERMINI).reverse();
399
+ const textElements = termini.map((terminus) => this.createTerminalModification(terminus));
400
+ return textElements;
401
+ }
402
+
403
+ get svgElements(): SVGElement[] {
404
+ return this._svgElements;
405
+ }
406
+
407
+ getContentWidth(): number {
408
+ return this.strandSvgWrapper.getContentWidth() +
409
+ TERMINI
410
+ .map((terminus) => this.getTerminalModificationTextDimensions(terminus).width)
411
+ .reduce((acc, curr) => acc += curr, 0);
321
412
  }
322
413
 
323
414
  getContentHeight(): number {
@@ -17,21 +17,13 @@ export abstract class SVGBlockBase {
17
17
  shiftElements(shift: {x: number, y: number}): void {
18
18
  this.svgElements.forEach((element) => {
19
19
  const transform = element.getAttribute('transform') || '';
20
- const match = transform.match(/translate\(([^,]+),([^,]+)\)/);
21
- const x = match ? parseFloat(match[1]) : 0;
22
- const y = match ? parseFloat(match[2]) : 0;
23
- const newTransform = `translate(${x + shift.x},${y + shift.y})`;
20
+ // const match = transform.match(/translate\(([^,]+),([^,]+)\)/);
21
+ // const x = match ? parseFloat(match[1]) : 0;
22
+ // const y = match ? parseFloat(match[2]) : 0;
23
+ const newTransform = `translate(${shift.x},${shift.y})`;
24
24
  element.setAttribute('transform', `${transform} ${newTransform}`);
25
25
  });
26
26
  }
27
27
 
28
- adjustContentWithinGlobalContainer(globalWidth: number): void {
29
- const contentWidth = this.getContentWidth();
30
- if (contentWidth < globalWidth) {
31
- const shift = (globalWidth - contentWidth) / 2;
32
- this.shiftElements({x: shift, y: 0});
33
- }
34
- }
35
-
36
28
  abstract getContentWidth(): number;
37
29
  }
package/src/package.ts CHANGED
@@ -1,5 +1,6 @@
1
- import DG from 'datagrok-api/dg';
2
1
  import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
3
4
 
4
5
  import {MonomerLibWrapper} from './apps/common/model/monomer-lib/lib-wrapper';
5
6
  import {OligoToolkitPackage} from './apps/common/model/oligo-toolkit-package';