@teselagen/ove 0.7.26 → 0.7.28

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.
Files changed (304) hide show
  1. package/AASliver.js +187 -0
  2. package/AddLaddersDialog.js +82 -0
  3. package/AdditionalCutsiteInfoDialog.js +599 -0
  4. package/AlignmentView/Mismatches.d.ts +3 -3
  5. package/AlignmentVisibilityTool.js +105 -0
  6. package/AnnotationContainerHolder.js +20 -0
  7. package/AnnotationPositioner.js +27 -0
  8. package/AutoAnnotate.js +501 -0
  9. package/AutoAnnotateBpMatchingDialog.js +208 -0
  10. package/Axis.js +151 -0
  11. package/AxisNumbers.js +35 -0
  12. package/Browser.js +106 -0
  13. package/Caret.js +63 -0
  14. package/Chromatogram.js +293 -0
  15. package/CircularDnaSequence.js +73 -0
  16. package/CircularView/Labels/index.d.ts +1 -1
  17. package/CircularView/index.d.ts +0 -1
  18. package/CircularZoomMinimap.js +16 -0
  19. package/ColorPicker.js +30 -0
  20. package/CommandHotkeyHandler.js +44 -0
  21. package/CreateAnnotationsPage.d.ts +4 -4
  22. package/CreateAnnotationsPage.js +98 -0
  23. package/Cutsite.js +18 -0
  24. package/CutsiteProperties.js +176 -0
  25. package/CutsiteSelectionLayers.js +47 -0
  26. package/Cutsites.js +271 -0
  27. package/DeletionLayer.js +28 -0
  28. package/DigestTool/Ladder.d.ts +1 -1
  29. package/DropHandler.css +21 -0
  30. package/DropHandler.js +64 -0
  31. package/EditCaretPosition.js +234 -0
  32. package/EditTrackNameDialog.js +30 -0
  33. package/Feature.js +83 -0
  34. package/FeatureProperties.js +6 -0
  35. package/FillWindow.js +47 -0
  36. package/GenbankView.js +74 -0
  37. package/GeneralProperties.js +117 -0
  38. package/GenericAnnotationProperties.js +406 -0
  39. package/GlobalDialog.js +73 -0
  40. package/GlobalDialogUtils.js +110 -0
  41. package/GoToDialog.js +25 -0
  42. package/HorizontalPanelDragHandle.js +35 -0
  43. package/Keyboard.js +85 -0
  44. package/Labels.js +327 -0
  45. package/Ladder.css +20 -0
  46. package/Ladder.js +303 -0
  47. package/MeltingTemp.js +85 -0
  48. package/Menlo.ttf +0 -0
  49. package/Minimap.js +515 -0
  50. package/Mismatches.js +134 -0
  51. package/Monaco.ttf +0 -0
  52. package/MultipleSeqsDetectedOnImportDialog.js +74 -0
  53. package/Orf.js +109 -0
  54. package/OrfProperties.js +117 -0
  55. package/Orfs.js +35 -0
  56. package/PCRTool.js +179 -0
  57. package/PairwiseAlignmentView.js +68 -0
  58. package/Part.js +34 -0
  59. package/PartProperties.js +9 -0
  60. package/PassThrough.js +3 -0
  61. package/PerformantSelectionLayer.js +32 -0
  62. package/PinchHelper.js +24 -0
  63. package/PointedAnnotation.js +347 -0
  64. package/PositionAnnotationOnCircle.js +26 -0
  65. package/Primer.js +41 -0
  66. package/PrimerProperties.js +19 -0
  67. package/Reflex/index.d.ts +0 -1
  68. package/ReflexContainer.js +802 -0
  69. package/ReflexElement.js +160 -0
  70. package/ReflexEvents.js +77 -0
  71. package/ReflexSplitter.js +205 -0
  72. package/RenameSequenceDialog.js +7 -0
  73. package/RotateCircularViewSlider.js +93 -0
  74. package/RowView/index.d.ts +0 -1
  75. package/SelectDialog.js +150 -0
  76. package/SequenceName.js +15 -0
  77. package/SimpleCircularOrLinearView.js +381 -0
  78. package/SimpleOligoPreview.js +39 -0
  79. package/SingleEnzymeCutsiteInfo.js +139 -0
  80. package/ToolBar/ToolbarItem.d.ts +1 -3
  81. package/ToolbarItem.js +192 -0
  82. package/Translation.js +198 -0
  83. package/TranslationProperties.js +149 -0
  84. package/UncontrolledSliderWithPlusMinusBtns.css +5 -0
  85. package/UncontrolledSliderWithPlusMinusBtns.js +134 -0
  86. package/VeTopRightContainer.js +12 -0
  87. package/ZoomCircularViewSlider.js +62 -0
  88. package/ZoomLinearView.js +47 -0
  89. package/addAlignment.js +6 -0
  90. package/addMetaToActionCreators.js +12 -0
  91. package/addWrappedAddons.js +20 -0
  92. package/alignmentTool.js +503 -0
  93. package/alignments.js +379 -0
  94. package/annotationLabelVisibility.js +2 -0
  95. package/annotationSearchSelector.js +24 -0
  96. package/annotationTypes.js +35 -0
  97. package/annotationVisibility.js +196 -0
  98. package/annotationsToSupport.js +104 -0
  99. package/arrayToObjWithIds.js +17 -0
  100. package/arrayUtils.js +19 -0
  101. package/array_move.js +10 -0
  102. package/calculateTickMarkPositionsForGivenRange.js +47 -0
  103. package/caretPosition.js +27 -0
  104. package/cdsFeaturesSelector.js +9 -0
  105. package/charWidth.js +22 -0
  106. package/circular.js +19 -0
  107. package/circularSelector.js +4 -0
  108. package/clickAndDragUtils.js +576 -0
  109. package/coerceInitialValue.js +7 -0
  110. package/combineReducersDontIgnoreKeys.js +12 -0
  111. package/commandUtils.js +20 -0
  112. package/constants.js +2 -0
  113. package/copyOptions.js +34 -0
  114. package/createFragmentLines.js +120 -0
  115. package/createMergedDefaultStateReducer.js +30 -0
  116. package/createMetaAction.js +12 -0
  117. package/createSequenceInputPopup.js +290 -0
  118. package/createSequenceInputPopupStyle.css +87 -0
  119. package/createSimpleDialog.js +89 -0
  120. package/createYourOwnEnzyme.js +39 -0
  121. package/cutsiteLabelColorSelector.js +6 -0
  122. package/cutsiteTool.js +88 -0
  123. package/cutsitesByRangeSelector.js +5 -0
  124. package/cutsitesSelector.js +61 -0
  125. package/darkmode.css +98 -0
  126. package/defaultConfig.js +150 -0
  127. package/deletionLayers.js +36 -0
  128. package/description.js +21 -0
  129. package/digestTool.js +34 -0
  130. package/dnaToColor.js +17 -0
  131. package/downloadTool.js +39 -0
  132. package/draggableClassnames.js +5 -0
  133. package/drawAnnotations.js +440 -0
  134. package/drawDirectedPiePiece.js +142 -0
  135. package/editTool.js +49 -0
  136. package/editorSelector.js +2 -0
  137. package/editorUtils.js +205 -0
  138. package/estimateRowHeight.js +184 -0
  139. package/featureLengthsToHide.js +27 -0
  140. package/featureTool.js +34 -0
  141. package/features.js +19 -0
  142. package/featuresSelector.js +8 -0
  143. package/filteredCutsitesSelector.js +136 -0
  144. package/filteredFeaturesSelector.js +32 -0
  145. package/filteredPartsSelector.js +57 -0
  146. package/filteredPrimersSelector.js +27 -0
  147. package/filteredRestrictionEnzymesSelector.js +1 -0
  148. package/find.png +0 -0
  149. package/findTool.js +79 -0
  150. package/findToolConstants.js +1 -0
  151. package/frameTranslations.js +52 -0
  152. package/fullscreen.png +0 -0
  153. package/getAdditionalEnzymesSelector.js +46 -0
  154. package/getAngleForPositionMidpoint.js +3 -0
  155. package/getAnnotationClassnames.js +12 -0
  156. package/getAnnotationNameAndStartStopString.js +61 -0
  157. package/getBpsPerRow.js +19 -0
  158. package/getCutsiteLabelHeights.js +56 -0
  159. package/getGapMap.js +12 -0
  160. package/getGaps.js +27 -0
  161. package/getInternalLabel.js +40 -0
  162. package/getOveHotkeyDefs.js +12 -0
  163. package/getPairwiseOverviewLinearViewOptions.js +38 -0
  164. package/getRangeAnglesSpecial.js +12 -0
  165. package/getStructuredBases.js +97 -0
  166. package/getTrackFromEvent.js +25 -0
  167. package/getVisibleStartEnd.js +7 -0
  168. package/getXStartAndWidthFromNonCircularRange.js +12 -0
  169. package/getXStartAndWidthOfRangeWrtRow.js +27 -0
  170. package/getXStartAndWidthOfRowAnnotation.js +19 -0
  171. package/getYOffset.js +15 -0
  172. package/hoveredAnnotation.js +24 -0
  173. package/{html2canvas.esm--JN4fLQL.js → html2canvas.esm-DiGWN1gP.js} +187 -229
  174. package/{html2canvas.esm-B7d7VJmQ.cjs → html2canvas.esm-J1esNpMJ.cjs} +187 -229
  175. package/importTool.js +27 -0
  176. package/index.cjs.js +48165 -47142
  177. package/index.es.js +47699 -46676
  178. package/index.js +71 -0
  179. package/inlineFindTool.js +38 -0
  180. package/isElementInViewport.js +29 -0
  181. package/isEnzymeFilterAndSelector.js +1 -0
  182. package/isTargetWithinEl.js +6 -0
  183. package/labelLineIntensity.js +25 -0
  184. package/labelSize.js +23 -0
  185. package/ladderDefaults.js +25 -0
  186. package/lastSavedId.js +20 -0
  187. package/lineageLines.js +11 -0
  188. package/linear.png +0 -0
  189. package/makeStore.js +34 -0
  190. package/massageTickSpacing.js +19 -0
  191. package/materiallyAvailable.js +19 -0
  192. package/middleware.js +112 -0
  193. package/minimumOrfSize.js +24 -0
  194. package/minimumOrfSizeSelector.js +2 -0
  195. package/modalActions.js +3 -0
  196. package/moveCaret.js +58 -0
  197. package/name.js +19 -0
  198. package/normalizeAngle.js +3 -0
  199. package/normalizeAngleRange.js +9 -0
  200. package/oligoTool.js +30 -0
  201. package/onlyUpdateForKeysDeep.js +31 -0
  202. package/orfFrameToColorMap.js +10 -0
  203. package/orfTool.js +136 -0
  204. package/orfsSelector.js +15 -0
  205. package/ove.css +12107 -0
  206. package/package.json +8 -7
  207. package/panelsShown.js +294 -0
  208. package/partLengthsToHide.js +23 -0
  209. package/partOverhangs.js +6 -0
  210. package/partTagSearch.js +69 -0
  211. package/partTool.js +45 -0
  212. package/parts.js +19 -0
  213. package/partsSelector.js +8 -0
  214. package/pie.png +0 -0
  215. package/polarToSpecialCartesian.js +7 -0
  216. package/positionCutsites.js +6 -0
  217. package/prepareRowData.js +64 -0
  218. package/primerBases.js +221 -0
  219. package/primerLengthsToHide.js +27 -0
  220. package/primers.js +19 -0
  221. package/primersSelector.js +8 -0
  222. package/print.png +0 -0
  223. package/printTool.js +31 -0
  224. package/propertiesTool.js +40 -0
  225. package/proteinUtils.js +3 -0
  226. package/pureNoFunc.js +18 -0
  227. package/readOnly.js +25 -0
  228. package/redoTool.js +30 -0
  229. package/reflex-styles.css +128 -0
  230. package/reflex-styles.css.map +9 -0
  231. package/relaxLabelAngles.js +157 -0
  232. package/relaxLabels_DEPRECATED.js +105 -0
  233. package/replacementLayers.js +36 -0
  234. package/restrictionEnzymes.js +52 -0
  235. package/restrictionEnzymesSelector.js +34 -0
  236. package/rowviewContants.js +3 -0
  237. package/ruler.css +89 -0
  238. package/save.png +0 -0
  239. package/saveTool.js +44 -0
  240. package/searchLayersSelector.js +71 -0
  241. package/selectedAnnotations.js +89 -0
  242. package/selectedAnnotationsSelector.js +1 -0
  243. package/selectedCutsitesSelector.js +21 -0
  244. package/selectedPartTags.js +21 -0
  245. package/selectionLayer.js +25 -0
  246. package/selectors/annotationSearchSelector.d.ts +1 -1
  247. package/sequence.js +12 -0
  248. package/sequenceDataHistory.js +43 -0
  249. package/sequenceDataSelector.js +2 -0
  250. package/sequenceLengthSelector.js +5 -0
  251. package/sequenceSelector.js +4 -0
  252. package/sharedActionCreators.js +0 -0
  253. package/shouldFlipText.js +4 -0
  254. package/shouldRerender.js +27 -0
  255. package/showFileDialog.js +25 -0
  256. package/showGCContent.js +23 -0
  257. package/show_cut_sites.png +0 -0
  258. package/show_features.png +0 -0
  259. package/show_orfs.png +0 -0
  260. package/show_primers.png +0 -0
  261. package/simpleDialog.css +13 -0
  262. package/specialCutsiteFilterOptions.js +22 -0
  263. package/src/Editor/DropHandler.js +2 -1
  264. package/src/Editor/index.js +0 -2
  265. package/src/RowItem/StackedAnnotations/getStructuredBases.js +20 -6
  266. package/src/ToolBar/cutsiteTool.js +1 -1
  267. package/src/helperComponents/PropertiesDialog/TranslationProperties.js +2 -1
  268. package/style.css +3 -12100
  269. package/tagsToBoldSelector.js +2 -0
  270. package/toggle_views.svg +1 -0
  271. package/toolBar.js +23 -0
  272. package/translationSearchMatchesSelector.js +14 -0
  273. package/translations.js +20 -0
  274. package/translationsRawSelector.js +8 -0
  275. package/translationsSelector.js +137 -0
  276. package/typeField.js +24 -0
  277. package/undoTool.js +30 -0
  278. package/updateEditor.d.ts +1 -3
  279. package/updateEditor.js +200 -0
  280. package/updateLabelsForInViewFeatures.js +55 -0
  281. package/updateLabelsForInViewFeaturesCircView.js +41 -0
  282. package/updateTrackHelper.js +58 -0
  283. package/uppercaseSequenceMapFont.js +25 -0
  284. package/upsertDeleteActionGenerator.js +31 -0
  285. package/useAAColorType.js +8 -0
  286. package/useAdditionalOrfStartCodons.js +24 -0
  287. package/useAnnotationLimits.js +42 -0
  288. package/useChromatogramPrefs.js +31 -0
  289. package/useFormValue.js +7 -0
  290. package/useLadders.js +6 -0
  291. package/useMeltingTemp.js +7 -0
  292. package/useTmType.js +10 -0
  293. package/userDefinedHandlersAndOpts.js +61 -0
  294. package/utils/getAnnotationNameAndStartStopString.d.ts +1 -5
  295. package/utils/selectionLayer.d.ts +2 -2
  296. package/utils.js +37 -0
  297. package/versionHistory.js +26 -0
  298. package/versionHistoryTool.js +21 -0
  299. package/viewSubmenu.js +479 -0
  300. package/visibilityTool.js +39 -0
  301. package/withEditorInteractions/getBpsPerRow.d.ts +1 -3
  302. package/withHover.js +113 -0
  303. package/withRestrictionEnzymes.js +15 -0
  304. package/index.umd.js +0 -188322
