@jbrowse/plugin-dotplot-view 3.6.4 → 3.7.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.
Files changed (97) hide show
  1. package/dist/DiagonalizeDotplotRpc.d.ts +30 -0
  2. package/dist/DiagonalizeDotplotRpc.js +156 -0
  3. package/dist/DotplotDisplay/renderDotplotBlock.js +3 -0
  4. package/dist/DotplotDisplay/stateModelFactory.d.ts +6 -0
  5. package/dist/DotplotDisplay/stateModelFactory.js +15 -0
  6. package/dist/DotplotRenderer/DotplotRenderer.d.ts +3 -12
  7. package/dist/DotplotRenderer/clamp.d.ts +7 -0
  8. package/dist/DotplotRenderer/clamp.js +62 -0
  9. package/dist/DotplotRenderer/drawDotplot.d.ts +5 -4
  10. package/dist/DotplotRenderer/drawDotplot.js +92 -96
  11. package/dist/DotplotView/1dview.js +5 -3
  12. package/dist/DotplotView/components/ColorBySelector.d.ts +5 -0
  13. package/dist/DotplotView/components/ColorBySelector.js +79 -0
  14. package/dist/DotplotView/components/DiagonalizationProgressDialog.d.ts +6 -0
  15. package/dist/DotplotView/components/DiagonalizationProgressDialog.js +125 -0
  16. package/dist/DotplotView/components/DotplotControls.js +84 -12
  17. package/dist/DotplotView/components/DotplotTooltips.d.ts +15 -0
  18. package/dist/DotplotView/components/DotplotTooltips.js +43 -0
  19. package/dist/DotplotView/components/DotplotView.js +16 -191
  20. package/dist/DotplotView/components/DotplotWarnings.js +3 -3
  21. package/dist/DotplotView/components/ImportForm/index.js +0 -1
  22. package/dist/DotplotView/components/MinLengthSlider.d.ts +5 -0
  23. package/dist/DotplotView/components/MinLengthSlider.js +44 -0
  24. package/dist/DotplotView/components/MouseInteractionLayer.d.ts +17 -0
  25. package/dist/DotplotView/components/MouseInteractionLayer.js +18 -0
  26. package/dist/DotplotView/components/OpacitySlider.d.ts +5 -0
  27. package/dist/DotplotView/components/OpacitySlider.js +43 -0
  28. package/dist/DotplotView/components/SelectionContextMenu.d.ts +13 -0
  29. package/dist/DotplotView/components/SelectionContextMenu.js +42 -0
  30. package/dist/DotplotView/components/SliderTooltip.d.ts +2 -0
  31. package/dist/DotplotView/components/SliderTooltip.js +9 -0
  32. package/dist/DotplotView/components/hooks/useCtrlKeyTracking.d.ts +1 -0
  33. package/dist/DotplotView/components/hooks/useCtrlKeyTracking.js +24 -0
  34. package/dist/DotplotView/components/hooks/useCursorMode.d.ts +7 -0
  35. package/dist/DotplotView/components/hooks/useCursorMode.js +19 -0
  36. package/dist/DotplotView/components/hooks/useMouseCoordinates.d.ts +29 -0
  37. package/dist/DotplotView/components/hooks/useMouseCoordinates.js +52 -0
  38. package/dist/DotplotView/components/hooks/useMouseMoveHandler.d.ts +6 -0
  39. package/dist/DotplotView/components/hooks/useMouseMoveHandler.js +27 -0
  40. package/dist/DotplotView/components/hooks/useMouseUpHandler.d.ts +3 -0
  41. package/dist/DotplotView/components/hooks/useMouseUpHandler.js +31 -0
  42. package/dist/DotplotView/components/hooks/useWheelHandler.d.ts +8 -0
  43. package/dist/DotplotView/components/hooks/useWheelHandler.js +47 -0
  44. package/dist/DotplotView/components/util.js +1 -3
  45. package/dist/DotplotView/model.d.ts +5 -0
  46. package/dist/DotplotView/model.js +35 -20
  47. package/dist/ServerSideRenderedBlockContent.js +3 -20
  48. package/dist/index.js +2 -0
  49. package/esm/DiagonalizeDotplotRpc.d.ts +30 -0
  50. package/esm/DiagonalizeDotplotRpc.js +150 -0
  51. package/esm/DotplotDisplay/renderDotplotBlock.js +3 -0
  52. package/esm/DotplotDisplay/stateModelFactory.d.ts +6 -0
  53. package/esm/DotplotDisplay/stateModelFactory.js +15 -0
  54. package/esm/DotplotRenderer/DotplotRenderer.d.ts +3 -12
  55. package/esm/DotplotRenderer/clamp.d.ts +7 -0
  56. package/esm/DotplotRenderer/clamp.js +58 -0
  57. package/esm/DotplotRenderer/drawDotplot.d.ts +5 -4
  58. package/esm/DotplotRenderer/drawDotplot.js +92 -96
  59. package/esm/DotplotView/1dview.js +5 -3
  60. package/esm/DotplotView/components/ColorBySelector.d.ts +5 -0
  61. package/esm/DotplotView/components/ColorBySelector.js +74 -0
  62. package/esm/DotplotView/components/DiagonalizationProgressDialog.d.ts +6 -0
  63. package/esm/DotplotView/components/DiagonalizationProgressDialog.js +123 -0
  64. package/esm/DotplotView/components/DotplotControls.js +52 -13
  65. package/esm/DotplotView/components/DotplotTooltips.d.ts +15 -0
  66. package/esm/DotplotView/components/DotplotTooltips.js +7 -0
  67. package/esm/DotplotView/components/DotplotView.js +17 -159
  68. package/esm/DotplotView/components/DotplotWarnings.js +4 -4
  69. package/esm/DotplotView/components/ImportForm/index.js +0 -1
  70. package/esm/DotplotView/components/MinLengthSlider.d.ts +5 -0
  71. package/esm/DotplotView/components/MinLengthSlider.js +39 -0
  72. package/esm/DotplotView/components/MouseInteractionLayer.d.ts +17 -0
  73. package/esm/DotplotView/components/MouseInteractionLayer.js +12 -0
  74. package/esm/DotplotView/components/OpacitySlider.d.ts +5 -0
  75. package/esm/DotplotView/components/OpacitySlider.js +38 -0
  76. package/esm/DotplotView/components/SelectionContextMenu.d.ts +13 -0
  77. package/esm/DotplotView/components/SelectionContextMenu.js +39 -0
  78. package/esm/DotplotView/components/SliderTooltip.d.ts +2 -0
  79. package/esm/DotplotView/components/SliderTooltip.js +6 -0
  80. package/esm/DotplotView/components/hooks/useCtrlKeyTracking.d.ts +1 -0
  81. package/esm/DotplotView/components/hooks/useCtrlKeyTracking.js +21 -0
  82. package/esm/DotplotView/components/hooks/useCursorMode.d.ts +7 -0
  83. package/esm/DotplotView/components/hooks/useCursorMode.js +16 -0
  84. package/esm/DotplotView/components/hooks/useMouseCoordinates.d.ts +29 -0
  85. package/esm/DotplotView/components/hooks/useMouseCoordinates.js +49 -0
  86. package/esm/DotplotView/components/hooks/useMouseMoveHandler.d.ts +6 -0
  87. package/esm/DotplotView/components/hooks/useMouseMoveHandler.js +24 -0
  88. package/esm/DotplotView/components/hooks/useMouseUpHandler.d.ts +3 -0
  89. package/esm/DotplotView/components/hooks/useMouseUpHandler.js +28 -0
  90. package/esm/DotplotView/components/hooks/useWheelHandler.d.ts +8 -0
  91. package/esm/DotplotView/components/hooks/useWheelHandler.js +44 -0
  92. package/esm/DotplotView/components/util.js +1 -3
  93. package/esm/DotplotView/model.d.ts +5 -0
  94. package/esm/DotplotView/model.js +35 -20
  95. package/esm/ServerSideRenderedBlockContent.js +4 -21
  96. package/esm/index.js +2 -0
  97. package/package.json +4 -4
