@datagrok/sequence-translator 0.0.3 → 0.0.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.
@@ -1,8 +1,8 @@
1
- import {axolabsMap} from "./axolabsMap";
1
+ import {axolabsMap} from './axolabsMap';
2
2
 
3
3
  // https://uxdesign.cc/star-rating-make-svg-great-again-d4ce4731347e
4
- function getPointsToDrawStar(centerX: number, centerY: number) {
5
- const innerCirclePoints = 5; // a 5 point star
4
+ function getPointsToDrawStar(centerX: number, centerY: number): string {
5
+ const innerCirclePoints = 5; // a 5 point star
6
6
  const innerRadius = 15 / innerCirclePoints;
7
7
  const innerOuterRadiusRatio = 2; // outter circle is x2 the inner
8
8
  const outerRadius = innerRadius * innerOuterRadiusRatio;
@@ -12,9 +12,9 @@ function getPointsToDrawStar(centerX: number, centerY: number) {
12
12
 
13
13
  let points = '';
14
14
  for (let i = 0; i < totalNumberOfPoints; i++) {
15
- let r = (i % 2 == 0) ? outerRadius : innerRadius;
16
- let currentX = centerX + Math.cos(i * angle + angleOffsetToCenterStar) * r;
17
- let currentY = centerY + Math.sin(i * angle + angleOffsetToCenterStar) * r;
15
+ const r = (i % 2 == 0) ? outerRadius : innerRadius;
16
+ const currentX = centerX + Math.cos(i * angle + angleOffsetToCenterStar) * r;
17
+ const currentY = centerY + Math.sin(i * angle + angleOffsetToCenterStar) * r;
18
18
  points += currentX + ',' + currentY + ' ';
19
19
  }
20
20
  return points;
@@ -35,121 +35,137 @@ function getTextWidth(text: string, font: number): number {
35
35
  return 2 * context.measureText(text).width;
36
36
  }
37
37
 
38
- function getTextInsideCircle(bases: string[], index: number, nucleotideCounter: number, numberOfNucleotides: number, enumerateModifications: string[]): string {
39
- return (bases[index].slice(-3) == "(o)") || !enumerateModifications.includes(bases[index]) ? "" :
38
+ function getTextInsideCircle(
39
+ bases: string[], index: number, nucleotideCounter: number,
40
+ numberOfNucleotides: number, enumerateModifications: string[]): string {
41
+ return (bases[index].slice(-3) == '(o)') || !enumerateModifications.includes(bases[index]) ? '' :
40
42
  ['A', 'G', 'C', 'U', 'T'].includes(bases[index]) ? bases[index] : String(numberOfNucleotides - nucleotideCounter);
41
43
  }
42
44
 
43
- function getFontColorVisibleOnBackground(rgbString: string) {
44
- const rgbIntList = rgbString.match(/\d+/g)!.map(e => Number(e));
45
- return (rgbIntList[0] * 0.299 + rgbIntList[1] * 0.587 + rgbIntList[2] * 0.114) > 186 ? '#333333' : '#ffffff';
45
+ function getFontColorVisibleOnBackground(rgbString: string): string {
46
+ const rgbIntList = rgbString.match(/\d+/g)!.map((e) => Number(e));
47
+ return (rgbIntList[0] * 0.299 + rgbIntList[1] * 0.587 + rgbIntList[2] * 0.114) > 186 ? '#33333' : '#ffffff';
46
48
  }
47
49
 
48
50
  function getBaseColor(base: string): string {
49
- return axolabsMap[base]["color"];
51
+ return axolabsMap[base]['color'];
50
52
  }
51
53
 
52
- export function drawAxolabsPattern(patternName: string, asExists: boolean, ssBases: string[], asBases: string[], ssPtoStatuses: boolean[], asPtoStatuses: boolean[],
53
- ssThreeModification: string, ssFiveModification: string, asThreeModification: string, asFiveModification: string, comment: string,
54
- enumerateModifications: string[]) {
55
-
54
+ export function drawAxolabsPattern(
55
+ patternName: string, asExists: boolean, ssBases: string[],
56
+ asBases: string[], ssPtoStatuses: boolean[], asPtoStatuses: boolean[],
57
+ ssThreeModification: string, ssFiveModification: string,
58
+ asThreeModification: string, asFiveModification: string, comment: string,
59
+ enumerateModifications: string[]) {
56
60
  function getEquidistantXForLegend(index: number): number {
57
61
  return Math.round((index + startFrom) * width / (uniqueBases.length + startFrom) + legendRadius);
58
62
  }
59
63
 
60
64
  function getXOfBaseCircles(index: number, rightOverhangs: number): number {
61
- return widthOfRightModification + (resultingNumberOfNucleotidesInStrands - index + rightOverhangs + 1) * baseDiameter;
65
+ return widthOfRightModification +
66
+ (resultingNumberOfNucleotidesInStrands - index + rightOverhangs + 1) * baseDiameter;
62
67
  }
63
68
 
64
69
  function getShiftToAlignNumberInsideCircle(bases: string[], generalIndex: number, nucleotideIndex: number): number {
65
- return (nucleotideIndex < 10 || ['A', 'G', 'C', 'U', 'T'].includes(bases[generalIndex])) ? shiftToAlignOneDigitNumberInsideCircle : shiftToAlignTwoDigitNumberInsideCircle;
70
+ return (nucleotideIndex < 10 || ['A', 'G', 'C', 'U', 'T'].
71
+ includes(bases[generalIndex])) ? shiftToAlignOneDigitNumberInsideCircle : shiftToAlignTwoDigitNumberInsideCircle;
66
72
  }
67
73
 
68
74
  const svg = {
69
- xmlns: "http://www.w3.org/2000/svg",
75
+ xmlns: 'http://www.w3.org/2000/svg',
70
76
  render: function(width: number, height: number) {
71
77
  const e = document.createElementNS(this.xmlns, 'svg');
72
- e.setAttribute("id", "mySvg");
73
- e.setAttribute("width", String(width));
74
- e.setAttribute("height", String(height));
78
+ e.setAttribute('id', 'mySvg');
79
+ e.setAttribute('width', String(width));
80
+ e.setAttribute('height', String(height));
75
81
  return e;
76
82
  },
77
83
  circle: function(x: number, y: number, radius: number, color: string) {
78
84
  const e = document.createElementNS(this.xmlns, 'circle');
79
- e.setAttribute("cx", String(x));
80
- e.setAttribute("cy", String(y));
81
- e.setAttribute("r", String(radius));
82
- e.setAttribute("fill", color);
85
+ e.setAttribute('cx', String(x));
86
+ e.setAttribute('cy', String(y));
87
+ e.setAttribute('r', String(radius));
88
+ e.setAttribute('fill', color);
83
89
  return e;
84
90
  },
85
91
  text: function(text: string, x: number, y: number, fontSize: number, color: string) {
86
92
  const e = document.createElementNS(this.xmlns, 'text');
87
- e.setAttribute("x", String(x));
88
- e.setAttribute("y", String(y));
89
- e.setAttribute("font-size", String(fontSize));
90
- e.setAttribute("font-weight", "normal");
91
- e.setAttribute("font-family", "Arial");
92
- e.setAttribute("fill", color);
93
+ e.setAttribute('x', String(x));
94
+ e.setAttribute('y', String(y));
95
+ e.setAttribute('font-size', String(fontSize));
96
+ e.setAttribute('font-weight', 'normal');
97
+ e.setAttribute('font-family', 'Arial');
98
+ e.setAttribute('fill', color);
93
99
  e.innerHTML = text;
94
100
  return e;
95
101
  },
96
102
  star: function(x: number, y: number, fill: string) {
97
- const e = document.createElementNS(this.xmlns, "polygon");
98
- e.setAttribute("points", getPointsToDrawStar(x, y));
99
- e.setAttribute("fill", fill);
103
+ const e = document.createElementNS(this.xmlns, 'polygon');
104
+ e.setAttribute('points', getPointsToDrawStar(x, y));
105
+ e.setAttribute('fill', fill);
100
106
  return e;
101
- }
107
+ },
102
108
  };
103
109
 
104
110
  ssBases = ssBases.reverse();
105
111
  ssPtoStatuses = ssPtoStatuses.reverse();
106
112
 
107
- const baseRadius = 15,
108
- shiftToAlignTwoDigitNumberInsideCircle = -10,
109
- shiftToAlignOneDigitNumberInsideCircle = -5,
110
- legendRadius = 6,
111
- psLinkageRadius = 5,
112
- baseFontSize = 17,
113
- legendFontSize = 14,
114
- psLinkageColor = 'red',
115
- fontColor = 'var(--grey-6)',
116
- titleFontColor = 'black',
117
- modificationsColor = 'red',
118
- ssLeftText = "SS: 5'",
119
- asLeftText = "AS: 3'",
120
- ssRightText = "3'",
121
- asRightText = "5'";
113
+ const baseRadius = 15;
114
+ const shiftToAlignTwoDigitNumberInsideCircle = -10;
115
+ const shiftToAlignOneDigitNumberInsideCircle = -5;
116
+ const legendRadius = 6;
117
+ const psLinkageRadius = 5;
118
+ const baseFontSize = 17;
119
+ const legendFontSize = 14;
120
+ const psLinkageColor = 'red';
121
+ const fontColor = 'var(--grey-6)';
122
+ const titleFontColor = 'black';
123
+ const modificationsColor = 'red';
124
+ const ssLeftText = 'SS: 5\'';
125
+ const asLeftText = 'AS: 3\'';
126
+ const ssRightText = '3\'';
127
+ const asRightText = '5\'';
122
128
 
123
129
  const ssRightOverhangs = countOverhangsOnTheRightEdge(ssBases);
124
130
  const asRightOverhangs = countOverhangsOnTheRightEdge(asBases);
125
- const resultingNumberOfNucleotidesInStrands = Math.max(ssBases.length - ssRightOverhangs, asBases.length - asRightOverhangs),
126
- baseDiameter = 2 * baseRadius,
127
- widthOfBases = baseDiameter * (resultingNumberOfNucleotidesInStrands + Math.max(ssRightOverhangs, asRightOverhangs)),
128
- widthOfLeftModification = Math.max(getTextWidth(ssThreeModification, baseFontSize), getTextWidth(asFiveModification, baseFontSize)),
129
- widthOfRightModification = Math.max(getTextWidth(ssFiveModification, baseFontSize), getTextWidth(asThreeModification, baseFontSize)),
130
- widthOfLeftText = Math.max(getTextWidth(ssLeftText, baseFontSize), getTextWidth(asLeftText, baseFontSize)),
131
- widthOfRightText = Math.max(getTextWidth(ssRightText, baseFontSize), getTextWidth(asRightText, baseFontSize)),
132
- width = widthOfLeftText + widthOfLeftModification + widthOfBases + widthOfRightModification + widthOfRightText + baseDiameter,
133
- height = asExists ? 11 * baseRadius : 9 * baseRadius,
134
- xOfTitle = baseRadius,// Math.round(width / 4),
135
- uniqueBases = asExists ? [...new Set(ssBases.concat(asBases))] : [...new Set(ssBases)],
136
- isPtoExist = asExists ? [...new Set(ssPtoStatuses.concat(asPtoStatuses))].includes(true) : [...new Set(ssPtoStatuses)].includes(true),
137
- startFrom = isPtoExist ? 1 : 0,
138
- xOfLeftTexts = 0,
139
- xOfLeftModifications = xOfLeftTexts + widthOfLeftText - 5,
140
- xOfSsRightModifications = ssRightOverhangs * baseDiameter + getXOfBaseCircles(-0.5, 0),
141
- xOfAsRightModifications = asRightOverhangs * baseDiameter + getXOfBaseCircles(-0.5, 0),
142
- xOfRightTexts = Math.max(xOfSsRightModifications, xOfAsRightModifications) + widthOfLeftModification + baseDiameter * (Math.max(ssRightOverhangs, asRightOverhangs)),
143
- yOfTitle = baseRadius,
144
- yOfSsTexts = 4 * baseRadius,
145
- yOfAsTexts = 7 * baseRadius,
146
- yOfComment = asExists ? 11 * baseRadius : 8.5 * baseRadius,
147
- yOfSsCircles = 3.5 * baseRadius,
148
- yOfAsCircles = 6.5 * baseRadius,
149
- yOfCirclesInLegends = asExists ? 9 * baseRadius : 6 * baseRadius,
150
- yOfTextLegend = asExists ? 9.5 * baseRadius - 3 : yOfAsCircles - 3;
151
-
152
- let image = svg.render(width, height);
131
+ const resultingNumberOfNucleotidesInStrands =
132
+ Math.max(ssBases.length - ssRightOverhangs, asBases.length - asRightOverhangs);
133
+ const baseDiameter = 2 * baseRadius;
134
+ const widthOfBases =
135
+ baseDiameter * (resultingNumberOfNucleotidesInStrands + Math.max(ssRightOverhangs, asRightOverhangs));
136
+ const widthOfLeftModification =
137
+ Math.max(getTextWidth(ssThreeModification, baseFontSize), getTextWidth(asFiveModification, baseFontSize));
138
+ const widthOfRightModification =
139
+ Math.max(getTextWidth(ssFiveModification, baseFontSize), getTextWidth(asThreeModification, baseFontSize));
140
+ const widthOfLeftText = Math.max(getTextWidth(ssLeftText, baseFontSize), getTextWidth(asLeftText, baseFontSize));
141
+ const widthOfRightText = Math.max(getTextWidth(ssRightText, baseFontSize), getTextWidth(asRightText, baseFontSize));
142
+ const width =
143
+ widthOfLeftText + widthOfLeftModification + widthOfBases +
144
+ widthOfRightModification + widthOfRightText + baseDiameter;
145
+ const height = asExists ? 11 * baseRadius : 9 * baseRadius;
146
+ const xOfTitle = baseRadius; // Math.round(width / 4),
147
+ const uniqueBases = asExists ? [...new Set(ssBases.concat(asBases))] : [...new Set(ssBases)];
148
+ const isPtoExist =
149
+ asExists ? [...new Set(ssPtoStatuses.concat(asPtoStatuses))].includes(true) :
150
+ [...new Set(ssPtoStatuses)].includes(true);
151
+ const startFrom = isPtoExist ? 1 : 0;
152
+ const xOfLeftTexts = 0;
153
+ const xOfLeftModifications = xOfLeftTexts + widthOfLeftText - 5;
154
+ const xOfSsRightModifications = ssRightOverhangs * baseDiameter + getXOfBaseCircles(-0.5, 0);
155
+ const xOfAsRightModifications = asRightOverhangs * baseDiameter + getXOfBaseCircles(-0.5, 0);
156
+ const xOfRightTexts =
157
+ Math.max(xOfSsRightModifications, xOfAsRightModifications) +
158
+ widthOfLeftModification + baseDiameter * (Math.max(ssRightOverhangs, asRightOverhangs));
159
+ const yOfTitle = baseRadius;
160
+ const yOfSsTexts = 4 * baseRadius;
161
+ const yOfAsTexts = 7 * baseRadius;
162
+ const yOfComment = asExists ? 11 * baseRadius : 8.5 * baseRadius;
163
+ const yOfSsCircles = 3.5 * baseRadius;
164
+ const yOfAsCircles = 6.5 * baseRadius;
165
+ const yOfCirclesInLegends = asExists ? 9 * baseRadius : 6 * baseRadius;
166
+ const yOfTextLegend = asExists ? 9.5 * baseRadius - 3 : yOfAsCircles - 3;
167
+
168
+ const image = svg.render(width, height);
153
169
 
154
170
  image.append(
155
171
  svg.text(ssLeftText, xOfLeftTexts, yOfSsTexts, baseFontSize, fontColor),
@@ -162,31 +178,40 @@ export function drawAxolabsPattern(patternName: string, asExists: boolean, ssBas
162
178
  asExists ? svg.text(asFiveModification, xOfAsRightModifications, yOfAsTexts, baseFontSize, modificationsColor) : '',
163
179
  svg.text(comment, xOfLeftTexts, yOfComment, legendFontSize, fontColor),
164
180
  isPtoExist ? svg.star(baseRadius, yOfCirclesInLegends, psLinkageColor) : '',
165
- isPtoExist ? svg.text('ps linkage', 2 * baseRadius - 8, yOfTextLegend, legendFontSize, fontColor) : ''
181
+ isPtoExist ? svg.text('ps linkage', 2 * baseRadius - 8, yOfTextLegend, legendFontSize, fontColor) : '',
166
182
  );
167
183
 
168
184
  let numberOfSsNucleotides = 0;
169
- for (let i = 0; i < ssBases.length; i++)
185
+ for (let i = 0; i < ssBases.length; i++) {
170
186
  if (ssBases[i].slice(-3) != '(o)')
171
187
  numberOfSsNucleotides++;
188
+ }
172
189
  let nucleotideCounter = numberOfSsNucleotides;
173
190
  for (let i = ssBases.length - 1; i > -1; i--) {
174
191
  if (ssBases[i].slice(-3) != '(o)')
175
192
  nucleotideCounter--;
176
193
  image.append(
177
194
  svg.circle(getXOfBaseCircles(i, ssRightOverhangs), yOfSsCircles, baseRadius, getBaseColor(ssBases[i])),
178
- svg.text(getTextInsideCircle(ssBases, i, nucleotideCounter, numberOfSsNucleotides, enumerateModifications), getXOfBaseCircles(i, ssRightOverhangs) + getShiftToAlignNumberInsideCircle(ssBases, ssBases.length - i, numberOfSsNucleotides - nucleotideCounter), yOfSsTexts, baseFontSize, getFontColorVisibleOnBackground(axolabsMap[ssBases[i]]["color"])),
179
- ssPtoStatuses[i] ? svg.star(getXOfBaseCircles(i, ssRightOverhangs) + baseRadius, yOfSsTexts + psLinkageRadius, psLinkageColor) : ''
195
+ svg.text(getTextInsideCircle(ssBases, i, nucleotideCounter, numberOfSsNucleotides, enumerateModifications),
196
+ getXOfBaseCircles(i, ssRightOverhangs) +
197
+ getShiftToAlignNumberInsideCircle(ssBases, ssBases.length - i, numberOfSsNucleotides - nucleotideCounter),
198
+ yOfSsTexts, baseFontSize, getFontColorVisibleOnBackground(axolabsMap[ssBases[i]]['color'])),
199
+ ssPtoStatuses[i] ?
200
+ svg.star(getXOfBaseCircles(i, ssRightOverhangs) + baseRadius, yOfSsTexts + psLinkageRadius, psLinkageColor) :
201
+ '',
180
202
  );
181
203
  }
182
204
  image.append(
183
- ssPtoStatuses[ssBases.length] ? svg.star(getXOfBaseCircles(ssBases.length, ssRightOverhangs) + baseRadius, yOfSsTexts + psLinkageRadius, psLinkageColor) : ''
205
+ ssPtoStatuses[ssBases.length] ?
206
+ svg.star(getXOfBaseCircles(ssBases.length, ssRightOverhangs) +
207
+ baseRadius, yOfSsTexts + psLinkageRadius, psLinkageColor) : '',
184
208
  );
185
209
 
186
210
  let numberOfAsNucleotides = 0;
187
- for (let i = 0; i < asBases.length; i++)
211
+ for (let i = 0; i < asBases.length; i++) {
188
212
  if (asBases[i].slice(-3) != '(o)')
189
213
  numberOfAsNucleotides++;
214
+ }
190
215
  if (asExists) {
191
216
  let nucleotideCounter = numberOfAsNucleotides;
192
217
  for (let i = asBases.length - 1; i > -1; i--) {
@@ -194,21 +219,31 @@ export function drawAxolabsPattern(patternName: string, asExists: boolean, ssBas
194
219
  nucleotideCounter--;
195
220
  image.append(
196
221
  svg.circle(getXOfBaseCircles(i, asRightOverhangs), yOfAsCircles, baseRadius, getBaseColor(asBases[i])),
197
- svg.text(getTextInsideCircle(asBases, i, numberOfAsNucleotides - nucleotideCounter - 1, numberOfAsNucleotides, enumerateModifications), getXOfBaseCircles(i, asRightOverhangs) + getShiftToAlignNumberInsideCircle(asBases, i, nucleotideCounter + 1), yOfAsTexts, baseFontSize, getFontColorVisibleOnBackground(axolabsMap[asBases[i]]["color"])),
198
- asPtoStatuses[i] ? svg.star(getXOfBaseCircles(i, asRightOverhangs) + baseRadius, yOfAsTexts + psLinkageRadius, psLinkageColor) : ''
222
+ svg.text(getTextInsideCircle(
223
+ asBases, i, numberOfAsNucleotides - nucleotideCounter - 1, numberOfAsNucleotides, enumerateModifications),
224
+ getXOfBaseCircles(i, asRightOverhangs) +
225
+ getShiftToAlignNumberInsideCircle(asBases, i, nucleotideCounter + 1),
226
+ yOfAsTexts, baseFontSize, getFontColorVisibleOnBackground(axolabsMap[asBases[i]]['color'])),
227
+ asPtoStatuses[i] ? svg.star(getXOfBaseCircles(i, asRightOverhangs) +
228
+ baseRadius, yOfAsTexts + psLinkageRadius, psLinkageColor) : '',
199
229
  );
200
230
  }
201
231
  image.append(
202
- asPtoStatuses[asBases.length] ? svg.star(getXOfBaseCircles(asBases.length, asRightOverhangs) + baseRadius, yOfAsTexts + psLinkageRadius, psLinkageColor) : ''
232
+ asPtoStatuses[asBases.length] ?
233
+ svg.star(getXOfBaseCircles(asBases.length, asRightOverhangs) +
234
+ baseRadius, yOfAsTexts + psLinkageRadius, psLinkageColor) : '',
203
235
  );
204
236
  }
205
237
 
206
- let title = patternName + ' for ' + String(numberOfSsNucleotides) + (asExists ? '/' + String(numberOfAsNucleotides) : '') + 'mer';
238
+ const title = patternName + ' for ' +
239
+ String(numberOfSsNucleotides) + (asExists ? '/' + String(numberOfAsNucleotides) : '') + 'mer';
207
240
  image.append(svg.text(title, xOfTitle, yOfTitle, baseFontSize, titleFontColor));
208
- for (let i = 0; i < uniqueBases.length; i++)
241
+ for (let i = 0; i < uniqueBases.length; i++) {
209
242
  image.append(
210
243
  svg.circle(getEquidistantXForLegend(i), yOfCirclesInLegends, legendRadius, getBaseColor(uniqueBases[i])),
211
- svg.text(uniqueBases[i], getEquidistantXForLegend(i) + legendRadius + 4, yOfTextLegend, legendFontSize, fontColor)
244
+ svg.text(uniqueBases[i], getEquidistantXForLegend(i) +
245
+ legendRadius + 4, yOfTextLegend, legendFontSize, fontColor),
212
246
  );
247
+ }
213
248
  return image;
214
- }
249
+ }