@@ -0,0 +1,440 @@
1
+ import React from "react";
2
+ import IntervalTree from "node-interval-tree";
3
+ import { sortBy, noop } from "lodash-es";
4
+ import { getRangeLength } from "@teselagen/range-utils";
5
+ import getRangeAngles from "./getRangeAnglesSpecial";
6
+ import getYOffset from "./getYOffset";
7
+ import withHover from "../helperComponents/withHover";
8
+ import PositionAnnotationOnCircle from "./PositionAnnotationOnCircle";
9
+ import getAnnotationNameAndStartStopString from "../utils/getAnnotationNameAndStartStopString";
10
+ import Feature from "./Feature";
11
+ import getAnnotationClassnames from "../utils/getAnnotationClassnames";
12
+ // import { normalizeAngleRange } from "./normalizeAngleRange";
13
+ // import { normalizeAngle } from "./normalizeAngle";
14
+
15
+ //annotations coming in can be positioned either by caretPosition or range
16
+ function drawAnnotations(props) {
17
+ const {
18
+ readOnly,
19
+ annotationType,
20
+ radius,
21
+ noHover,
22
+ isProtein,
23
+ type,
24
+ annotations,
25
+ annotationHeight,
26
+ noTitle,
27
+ spaceBetweenAnnotations,
28
+ sequenceLength,
29
+ showCicularViewInternalLabels,
30
+ // reverseAnnotations, //set true when drawing annotations that use the drawDirectedPiePiece function because that function returns things that need to be flipped
31
+ // editorName,
32
+ getColor,
33
+ useStartAngle, //use the startAngle instead of the centerAngle to position the labels
34
+ onClick = noop,
35
+ noHeight,
36
+ positionBy, //by default the annotation.start and annotation.end are used to position the annotation on the circle, but passing a function here gives an option to override that
37
+ allOnSameLevel, //by default overlapping annotations are given different yOffsets. Setting this to true prevents that and positions all annotations on the same level (no y-offsets given). Cutsites for example just get drawn all on the same level
38
+ onRightClicked = noop,
39
+ onDoubleClick = noop,
40
+ showLabels,
41
+ hideAnnotation,
42
+ // rotationRadians,
43
+ labelOptions,
44
+ annotationProps,
45
+ fontStyle
46
+ // isZoomedIn,
47
+ // visibleAngleRange
48
+ } = props;
49
+ const totalAnnotationHeight = annotationHeight + spaceBetweenAnnotations;
50
+ const featureITree = new IntervalTree();
51
+ let maxYOffset = 0;
52
+ const svgGroup = [];
53
+ const labels = {};
54
+
55
+ if (!Object.keys(annotations).length) return null;
56
+ sortBy(annotations, a => {
57
+ return -getRangeLength(a, sequenceLength);
58
+ })
59
+ .map(annotation => {
60
+ const { startAngle, endAngle, totalAngle, centerAngle, locationAngles } =
61
+ getRangeAngles(
62
+ positionBy ? positionBy(annotation) : annotation,
63
+ sequenceLength
64
+ );
65
+ const spansOrigin = startAngle > endAngle;
66
+ const annotationCopy = {
67
+ ...annotation,
68
+ startAngle,
69
+ endAngle,
70
+ locationAngles,
71
+ totalAngle,
72
+ centerAngle,
73
+ yOffset: 0
74
+ };
75
+ if (!allOnSameLevel) {
76
+ //expand the end angle if annotation spans the origin
77
+ const expandedEndAngle = spansOrigin
78
+ ? endAngle + 2 * Math.PI
79
+ : endAngle;
80
+ let yOffset1;
81
+ let yOffset2;
82
+ if (spansOrigin) {
83
+ annotationCopy.yOffset = getYOffset(
84
+ featureITree,
85
+ startAngle,
86
+ expandedEndAngle
87
+ );
88
+ } else {
89
+ //we need to check both locations to account for annotations that span the origin
90
+ yOffset1 = getYOffset(featureITree, startAngle, expandedEndAngle);
91
+ yOffset2 = getYOffset(
92
+ featureITree,
93
+ startAngle + Math.PI * 2,
94
+ expandedEndAngle + Math.PI * 2
95
+ );
96
+ annotationCopy.yOffset = Math.max(yOffset1, yOffset2);
97
+ }
98
+
99
+ if (spansOrigin) {
100
+ featureITree.insert(startAngle, expandedEndAngle, {
101
+ ...annotationCopy
102
+ });
103
+ } else {
104
+ //normal feature
105
+ // we need to add it twice to the interval tree to accomodate features which span the origin
106
+ featureITree.insert(startAngle, expandedEndAngle, {
107
+ ...annotationCopy
108
+ });
109
+ featureITree.insert(
110
+ startAngle + 2 * Math.PI,
111
+ expandedEndAngle + 2 * Math.PI,
112
+
113
+ { ...annotationCopy }
114
+ );
115
+ }
116
+
117
+ if (annotationCopy.yOffset > maxYOffset) {
118
+ maxYOffset = annotationCopy.yOffset;
119
+ }
120
+ }
121
+
122
+ return annotationCopy;
123
+ })
124
+ .forEach(function (annotation, index) {
125
+ annotation.yOffset = maxYOffset - annotation.yOffset;
126
+ function _onClick(event) {
127
+ onClick && onClick({ event, annotation });
128
+ annotation.onClick && annotation.onClick({ event, annotation });
129
+ }
130
+ function onContextMenu(event) {
131
+ onRightClicked({ event, annotation });
132
+ if (annotation.onRightClick) {
133
+ annotation.onRightClick({ event, annotation });
134
+ }
135
+ }
136
+ function _onDoubleClick(event) {
137
+ onDoubleClick && onDoubleClick({ event, annotation });
138
+ if (annotation.onDoubleClick) {
139
+ annotation.onDoubleClick({ event, annotation });
140
+ }
141
+ }
142
+
143
+ const {
144
+ startAngle,
145
+ endAngle,
146
+ totalAngle,
147
+ centerAngle,
148
+ locationAngles,
149
+ ...rest
150
+ } = annotation;
151
+
152
+ const _annotationProps = {
153
+ ...annotationProps,
154
+ ...rest
155
+ };
156
+
157
+ const titleText = getAnnotationNameAndStartStopString(annotation, {
158
+ isProtein,
159
+ readOnly
160
+ });
161
+
162
+ const classNames = getAnnotationClassnames(annotation, {
163
+ viewName: "CircularView",
164
+ type,
165
+ isProtein,
166
+ readOnly
167
+ });
168
+
169
+ const annotationRadius =
170
+ radius + annotation.yOffset * totalAnnotationHeight;
171
+ const name =
172
+ annotation.name ||
173
+ (annotation.restrictionEnzyme && annotation.restrictionEnzyme.name);
174
+ let ellipsizedName;
175
+ // let spaceBeforeName = 0;
176
+ let angleAdjust;
177
+
178
+ if (name && showCicularViewInternalLabels) {
179
+ // eslint-disable-next-line no-inner-declarations
180
+ function getEllipsizedName(totalAngle) {
181
+ let ellipsizedName;
182
+ const arcLength =
183
+ 2 * Math.PI * (annotationRadius - annotationHeight) * totalAngle; //for arrowhead
184
+
185
+ const annLength = Math.max(0, Math.floor(arcLength / 55 - 3));
186
+ ellipsizedName = name.slice(0, annLength);
187
+ if (ellipsizedName && ellipsizedName !== name) {
188
+ if (ellipsizedName.length >= name.length - 2) {
189
+ ellipsizedName = name;
190
+ } else if (ellipsizedName.length > 3) {
191
+ ellipsizedName += "..";
192
+ } else {
193
+ ellipsizedName = undefined;
194
+ }
195
+ }
196
+ return ellipsizedName;
197
+ }
198
+ if (locationAngles) {
199
+ annotation.locationAngles = locationAngles.map(l => {
200
+ const en = getEllipsizedName(l.totalAngle);
201
+ if (en?.length > (ellipsizedName?.length || 0)) {
202
+ ellipsizedName = en;
203
+ }
204
+ return {
205
+ ...l,
206
+ ellipsizedName: en
207
+ };
208
+ });
209
+ } else {
210
+ ellipsizedName = getEllipsizedName(totalAngle);
211
+ }
212
+
213
+ // //tnr: WIP to try to adjust the inline label in the circular view to always show up even when zoomed in
214
+ // if (ellipsizedName && isZoomedIn) {
215
+ // const nameAngle =
216
+ // ((ellipsizedName.length + 3) * 55) /
217
+ // (2 * Math.PI * (annotationRadius - annotationHeight));
218
+ // const maxAngleAdjust = (totalAngle - nameAngle) / 2;
219
+ // const idealAngle = normalizeAngle(
220
+ // -normalizeAngle(rotationRadians) - normalizeAngle(centerAngle)
221
+ // );
222
+ // angleAdjust = idealAngle;
223
+ // if (
224
+ // Math.min(maxAngleAdjust, idealAngle) !== idealAngle
225
+ // // &&
226
+ // // Math.min(maxAngleAdjust, 2 * Math.PI - idealAngle) !==
227
+ // // 2 * Math.PI - idealAngle
228
+ // ) {
229
+ // angleAdjust = -maxAngleAdjust;
230
+ // if (
231
+ // normalizeAngle(
232
+ // normalizeAngle(centerAngle) + normalizeAngle(rotationRadians)
233
+ // ) > Math.PI
234
+ // ) {
235
+ // angleAdjust = -angleAdjust;
236
+ // }
237
+ // }
238
+ // // angleAdjust =idealAngle
239
+ // angleAdjust = (angleAdjust / Math.PI) * 180;
240
+ // // if (normalizeAngle(normalizeAngle(centerAngle) + normalizeAngle(rotationRadians)) > Math.PI) {
241
+ // // angleAdjust = -angleAdjust;
242
+ // // }
243
+ // }
244
+ }
245
+ if (showLabels && !ellipsizedName) {
246
+ //add labels to the exported label array (to be drawn by the label component)
247
+ labels[annotation.id] = {
248
+ annotation,
249
+ annotationType,
250
+ annotationCenterAngle: useStartAngle ? startAngle : centerAngle,
251
+ annotationCenterRadius: annotationRadius,
252
+ text: name,
253
+ id: annotation.id,
254
+ title: titleText,
255
+ className: `${classNames} ${annotation.labelClassName || ""}`,
256
+ highPriorityLabel: annotation.highPriorityLabel,
257
+ onClick: _onClick,
258
+ onDoubleClick: _onDoubleClick,
259
+ fontStyle: fontStyle || "normal",
260
+ color:
261
+ annotation.labelColor ||
262
+ (annotationType === "part" ? "#ac68cc" : "black"),
263
+ onContextMenu,
264
+ ...labelOptions
265
+ };
266
+ }
267
+ if (!hideAnnotation) {
268
+ const annotationColor = getColor
269
+ ? getColor(annotation)
270
+ : annotation.color || "#ac68cc";
271
+ DrawAnnotation.displayName = annotationType + "--- DrawAnnotation";
272
+ const CompToUse = noHover ? DrawAnnotationInner : DrawAnnotation;
273
+ svgGroup.push(
274
+ <CompToUse
275
+ {...{
276
+ ...props,
277
+ ...rest,
278
+ ...annotation,
279
+ angleAdjust,
280
+ ellipsizedName,
281
+ name,
282
+ annotationHeight,
283
+ annotationRadius,
284
+ annotationType,
285
+ isProtein,
286
+ noTitle,
287
+ titleText,
288
+ classNames,
289
+ onClick: _onClick,
290
+ onDoubleClick: _onDoubleClick,
291
+ onContextMenu,
292
+ annotation,
293
+ annotationColor,
294
+ totalAngle,
295
+ centerAngle,
296
+ annotationProps: _annotationProps
297
+ }}
298
+ id={annotation.id}
299
+ key={"veAnnotation-" + annotationType + index}
300
+ />
301
+ );
302
+ }
303
+ });
304
+ return {
305
+ component: (
306
+ <g
307
+ className={"veAnnotations-" + annotationType}
308
+ key={"veAnnotations-" + annotationType}
309
+ >
310
+ {svgGroup}
311
+ </g>
312
+ ),
313
+ height: noHeight
314
+ ? 0
315
+ : maxYOffset * totalAnnotationHeight + 0.5 * annotationHeight,
316
+ labels
317
+ };
318
+ }
319
+
320
+ export default drawAnnotations;
321
+
322
+ function DrawAnnotationInner({
323
+ className,
324
+ startAngle,
325
+ endAngle,
326
+ onClick,
327
+ onDoubleClick,
328
+ onContextMenu,
329
+ titleText,
330
+ classNames,
331
+ locationAngles,
332
+ annotation,
333
+ reverseAnnotations,
334
+ Annotation = Feature,
335
+ totalAngle,
336
+ annotationColor,
337
+ isProtein,
338
+ annotationRadius,
339
+ annotationHeight,
340
+ onMouseLeave,
341
+ onMouseOver,
342
+ annotationType,
343
+ annotationProps,
344
+ addHeight,
345
+ noTitle,
346
+ useCenter,
347
+ centerAngle,
348
+ perAnnotationProps,
349
+ passAnnotation,
350
+ ellipsizedName,
351
+ angleAdjust,
352
+ rotationRadians
353
+ }) {
354
+ const sharedProps = {
355
+ style: noTitle ? undefined : { cursor: "pointer" },
356
+ className: `${className} ${classNames}`,
357
+ onContextMenu: onContextMenu,
358
+ onClick: onClick,
359
+ onDoubleClick: onDoubleClick,
360
+ onMouseLeave,
361
+ onMouseOver
362
+ };
363
+ function getInner(
364
+ {
365
+ startAngle,
366
+ endAngle,
367
+ totalAngle,
368
+ isNotLocation,
369
+ containsLocations,
370
+ ellipsizedName: ellipsizedNameLocation
371
+ },
372
+ i
373
+ ) {
374
+ const { transform, revTransform } = PositionAnnotationOnCircle({
375
+ sAngle: useCenter ? centerAngle : startAngle,
376
+ eAngle: useCenter ? centerAngle : endAngle,
377
+ height: addHeight ? annotationRadius : undefined,
378
+ forward: reverseAnnotations ? !annotation.forward : annotation.forward
379
+ });
380
+ return (
381
+ <g
382
+ transform={transform}
383
+ data-title={noTitle ? null : titleText}
384
+ {...avoidOverlapWith}
385
+ key={
386
+ isNotLocation
387
+ ? "notLocation"
388
+ : "location--" + annotation.id + "--" + i
389
+ }
390
+ {...sharedProps}
391
+ >
392
+ {noTitle ? null : (
393
+ <g hidden style={{ display: "none" }}>
394
+ {titleText}
395
+ </g>
396
+ )}
397
+ <Annotation
398
+ {...(passAnnotation && { annotation })}
399
+ annotationType={annotationType}
400
+ arrowheadType={annotation.arrowheadType}
401
+ totalAngle={totalAngle}
402
+ centerAngle={centerAngle}
403
+ revTransform={revTransform}
404
+ rotationRadians={rotationRadians}
405
+ ellipsizedName={
406
+ containsLocations ? ellipsizedNameLocation : ellipsizedName
407
+ }
408
+ locationNumber={i}
409
+ angleAdjust={angleAdjust}
410
+ color={annotationColor}
411
+ isProtein={isProtein}
412
+ containsLocations={containsLocations}
413
+ radius={annotationRadius}
414
+ annotationHeight={annotationHeight}
415
+ {...annotationProps}
416
+ {...(perAnnotationProps && perAnnotationProps(annotation))}
417
+ />
418
+ </g>
419
+ );
420
+ }
421
+ return (
422
+ <React.Fragment>
423
+ {getInner({
424
+ startAngle,
425
+ endAngle,
426
+ totalAngle,
427
+ centerAngle,
428
+ containsLocations: !!locationAngles
429
+ })}
430
+ {locationAngles && locationAngles.map(getInner)}
431
+ </React.Fragment>
432
+ );
433
+ }
434
+
435
+ const DrawAnnotation = withHover(DrawAnnotationInner);
436
+
437
+ export const avoidOverlapWith = {
438
+ "data-avoid": ".topLevelLabelGroup",
439
+ "data-avoid-backup": ".veLabel.veAnnotationHovered"
440
+ };
@@ -0,0 +1,142 @@
1
+ import Path from "paths-js/path";
2
+ function polarToSpecialCartesian(radius, angleInRadians) {
3
+ //the 0 angle returns the 0,1 point on the unit circle instead of the 1,0 point like normal
4
+ return {
5
+ x: radius * Math.cos(angleInRadians - Math.PI / 2),
6
+ y: radius * Math.sin(angleInRadians - Math.PI / 2)
7
+ };
8
+ }
9
+ const stickOutThisMuch = 0.03;
10
+
11
+ // draws a directed piece of the pie with an arrowhead, starts at 0 angle, only draws in one direction (use transforms to move it around the )
12
+ export default function drawDirectedPiePiece({
13
+ tailThickness = 0.6,
14
+ // arrowheadLength = 1,
15
+ radius,
16
+ arrowheadType,
17
+ overlapsSelf,
18
+ annotationHeight,
19
+ totalAngle,
20
+ hasLabel,
21
+ labelNeedsFlip,
22
+ returnTextPath
23
+ }) {
24
+ const tailHeight = annotationHeight * tailThickness;
25
+
26
+ const arrowheadOuterRadius = radius + annotationHeight / 2;
27
+ const arrowheadInnerRadius = radius - annotationHeight / 2;
28
+ const tailOuterRadius = radius + tailHeight / 2;
29
+ const tailInnerRadius = radius - tailHeight / 2;
30
+
31
+ // var arrowheadAngle = totalAngle / 2
32
+ let arrowheadAngle = 80 / radius / (Math.PI * 2);
33
+
34
+ if (totalAngle < arrowheadAngle) {
35
+ //set arrowhead length to the angle in radians length
36
+ arrowheadAngle = totalAngle;
37
+ }
38
+
39
+ if (arrowheadType === "NONE") arrowheadAngle = 0;
40
+ const arcAngle = totalAngle - arrowheadAngle;
41
+
42
+ //the main points we need to draw the arrow and in the order we draw them in:
43
+ const arrowheadPoint = polarToSpecialCartesian(radius, 0);
44
+
45
+ const arrowheadBottom = polarToSpecialCartesian(
46
+ arrowheadInnerRadius,
47
+ arrowheadAngle
48
+ );
49
+ const arcLeftBottom = polarToSpecialCartesian(
50
+ tailInnerRadius,
51
+ arrowheadAngle
52
+ );
53
+ const arcRightBottom = polarToSpecialCartesian(tailInnerRadius, totalAngle);
54
+ const arcRightTop = polarToSpecialCartesian(tailOuterRadius, totalAngle);
55
+ const arcRightMiddle = polarToSpecialCartesian(radius, totalAngle);
56
+ const arcRightMiddleOuter = polarToSpecialCartesian(
57
+ radius,
58
+ totalAngle + stickOutThisMuch
59
+ );
60
+ const arcLeftTop = polarToSpecialCartesian(tailOuterRadius, arrowheadAngle);
61
+ const arrowheadTop = polarToSpecialCartesian(
62
+ arrowheadOuterRadius,
63
+ arrowheadAngle
64
+ );
65
+
66
+ const largeArcFlag = arcAngle > Math.PI ? 1 : 0;
67
+ let path = Path().moveto(arrowheadPoint.x, arrowheadPoint.y);
68
+
69
+ if (overlapsSelf) {
70
+ const arrowheadPointInner = polarToSpecialCartesian(
71
+ radius,
72
+ -stickOutThisMuch
73
+ );
74
+ path = path
75
+ .lineto(arrowheadPointInner.x, arrowheadPointInner.y)
76
+ .lineto(arrowheadPoint.x, arrowheadPoint.y);
77
+ }
78
+
79
+ path = path
80
+ .lineto(arrowheadBottom.x, arrowheadBottom.y)
81
+ .lineto(arcLeftBottom.x, arcLeftBottom.y)
82
+ .arc({
83
+ rx: tailInnerRadius,
84
+ ry: tailInnerRadius,
85
+ xrot: 0,
86
+ largeArcFlag,
87
+ sweepFlag: 1,
88
+ x: arcRightBottom.x,
89
+ y: arcRightBottom.y
90
+ });
91
+
92
+ if (overlapsSelf) {
93
+ path = path
94
+ .lineto(arcRightMiddle.x, arcRightMiddle.y)
95
+ .lineto(arcRightMiddleOuter.x, arcRightMiddleOuter.y)
96
+ .lineto(arcRightMiddle.x, arcRightMiddle.y);
97
+ }
98
+ let textPath;
99
+ if (returnTextPath && hasLabel) {
100
+ if (labelNeedsFlip) {
101
+ const arcLeftTop = polarToSpecialCartesian(tailOuterRadius, 0);
102
+ textPath = Path().moveto(arcRightTop.x, arcRightTop.y).arc({
103
+ rx: tailOuterRadius,
104
+ ry: tailOuterRadius,
105
+ xrot: 0,
106
+ largeArcFlag,
107
+ sweepFlag: 0,
108
+ x: arcLeftTop.x,
109
+ y: arcLeftTop.y
110
+ });
111
+ } else {
112
+ const arcLeftBottom = polarToSpecialCartesian(tailInnerRadius, 0);
113
+ textPath = Path().moveto(arcLeftBottom.x, arcLeftBottom.y).arc({
114
+ rx: tailInnerRadius,
115
+ ry: tailInnerRadius,
116
+ xrot: 0,
117
+ largeArcFlag,
118
+ sweepFlag: 1,
119
+ x: arcRightBottom.x,
120
+ y: arcRightBottom.y
121
+ });
122
+ }
123
+ }
124
+ path = path
125
+
126
+ .lineto(arcRightTop.x, arcRightTop.y)
127
+ .arc({
128
+ rx: tailOuterRadius,
129
+ ry: tailOuterRadius,
130
+ xrot: 0,
131
+ largeArcFlag,
132
+ sweepFlag: 0,
133
+ x: arcLeftTop.x,
134
+ y: arcLeftTop.y
135
+ })
136
+ .lineto(arrowheadTop.x, arrowheadTop.y)
137
+ .closepath();
138
+ if (returnTextPath) {
139
+ return [path, textPath];
140
+ }
141
+ return path;
142
+ }
package/editTool.js ADDED
@@ -0,0 +1,49 @@
1
+ import React, { useState } from "react";
2
+ import { Icon } from "@blueprintjs/core";
3
+ import ToolbarItem from "./ToolbarItem";
4
+ import { connectToEditor } from "../withEditorProps";
5
+
6
+ export default connectToEditor(editorState => {
7
+ return {
8
+ readOnly: editorState.readOnly
9
+ };
10
+ })(props => {
11
+ const { toolbarItemProps, readOnly, disableSetReadOnly } = props;
12
+ const [isLoading, setIsLoading] = useState(false);
13
+ const readOnlyTooltip = ({ readOnly, disableSetReadOnly }) => {
14
+ if (isLoading) {
15
+ return "Loading...";
16
+ } else if (disableSetReadOnly) {
17
+ return "You do not have permission to edit locks on this sequence";
18
+ }
19
+ return readOnly ? "Click to enable editing" : "Click to disable editing";
20
+ };
21
+ return (
22
+ <ToolbarItem
23
+ {...{
24
+ disabled: isLoading || disableSetReadOnly,
25
+ Icon: <Icon icon={readOnly ? "lock" : "unlock"} />,
26
+ onIconClick: () =>
27
+ handleReadOnlyChange(!readOnly, { ...props, setIsLoading }),
28
+ tooltip: readOnlyTooltip({ readOnly, disableSetReadOnly }),
29
+ ...toolbarItemProps
30
+ }}
31
+ />
32
+ );
33
+ });
34
+
35
+ export async function handleReadOnlyChange(
36
+ newVal,
37
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
38
+ { beforeReadOnlyChange, updateReadOnlyMode, setIsLoading = () => {} }
39
+ ) {
40
+ if (beforeReadOnlyChange) {
41
+ setIsLoading(true);
42
+ const shouldChange = await beforeReadOnlyChange(newVal);
43
+ setIsLoading(false);
44
+ if (shouldChange === false) {
45
+ return;
46
+ }
47
+ }
48
+ updateReadOnlyMode(newVal);
49
+ }
@@ -0,0 +1,2 @@
1
+ const sequenceDataSelector = state => state.sequenceData;
2
+ export default sequenceDataSelector;