@@ -0,0 +1,5 @@
1
+ import type { DotplotViewModel } from '../model';
2
+ declare const ColorBySelector: ({ model, }: {
3
+ model: DotplotViewModel;
4
+ }) => import("react/jsx-runtime").JSX.Element;
5
+ export default ColorBySelector;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const CascadingMenuButton_1 = __importDefault(require("@jbrowse/core/ui/CascadingMenuButton"));
8
+ const Palette_1 = __importDefault(require("@mui/icons-material/Palette"));
9
+ const mobx_react_1 = require("mobx-react");
10
+ const ColorBySelector = (0, mobx_react_1.observer)(function ({ model, }) {
11
+ var _a, _b;
12
+ const firstDisplay = (_a = model.tracks[0]) === null || _a === void 0 ? void 0 : _a.displays[0];
13
+ const colorBy = (_b = firstDisplay === null || firstDisplay === void 0 ? void 0 : firstDisplay.colorBy) !== null && _b !== void 0 ? _b : 'default';
14
+ const setColorBy = (value) => {
15
+ for (const track of model.tracks) {
16
+ for (const display of track.displays) {
17
+ ;
18
+ display.setColorBy(value);
19
+ }
20
+ }
21
+ };
22
+ return ((0, jsx_runtime_1.jsx)(CascadingMenuButton_1.default, { menuItems: [
23
+ {
24
+ label: 'Default',
25
+ type: 'radio',
26
+ checked: colorBy === 'default',
27
+ onClick: () => {
28
+ setColorBy('default');
29
+ },
30
+ helpText: 'Use the default color scheme specified in the track configuration. This respects the color settings defined in the config file.',
31
+ },
32
+ {
33
+ label: 'Identity',
34
+ type: 'radio',
35
+ checked: colorBy === 'identity',
36
+ onClick: () => {
37
+ setColorBy('identity');
38
+ },
39
+ helpText: 'Color alignments by sequence identity percentage. Higher identity matches appear in warmer colors, while lower identity matches appear cooler. Useful for identifying highly conserved vs. divergent regions.',
40
+ },
41
+ {
42
+ label: 'Mean Query Identity',
43
+ type: 'radio',
44
+ checked: colorBy === 'meanQueryIdentity',
45
+ onClick: () => {
46
+ setColorBy('meanQueryIdentity');
47
+ },
48
+ helpText: 'Color alignments based on the mean identity across the query sequence. This provides a smoothed view of overall alignment quality, reducing noise from local variations. For instance, a single long query of e.g. a contig of an assembly, when aligned to the target, may get split into many smaller "hits". This score aggregates across them, and colors them all the same. Similar code exists in the program dotPlotly',
49
+ },
50
+ {
51
+ label: 'Mapping Quality',
52
+ type: 'radio',
53
+ checked: colorBy === 'mappingQuality',
54
+ onClick: () => {
55
+ setColorBy('mappingQuality');
56
+ },
57
+ helpText: 'Color alignments by mapping quality score (MAPQ). Higher quality mappings (more unique/confident) appear in darker colors. Useful for identifying ambiguous or multi-mapping regions.',
58
+ },
59
+ {
60
+ label: 'Strand',
61
+ type: 'radio',
62
+ checked: colorBy === 'strand',
63
+ onClick: () => {
64
+ setColorBy('strand');
65
+ },
66
+ helpText: 'Color alignments by strand orientation. Forward strand alignments and reverse strand alignments are shown in different colors, making it easy to identify inversions and strand-specific patterns.',
67
+ },
68
+ {
69
+ label: 'Query',
70
+ type: 'radio',
71
+ checked: colorBy === 'query',
72
+ onClick: () => {
73
+ setColorBy('query');
74
+ },
75
+ helpText: 'Color alignments by query sequence name. Each unique query sequence is assigned a consistent color based on its name, making it easy to visually distinguish between different sequences.',
76
+ },
77
+ ], children: (0, jsx_runtime_1.jsx)(Palette_1.default, {}) }));
78
+ });
79
+ exports.default = ColorBySelector;
@@ -0,0 +1,6 @@
1
+ import type { DotplotViewModel } from '../model';
2
+ declare const DiagonalizationProgressDialog: ({ handleClose, model, }: {
3
+ handleClose: () => void;
4
+ model: Pick<DotplotViewModel, "tracks" | "hview" | "vview" | "id" | "type" | "displayName">;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ export default DiagonalizationProgressDialog;
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const jsx_runtime_1 = require("react/jsx-runtime");
4
+ const react_1 = require("react");
5
+ const ui_1 = require("@jbrowse/core/ui");
6
+ const util_1 = require("@jbrowse/core/util");
7
+ const stopToken_1 = require("@jbrowse/core/util/stopToken");
8
+ const material_1 = require("@mui/material");
9
+ const mobx_1 = require("mobx");
10
+ const mobx_react_1 = require("mobx-react");
11
+ async function runDiagonalization({ model, session, stopToken, setProgress, setMessage, }) {
12
+ setProgress(0);
13
+ setMessage('Preparing diagonalization...');
14
+ const track = model.tracks[0];
15
+ if (!track) {
16
+ throw new Error('No tracks found');
17
+ }
18
+ const display = track.displays[0];
19
+ if (!display) {
20
+ throw new Error('No display found');
21
+ }
22
+ const result = (await session.rpcManager.call(model.id, 'DiagonalizeDotplot', {
23
+ sessionId: `diagonalize-${Date.now()}`,
24
+ view: {
25
+ hview: model.hview,
26
+ vview: model.vview,
27
+ },
28
+ adapterConfig: display.adapterConfig,
29
+ stopToken,
30
+ statusCallback: (msg) => {
31
+ setMessage(msg);
32
+ if (msg.includes('Initializing')) {
33
+ setProgress(5);
34
+ }
35
+ else if (msg.includes('Getting renderer')) {
36
+ setProgress(10);
37
+ }
38
+ else if (msg.includes('Fetching features')) {
39
+ setProgress(20);
40
+ }
41
+ else if (msg.includes('Extracting')) {
42
+ setProgress(30);
43
+ }
44
+ else if (msg.includes('Running diagonalization')) {
45
+ setProgress(40);
46
+ }
47
+ else if (msg.includes('Grouping')) {
48
+ setProgress(50);
49
+ }
50
+ else if (msg.includes('Determining')) {
51
+ setProgress(65);
52
+ }
53
+ else if (msg.includes('Sorting')) {
54
+ setProgress(80);
55
+ }
56
+ else if (msg.includes('Building')) {
57
+ setProgress(90);
58
+ }
59
+ else if (msg.includes('complete')) {
60
+ setProgress(100);
61
+ }
62
+ },
63
+ }));
64
+ setMessage('Applying new layout...');
65
+ setProgress(95);
66
+ if (result.newRegions.length > 0) {
67
+ (0, mobx_1.transaction)(() => {
68
+ model.vview.setDisplayedRegions(result.newRegions);
69
+ });
70
+ setProgress(100);
71
+ setMessage(`Diagonalization complete! Reordered ${result.stats.regionsReordered} regions, reversed ${result.stats.regionsReversed}`);
72
+ return result;
73
+ }
74
+ else {
75
+ throw new Error('No regions to reorder');
76
+ }
77
+ }
78
+ const DiagonalizationProgressDialog = (0, mobx_react_1.observer)(function ({ handleClose, model, }) {
79
+ const [progress, setProgress] = (0, react_1.useState)(0);
80
+ const [message, setMessage] = (0, react_1.useState)('Ready to start diagonalization');
81
+ const [error, setError] = (0, react_1.useState)();
82
+ const [isRunning, setIsRunning] = (0, react_1.useState)(false);
83
+ const [stopToken, setStopToken] = (0, react_1.useState)();
84
+ const handleStart = async () => {
85
+ const session = (0, util_1.getSession)(model);
86
+ const token = (0, stopToken_1.createStopToken)();
87
+ setStopToken(token);
88
+ try {
89
+ setIsRunning(true);
90
+ await runDiagonalization({
91
+ model,
92
+ session,
93
+ stopToken: token,
94
+ setProgress,
95
+ setMessage,
96
+ });
97
+ setTimeout(() => {
98
+ handleClose();
99
+ }, 2000);
100
+ }
101
+ catch (err) {
102
+ console.error(err);
103
+ setError(err);
104
+ }
105
+ finally {
106
+ setIsRunning(false);
107
+ }
108
+ };
109
+ const handleCancel = () => {
110
+ if (stopToken) {
111
+ (0, stopToken_1.stopStopToken)(stopToken);
112
+ setStopToken(undefined);
113
+ }
114
+ handleClose();
115
+ };
116
+ const handleDialogClose = () => {
117
+ if (!isRunning) {
118
+ handleClose();
119
+ }
120
+ };
121
+ return ((0, jsx_runtime_1.jsxs)(ui_1.Dialog, { open: true, title: "Diagonalize Dotplot", onClose: handleDialogClose, maxWidth: "lg", children: [(0, jsx_runtime_1.jsxs)(material_1.DialogContent, { style: { minWidth: 400 }, children: [message ? (0, jsx_runtime_1.jsx)(material_1.Typography, { children: message }) : null, error ? (0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: error }) : null, isRunning ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.LinearProgress, { variant: "determinate", value: progress, style: { marginTop: 16 }, color: error ? 'error' : 'primary' }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "caption", color: "textSecondary", style: { marginTop: 8, display: 'block' }, children: [Math.round(progress), "% complete"] })] })) : null] }), (0, jsx_runtime_1.jsxs)(material_1.DialogActions, { children: [!isRunning ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { onClick: handleClose, color: "secondary", variant: "contained", children: "Cancel" }), (0, jsx_runtime_1.jsx)(material_1.Button, { onClick: () => {
122
+ handleStart();
123
+ }, color: "primary", variant: "contained", children: "Start" })] })) : null, isRunning ? ((0, jsx_runtime_1.jsx)(material_1.Button, { onClick: handleCancel, color: "secondary", variant: "contained", children: "Cancel" })) : null] })] }));
124
+ });
125
+ exports.default = DiagonalizationProgressDialog;
@@ -1,46 +1,100 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
39
  const jsx_runtime_1 = require("react/jsx-runtime");
