@teselagen/ove 0.7.28 → 0.7.29
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/index.cjs.js +1055 -996
- package/index.es.js +1055 -996
- package/index.umd.js +189036 -0
- package/ove.css +1 -1
- package/package.json +2 -6
- package/src/helperComponents/PropertiesDialog/TranslationProperties.js +1 -1
- package/AASliver.js +0 -187
- package/AddLaddersDialog.js +0 -82
- package/AdditionalCutsiteInfoDialog.js +0 -599
- package/AlignmentVisibilityTool.js +0 -105
- package/AnnotationContainerHolder.js +0 -20
- package/AnnotationPositioner.js +0 -27
- package/AutoAnnotate.js +0 -501
- package/AutoAnnotateBpMatchingDialog.js +0 -208
- package/Axis.js +0 -151
- package/AxisNumbers.js +0 -35
- package/Browser.js +0 -106
- package/Caret.js +0 -63
- package/Chromatogram.js +0 -293
- package/CircularDnaSequence.js +0 -73
- package/CircularZoomMinimap.js +0 -16
- package/ColorPicker.js +0 -30
- package/CommandHotkeyHandler.js +0 -44
- package/CreateAnnotationsPage.js +0 -98
- package/Cutsite.js +0 -18
- package/CutsiteProperties.js +0 -176
- package/CutsiteSelectionLayers.js +0 -47
- package/Cutsites.js +0 -271
- package/DeletionLayer.js +0 -28
- package/DropHandler.css +0 -21
- package/DropHandler.js +0 -64
- package/EditCaretPosition.js +0 -234
- package/EditTrackNameDialog.js +0 -30
- package/Feature.js +0 -83
- package/FeatureProperties.js +0 -6
- package/FillWindow.js +0 -47
- package/GenbankView.js +0 -74
- package/GeneralProperties.js +0 -117
- package/GenericAnnotationProperties.js +0 -406
- package/GlobalDialog.js +0 -73
- package/GlobalDialogUtils.js +0 -110
- package/GoToDialog.js +0 -25
- package/HorizontalPanelDragHandle.js +0 -35
- package/Keyboard.js +0 -85
- package/Labels.js +0 -327
- package/Ladder.css +0 -20
- package/Ladder.js +0 -303
- package/MeltingTemp.js +0 -85
- package/Menlo.ttf +0 -0
- package/Minimap.js +0 -515
- package/Mismatches.js +0 -134
- package/Monaco.ttf +0 -0
- package/MultipleSeqsDetectedOnImportDialog.js +0 -74
- package/Orf.js +0 -109
- package/OrfProperties.js +0 -117
- package/Orfs.js +0 -35
- package/PCRTool.js +0 -179
- package/PairwiseAlignmentView.js +0 -68
- package/Part.js +0 -34
- package/PartProperties.js +0 -9
- package/PassThrough.js +0 -3
- package/PerformantSelectionLayer.js +0 -32
- package/PinchHelper.js +0 -24
- package/PointedAnnotation.js +0 -347
- package/PositionAnnotationOnCircle.js +0 -26
- package/Primer.js +0 -41
- package/PrimerProperties.js +0 -19
- package/ReflexContainer.js +0 -802
- package/ReflexElement.js +0 -160
- package/ReflexEvents.js +0 -77
- package/ReflexSplitter.js +0 -205
- package/RenameSequenceDialog.js +0 -7
- package/RotateCircularViewSlider.js +0 -93
- package/SelectDialog.js +0 -150
- package/SequenceName.js +0 -15
- package/SimpleCircularOrLinearView.js +0 -381
- package/SimpleOligoPreview.js +0 -39
- package/SingleEnzymeCutsiteInfo.js +0 -139
- package/ToolbarItem.js +0 -192
- package/Translation.js +0 -198
- package/TranslationProperties.js +0 -149
- package/UncontrolledSliderWithPlusMinusBtns.css +0 -5
- package/UncontrolledSliderWithPlusMinusBtns.js +0 -134
- package/VeTopRightContainer.js +0 -12
- package/ZoomCircularViewSlider.js +0 -62
- package/ZoomLinearView.js +0 -47
- package/addAlignment.js +0 -6
- package/addMetaToActionCreators.js +0 -12
- package/addWrappedAddons.js +0 -20
- package/alignmentTool.js +0 -503
- package/alignments.js +0 -379
- package/annotationLabelVisibility.js +0 -2
- package/annotationSearchSelector.js +0 -24
- package/annotationTypes.js +0 -35
- package/annotationVisibility.js +0 -196
- package/annotationsToSupport.js +0 -104
- package/arrayToObjWithIds.js +0 -17
- package/arrayUtils.js +0 -19
- package/array_move.js +0 -10
- package/calculateTickMarkPositionsForGivenRange.js +0 -47
- package/caretPosition.js +0 -27
- package/cdsFeaturesSelector.js +0 -9
- package/charWidth.js +0 -22
- package/circular.js +0 -19
- package/circularSelector.js +0 -4
- package/clickAndDragUtils.js +0 -576
- package/coerceInitialValue.js +0 -7
- package/combineReducersDontIgnoreKeys.js +0 -12
- package/commandUtils.js +0 -20
- package/constants.js +0 -2
- package/copyOptions.js +0 -34
- package/createFragmentLines.js +0 -120
- package/createMergedDefaultStateReducer.js +0 -30
- package/createMetaAction.js +0 -12
- package/createSequenceInputPopup.js +0 -290
- package/createSequenceInputPopupStyle.css +0 -87
- package/createSimpleDialog.js +0 -89
- package/createYourOwnEnzyme.js +0 -39
- package/cutsiteLabelColorSelector.js +0 -6
- package/cutsiteTool.js +0 -88
- package/cutsitesByRangeSelector.js +0 -5
- package/cutsitesSelector.js +0 -61
- package/darkmode.css +0 -98
- package/defaultConfig.js +0 -150
- package/deletionLayers.js +0 -36
- package/description.js +0 -21
- package/digestTool.js +0 -34
- package/dnaToColor.js +0 -17
- package/downloadTool.js +0 -39
- package/draggableClassnames.js +0 -5
- package/drawAnnotations.js +0 -440
- package/drawDirectedPiePiece.js +0 -142
- package/editTool.js +0 -49
- package/editorSelector.js +0 -2
- package/editorUtils.js +0 -205
- package/estimateRowHeight.js +0 -184
- package/featureLengthsToHide.js +0 -27
- package/featureTool.js +0 -34
- package/features.js +0 -19
- package/featuresSelector.js +0 -8
- package/filteredCutsitesSelector.js +0 -136
- package/filteredFeaturesSelector.js +0 -32
- package/filteredPartsSelector.js +0 -57
- package/filteredPrimersSelector.js +0 -27
- package/filteredRestrictionEnzymesSelector.js +0 -1
- package/find.png +0 -0
- package/findTool.js +0 -79
- package/findToolConstants.js +0 -1
- package/frameTranslations.js +0 -52
- package/fullscreen.png +0 -0
- package/getAdditionalEnzymesSelector.js +0 -46
- package/getAngleForPositionMidpoint.js +0 -3
- package/getAnnotationClassnames.js +0 -12
- package/getAnnotationNameAndStartStopString.js +0 -61
- package/getBpsPerRow.js +0 -19
- package/getCutsiteLabelHeights.js +0 -56
- package/getGapMap.js +0 -12
- package/getGaps.js +0 -27
- package/getInternalLabel.js +0 -40
- package/getOveHotkeyDefs.js +0 -12
- package/getPairwiseOverviewLinearViewOptions.js +0 -38
- package/getRangeAnglesSpecial.js +0 -12
- package/getStructuredBases.js +0 -97
- package/getTrackFromEvent.js +0 -25
- package/getVisibleStartEnd.js +0 -7
- package/getXStartAndWidthFromNonCircularRange.js +0 -12
- package/getXStartAndWidthOfRangeWrtRow.js +0 -27
- package/getXStartAndWidthOfRowAnnotation.js +0 -19
- package/getYOffset.js +0 -15
- package/hoveredAnnotation.js +0 -24
- package/importTool.js +0 -27
- package/index.js +0 -71
- package/inlineFindTool.js +0 -38
- package/isElementInViewport.js +0 -29
- package/isEnzymeFilterAndSelector.js +0 -1
- package/isTargetWithinEl.js +0 -6
- package/labelLineIntensity.js +0 -25
- package/labelSize.js +0 -23
- package/ladderDefaults.js +0 -25
- package/lastSavedId.js +0 -20
- package/lineageLines.js +0 -11
- package/linear.png +0 -0
- package/makeStore.js +0 -34
- package/massageTickSpacing.js +0 -19
- package/materiallyAvailable.js +0 -19
- package/middleware.js +0 -112
- package/minimumOrfSize.js +0 -24
- package/minimumOrfSizeSelector.js +0 -2
- package/modalActions.js +0 -3
- package/moveCaret.js +0 -58
- package/name.js +0 -19
- package/normalizeAngle.js +0 -3
- package/normalizeAngleRange.js +0 -9
- package/oligoTool.js +0 -30
- package/onlyUpdateForKeysDeep.js +0 -31
- package/orfFrameToColorMap.js +0 -10
- package/orfTool.js +0 -136
- package/orfsSelector.js +0 -15
- package/panelsShown.js +0 -294
- package/partLengthsToHide.js +0 -23
- package/partOverhangs.js +0 -6
- package/partTagSearch.js +0 -69
- package/partTool.js +0 -45
- package/parts.js +0 -19
- package/partsSelector.js +0 -8
- package/pie.png +0 -0
- package/polarToSpecialCartesian.js +0 -7
- package/positionCutsites.js +0 -6
- package/prepareRowData.js +0 -64
- package/primerBases.js +0 -221
- package/primerLengthsToHide.js +0 -27
- package/primers.js +0 -19
- package/primersSelector.js +0 -8
- package/print.png +0 -0
- package/printTool.js +0 -31
- package/propertiesTool.js +0 -40
- package/proteinUtils.js +0 -3
- package/pureNoFunc.js +0 -18
- package/readOnly.js +0 -25
- package/redoTool.js +0 -30
- package/reflex-styles.css +0 -128
- package/reflex-styles.css.map +0 -9
- package/relaxLabelAngles.js +0 -157
- package/relaxLabels_DEPRECATED.js +0 -105
- package/replacementLayers.js +0 -36
- package/restrictionEnzymes.js +0 -52
- package/restrictionEnzymesSelector.js +0 -34
- package/rowviewContants.js +0 -3
- package/ruler.css +0 -89
- package/save.png +0 -0
- package/saveTool.js +0 -44
- package/searchLayersSelector.js +0 -71
- package/selectedAnnotations.js +0 -89
- package/selectedAnnotationsSelector.js +0 -1
- package/selectedCutsitesSelector.js +0 -21
- package/selectedPartTags.js +0 -21
- package/selectionLayer.js +0 -25
- package/sequence.js +0 -12
- package/sequenceDataHistory.js +0 -43
- package/sequenceDataSelector.js +0 -2
- package/sequenceLengthSelector.js +0 -5
- package/sequenceSelector.js +0 -4
- package/sharedActionCreators.js +0 -0
- package/shouldFlipText.js +0 -4
- package/shouldRerender.js +0 -27
- package/showFileDialog.js +0 -25
- package/showGCContent.js +0 -23
- package/show_cut_sites.png +0 -0
- package/show_features.png +0 -0
- package/show_orfs.png +0 -0
- package/show_primers.png +0 -0
- package/simpleDialog.css +0 -13
- package/specialCutsiteFilterOptions.js +0 -22
- package/style.css +0 -10
- package/tagsToBoldSelector.js +0 -2
- package/toggle_views.svg +0 -1
- package/toolBar.js +0 -23
- package/translationSearchMatchesSelector.js +0 -14
- package/translations.js +0 -20
- package/translationsRawSelector.js +0 -8
- package/translationsSelector.js +0 -137
- package/typeField.js +0 -24
- package/undoTool.js +0 -30
- package/updateEditor.js +0 -200
- package/updateLabelsForInViewFeatures.js +0 -55
- package/updateLabelsForInViewFeaturesCircView.js +0 -41
- package/updateTrackHelper.js +0 -58
- package/uppercaseSequenceMapFont.js +0 -25
- package/upsertDeleteActionGenerator.js +0 -31
- package/useAAColorType.js +0 -8
- package/useAdditionalOrfStartCodons.js +0 -24
- package/useAnnotationLimits.js +0 -42
- package/useChromatogramPrefs.js +0 -31
- package/useFormValue.js +0 -7
- package/useLadders.js +0 -6
- package/useMeltingTemp.js +0 -7
- package/useTmType.js +0 -10
- package/userDefinedHandlersAndOpts.js +0 -61
- package/utils.js +0 -37
- package/versionHistory.js +0 -26
- package/versionHistoryTool.js +0 -21
- package/viewSubmenu.js +0 -479
- package/visibilityTool.js +0 -39
- package/withHover.js +0 -113
- package/withRestrictionEnzymes.js +0 -15
package/Minimap.js
DELETED
|
@@ -1,515 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import Draggable from "react-draggable";
|
|
3
|
-
import ReactList from "@teselagen/react-list";
|
|
4
|
-
import Axis from "../RowItem/Axis";
|
|
5
|
-
import getXStartAndWidthFromNonCircularRange from "../RowItem/getXStartAndWidthFromNonCircularRange";
|
|
6
|
-
import { view } from "@risingstack/react-easy-state";
|
|
7
|
-
import { flatMap, some, toNumber } from "lodash-es";
|
|
8
|
-
import {
|
|
9
|
-
getOverlapOfNonCircularRanges,
|
|
10
|
-
invertRange,
|
|
11
|
-
isPositionWithinRange,
|
|
12
|
-
splitRangeIntoTwoPartsIfItIsCircular
|
|
13
|
-
} from "@teselagen/range-utils";
|
|
14
|
-
import { massageTickSpacing } from "../utils/massageTickSpacing";
|
|
15
|
-
import { getClientX, getClientY } from "../utils/editorUtils";
|
|
16
|
-
export default class Minimap extends React.Component {
|
|
17
|
-
shouldComponentUpdate(newProps) {
|
|
18
|
-
const { props } = this;
|
|
19
|
-
if (
|
|
20
|
-
[
|
|
21
|
-
"alignmentTracks",
|
|
22
|
-
"numBpsShownInLinearView",
|
|
23
|
-
"scrollAlignmentView",
|
|
24
|
-
"laneHeight",
|
|
25
|
-
"laneSpacing"
|
|
26
|
-
].some(key => props[key] !== newProps[key])
|
|
27
|
-
)
|
|
28
|
-
return true;
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
handleMinimapClick = e => {
|
|
32
|
-
if (
|
|
33
|
-
this.isDragging ||
|
|
34
|
-
(e.target && e.target.classList.contains("minimapCaret"))
|
|
35
|
-
) {
|
|
36
|
-
e.stopPropagation();
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const {
|
|
40
|
-
onMinimapScrollX,
|
|
41
|
-
dimensions: { width = 200 }
|
|
42
|
-
} = this.props;
|
|
43
|
-
const scrollHandleWidth = this.getScrollHandleWidth();
|
|
44
|
-
const percent =
|
|
45
|
-
(this.getXPositionOfClickInMinimap(e) - scrollHandleWidth / 2) /
|
|
46
|
-
(width - scrollHandleWidth);
|
|
47
|
-
onMinimapScrollX(percent);
|
|
48
|
-
this.scrollMinimapVertical({ e, force: true });
|
|
49
|
-
};
|
|
50
|
-
getSeqLen = () => {
|
|
51
|
-
const { alignmentTracks = [] } = this.props;
|
|
52
|
-
const [template] = alignmentTracks;
|
|
53
|
-
const seqLength = template.alignmentData.sequence.length;
|
|
54
|
-
return seqLength;
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* @returns current nucleotide char
|
|
58
|
-
* width, nucelotide char width scales with zooming
|
|
59
|
-
*/
|
|
60
|
-
getCharWidth = () => {
|
|
61
|
-
const {
|
|
62
|
-
dimensions: { width = 200 }
|
|
63
|
-
} = this.props;
|
|
64
|
-
const seqLength = this.getSeqLen();
|
|
65
|
-
const charWidth = Math.min(16, width / seqLength);
|
|
66
|
-
return charWidth || 12;
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* @returns the width of the highlighted region of the minimap
|
|
70
|
-
*/
|
|
71
|
-
getScrollHandleWidth = () => {
|
|
72
|
-
const { numBpsShownInLinearView, dimensions } = this.props;
|
|
73
|
-
const charWidth = this.getCharWidth();
|
|
74
|
-
const { width } = getXStartAndWidthFromNonCircularRange(
|
|
75
|
-
{ start: 0, end: Math.max(numBpsShownInLinearView - 1, 0) },
|
|
76
|
-
charWidth
|
|
77
|
-
);
|
|
78
|
-
return Math.min(width, dimensions.width);
|
|
79
|
-
};
|
|
80
|
-
getXPositionOfClickInMinimap = e => {
|
|
81
|
-
const leftStart = this.minimap.getBoundingClientRect().left;
|
|
82
|
-
return Math.max(getClientX(e) - leftStart, 0);
|
|
83
|
-
};
|
|
84
|
-
getYPositionOfClickInMinimap = e => {
|
|
85
|
-
const topStart = this.minimap.getBoundingClientRect().top;
|
|
86
|
-
return Math.max(getClientY(e) + this.minimapTracks.scrollTop - topStart, 0);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
scrollMinimapVertical = ({ e, force, initialDragYOffsetFromCenter }) => {
|
|
90
|
-
const clientY = getClientY(e) - (initialDragYOffsetFromCenter || 0);
|
|
91
|
-
try {
|
|
92
|
-
if (
|
|
93
|
-
!force &&
|
|
94
|
-
isPositionWithinRange(clientY, {
|
|
95
|
-
start: this.lastYPosition - 5,
|
|
96
|
-
end: this.lastYPosition + 5
|
|
97
|
-
})
|
|
98
|
-
) {
|
|
99
|
-
// this.lastYPosition = clientY
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const lanes = document.querySelectorAll(".minimapLane");
|
|
103
|
-
some(lanes, lane => {
|
|
104
|
-
const rect = lane.getBoundingClientRect();
|
|
105
|
-
if (rect.top > clientY && rect.top - rect.height < clientY) {
|
|
106
|
-
const laneI = toNumber(lane.getAttribute("data-lane-index"));
|
|
107
|
-
let scrollToLane = laneI - 3;
|
|
108
|
-
if (laneI === lanes.length - 1) {
|
|
109
|
-
scrollToLane = laneI - 1;
|
|
110
|
-
} else if (laneI === lanes.length - 2) {
|
|
111
|
-
scrollToLane = laneI - 2;
|
|
112
|
-
}
|
|
113
|
-
this.props.scrollYToTrack(Math.max(scrollToLane, 0));
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
return false;
|
|
117
|
-
});
|
|
118
|
-
this.lastYPosition = clientY;
|
|
119
|
-
} catch (error) {
|
|
120
|
-
console.error(`error in scrollMinimapVertical:`, error);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
handleDragStop = () => {
|
|
124
|
-
// this.hasSetDirection = false;
|
|
125
|
-
setTimeout(() => {
|
|
126
|
-
this.isDragging = false;
|
|
127
|
-
}, 150);
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* Handler for beginning to drag across the minimap
|
|
131
|
-
* Sets this.initialDragXOffsetFromCenter and Y for dragging
|
|
132
|
-
* @param {*} e - event
|
|
133
|
-
*/
|
|
134
|
-
handleDragStart = e => {
|
|
135
|
-
const eventX = e.pageX;
|
|
136
|
-
const handleEl = window.document.querySelector(".verticalScrollDisplay");
|
|
137
|
-
if (!handleEl) return;
|
|
138
|
-
const { x, width } = handleEl.getBoundingClientRect();
|
|
139
|
-
const yellowScrollHandleXCenter = x + width / 2;
|
|
140
|
-
this.initialDragXOffsetFromCenter = eventX - yellowScrollHandleXCenter;
|
|
141
|
-
const eventY = e.pageY;
|
|
142
|
-
|
|
143
|
-
if (!handleEl) return;
|
|
144
|
-
const { y, height } = handleEl.getBoundingClientRect();
|
|
145
|
-
const yellowScrollHandleYCenter = y + height / 2;
|
|
146
|
-
this.initialDragYOffsetFromCenter = eventY - yellowScrollHandleYCenter;
|
|
147
|
-
};
|
|
148
|
-
/**
|
|
149
|
-
* Moves the highlighted region as we drag
|
|
150
|
-
* @param {*} e - event
|
|
151
|
-
*/
|
|
152
|
-
handleDrag = e => {
|
|
153
|
-
const {
|
|
154
|
-
onMinimapScrollX,
|
|
155
|
-
dimensions: { width = 200 }
|
|
156
|
-
} = this.props;
|
|
157
|
-
this.isDragging = true; //needed to block erroneous click events from being triggered!
|
|
158
|
-
|
|
159
|
-
const scrollHandleWidth = this.getScrollHandleWidth();
|
|
160
|
-
const percent =
|
|
161
|
-
(this.getXPositionOfClickInMinimap(e) -
|
|
162
|
-
(this.initialDragXOffsetFromCenter || 0) -
|
|
163
|
-
scrollHandleWidth / 2) /
|
|
164
|
-
(width - scrollHandleWidth);
|
|
165
|
-
onMinimapScrollX(percent);
|
|
166
|
-
this.scrollMinimapVertical({
|
|
167
|
-
e,
|
|
168
|
-
initialDragYOffsetFromCenter: this.initialDragYOffsetFromCenter
|
|
169
|
-
});
|
|
170
|
-
};
|
|
171
|
-
/**
|
|
172
|
-
* @returns this.props.laneheight
|
|
173
|
-
*/
|
|
174
|
-
itemSizeGetter = () => {
|
|
175
|
-
return this.props.laneHeight;
|
|
176
|
-
};
|
|
177
|
-
/**
|
|
178
|
-
* Renders a lane (one by one for each call)
|
|
179
|
-
* @param {*} i - lane info
|
|
180
|
-
*/
|
|
181
|
-
renderItem = i => {
|
|
182
|
-
const {
|
|
183
|
-
alignmentTracks = [],
|
|
184
|
-
dimensions: { width = 200 },
|
|
185
|
-
laneHeight,
|
|
186
|
-
laneSpacing = 1
|
|
187
|
-
} = this.props;
|
|
188
|
-
const charWidth = this.getCharWidth();
|
|
189
|
-
|
|
190
|
-
const {
|
|
191
|
-
matchHighlightRanges: _matchHighlightRanges,
|
|
192
|
-
alignmentData: { trimmedRange } = {}
|
|
193
|
-
} = alignmentTracks[i];
|
|
194
|
-
const matchHighlightRanges = !trimmedRange
|
|
195
|
-
? _matchHighlightRanges
|
|
196
|
-
: flatMap(_matchHighlightRanges, r => {
|
|
197
|
-
const overlap = getOverlapOfNonCircularRanges(r, trimmedRange);
|
|
198
|
-
if (!overlap) return [];
|
|
199
|
-
return { ...r, ...overlap };
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
//need to get the chunks that can be rendered
|
|
203
|
-
let redPath = ""; //draw these as just 1 path instead of a bunch of rectangles to improve browser performance
|
|
204
|
-
let bluePath = "";
|
|
205
|
-
// draw one grey rectangle then draw red/mismatching regions on top of it
|
|
206
|
-
const height = laneHeight - laneSpacing;
|
|
207
|
-
const y = 0;
|
|
208
|
-
const firstRange = getXStartAndWidthFromNonCircularRange(
|
|
209
|
-
matchHighlightRanges[0],
|
|
210
|
-
charWidth
|
|
211
|
-
);
|
|
212
|
-
const lastRange = getXStartAndWidthFromNonCircularRange(
|
|
213
|
-
matchHighlightRanges[matchHighlightRanges.length - 1],
|
|
214
|
-
charWidth
|
|
215
|
-
);
|
|
216
|
-
bluePath += `M${firstRange.xStart},${y} L${
|
|
217
|
-
lastRange.xStart + lastRange.width
|
|
218
|
-
},${y} L${lastRange.xStart + lastRange.width},${y + height} L${
|
|
219
|
-
firstRange.xStart
|
|
220
|
-
},${y + height}`;
|
|
221
|
-
matchHighlightRanges.forEach(range => {
|
|
222
|
-
const { xStart, width } = getXStartAndWidthFromNonCircularRange(
|
|
223
|
-
range,
|
|
224
|
-
charWidth
|
|
225
|
-
);
|
|
226
|
-
const toAdd = `M${xStart},${y} L${xStart + width},${y} L${
|
|
227
|
-
xStart + width
|
|
228
|
-
},${y + height} L${xStart},${y + height}`;
|
|
229
|
-
if (!range.isMatch) {
|
|
230
|
-
redPath += toAdd;
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
return (
|
|
234
|
-
<div
|
|
235
|
-
key={i + "-lane"}
|
|
236
|
-
className="minimapLane"
|
|
237
|
-
data-lane-index={i}
|
|
238
|
-
style={{ height: laneHeight, maxHeight: laneHeight }}
|
|
239
|
-
>
|
|
240
|
-
<svg
|
|
241
|
-
height={laneHeight}
|
|
242
|
-
width={width}
|
|
243
|
-
shapeRendering="geometricPrecision"
|
|
244
|
-
>
|
|
245
|
-
<path className="miniBluePath" d={bluePath} fill="#9abeff" />
|
|
246
|
-
<path className="miniRedPath" d={redPath} fill="red" />
|
|
247
|
-
</svg>
|
|
248
|
-
</div>
|
|
249
|
-
);
|
|
250
|
-
};
|
|
251
|
-
/**
|
|
252
|
-
* @returns minimap compoent
|
|
253
|
-
*/
|
|
254
|
-
render() {
|
|
255
|
-
const {
|
|
256
|
-
alignmentTracks = [],
|
|
257
|
-
dimensions: { width = 200 },
|
|
258
|
-
laneHeight,
|
|
259
|
-
onSizeAdjust,
|
|
260
|
-
minSliderSize,
|
|
261
|
-
onMinimapScrollX,
|
|
262
|
-
easyStore,
|
|
263
|
-
selectionLayerComp
|
|
264
|
-
} = this.props;
|
|
265
|
-
|
|
266
|
-
const [template /* ...nonTemplates */] = alignmentTracks;
|
|
267
|
-
const seqLength = template.alignmentData.sequence.length;
|
|
268
|
-
const charWidth = this.getCharWidth();
|
|
269
|
-
const scrollHandleWidth = this.getScrollHandleWidth();
|
|
270
|
-
const minimapTracksPartialHeight = laneHeight * alignmentTracks.length;
|
|
271
|
-
|
|
272
|
-
return (
|
|
273
|
-
<div
|
|
274
|
-
ref={ref => (this.minimap = ref)}
|
|
275
|
-
className="alignmentMinimap"
|
|
276
|
-
style={{
|
|
277
|
-
position: "relative",
|
|
278
|
-
width,
|
|
279
|
-
display: "flex",
|
|
280
|
-
flexDirection: "column",
|
|
281
|
-
overflowX: "visible"
|
|
282
|
-
}}
|
|
283
|
-
onClick={this.handleMinimapClick}
|
|
284
|
-
>
|
|
285
|
-
{selectionLayerComp}
|
|
286
|
-
<div
|
|
287
|
-
ref={ref => {
|
|
288
|
-
if (ref) {
|
|
289
|
-
this.minimapTracks = ref;
|
|
290
|
-
}
|
|
291
|
-
}}
|
|
292
|
-
style={{
|
|
293
|
-
overflowY: minimapTracksPartialHeight > 190 ? "auto" : "hidden",
|
|
294
|
-
overflowX: "hidden",
|
|
295
|
-
position: "relative"
|
|
296
|
-
}}
|
|
297
|
-
className="alignmentMinimapTracks"
|
|
298
|
-
>
|
|
299
|
-
<YellowScrollHandle
|
|
300
|
-
width={width}
|
|
301
|
-
handleDragStart={this.handleDragStart}
|
|
302
|
-
handleDrag={this.handleDrag}
|
|
303
|
-
handleDragStop={this.handleDragStop}
|
|
304
|
-
onMinimapScrollX={onMinimapScrollX}
|
|
305
|
-
minSliderSize={minSliderSize}
|
|
306
|
-
onSizeAdjust={onSizeAdjust}
|
|
307
|
-
easyStore={easyStore} //we use react-easy-state here to prevent costly setStates from being called
|
|
308
|
-
scrollHandleWidth={scrollHandleWidth}
|
|
309
|
-
alignmentTracks={alignmentTracks}
|
|
310
|
-
laneHeight={laneHeight}
|
|
311
|
-
minimapTracksPartialHeight={minimapTracksPartialHeight}
|
|
312
|
-
/>
|
|
313
|
-
|
|
314
|
-
<ReactList
|
|
315
|
-
itemsRenderer={(items, ref) => (
|
|
316
|
-
<div
|
|
317
|
-
style={{
|
|
318
|
-
marginTop: -3
|
|
319
|
-
}}
|
|
320
|
-
ref={ref}
|
|
321
|
-
>
|
|
322
|
-
{items}
|
|
323
|
-
</div>
|
|
324
|
-
)}
|
|
325
|
-
type="uniform"
|
|
326
|
-
itemSizeGetter={this.itemSizeGetter}
|
|
327
|
-
itemRenderer={this.renderItem}
|
|
328
|
-
length={alignmentTracks.length}
|
|
329
|
-
/>
|
|
330
|
-
</div>
|
|
331
|
-
|
|
332
|
-
<Axis
|
|
333
|
-
{...{
|
|
334
|
-
row: { start: 0, end: seqLength - 1 },
|
|
335
|
-
tickSpacing: massageTickSpacing(Math.floor(seqLength / 10)),
|
|
336
|
-
bpsPerRow: seqLength,
|
|
337
|
-
charWidth,
|
|
338
|
-
annotationHeight: 15,
|
|
339
|
-
sequenceLength: seqLength,
|
|
340
|
-
style: {
|
|
341
|
-
height: 17,
|
|
342
|
-
width: "100%"
|
|
343
|
-
}
|
|
344
|
-
}}
|
|
345
|
-
/>
|
|
346
|
-
</div>
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Yellow Scroll handle
|
|
352
|
-
* Responsible for designating the current viewing area
|
|
353
|
-
* Also supports zoom/resizing using handles
|
|
354
|
-
*/
|
|
355
|
-
const YellowScrollHandle = view(
|
|
356
|
-
class YellowScrollHandleInner extends React.Component {
|
|
357
|
-
render() {
|
|
358
|
-
const {
|
|
359
|
-
scrollHandleWidth,
|
|
360
|
-
width,
|
|
361
|
-
easyStore,
|
|
362
|
-
handleDrag,
|
|
363
|
-
handleDragStop,
|
|
364
|
-
minSliderSize,
|
|
365
|
-
laneHeight,
|
|
366
|
-
onSizeAdjust,
|
|
367
|
-
handleDragStart,
|
|
368
|
-
minimapTracksPartialHeight
|
|
369
|
-
} = this.props;
|
|
370
|
-
const { verticalVisibleRange, percentScrolled } = easyStore;
|
|
371
|
-
const xScroll = percentScrolled * (width - scrollHandleWidth);
|
|
372
|
-
return (
|
|
373
|
-
<Draggable
|
|
374
|
-
bounds="parent"
|
|
375
|
-
zIndex={105}
|
|
376
|
-
handle=".handle"
|
|
377
|
-
position={{ x: xScroll, y: 0 }}
|
|
378
|
-
axis="x"
|
|
379
|
-
// onStart={this.onStart}
|
|
380
|
-
onStop={handleDragStop}
|
|
381
|
-
onDrag={handleDrag}
|
|
382
|
-
onStart={handleDragStart}
|
|
383
|
-
>
|
|
384
|
-
<div
|
|
385
|
-
style={{
|
|
386
|
-
height: minimapTracksPartialHeight || 0,
|
|
387
|
-
// height: "100%",
|
|
388
|
-
border: "none",
|
|
389
|
-
top: "0px",
|
|
390
|
-
position: "absolute",
|
|
391
|
-
zIndex: "10"
|
|
392
|
-
}}
|
|
393
|
-
>
|
|
394
|
-
{/* left hand side drag handle */}
|
|
395
|
-
<Draggable
|
|
396
|
-
bounds={{
|
|
397
|
-
left: -xScroll,
|
|
398
|
-
right: scrollHandleWidth - minSliderSize
|
|
399
|
-
}}
|
|
400
|
-
zIndex={105}
|
|
401
|
-
position={{ x: 0, y: 0 }}
|
|
402
|
-
axis="x"
|
|
403
|
-
onStart={(e, { x }) => {
|
|
404
|
-
this.x = x;
|
|
405
|
-
}}
|
|
406
|
-
onStop={(e, { x }) => {
|
|
407
|
-
const deltaX = x - this.x;
|
|
408
|
-
|
|
409
|
-
const newSliderSize = scrollHandleWidth - deltaX;
|
|
410
|
-
//user is resizing to the left so we need to update the scroll percentage so the slider does not jump
|
|
411
|
-
const newScrollPercent = Math.min(
|
|
412
|
-
1,
|
|
413
|
-
(xScroll + deltaX) / (width - newSliderSize)
|
|
414
|
-
);
|
|
415
|
-
onSizeAdjust(newSliderSize, newScrollPercent);
|
|
416
|
-
}}
|
|
417
|
-
>
|
|
418
|
-
{/* caret component */}
|
|
419
|
-
<div
|
|
420
|
-
style={{
|
|
421
|
-
height: minimapTracksPartialHeight || 0,
|
|
422
|
-
// height: "100%",
|
|
423
|
-
border: "none",
|
|
424
|
-
cursor: "ew-resize",
|
|
425
|
-
opacity: "1",
|
|
426
|
-
top: "0px",
|
|
427
|
-
position: "absolute",
|
|
428
|
-
zIndex: "10",
|
|
429
|
-
width: 2,
|
|
430
|
-
background: "black"
|
|
431
|
-
}}
|
|
432
|
-
className="minimapCaret"
|
|
433
|
-
/>
|
|
434
|
-
</Draggable>
|
|
435
|
-
{/* the actual handle component */}
|
|
436
|
-
<div
|
|
437
|
-
className="handle alignmentMinimapScrollHandle"
|
|
438
|
-
dataname="scrollGroup"
|
|
439
|
-
style={{
|
|
440
|
-
height: minimapTracksPartialHeight || 0,
|
|
441
|
-
border: "none",
|
|
442
|
-
cursor: "move",
|
|
443
|
-
|
|
444
|
-
zIndex: "10",
|
|
445
|
-
width: scrollHandleWidth,
|
|
446
|
-
background: "transparent"
|
|
447
|
-
}}
|
|
448
|
-
>
|
|
449
|
-
{/* this is the vertical scroll position display element */}
|
|
450
|
-
<div
|
|
451
|
-
className="verticalScrollDisplay"
|
|
452
|
-
style={{
|
|
453
|
-
height:
|
|
454
|
-
(verticalVisibleRange.end -
|
|
455
|
-
verticalVisibleRange.start +
|
|
456
|
-
1) *
|
|
457
|
-
laneHeight,
|
|
458
|
-
zIndex: "-10",
|
|
459
|
-
background: "#fbfb2873",
|
|
460
|
-
borderTop: "2px solid yellow",
|
|
461
|
-
borderBottom: "2px solid yellow",
|
|
462
|
-
position: "relative",
|
|
463
|
-
top: verticalVisibleRange.start * laneHeight
|
|
464
|
-
}}
|
|
465
|
-
/>
|
|
466
|
-
</div>
|
|
467
|
-
{/* right hand side drag handle */}
|
|
468
|
-
<Draggable
|
|
469
|
-
bounds={{
|
|
470
|
-
right: minSliderSize + width - xScroll,
|
|
471
|
-
left: minSliderSize
|
|
472
|
-
}}
|
|
473
|
-
zIndex={105}
|
|
474
|
-
position={{ x: scrollHandleWidth, y: 0 }}
|
|
475
|
-
axis="x"
|
|
476
|
-
onStart={(e, { x }) => {
|
|
477
|
-
this.x = x;
|
|
478
|
-
}}
|
|
479
|
-
onStop={(e, { x }) => {
|
|
480
|
-
const deltaX = this.x - x;
|
|
481
|
-
const newSliderSize = scrollHandleWidth - deltaX;
|
|
482
|
-
//user is resizing to the right so we need to update the scroll percentage so the slider does not jump
|
|
483
|
-
const newScrollPercent = xScroll / (width - newSliderSize);
|
|
484
|
-
onSizeAdjust(newSliderSize, newScrollPercent);
|
|
485
|
-
}}
|
|
486
|
-
>
|
|
487
|
-
<div
|
|
488
|
-
style={{
|
|
489
|
-
height: minimapTracksPartialHeight || 0,
|
|
490
|
-
// height: "100%",
|
|
491
|
-
border: "none",
|
|
492
|
-
cursor: "ew-resize",
|
|
493
|
-
opacity: "1",
|
|
494
|
-
top: "0px",
|
|
495
|
-
// right: 0,
|
|
496
|
-
position: "absolute",
|
|
497
|
-
zIndex: "10",
|
|
498
|
-
width: 2,
|
|
499
|
-
background: "black"
|
|
500
|
-
}}
|
|
501
|
-
className="minimapCaret"
|
|
502
|
-
/>
|
|
503
|
-
</Draggable>
|
|
504
|
-
</div>
|
|
505
|
-
</Draggable>
|
|
506
|
-
);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
);
|
|
510
|
-
|
|
511
|
-
export function getTrimmedRangesToDisplay({ trimmedRange, seqLen }) {
|
|
512
|
-
if (!trimmedRange) return [];
|
|
513
|
-
const inverted = invertRange(trimmedRange, seqLen);
|
|
514
|
-
return splitRangeIntoTwoPartsIfItIsCircular(inverted, seqLen);
|
|
515
|
-
}
|
package/Mismatches.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { DataTable, withSelectedEntities } from "@teselagen/ui";
|
|
3
|
-
|
|
4
|
-
class Mismatches extends React.Component {
|
|
5
|
-
UNSAFE_componentWillMount() {
|
|
6
|
-
const { alignmentData, mismatches } = this.props;
|
|
7
|
-
// const { alignmentId, alignments } = this.props;
|
|
8
|
-
const mismatchList = this.getMismatchList(alignmentData, mismatches);
|
|
9
|
-
// const mismatchListAll = this.getMismatchList(alignmentId, alignments);
|
|
10
|
-
const schema = {
|
|
11
|
-
fields: [{ path: "mismatches", type: "number" }]
|
|
12
|
-
};
|
|
13
|
-
this.setState({ mismatchList, schema });
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
getGapMap = sequence => {
|
|
17
|
-
const gapMap = [0]; //a map of position to how many gaps come before that position [0,0,0,5,5,5,5,17,17,17, ]
|
|
18
|
-
sequence.split("").forEach(char => {
|
|
19
|
-
if (char === "-") {
|
|
20
|
-
gapMap[Math.max(0, gapMap.length - 1)] =
|
|
21
|
-
(gapMap[Math.max(0, gapMap.length - 1)] || 0) + 1;
|
|
22
|
-
} else {
|
|
23
|
-
gapMap.push(gapMap[gapMap.length - 1] || 0);
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
return gapMap;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
getMismatchList = (alignmentData, mismatches) => {
|
|
30
|
-
// getMismatchList = (alignmentId, alignments) => {
|
|
31
|
-
// let mismatchListAll = [];
|
|
32
|
-
// skip first sequence/ref seq, since there will be no mismatches
|
|
33
|
-
// for (let trackI = 1; trackI < alignments[alignmentId].alignmentTracks.length; trackI++) {
|
|
34
|
-
const mismatchList = [];
|
|
35
|
-
// const trackName = alignmentData.name;
|
|
36
|
-
// const editedTrackName = trackName.slice(trackName.indexOf("_") + 1);
|
|
37
|
-
|
|
38
|
-
let getGaps = () => ({
|
|
39
|
-
gapsBefore: 0,
|
|
40
|
-
gapsInside: 0
|
|
41
|
-
});
|
|
42
|
-
const gapMap = this.getGapMap(alignmentData.sequence);
|
|
43
|
-
getGaps = rangeOrCaretPosition => {
|
|
44
|
-
if (typeof rangeOrCaretPosition !== "object") {
|
|
45
|
-
return {
|
|
46
|
-
gapsBefore: gapMap[Math.min(rangeOrCaretPosition, gapMap.length - 1)]
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
const { start, end } = rangeOrCaretPosition;
|
|
50
|
-
const toReturn = {
|
|
51
|
-
gapsBefore: gapMap[start],
|
|
52
|
-
gapsInside:
|
|
53
|
-
gapMap[Math.min(end, gapMap.length - 1)] -
|
|
54
|
-
gapMap[Math.min(start, gapMap.length - 1)]
|
|
55
|
-
};
|
|
56
|
-
return toReturn;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const gapsBeforeSequence = getGaps(0).gapsBefore;
|
|
60
|
-
for (let mismatchI = 0; mismatchI < mismatches.length; mismatchI++) {
|
|
61
|
-
const mismatchEnd = mismatches[mismatchI].end;
|
|
62
|
-
const mismatchStart = mismatches[mismatchI].start;
|
|
63
|
-
const mismatchDifference = mismatchEnd - mismatchStart;
|
|
64
|
-
// display 'position' as 1-based but store 'start' & 'end' as 0-based
|
|
65
|
-
if (mismatchDifference === 0) {
|
|
66
|
-
mismatchList.push({
|
|
67
|
-
mismatches: mismatchStart + 1 - gapsBeforeSequence,
|
|
68
|
-
start: mismatchStart - gapsBeforeSequence,
|
|
69
|
-
end: mismatchStart - gapsBeforeSequence
|
|
70
|
-
});
|
|
71
|
-
} else {
|
|
72
|
-
for (let innerI = 0; innerI <= mismatchDifference; innerI++) {
|
|
73
|
-
mismatchList.push({
|
|
74
|
-
mismatches: mismatchStart + innerI + 1 - gapsBeforeSequence,
|
|
75
|
-
start: mismatchStart + innerI - gapsBeforeSequence,
|
|
76
|
-
end: mismatchStart + innerI - gapsBeforeSequence
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return mismatchList;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
render() {
|
|
85
|
-
const { mismatchList, schema } = this.state;
|
|
86
|
-
let tableOfMismatches;
|
|
87
|
-
if (mismatchList.length === 0) {
|
|
88
|
-
tableOfMismatches = null;
|
|
89
|
-
} else {
|
|
90
|
-
tableOfMismatches = (
|
|
91
|
-
<DataTable
|
|
92
|
-
maxHeight={168}
|
|
93
|
-
formName={"mismatchesTable"}
|
|
94
|
-
isSimple
|
|
95
|
-
compact
|
|
96
|
-
noRouter
|
|
97
|
-
// onRowSelect={this.handleMismatchClick}
|
|
98
|
-
schema={schema}
|
|
99
|
-
entities={mismatchList}
|
|
100
|
-
/>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<div style={{ maxHeight: 180.8, overflowY: "scroll" }}>
|
|
106
|
-
{/* <div style={{ fontSize: 15, textAlign: "center" }}><b>Positions of Mismatches</b></div> */}
|
|
107
|
-
<div
|
|
108
|
-
style={{
|
|
109
|
-
// margin: 10,
|
|
110
|
-
display: "flex",
|
|
111
|
-
flexDirection: "column",
|
|
112
|
-
alignItems: "center"
|
|
113
|
-
}}
|
|
114
|
-
>
|
|
115
|
-
<div style={{ width: 100, margin: 4 }}>
|
|
116
|
-
{/* <div style={{
|
|
117
|
-
paddingBottom: 10,
|
|
118
|
-
textOverflow: "ellipsis",
|
|
119
|
-
overflowY: "auto",
|
|
120
|
-
whiteSpace: "nowrap",
|
|
121
|
-
fontSize: 13,
|
|
122
|
-
textAlign: "center"
|
|
123
|
-
}}>
|
|
124
|
-
<b>{mismatchList[0].name}</b>
|
|
125
|
-
</div> */}
|
|
126
|
-
{tableOfMismatches}
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
</div>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export default withSelectedEntities("mismatchesTable")(Mismatches);
|
package/Monaco.ttf
DELETED
|
Binary file
|