react-msaview 6.4.2 → 7.0.0
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/README.md +6 -5
- package/bundle/index.js +100 -101
- package/bundle/index.js.map +4 -4
- package/dist/components/Loading.js +2 -2
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +10 -2
- package/dist/components/MSAViewer.js +90 -2
- package/dist/components/MSAViewer.js.map +1 -1
- package/dist/components/ResizeHandles.d.ts +3 -3
- package/dist/components/ResizeHandles.js +28 -21
- package/dist/components/ResizeHandles.js.map +1 -1
- package/dist/components/dialogs/{InterProScanDialog.d.ts → AnnotationFileDialog.d.ts} +2 -2
- package/dist/components/dialogs/AnnotationFileDialog.js +92 -0
- package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -0
- package/dist/components/dialogs/FeatureDialog.js +13 -9
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/header/Header.js +4 -0
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderStatusArea.js +0 -2
- package/dist/components/header/HeaderStatusArea.js.map +1 -1
- package/dist/components/header/LoadWarnings.d.ts +6 -0
- package/dist/components/header/LoadWarnings.js +36 -0
- package/dist/components/header/LoadWarnings.js.map +1 -0
- package/dist/components/header/MultiAlignmentSelector.js +0 -0
- package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
- package/dist/components/header/TreeSettingsMenu.js +9 -1
- package/dist/components/header/TreeSettingsMenu.js.map +1 -1
- package/dist/components/header/UnshareableDataWarning.d.ts +6 -0
- package/dist/components/header/UnshareableDataWarning.js +42 -0
- package/dist/components/header/UnshareableDataWarning.js.map +1 -0
- package/dist/components/header/getAnnotationsMenu.js +14 -14
- package/dist/components/header/getAnnotationsMenu.js.map +1 -1
- package/dist/components/import/ImportForm.js +1 -1
- package/dist/components/import/ImportForm.js.map +1 -1
- package/dist/components/import/ImportFormExamples.js +2 -6
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/import/util.js +3 -0
- package/dist/components/import/util.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.js +4 -5
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/msaRaster.d.ts +13 -3
- package/dist/components/msa/msaRaster.js +173 -61
- package/dist/components/msa/msaRaster.js.map +1 -1
- package/dist/components/msa/renderHighlights.d.ts +39 -1
- package/dist/components/msa/renderHighlights.js +71 -6
- package/dist/components/msa/renderHighlights.js.map +1 -1
- package/dist/components/msa/renderMSABlock.d.ts +1 -2
- package/dist/components/msa/renderMSABlock.js +24 -28
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +9 -30
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/renderCtx.d.ts +1 -1
- package/dist/components/tracks/TrackBlocks.js +10 -11
- package/dist/components/tracks/TrackBlocks.js.map +1 -1
- package/dist/components/tracks/drawTracks.d.ts +26 -8
- package/dist/components/tracks/drawTracks.js +123 -13
- package/dist/components/tracks/drawTracks.js.map +1 -1
- package/dist/components/tree/TreeCanvas.js +2 -3
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +4 -2
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeRuler.js +13 -3
- package/dist/components/tree/TreeRuler.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.d.ts +0 -1
- package/dist/components/tree/renderTreeCanvas.js +70 -30
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/components/tree/scaleBar.d.ts +10 -0
- package/dist/components/tree/scaleBar.js +24 -0
- package/dist/components/tree/scaleBar.js.map +1 -0
- package/dist/constants.d.ts +3 -1
- package/dist/constants.js +18 -1
- package/dist/constants.js.map +1 -1
- package/dist/fetchUtils.d.ts +7 -7
- package/dist/fetchUtils.js +4 -32
- package/dist/fetchUtils.js.map +1 -1
- package/dist/hierarchy.d.ts +2 -1
- package/dist/hierarchy.js +16 -10
- package/dist/hierarchy.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/model/DataModel.js +5 -2
- package/dist/model/DataModel.js.map +1 -1
- package/dist/model.d.ts +454 -177
- package/dist/model.js +1180 -511
- package/dist/model.js.map +1 -1
- package/dist/renderToStaticMarkup.d.ts +11 -0
- package/dist/renderToStaticMarkup.js +30 -7
- package/dist/renderToStaticMarkup.js.map +1 -1
- package/dist/renderToSvg.js +25 -19
- package/dist/renderToSvg.js.map +1 -1
- package/dist/rowCoordinateCalculations.d.ts +25 -25
- package/dist/rowCoordinateCalculations.js +12 -36
- package/dist/rowCoordinateCalculations.js.map +1 -1
- package/dist/seqPosToGlobalCol.js +3 -1
- package/dist/seqPosToGlobalCol.js.map +1 -1
- package/dist/svgTestUtil.d.ts +144 -82
- package/dist/types.d.ts +97 -3
- package/dist/util.d.ts +11 -4
- package/dist/util.js +30 -10
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/wuss.d.ts +14 -0
- package/dist/wuss.js +55 -0
- package/dist/wuss.js.map +1 -0
- package/package.json +10 -8
- package/src/components/Loading.tsx +12 -2
- package/src/components/MSAViewer.tsx +106 -2
- package/src/components/ResizeHandles.tsx +31 -31
- package/src/components/dialogs/AnnotationFileDialog.tsx +162 -0
- package/src/components/dialogs/FeatureDialog.tsx +13 -9
- package/src/components/header/Header.tsx +4 -0
- package/src/components/header/HeaderStatusArea.tsx +0 -5
- package/src/components/header/LoadWarnings.tsx +49 -0
- package/src/components/header/MultiAlignmentSelector.tsx +0 -0
- package/src/components/header/TreeSettingsMenu.tsx +9 -1
- package/src/components/header/UnshareableDataWarning.tsx +58 -0
- package/src/components/header/getAnnotationsMenu.ts +16 -17
- package/src/components/import/ImportForm.tsx +2 -2
- package/src/components/import/ImportFormExamples.tsx +2 -6
- package/src/components/import/util.ts +3 -0
- package/src/components/msa/MSACanvasBlock.tsx +4 -5
- package/src/components/msa/msaRaster.ts +216 -59
- package/src/components/msa/renderHighlights.ts +103 -5
- package/src/components/msa/renderMSABlock.ts +25 -36
- package/src/components/msa/renderMSAMouseover.ts +9 -39
- package/src/components/renderCtx.ts +1 -0
- package/src/components/tracks/TrackBlocks.tsx +10 -13
- package/src/components/tracks/drawTracks.ts +165 -17
- package/src/components/tree/TreeCanvas.tsx +2 -3
- package/src/components/tree/TreeCanvasBlock.tsx +4 -2
- package/src/components/tree/TreeRuler.tsx +38 -3
- package/src/components/tree/renderTreeCanvas.ts +79 -35
- package/src/components/tree/scaleBar.ts +23 -0
- package/src/constants.ts +20 -1
- package/src/fetchUtils.ts +7 -40
- package/src/hierarchy.ts +20 -11
- package/src/index.ts +18 -2
- package/src/model/DataModel.ts +6 -2
- package/src/model.ts +1352 -616
- package/src/rawImports.d.ts +9 -0
- package/src/renderToStaticMarkup.ts +34 -7
- package/src/renderToSvg.tsx +33 -27
- package/src/rowCoordinateCalculations.ts +15 -59
- package/src/seqPosToGlobalCol.ts +3 -1
- package/src/types.ts +131 -4
- package/src/util.ts +31 -14
- package/src/version.ts +1 -1
- package/src/wuss.ts +62 -0
- package/dist/components/dialogs/InterProScanDialog.js +0 -137
- package/dist/components/dialogs/InterProScanDialog.js.map +0 -1
- package/dist/components/dialogs/InterProScanFileDialog.d.ts +0 -7
- package/dist/components/dialogs/InterProScanFileDialog.js +0 -64
- package/dist/components/dialogs/InterProScanFileDialog.js.map +0 -1
- package/dist/launchInterProScan.d.ts +0 -13
- package/dist/launchInterProScan.js +0 -110
- package/dist/launchInterProScan.js.map +0 -1
- package/dist/useColorContrast.d.ts +0 -10
- package/dist/useColorContrast.js +0 -13
- package/dist/useColorContrast.js.map +0 -1
- package/src/clustalX.test.ts +0 -74
- package/src/colSpace.test.ts +0 -67
- package/src/collapseLogic.test.ts +0 -115
- package/src/colorSchemes.docs.test.ts +0 -57
- package/src/columnCounts.test.ts +0 -73
- package/src/columnStats.test.ts +0 -94
- package/src/columnTracks.test.ts +0 -97
- package/src/components/dialogs/InterProScanDialog.tsx +0 -214
- package/src/components/dialogs/InterProScanFileDialog.tsx +0 -138
- package/src/components/minimap/minimapLayout.test.ts +0 -71
- package/src/components/msa/msaRaster.test.ts +0 -145
- package/src/components/msa/renderBoxFeatureCanvasBlock.test.ts +0 -51
- package/src/components/tree/renderTreeCanvas.test.ts +0 -296
- package/src/dataInitialized.test.ts +0 -42
- package/src/domainBands.test.ts +0 -122
- package/src/domainLetterColor.test.ts +0 -80
- package/src/exportFileName.test.ts +0 -40
- package/src/fetchUtils.test.ts +0 -83
- package/src/flatToTree.test.ts +0 -51
- package/src/hierarchy.test.ts +0 -228
- package/src/highlights.test.ts +0 -70
- package/src/impgRender.test.tsx +0 -68
- package/src/largeTree.test.ts +0 -67
- package/src/launchInterProScan.ts +0 -167
- package/src/loadErrorDisplay.test.tsx +0 -102
- package/src/modelFilehandleLoaders.test.ts +0 -137
- package/src/modelReset.test.ts +0 -120
- package/src/neighborJoining.test.ts +0 -164
- package/src/parseAsn1.test.ts +0 -36
- package/src/propertyConservation.test.ts +0 -36
- package/src/renderColumnTracksSvg.test.tsx +0 -108
- package/src/renderDomainsSvg.test.tsx +0 -118
- package/src/renderHighlightsSvg.test.tsx +0 -85
- package/src/renderMinimapSvg.test.tsx +0 -62
- package/src/renderRasterSvg.test.tsx +0 -144
- package/src/renderSequenceLogoSvg.test.tsx +0 -165
- package/src/renderToSvg.test.tsx +0 -65
- package/src/reset.test.ts +0 -61
- package/src/rowCoordinateCalculations.test.ts +0 -211
- package/src/rowSpace.test.ts +0 -46
- package/src/segmentOverlay.test.ts +0 -70
- package/src/seqPosToGlobalCol.test.ts +0 -59
- package/src/sequenceLogo.test.ts +0 -88
- package/src/setFontSize.test.ts +0 -33
- package/src/stripDefault.test.ts +0 -48
- package/src/stripDefaultSnapshot.test.ts +0 -87
- package/src/treeMetadata.test.ts +0 -39
- package/src/useCanvasAutorun.test.tsx +0 -98
- package/src/useColorContrast.ts +0 -18
- package/src/viewChrome.test.tsx +0 -134
- package/src/wheelZoom.test.ts +0 -46
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeSettingsMenu.js","sourceRoot":"","sources":["../../../src/components/header/TreeSettingsMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,mBAAmB,MAAM,sCAAsC,CAAA;AACtE,OAAO,WAAW,MAAM,iCAAiC,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAI9D,MAAM,gBAAgB,GAAG,QAAQ,CAAC,UAAU,EAC1C,KAAK,GAGN;IACC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IACtB,OAAO,CACL,oBAAC,mBAAmB,mBACN,oBAAoB,EAChC,OAAO,EAAC,eAAe,EACvB,mBAAmB,EAAE,KAAK,EAC1B,YAAY,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,eAAe,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,SAAS,EAAE;YACT,GAAG,qBAAqB,CAAC,KAAK,CAAC;YAC/B,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC;gBAClB,CAAC,CAAC;oBACE;wBACE,KAAK,EAAE,UAAU;wBACjB,IAAI,EAAE,SAAkB;wBACxB,OAAO,EAAE;4BACP;gCACE,KAAK,EAAE,4CAA4C;
|
|
1
|
+
{"version":3,"file":"TreeSettingsMenu.js","sourceRoot":"","sources":["../../../src/components/header/TreeSettingsMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,mBAAmB,MAAM,sCAAsC,CAAA;AACtE,OAAO,WAAW,MAAM,iCAAiC,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAI9D,MAAM,gBAAgB,GAAG,QAAQ,CAAC,UAAU,EAC1C,KAAK,GAGN;IACC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IACtB,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,GAAG,sBAAsB,CAAA;IACxD,OAAO,CACL,oBAAC,mBAAmB,mBACN,oBAAoB,EAChC,OAAO,EAAC,eAAe,EACvB,mBAAmB,EAAE,KAAK,EAC1B,YAAY,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,eAAe,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,SAAS,EAAE;YACT,GAAG,qBAAqB,CAAC,KAAK,CAAC;YAC/B,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC;gBAClB,CAAC,CAAC;oBACE;wBACE,KAAK,EAAE,UAAU;wBACjB,IAAI,EAAE,SAAkB;wBACxB,OAAO,EAAE;4BACP;gCACE,wDAAwD;gCACxD,uDAAuD;gCACvD,iBAAiB;gCACjB,KAAK,EAAE,WAAW;oCAChB,CAAC,CAAC,yCAAyC,sBAAsB,sBAAsB;oCACvF,CAAC,CAAC,4CAA4C;gCAChD,QAAQ,EAAE,WAAW;gCACrB,OAAO,EAAE,GAAG,EAAE;oCACZ,IAAI,CAAC;wCACH,KAAK,CAAC,mCAAmC,EAAE,CAAA;oCAC7C,CAAC;oCAAC,OAAO,CAAC,EAAE,CAAC;wCACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAA;wCAChD,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;oCACnB,CAAC;gCACH,CAAC;6BACF;yBACF;qBACF;iBACF;gBACH,CAAC,CAAC,EAAE,CAAC;SACR;QAED,oBAAC,WAAW,OAAG,CACK,CACvB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
|
+
import LinkOff from '@mui/icons-material/LinkOff';
|
|
4
|
+
import { Tooltip, Typography } from '@mui/material';
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
const useStyles = makeStyles()(theme => ({
|
|
7
|
+
warning: {
|
|
8
|
+
display: 'flex',
|
|
9
|
+
alignItems: 'center',
|
|
10
|
+
gap: 4,
|
|
11
|
+
margin: 'auto',
|
|
12
|
+
marginLeft: 10,
|
|
13
|
+
whiteSpace: 'nowrap',
|
|
14
|
+
color: theme.palette.warning.main,
|
|
15
|
+
cursor: 'help',
|
|
16
|
+
},
|
|
17
|
+
}));
|
|
18
|
+
function size(bytes) {
|
|
19
|
+
return bytes < 1_000_000
|
|
20
|
+
? `${Math.round(bytes / 1000)} kB`
|
|
21
|
+
: `${(bytes / 1_000_000).toFixed(1)} MB`;
|
|
22
|
+
}
|
|
23
|
+
// The viewer holds documents its own snapshot does not carry, and until this
|
|
24
|
+
// existed it said nothing about it: the view worked, the URL quietly lost the
|
|
25
|
+
// data, and whoever copied the link found out from the person who opened it.
|
|
26
|
+
// See `unshareableData` on the model.
|
|
27
|
+
const UnshareableDataWarning = observer(function ({ model, }) {
|
|
28
|
+
const { unshareableData } = model;
|
|
29
|
+
const { classes } = useStyles();
|
|
30
|
+
if (unshareableData.length === 0) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const what = unshareableData
|
|
34
|
+
.map(({ what, bytes }) => `${what} (${size(bytes)})`)
|
|
35
|
+
.join(' and the ');
|
|
36
|
+
return (React.createElement(Tooltip, { title: `The ${what} came from this computer and is too large to travel in a URL, so a link to this page opens without it. Serve the file over HTTP and open it by URL to share the view.` },
|
|
37
|
+
React.createElement(Typography, { component: "div", className: classes.warning },
|
|
38
|
+
React.createElement(LinkOff, { fontSize: "small" }),
|
|
39
|
+
"Not in the link")));
|
|
40
|
+
});
|
|
41
|
+
export default UnshareableDataWarning;
|
|
42
|
+
//# sourceMappingURL=UnshareableDataWarning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnshareableDataWarning.js","sourceRoot":"","sources":["../../../src/components/header/UnshareableDataWarning.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACzD,OAAO,OAAO,MAAM,6BAA6B,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACvC,OAAO,EAAE;QACP,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,QAAQ;QACpB,GAAG,EAAE,CAAC;QACN,MAAM,EAAE,MAAM;QACd,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,QAAQ;QACpB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI;QACjC,MAAM,EAAE,MAAM;KACf;CACF,CAAC,CAAC,CAAA;AAEH,SAAS,IAAI,CAAC,KAAa;IACzB,OAAO,KAAK,GAAG,SAAS;QACtB,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;QAClC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAA;AAC5C,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,sCAAsC;AACtC,MAAM,sBAAsB,GAAG,QAAQ,CAAC,UAAU,EAChD,KAAK,GAGN;IACC,MAAM,EAAE,eAAe,EAAE,GAAG,KAAK,CAAA;IACjC,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAA;IAC/B,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,IAAI,GAAG,eAAe;SACzB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;SACpD,IAAI,CAAC,WAAW,CAAC,CAAA;IACpB,OAAO,CACL,oBAAC,OAAO,IACN,KAAK,EAAE,OAAO,IAAI,uKAAuK;QAEzL,oBAAC,UAAU,IAAC,SAAS,EAAC,KAAK,EAAC,SAAS,EAAE,OAAO,CAAC,OAAO;YACpD,oBAAC,OAAO,IAAC,QAAQ,EAAC,OAAO,GAAG;8BAEjB,CACL,CACX,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,sBAAsB,CAAA"}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { lazy } from 'react';
|
|
2
2
|
import FilterAlt from '@mui/icons-material/FilterAlt';
|
|
3
3
|
import FolderOpen from '@mui/icons-material/FolderOpen';
|
|
4
|
-
import
|
|
4
|
+
import MenuBook from '@mui/icons-material/MenuBook';
|
|
5
5
|
import Sort from '@mui/icons-material/Sort';
|
|
6
6
|
import Visibility from '@mui/icons-material/Visibility';
|
|
7
7
|
const FeatureFilterDialog = lazy(() => import('../dialogs/FeatureDialog.js'));
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const AnnotationFileDialog = lazy(() => import('../dialogs/AnnotationFileDialog.js'));
|
|
9
|
+
const domainsTutorial = 'https://gmod.org/JBrowseMSA/tutorials/protein_family';
|
|
10
10
|
export function getAnnotationsMenu({ model }) {
|
|
11
11
|
const { showDomains, actuallyShowDomains, subFeatureRows, noDomains } = model;
|
|
12
12
|
const noneLoaded = noDomains ? ' (none loaded)' : '';
|
|
13
13
|
return [
|
|
14
14
|
{
|
|
15
|
-
label: 'Open
|
|
15
|
+
label: 'Open annotation file...',
|
|
16
16
|
icon: FolderOpen,
|
|
17
17
|
onClick: () => {
|
|
18
18
|
model.queueDialog(handleClose => [
|
|
19
|
-
|
|
19
|
+
AnnotationFileDialog,
|
|
20
20
|
{
|
|
21
21
|
handleClose,
|
|
22
22
|
model,
|
|
@@ -24,17 +24,17 @@ export function getAnnotationsMenu({ model }) {
|
|
|
24
24
|
]);
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
|
+
// The viewer used to submit the whole alignment to the EBI iprscan5 queue
|
|
28
|
+
// and poll it for about fifteen minutes, capped at 140 rows and under a
|
|
29
|
+
// hardcoded email address. `react-msaview-cli interpro` answers the same
|
|
30
|
+
// question from InterPro's precomputed matches in seconds, and
|
|
31
|
+
// `interproscan` covers rows InterPro has not seen. Neither belongs in a
|
|
32
|
+
// browser tab, so this points at the page that walks through them.
|
|
27
33
|
{
|
|
28
|
-
label: '
|
|
29
|
-
icon:
|
|
34
|
+
label: 'How to get a domain file...',
|
|
35
|
+
icon: MenuBook,
|
|
30
36
|
onClick: () => {
|
|
31
|
-
|
|
32
|
-
InterProScanDialog,
|
|
33
|
-
{
|
|
34
|
-
handleClose,
|
|
35
|
-
model,
|
|
36
|
-
},
|
|
37
|
-
]);
|
|
37
|
+
window.open(domainsTutorial, '_blank', 'noopener,noreferrer');
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
40
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAnnotationsMenu.js","sourceRoot":"","sources":["../../../src/components/header/getAnnotationsMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAE5B,OAAO,SAAS,MAAM,+BAA+B,CAAA;AACrD,OAAO,UAAU,MAAM,gCAAgC,CAAA;AACvD,OAAO,
|
|
1
|
+
{"version":3,"file":"getAnnotationsMenu.js","sourceRoot":"","sources":["../../../src/components/header/getAnnotationsMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAE5B,OAAO,SAAS,MAAM,+BAA+B,CAAA;AACrD,OAAO,UAAU,MAAM,gCAAgC,CAAA;AACvD,OAAO,QAAQ,MAAM,8BAA8B,CAAA;AACnD,OAAO,IAAI,MAAM,0BAA0B,CAAA;AAC3C,OAAO,UAAU,MAAM,gCAAgC,CAAA;AAIvD,MAAM,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,6BAA8B,CAAC,CAAC,CAAA;AAC9E,MAAM,oBAAoB,GAAG,IAAI,CAC/B,GAAG,EAAE,CAAC,MAAM,CAAC,oCAAqC,CAAC,CACpD,CAAA;AAED,MAAM,eAAe,GAAG,sDAAsD,CAAA;AAE9E,MAAM,UAAU,kBAAkB,CAAC,EAAE,KAAK,EAA2B;IACnE,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC7E,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAA;IACpD,OAAO;QACL;YACE,KAAK,EAAE,yBAAyB;YAChC,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,GAAG,EAAE;gBACZ,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC/B,oBAAoB;oBACpB;wBACE,WAAW;wBACX,KAAK;qBACN;iBACF,CAAC,CAAA;YACJ,CAAC;SACF;QACD,0EAA0E;QAC1E,wEAAwE;QACxE,yEAAyE;QACzE,+DAA+D;QAC/D,yEAAyE;QACzE,mEAAmE;QACnE;YACE,KAAK,EAAE,6BAA6B;YACpC,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,GAAG,EAAE;gBACZ,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,EAAE,qBAAqB,CAAC,CAAA;YAC/D,CAAC;SACF;QACD;YACE,KAAK,EAAE,mBAAmB,UAAU,EAAE;YACtC,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,mBAAmB;YAC5B,IAAI,EAAE,UAAmB;YACzB,OAAO,EAAE,GAAG,EAAE;gBACZ,KAAK,CAAC,cAAc,CAAC,CAAC,WAAW,CAAC,CAAA;YACpC,CAAC;SACF;QACD;YACE,KAAK,EAAE,qBAAqB,UAAU,EAAE;YACxC,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK;YACrD,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,UAAmB;YACzB,OAAO,EAAE,GAAG,EAAE;gBACZ,KAAK,CAAC,iBAAiB,CAAC,CAAC,cAAc,CAAC,CAAA;YAC1C,CAAC;SACF;QACD;YACE,KAAK,EAAE,qBAAqB,UAAU,EAAE;YACxC,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,GAAG,EAAE;gBACZ,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3B,mBAAmB;oBACnB;wBACE,OAAO;wBACP,KAAK;qBACN;iBACF,CAAC,CAAA;YACJ,CAAC;SACF;KACF,CAAA;AACH,CAAC"}
|
|
@@ -12,7 +12,7 @@ const ImportForm = observer(function ({ model }) {
|
|
|
12
12
|
return (React.createElement(Container, null,
|
|
13
13
|
React.createElement("div", { style: { width: '50%' } },
|
|
14
14
|
error ? React.createElement(ErrorMessage, { error: error }) : null,
|
|
15
|
-
React.createElement(Typography, null, "Open an MSA file (
|
|
15
|
+
React.createElement(Typography, null, "Open an MSA file (FASTA, Stockholm, Clustal, A3M or EMF format) and/or a tree file (Newick format)."),
|
|
16
16
|
React.createElement(Typography, { color: "error" }, "Note: you can open up just an MSA or just a tree, both are not required. Some MSA files e.g. stockholm format have an embedded tree also and this is fine, and opening a separate tree file is not required.")),
|
|
17
17
|
React.createElement("div", { style: {
|
|
18
18
|
display: 'flex',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImportForm.js","sourceRoot":"","sources":["../../../src/components/import/ImportForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,kBAAkB,MAAM,yBAA0B,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAKhC,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,KAAK,EAA2B;IACtE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAgB,CAAA;IACtD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,EAAgB,CAAA;IACxD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAgB,CAAA;IACtD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;IAEvB,OAAO,CACL,oBAAC,SAAS;QACR,6BAAK,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;YACzB,KAAK,CAAC,CAAC,CAAC,oBAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC,CAAC,IAAI;YAC9C,oBAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"ImportForm.js","sourceRoot":"","sources":["../../../src/components/import/ImportForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,kBAAkB,MAAM,yBAA0B,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAKhC,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,KAAK,EAA2B;IACtE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAgB,CAAA;IACtD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,EAAgB,CAAA;IACxD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAgB,CAAA;IACtD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;IAEvB,OAAO,CACL,oBAAC,SAAS;QACR,6BAAK,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;YACzB,KAAK,CAAC,CAAC,CAAC,oBAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC,CAAC,IAAI;YAC9C,oBAAC,UAAU,8GAGE;YACb,oBAAC,UAAU,IAAC,KAAK,EAAC,OAAO,mNAKZ,CACT;QAEN,6BACE,KAAK,EAAE;gBACL,OAAO,EAAE,MAAM;gBACf,cAAc,EAAE,QAAQ;gBACxB,UAAU,EAAE,QAAQ;gBACpB,GAAG,EAAE,EAAE;aACR;YAED;gBACE;oBACE,oBAAC,UAAU,0BAA6B;oBACxC,oBAAC,YAAY,IAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,GAAI,CACxD;gBACN;oBACE,oBAAC,UAAU,2BAA8B;oBACzC,oBAAC,YAAY,IAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,GAAI,CAC1D;gBACN;oBACE,oBAAC,UAAU,gDAAmD;oBAC9D,oBAAC,YAAY,IAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,GAAI,CACxD,CACF;YACN;gBACE,oBAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE;wBACZ,IAAI,CAAC;4BACH,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;wBACzC,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;4BAChB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;wBACnB,CAAC;oBACH,CAAC,EACD,OAAO,EAAC,WAAW,EACnB,KAAK,EAAC,SAAS,EACf,QAAQ,EAAE,CAAC,OAAO,IAAI,CAAC,QAAQ,WAGxB,CACL;YAEN;gBACE,oBAAC,UAAU,mBAAsB;gBACjC,oBAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,GAAI,CAChC,CACF,CACI,CACb,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,UAAU,CAAA"}
|
|
@@ -4,7 +4,7 @@ import { observer } from 'mobx-react';
|
|
|
4
4
|
import { smallMSA, smallMSAOnly, smallTree } from './data/seq2.js';
|
|
5
5
|
import { load } from './util.js';
|
|
6
6
|
const BASE = 'https://jbrowse.org/genomes/multiple_sequence_alignments';
|
|
7
|
-
const TREES = 'https://jbrowse.org/genomes/
|
|
7
|
+
const TREES = 'https://jbrowse.org/genomes/newick_trees';
|
|
8
8
|
const examples = [
|
|
9
9
|
{
|
|
10
10
|
label: '230k COVID-19 samples (tree only)',
|
|
@@ -19,11 +19,7 @@ const examples = [
|
|
|
19
19
|
inline: { msa: smallMSAOnly },
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
|
-
label: 'PFAM SARS-CoV2 multi-stockholm',
|
|
23
|
-
msa: `${BASE}/pfam-cov2.stock`,
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
label: 'PFAM SARS-CoV2 multi-stockholm w/ domains loaded',
|
|
22
|
+
label: 'PFAM SARS-CoV2 multi-stockholm with domains',
|
|
27
23
|
msa: `${BASE}/pfam-cov2.stock`,
|
|
28
24
|
gff: `${BASE}/pfam-cov2-domains.gff`,
|
|
29
25
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImportFormExamples.js","sourceRoot":"","sources":["../../../src/components/import/ImportFormExamples.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAIhC,MAAM,IAAI,GAAG,0DAA0D,CAAA;AACvE,MAAM,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"ImportFormExamples.js","sourceRoot":"","sources":["../../../src/components/import/ImportFormExamples.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAIhC,MAAM,IAAI,GAAG,0DAA0D,CAAA;AACvE,MAAM,KAAK,GAAG,0CAA0C,CAAA;AAYxD,MAAM,QAAQ,GAAc;IAC1B;QACE,KAAK,EAAE,mCAAmC;QAC1C,IAAI,EAAE,GAAG,KAAK,0BAA0B;KACzC;IACD;QACE,KAAK,EAAE,wBAAwB;QAC/B,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;KAC3C;IACD;QACE,KAAK,EAAE,gBAAgB;QACvB,MAAM,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE;KAC9B;IACD;QACE,KAAK,EAAE,6CAA6C;QACpD,GAAG,EAAE,GAAG,IAAI,kBAAkB;QAC9B,GAAG,EAAE,GAAG,IAAI,wBAAwB;KACrC;IACD;QACE,KAAK,EAAE,uBAAuB;QAC9B,GAAG,EAAE,GAAG,IAAI,eAAe;KAC5B;IACD;QACE,KAAK,EAAE,kDAAkD;QACzD,GAAG,EAAE,GAAG,IAAI,mBAAmB;KAChC;IACD;QACE,KAAK,EAAE,gEAAgE;QACvE,GAAG,EAAE,GAAG,IAAI,kBAAkB;KAC/B;IACD;QACE,KAAK,EAAE,mCAAmC;QAC1C,GAAG,EAAE,GAAG,IAAI,2CAA2C;QACvD,IAAI,EAAE,GAAG,IAAI,2CAA2C;KACzD;IACD;QACE,KAAK,EAAE,yBAAyB;QAChC,GAAG,EAAE,sCAAsC;KAC5C;CACF,CAAA;AAED,SAAS,GAAG,CAAC,GAAY;IACvB,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,aAAsB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AAC7E,CAAC;AAED,MAAM,kBAAkB,GAAG,QAAQ,CAAC,UAAU,EAC5C,KAAK,GAGN;IACC,OAAO,CACL,gCACG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnD,4BAAI,GAAG,EAAE,KAAK;QACZ,oBAAC,IAAI,IACH,IAAI,EAAC,GAAG,EACR,OAAO,EAAE,KAAK,CAAC,EAAE;gBACf,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;gBACzB,IAAI,CAAC;oBACH,IAAI,MAAM,EAAE,CAAC;wBACX,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;oBACvB,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;oBAC5C,CAAC;gBACH,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;oBAChB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;gBACnB,CAAC;YACH,CAAC;YAED,oBAAC,UAAU,IAAC,SAAS,EAAC,MAAM,IAAE,KAAK,CAAc,CAC5C,CACJ,CACN,CAAC,CACC,CACN,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,kBAAkB,CAAA"}
|
|
@@ -8,6 +8,9 @@ export function load(model, msaFile, treeFile, gffFile) {
|
|
|
8
8
|
}
|
|
9
9
|
if (gffFile) {
|
|
10
10
|
model.setGFFFilehandle(gffFile);
|
|
11
|
+
// asked for by hand, so drawn -- even if the reader hid the overlay
|
|
12
|
+
// earlier in this view
|
|
13
|
+
model.setShowDomains(true);
|
|
11
14
|
}
|
|
12
15
|
}
|
|
13
16
|
//# sourceMappingURL=util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/components/import/util.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,IAAI,CAClB,KAAmB,EACnB,OAAsB,EACtB,QAAuB,EACvB,OAAsB;IAEtB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IACzB,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IACnC,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/components/import/util.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,IAAI,CAClB,KAAmB,EACnB,OAAsB,EACtB,QAAuB,EACvB,OAAsB;IAEtB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IACzB,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IACnC,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC/B,oEAAoE;QACpE,uBAAuB;QACvB,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import BaseTooltip from '@jbrowse/core/ui/BaseTooltip';
|
|
3
|
+
import { useTheme } from '@mui/material';
|
|
3
4
|
import { observer } from 'mobx-react';
|
|
4
5
|
import { useCanvasAutorun } from '../../useCanvasAutorun.js';
|
|
5
|
-
import { useColorContrast } from '../../useColorContrast.js';
|
|
6
6
|
import ColumnStats from './ColumnStats.js';
|
|
7
7
|
import { drawMsaRaster, rasterSupported } from './msaRaster.js';
|
|
8
8
|
import { renderBoxFeatureCanvasBlock } from './renderBoxFeatureCanvasBlock.js';
|
|
9
9
|
import { renderMSABlock } from './renderMSABlock.js';
|
|
10
10
|
import { useMsaBlockMouse } from './useMsaBlockMouse.js';
|
|
11
11
|
const MSACanvasBlock = observer(function ({ model, offsetX, offsetY, }) {
|
|
12
|
-
const {
|
|
13
|
-
const
|
|
12
|
+
const { blockSize, highResScaleFactor } = model;
|
|
13
|
+
const theme = useTheme();
|
|
14
14
|
const { tooltipPoint, onMouseMove, onClick, onMouseLeave } = useMsaBlockMouse({
|
|
15
15
|
model,
|
|
16
16
|
offsetX,
|
|
@@ -39,14 +39,13 @@ const MSACanvasBlock = observer(function ({ model, offsetX, offsetY, }) {
|
|
|
39
39
|
theme,
|
|
40
40
|
offsetX,
|
|
41
41
|
offsetY,
|
|
42
|
-
contrastScheme,
|
|
43
42
|
model,
|
|
44
43
|
rasterTiles,
|
|
45
44
|
});
|
|
46
45
|
},
|
|
47
46
|
width: canvasSize,
|
|
48
47
|
height: canvasSize,
|
|
49
|
-
deps: [model, offsetX, offsetY, theme
|
|
48
|
+
deps: [model, offsetX, offsetY, theme],
|
|
50
49
|
});
|
|
51
50
|
const { hoveredInsertion, mouseOverDomains, showColumnStats } = model;
|
|
52
51
|
return (React.createElement(React.Fragment, null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MSACanvasBlock.js","sourceRoot":"","sources":["../../../src/components/msa/MSACanvasBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,WAAW,MAAM,8BAA8B,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"MSACanvasBlock.js","sourceRoot":"","sources":["../../../src/components/msa/MSACanvasBlock.tsx"],"names":[],"mappings":"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"}
|
|
@@ -24,9 +24,11 @@ export declare function cssColorToPixel(css: string): number;
|
|
|
24
24
|
* also leaves behind.
|
|
25
25
|
*
|
|
26
26
|
* `colStep`/`rowStep` sample instead of covering, which is how the minimap fits
|
|
27
|
-
* a whole alignment into a 12px bar.
|
|
27
|
+
* a whole alignment into a 12px bar. `colSpan`/`rowSpan` average each block of
|
|
28
|
+
* that many cells into one pixel instead, so a zoom below a device pixel per
|
|
29
|
+
* column still shows every column's color without blending neighbouring rows.
|
|
28
30
|
*/
|
|
29
|
-
export declare function rasterPixels({ spec, col0, row0, width, height, colStep, rowStep, toPixel, }: {
|
|
31
|
+
export declare function rasterPixels({ spec, col0, row0, width, height, colStep, rowStep, colSpan, rowSpan, toPixel, out, }: {
|
|
30
32
|
spec: RasterSpec;
|
|
31
33
|
col0: number;
|
|
32
34
|
row0: number;
|
|
@@ -34,14 +36,22 @@ export declare function rasterPixels({ spec, col0, row0, width, height, colStep,
|
|
|
34
36
|
height: number;
|
|
35
37
|
colStep?: number;
|
|
36
38
|
rowStep?: number;
|
|
39
|
+
colSpan?: number;
|
|
40
|
+
rowSpan?: number;
|
|
37
41
|
toPixel?: (css: string) => number;
|
|
38
|
-
|
|
42
|
+
out?: Uint32Array;
|
|
43
|
+
}): Uint32Array<ArrayBufferLike>;
|
|
39
44
|
export declare function rasterSupported(): boolean;
|
|
40
45
|
/**
|
|
41
46
|
* Paints the alignment background of one MSA block from cached
|
|
42
47
|
* one-pixel-per-cell tiles. The tiles do not depend on the zoom level, so a zoom
|
|
43
48
|
* frame costs a handful of drawImage calls instead of a fillRect per visible
|
|
44
49
|
* cell -- which ran to 885ms per block at the minimum column width.
|
|
50
|
+
*
|
|
51
|
+
* Below a device pixel per cell the tiles average cells together instead, and
|
|
52
|
+
* only along the axis that needs it. Leaving the downsampling to the browser's
|
|
53
|
+
* image smoothing blurred both axes at once: at fit-to-width, where only the
|
|
54
|
+
* columns are narrow, every row boundary turned into a gradient.
|
|
45
55
|
*/
|
|
46
56
|
export declare function drawMsaRaster({ ctx, model, theme, offsetX, offsetY, }: {
|
|
47
57
|
ctx: CanvasRenderingContext2D;
|
|
@@ -42,6 +42,19 @@ export function cssColorToPixel(css) {
|
|
|
42
42
|
colorCache.set(css, packed);
|
|
43
43
|
return packed;
|
|
44
44
|
}
|
|
45
|
+
function cellPixelFn(spec, toPixel) {
|
|
46
|
+
const { columns, relativeTo, colorAt, bg, hover } = spec;
|
|
47
|
+
const bgPixel = toPixel(bg);
|
|
48
|
+
const hoverPixel = toPixel(hover);
|
|
49
|
+
const reference = relativeTo ? columns.get(relativeTo) : undefined;
|
|
50
|
+
return (name, col, letter) => {
|
|
51
|
+
if (reference && name !== relativeTo && letter === reference[col]) {
|
|
52
|
+
return hoverPixel;
|
|
53
|
+
}
|
|
54
|
+
const color = colorAt(col, letter);
|
|
55
|
+
return color === undefined ? bgPixel : toPixel(color);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
45
58
|
/**
|
|
46
59
|
* Packs a rectangle of the alignment into one pixel per cell, in `rowNames`
|
|
47
60
|
* order, ready to hand to putImageData. Cells past the end of a row, and rows
|
|
@@ -49,14 +62,27 @@ export function cssColorToPixel(css) {
|
|
|
49
62
|
* also leaves behind.
|
|
50
63
|
*
|
|
51
64
|
* `colStep`/`rowStep` sample instead of covering, which is how the minimap fits
|
|
52
|
-
* a whole alignment into a 12px bar.
|
|
65
|
+
* a whole alignment into a 12px bar. `colSpan`/`rowSpan` average each block of
|
|
66
|
+
* that many cells into one pixel instead, so a zoom below a device pixel per
|
|
67
|
+
* column still shows every column's color without blending neighbouring rows.
|
|
53
68
|
*/
|
|
54
|
-
export function rasterPixels({ spec, col0, row0, width, height, colStep = 1, rowStep = 1, toPixel = cssColorToPixel, }) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
69
|
+
export function rasterPixels({ spec, col0, row0, width, height, colStep = 1, rowStep = 1, colSpan = 1, rowSpan = 1, toPixel = cssColorToPixel, out = new Uint32Array(width * height), }) {
|
|
70
|
+
if (colSpan > 1 || rowSpan > 1) {
|
|
71
|
+
averagePixels({
|
|
72
|
+
spec,
|
|
73
|
+
col0,
|
|
74
|
+
row0,
|
|
75
|
+
width,
|
|
76
|
+
height,
|
|
77
|
+
colSpan,
|
|
78
|
+
rowSpan,
|
|
79
|
+
toPixel,
|
|
80
|
+
out,
|
|
81
|
+
});
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
const { rowNames, columns } = spec;
|
|
85
|
+
const cellPixel = cellPixelFn(spec, toPixel);
|
|
60
86
|
for (let r = 0; r < height; r++) {
|
|
61
87
|
const name = rowNames[row0 + r * rowStep];
|
|
62
88
|
if (name === undefined) {
|
|
@@ -66,7 +92,6 @@ export function rasterPixels({ spec, col0, row0, width, height, colStep = 1, row
|
|
|
66
92
|
if (!str) {
|
|
67
93
|
continue;
|
|
68
94
|
}
|
|
69
|
-
const isReference = name === relativeTo;
|
|
70
95
|
const base = r * width;
|
|
71
96
|
for (let c = 0; c < width; c++) {
|
|
72
97
|
const col = col0 + c * colStep;
|
|
@@ -74,21 +99,64 @@ export function rasterPixels({ spec, col0, row0, width, height, colStep = 1, row
|
|
|
74
99
|
if (letter === undefined) {
|
|
75
100
|
break;
|
|
76
101
|
}
|
|
77
|
-
|
|
78
|
-
|
|
102
|
+
out[base + c] = cellPixel(name, col, letter);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
function averagePixels({ spec, col0, row0, width, height, colSpan, rowSpan, toPixel, out, }) {
|
|
108
|
+
const { rowNames, columns } = spec;
|
|
109
|
+
const cellPixel = cellPixelFn(spec, toPixel);
|
|
110
|
+
const cells = colSpan * rowSpan;
|
|
111
|
+
const rShift = littleEndian ? 0 : 24;
|
|
112
|
+
const gShift = littleEndian ? 8 : 16;
|
|
113
|
+
const bShift = littleEndian ? 16 : 8;
|
|
114
|
+
const aShift = littleEndian ? 24 : 0;
|
|
115
|
+
const names = [];
|
|
116
|
+
const strs = [];
|
|
117
|
+
for (let r = 0; r < height; r++) {
|
|
118
|
+
names.length = 0;
|
|
119
|
+
strs.length = 0;
|
|
120
|
+
for (let dr = 0; dr < rowSpan; dr++) {
|
|
121
|
+
const name = rowNames[row0 + r * rowSpan + dr];
|
|
122
|
+
const str = name === undefined ? undefined : columns.get(name);
|
|
123
|
+
if (name !== undefined && str) {
|
|
124
|
+
names.push(name);
|
|
125
|
+
strs.push(str);
|
|
79
126
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
127
|
+
}
|
|
128
|
+
const base = r * width;
|
|
129
|
+
for (let c = 0; c < width; c++) {
|
|
130
|
+
// premultiplied, so a cell past the end of a row dilutes the alpha of its
|
|
131
|
+
// pixel rather than darkening its color
|
|
132
|
+
let sumR = 0;
|
|
133
|
+
let sumG = 0;
|
|
134
|
+
let sumB = 0;
|
|
135
|
+
let sumA = 0;
|
|
136
|
+
for (let i = 0; i < strs.length; i++) {
|
|
137
|
+
const str = strs[i];
|
|
138
|
+
const name = names[i];
|
|
139
|
+
for (let dc = 0; dc < colSpan; dc++) {
|
|
140
|
+
const col = col0 + c * colSpan + dc;
|
|
141
|
+
const letter = str[col];
|
|
142
|
+
if (letter === undefined) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
const p = cellPixel(name, col, letter);
|
|
146
|
+
const a = (p >>> aShift) & 255;
|
|
147
|
+
sumR += ((p >>> rShift) & 255) * a;
|
|
148
|
+
sumG += ((p >>> gShift) & 255) * a;
|
|
149
|
+
sumB += ((p >>> bShift) & 255) * a;
|
|
150
|
+
sumA += a;
|
|
151
|
+
}
|
|
83
152
|
}
|
|
153
|
+
out[base + c] =
|
|
154
|
+
sumA === 0
|
|
155
|
+
? 0
|
|
156
|
+
: packRgba(Math.round(sumR / sumA), Math.round(sumG / sumA), Math.round(sumB / sumA), Math.round(sumA / cells));
|
|
84
157
|
}
|
|
85
158
|
}
|
|
86
|
-
return out;
|
|
87
159
|
}
|
|
88
|
-
// Getting a context object back is not the same as getting one that can do
|
|
89
|
-
// this: the headless render shim hands back a context carrying only measureText,
|
|
90
|
-
// which a truthiness test accepts and putImageData then does not survive. Name
|
|
91
|
-
// the methods the raster actually calls, so every caller degrades together.
|
|
92
160
|
function usableRasterCtx(ctx) {
|
|
93
161
|
const c = ctx;
|
|
94
162
|
return (!!c &&
|
|
@@ -109,13 +177,13 @@ function makeRasterCanvas(width, height) {
|
|
|
109
177
|
? { canvas: canvas, ctx }
|
|
110
178
|
: undefined;
|
|
111
179
|
}
|
|
112
|
-
function paint(
|
|
180
|
+
function paint(width, height, fill) {
|
|
113
181
|
const made = makeRasterCanvas(width, height);
|
|
114
182
|
if (!made) {
|
|
115
183
|
return undefined;
|
|
116
184
|
}
|
|
117
185
|
const image = made.ctx.createImageData(width, height);
|
|
118
|
-
new Uint32Array(image.data.buffer)
|
|
186
|
+
fill(new Uint32Array(image.data.buffer));
|
|
119
187
|
made.ctx.putImageData(image, 0, 0);
|
|
120
188
|
return made.canvas;
|
|
121
189
|
}
|
|
@@ -163,8 +231,16 @@ function getCache(model, theme) {
|
|
|
163
231
|
caches.set(model, next);
|
|
164
232
|
return next;
|
|
165
233
|
}
|
|
166
|
-
|
|
167
|
-
|
|
234
|
+
// Cells averaged into one tile pixel along an axis: the smallest power of two
|
|
235
|
+
// that brings a pixel back to at least one device pixel. Powers of two keep the
|
|
236
|
+
// number of distinct tile sets a zoom sweep builds to a handful.
|
|
237
|
+
function cellsPerPixel(devicePixelsPerCell) {
|
|
238
|
+
return devicePixelsPerCell >= 1
|
|
239
|
+
? 1
|
|
240
|
+
: 2 ** Math.ceil(Math.log2(1 / devicePixelsPerCell));
|
|
241
|
+
}
|
|
242
|
+
function getTile({ cache, tileRow, tileCol, colSpan, rowSpan, }) {
|
|
243
|
+
const key = `${colSpan}_${rowSpan}_${tileRow}_${tileCol}`;
|
|
168
244
|
const hit = cache.tiles.get(key);
|
|
169
245
|
if (hit) {
|
|
170
246
|
// re-inserting makes this the newest entry: a Map iterates in insertion
|
|
@@ -173,14 +249,25 @@ function getTile(cache, tileRow, tileCol) {
|
|
|
173
249
|
cache.tiles.set(key, hit);
|
|
174
250
|
return hit;
|
|
175
251
|
}
|
|
176
|
-
const col0 = tileCol * rasterTileSize;
|
|
177
|
-
const row0 = tileRow * rasterTileSize;
|
|
178
|
-
const width = Math.min(rasterTileSize, cache.numColumns - col0);
|
|
179
|
-
const height = Math.min(rasterTileSize, cache.numRows - row0);
|
|
252
|
+
const col0 = tileCol * rasterTileSize * colSpan;
|
|
253
|
+
const row0 = tileRow * rasterTileSize * rowSpan;
|
|
254
|
+
const width = Math.min(rasterTileSize, Math.ceil((cache.numColumns - col0) / colSpan));
|
|
255
|
+
const height = Math.min(rasterTileSize, Math.ceil((cache.numRows - row0) / rowSpan));
|
|
180
256
|
if (width <= 0 || height <= 0) {
|
|
181
257
|
return undefined;
|
|
182
258
|
}
|
|
183
|
-
const canvas = paint(
|
|
259
|
+
const canvas = paint(width, height, out => {
|
|
260
|
+
rasterPixels({
|
|
261
|
+
spec: cache.spec,
|
|
262
|
+
col0,
|
|
263
|
+
row0,
|
|
264
|
+
width,
|
|
265
|
+
height,
|
|
266
|
+
colSpan,
|
|
267
|
+
rowSpan,
|
|
268
|
+
out,
|
|
269
|
+
});
|
|
270
|
+
});
|
|
184
271
|
if (!canvas) {
|
|
185
272
|
return undefined;
|
|
186
273
|
}
|
|
@@ -198,28 +285,34 @@ function getTile(cache, tileRow, tileCol) {
|
|
|
198
285
|
* one-pixel-per-cell tiles. The tiles do not depend on the zoom level, so a zoom
|
|
199
286
|
* frame costs a handful of drawImage calls instead of a fillRect per visible
|
|
200
287
|
* cell -- which ran to 885ms per block at the minimum column width.
|
|
288
|
+
*
|
|
289
|
+
* Below a device pixel per cell the tiles average cells together instead, and
|
|
290
|
+
* only along the axis that needs it. Leaving the downsampling to the browser's
|
|
291
|
+
* image smoothing blurred both axes at once: at fit-to-width, where only the
|
|
292
|
+
* columns are narrow, every row boundary turned into a gradient.
|
|
201
293
|
*/
|
|
202
294
|
export function drawMsaRaster({ ctx, model, theme, offsetX, offsetY, }) {
|
|
203
295
|
const { colWidth, rowHeight, blockSize, highResScaleFactor } = model;
|
|
204
296
|
const cache = getCache(model, theme);
|
|
297
|
+
const colSpan = cellsPerPixel(colWidth * highResScaleFactor);
|
|
298
|
+
const rowSpan = cellsPerPixel(rowHeight * highResScaleFactor);
|
|
205
299
|
ctx.resetTransform();
|
|
206
300
|
ctx.scale(highResScaleFactor, highResScaleFactor);
|
|
207
301
|
ctx.translate(-offsetX, -offsetY);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
const tileHeight = rasterTileSize * rowHeight;
|
|
302
|
+
ctx.imageSmoothingEnabled = false;
|
|
303
|
+
const pixelWidth = colWidth * colSpan;
|
|
304
|
+
const pixelHeight = rowHeight * rowSpan;
|
|
305
|
+
const tileWidth = rasterTileSize * pixelWidth;
|
|
306
|
+
const tileHeight = rasterTileSize * pixelHeight;
|
|
214
307
|
const firstCol = Math.max(0, Math.floor(offsetX / tileWidth));
|
|
215
308
|
const lastCol = Math.floor((offsetX + blockSize) / tileWidth);
|
|
216
309
|
const firstRow = Math.max(0, Math.floor(offsetY / tileHeight));
|
|
217
310
|
const lastRow = Math.floor((offsetY + blockSize) / tileHeight);
|
|
218
311
|
for (let tileRow = firstRow; tileRow <= lastRow; tileRow++) {
|
|
219
312
|
for (let tileCol = firstCol; tileCol <= lastCol; tileCol++) {
|
|
220
|
-
const tile = getTile(cache, tileRow, tileCol);
|
|
313
|
+
const tile = getTile({ cache, tileRow, tileCol, colSpan, rowSpan });
|
|
221
314
|
if (tile) {
|
|
222
|
-
ctx.drawImage(tile, 0, 0, tile.width, tile.height, tileCol * tileWidth, tileRow * tileHeight, tile.width *
|
|
315
|
+
ctx.drawImage(tile, 0, 0, tile.width, tile.height, tileCol * tileWidth, tileRow * tileHeight, tile.width * pixelWidth, tile.height * pixelHeight);
|
|
223
316
|
}
|
|
224
317
|
}
|
|
225
318
|
}
|
|
@@ -262,7 +355,9 @@ export function canvasHref(canvas) {
|
|
|
262
355
|
}
|
|
263
356
|
}
|
|
264
357
|
// A canvas much past this many pixels fails to allocate, and the browser's own
|
|
265
|
-
// per-side limit is lower still, so a raster bigger than either
|
|
358
|
+
// per-side limit is lower still, so a raster bigger than either averages down,
|
|
359
|
+
// per axis: an alignment wide enough to hit the limit on columns alone keeps
|
|
360
|
+
// every row.
|
|
266
361
|
// The result is still drawn across the same rectangle -- it loses cell-exact
|
|
267
362
|
// detail at a size where no figure could show it anyway.
|
|
268
363
|
const maxImagePixels = 64e6;
|
|
@@ -285,23 +380,37 @@ export function rasterImageHref({ model, theme, col0, row0, numCols, numRows, })
|
|
|
285
380
|
return undefined;
|
|
286
381
|
}
|
|
287
382
|
const cache = getCache(model, theme);
|
|
288
|
-
let
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
step *= 2;
|
|
383
|
+
let colSpan = 1;
|
|
384
|
+
let rowSpan = 1;
|
|
385
|
+
while (Math.ceil(numCols / colSpan) > maxImageSide) {
|
|
386
|
+
colSpan *= 2;
|
|
293
387
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
388
|
+
while (Math.ceil(numRows / rowSpan) > maxImageSide) {
|
|
389
|
+
rowSpan *= 2;
|
|
390
|
+
}
|
|
391
|
+
while (Math.ceil(numCols / colSpan) * Math.ceil(numRows / rowSpan) >
|
|
392
|
+
maxImagePixels) {
|
|
393
|
+
if (numCols / colSpan >= numRows / rowSpan) {
|
|
394
|
+
colSpan *= 2;
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
rowSpan *= 2;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const width = Math.ceil(numCols / colSpan);
|
|
401
|
+
const height = Math.ceil(numRows / rowSpan);
|
|
402
|
+
return canvasHref(paint(width, height, out => {
|
|
403
|
+
rasterPixels({
|
|
404
|
+
spec: cache.spec,
|
|
405
|
+
col0,
|
|
406
|
+
row0,
|
|
407
|
+
width,
|
|
408
|
+
height,
|
|
409
|
+
colSpan,
|
|
410
|
+
rowSpan,
|
|
411
|
+
out,
|
|
412
|
+
});
|
|
413
|
+
}));
|
|
305
414
|
}
|
|
306
415
|
/**
|
|
307
416
|
* The whole alignment sampled down to a strip small enough to sit behind the
|
|
@@ -323,15 +432,18 @@ export function msaThumbnail({ model, theme, height, }) {
|
|
|
323
432
|
const h = Math.ceil(numRows / rowStep);
|
|
324
433
|
cache.thumbnail = {
|
|
325
434
|
height,
|
|
326
|
-
canvas: paint(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
435
|
+
canvas: paint(w, h, out => {
|
|
436
|
+
rasterPixels({
|
|
437
|
+
spec: cache.spec,
|
|
438
|
+
col0: 0,
|
|
439
|
+
row0: 0,
|
|
440
|
+
width: w,
|
|
441
|
+
height: h,
|
|
442
|
+
colStep,
|
|
443
|
+
rowStep,
|
|
444
|
+
out,
|
|
445
|
+
});
|
|
446
|
+
}),
|
|
335
447
|
};
|
|
336
448
|
}
|
|
337
449
|
return cache.thumbnail.canvas;
|