40
+ const react_1 = require("react");
7
41
  const CascadingMenuButton_1 = __importDefault(require("@jbrowse/core/ui/CascadingMenuButton"));
8
42
  const Icons_1 = require("@jbrowse/core/ui/Icons");
9
- const CropDin_1 = __importDefault(require("@mui/icons-material/CropDin"));
10
- const CropLandscape_1 = __importDefault(require("@mui/icons-material/CropLandscape"));
43
+ const util_1 = require("@jbrowse/core/util");
11
44
  const MoreVert_1 = __importDefault(require("@mui/icons-material/MoreVert"));
12
- const SettingsOverscan_1 = __importDefault(require("@mui/icons-material/SettingsOverscan"));
45
+ const Shuffle_1 = __importDefault(require("@mui/icons-material/Shuffle"));
13
46
  const ZoomIn_1 = __importDefault(require("@mui/icons-material/ZoomIn"));
14
47
  const ZoomOut_1 = __importDefault(require("@mui/icons-material/ZoomOut"));
15
48
  const material_1 = require("@mui/material");
16
49
  const mobx_react_1 = require("mobx-react");
50
+ const ColorBySelector_1 = __importDefault(require("./ColorBySelector"));
17
51
  const CursorIcon_1 = require("./CursorIcon");
52
+ const MinLengthSlider_1 = __importDefault(require("./MinLengthSlider"));
53
+ const OpacitySlider_1 = __importDefault(require("./OpacitySlider"));
54
+ const DiagonalizationProgressDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./DiagonalizationProgressDialog'))));
18
55
  const DotplotControls = (0, mobx_react_1.observer)(function ({ model, }) {
19
- return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, { onClick: () => {
56
+ var _a;
57
+ const [showDynamicControls, setShowDynamicControls] = (0, react_1.useState)(true);
58
+ const hasDisplays = (_a = model.tracks[0]) === null || _a === void 0 ? void 0 : _a.displays[0];
59
+ return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, { onClick: () => {
20
60
  model.zoomOut();
21
61
  }, children: (0, jsx_runtime_1.jsx)(ZoomOut_1.default, {}) }), (0, jsx_runtime_1.jsx)(material_1.IconButton, { onClick: () => {
22
62
  model.zoomIn();
23
63
  }, children: (0, jsx_runtime_1.jsx)(ZoomIn_1.default, {}) }), (0, jsx_runtime_1.jsx)(material_1.IconButton, { onClick: () => model.activateTrackSelector(), title: "Open track selector", children: (0, jsx_runtime_1.jsx)(Icons_1.TrackSelector, {}) }), (0, jsx_runtime_1.jsx)(CascadingMenuButton_1.default, { menuItems: [
24
64
  {
25
65
  label: 'Square view - same bp per pixel',
26
- icon: CropDin_1.default,
27
66
  onClick: () => {
28
67
  model.squareView();
29
68
  },
69
+ helpText: 'Makes both views use the same zoom level (bp per pixel), adjusting to the average of each. This ensures features are displayed at comparable scales for easier visual comparison.',
30
70
  },
31
71
  {
32
72
  label: 'Rectangular view - same total bp',
33
- icon: CropLandscape_1.default,
34
73
  onClick: () => {
35
74
  model.squareViewProportional();
36
75
  },
76
+ helpText: 'Adjusts zoom levels proportionally so both views show the same total number of base pairs. This accounts for different view widths while maintaining the same total genomic span.',
37
77
  },
38
78
  {
39
79
  label: 'Show all regions',
40
- icon: SettingsOverscan_1.default,
41
80
  onClick: () => {
42
81
  model.showAllRegions();
43
82
  },
83
+ helpText: 'Zooms out to display all genome assemblies in their entirety. Useful for getting a high-level overview or resetting the view after zooming into specific regions.',
84
+ },
85
+ {
86
+ label: 'Re-order chromosomes',
87
+ icon: Shuffle_1.default,
88
+ onClick: () => {
89
+ (0, util_1.getSession)(model).queueDialog(handleClose => [
90
+ DiagonalizationProgressDialog,
91
+ {
92
+ handleClose,
93
+ model,
94
+ },
95
+ ]);
96
+ },
97
+ helpText: 'Diagonalization algorithmically reorders and reorients chromosomes to minimize crossing synteny lines, creating a more diagonal pattern. This makes it easier to identify large-scale genomic rearrangements, inversions, and translocations. The process runs on the webworker for better performance.',
44
98
  },
45
99
  {
46
100
  type: 'checkbox',
@@ -49,6 +103,7 @@ const DotplotControls = (0, mobx_react_1.observer)(function ({ model, }) {
49
103
  onClick: () => {
50
104
  model.setDrawCigar(!model.drawCigar);
51
105
  },
106
+ helpText: 'Toggle detailed CIGAR string visualization showing matches, insertions, and deletions in alignments. Disable for a cleaner view that shows only broad syntenic blocks.',
52
107
  },
53
108
  {
54
109
  label: 'Show pan buttons',
@@ -57,48 +112,64 @@ const DotplotControls = (0, mobx_react_1.observer)(function ({ model, }) {
57
112
  onClick: () => {
58
113
  model.setShowPanButtons(!model.showPanButtons);
59
114
  },
115
+ helpText: 'Show or hide directional pan buttons that allow you to navigate the dotplot view by clicking arrows. Useful for precise navigation without using mouse drag.',
116
+ },
117
+ {
118
+ label: 'Show dynamic controls',
119
+ type: 'checkbox',
120
+ checked: showDynamicControls,
121
+ onClick: () => {
122
+ setShowDynamicControls(!showDynamicControls);
123
+ },
124
+ helpText: 'Toggle visibility of dynamic controls like opacity and minimum length sliders. These controls allow you to adjust dotplot visualization parameters in real-time.',
60
125
  },
61
126
  {
62
127
  label: 'Click and drag mode',
128
+ helpText: 'Configure how clicking and dragging behaves in the dotplot view. Choose between panning and region selection as the default action.',
63
129
  subMenu: [
64
130
  {
65
- label: 'Pan by default, select region when ctrl/cmd key is held',
131
+ label: 'Pan by default',
66
132
  icon: CursorIcon_1.CursorMove,
67
133
  type: 'radio',
68
134
  checked: model.cursorMode === 'move',
69
135
  onClick: () => {
70
136
  model.setCursorMode('move');
71
137
  },
138
+ helpText: 'Click and drag to pan the view. Hold Ctrl/Cmd while dragging to select a region for zooming or creating a linear synteny view.',
72
139
  },
73
140
  {
74
- label: 'Select region by default, pan when ctrl/cmd key is held',
141
+ label: 'Select region by default',
75
142
  icon: CursorIcon_1.CursorMouse,
76
143
  type: 'radio',
77
144
  checked: model.cursorMode === 'crosshair',
78
145
  onClick: () => {
79
146
  model.setCursorMode('crosshair');
80
147
  },
148
+ helpText: 'Click and drag to select a region for zooming or creating a linear synteny view. Hold Ctrl/Cmd while dragging to pan the view instead.',
81
149
  },
82
150
  ],
83
151
  },
84
152
  {
85
153
  label: 'Wheel scroll mode',
154
+ helpText: 'Configure how mouse wheel scrolling behaves in the dotplot view.',
86
155
  subMenu: [
87
156
  {
88
- label: 'Pans view',
157
+ label: 'Pan view',
89
158
  type: 'radio',
90
159
  checked: model.wheelMode === 'pan',
91
160
  onClick: () => {
92
161
  model.setWheelMode('pan');
93
162
  },
163
+ helpText: 'Mouse wheel scrolling will pan the view up/down. Useful for navigating through the genome without changing zoom level.',
94
164
  },
95
165
  {
96
- label: 'Zooms view',
166
+ label: 'Zoom view',
97
167
  type: 'radio',
98
168
  checked: model.wheelMode === 'zoom',
99
169
  onClick: () => {
100
170
  model.setWheelMode('zoom');
101
171
  },
172
+ helpText: 'Mouse wheel scrolling will zoom in/out of the view. Provides quick zoom control for detailed inspection of regions.',
102
173
  },
103
174
  {
104
175
  label: 'Disable',
@@ -107,9 +178,10 @@ const DotplotControls = (0, mobx_react_1.observer)(function ({ model, }) {
107
178
  onClick: () => {
108
179
  model.setWheelMode('none');
109
180
  },
181
+ helpText: 'Mouse wheel scrolling will be disabled for the dotplot view. Use this to prevent accidental zoom or pan when scrolling the page.',
110
182
  },
111
183
  ],
112
184
  },
113
- ], children: (0, jsx_runtime_1.jsx)(MoreVert_1.default, {}) })] }));
185
+ ], children: (0, jsx_runtime_1.jsx)(MoreVert_1.default, {}) }), (0, jsx_runtime_1.jsx)(ColorBySelector_1.default, { model: model }), hasDisplays && showDynamicControls ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OpacitySlider_1.default, { model: model }), (0, jsx_runtime_1.jsx)(MinLengthSlider_1.default, { model: model })] })) : null] }));
114
186
  });
