@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,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.
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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(${
|
|
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';
|