115
187
  exports.default = DotplotControls;
@@ -0,0 +1,15 @@
1
+ import type { DotplotViewModel } from '../model';
2
+ type Coord = [number, number] | undefined;
3
+ interface DotplotTooltipsProps {
4
+ model: DotplotViewModel;
5
+ mouseOvered: boolean;
6
+ validSelect: boolean;
7
+ mouserect: Coord;
8
+ mouserectClient: Coord;
9
+ xdistance: number;
10
+ mousedown: Coord;
11
+ mousedownClient: Coord;
12
+ ydistance: number;
13
+ }
14
+ export default function DotplotTooltips({ model, mouseOvered, validSelect, mouserect, mouserectClient, xdistance, mousedown, mousedownClient, ydistance, }: DotplotTooltipsProps): import("react/jsx-runtime").JSX.Element;
15
+ export {};
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.default = DotplotTooltips;
37
+ const jsx_runtime_1 = require("react/jsx-runtime");
38
+ const react_1 = require("react");
39
+ const TooltipWhereClicked = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./DotplotTooltipClick'))));
40
+ const TooltipWhereMouseovered = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./DotplotTooltipMouseover'))));
41
+ function DotplotTooltips({ model, mouseOvered, validSelect, mouserect, mouserectClient, xdistance, mousedown, mousedownClient, ydistance, }) {
42
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [mouseOvered && validSelect ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(TooltipWhereMouseovered, { model: model, mouserect: mouserect, mouserectClient: mouserectClient, xdistance: xdistance }) })) : null, validSelect ? ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: null, children: (0, jsx_runtime_1.jsx)(TooltipWhereClicked, { model: model, mousedown: mousedown, mousedownClient: mousedownClient, xdistance: xdistance, ydistance: ydistance }) })) : null] }));
43
+ }