react-msaview 5.0.16 → 5.1.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 (85) hide show
  1. package/bundle/index.js +23 -23
  2. package/bundle/index.js.LICENSE.txt +1 -1
  3. package/bundle/index.js.map +1 -1
  4. package/dist/clustalX.d.ts +5 -0
  5. package/dist/clustalX.js +88 -0
  6. package/dist/clustalX.js.map +1 -0
  7. package/dist/components/SequenceTextArea.js +2 -2
  8. package/dist/components/SequenceTextArea.js.map +1 -1
  9. package/dist/components/TextTrack.js +3 -5
  10. package/dist/components/TextTrack.js.map +1 -1
  11. package/dist/components/Track.d.ts +2 -1
  12. package/dist/components/Track.js +4 -3
  13. package/dist/components/Track.js.map +1 -1
  14. package/dist/components/VerticalScrollbar.js +6 -31
  15. package/dist/components/VerticalScrollbar.js.map +1 -1
  16. package/dist/components/dialogs/InterProScanDialog.js +5 -3
  17. package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
  18. package/dist/components/header/HeaderStatusArea.js +4 -2
  19. package/dist/components/header/HeaderStatusArea.js.map +1 -1
  20. package/dist/components/header/MSASettingsMenu.js +2 -27
  21. package/dist/components/header/MSASettingsMenu.js.map +1 -1
  22. package/dist/components/header/SettingsMenu.js +4 -69
  23. package/dist/components/header/SettingsMenu.js.map +1 -1
  24. package/dist/components/header/TreeSettingsMenu.js +3 -41
  25. package/dist/components/header/TreeSettingsMenu.js.map +1 -1
  26. package/dist/components/header/settingsMenuItems.d.ts +4 -0
  27. package/dist/components/header/settingsMenuItems.js +59 -0
  28. package/dist/components/header/settingsMenuItems.js.map +1 -0
  29. package/dist/components/minimap/Minimap.js +6 -31
  30. package/dist/components/minimap/Minimap.js.map +1 -1
  31. package/dist/components/msa/MSACanvasBlock.js +31 -33
  32. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  33. package/dist/components/msa/renderMSABlock.js +15 -9
  34. package/dist/components/msa/renderMSABlock.js.map +1 -1
  35. package/dist/components/tree/TreeCanvas.js +12 -14
  36. package/dist/components/tree/TreeCanvas.js.map +1 -1
  37. package/dist/components/tree/renderTreeCanvas.d.ts +9 -3
  38. package/dist/components/tree/renderTreeCanvas.js +14 -40
  39. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  40. package/dist/fetchUtils.d.ts +2 -1
  41. package/dist/fetchUtils.js +16 -2
  42. package/dist/fetchUtils.js.map +1 -1
  43. package/dist/hierarchy.d.ts +2 -0
  44. package/dist/hierarchy.js +25 -0
  45. package/dist/hierarchy.js.map +1 -1
  46. package/dist/launchInterProScan.d.ts +2 -1
  47. package/dist/launchInterProScan.js +31 -15
  48. package/dist/launchInterProScan.js.map +1 -1
  49. package/dist/model.d.ts +150 -494
  50. package/dist/model.js +23 -116
  51. package/dist/model.js.map +1 -1
  52. package/dist/useColorContrast.d.ts +10 -0
  53. package/dist/useColorContrast.js +13 -0
  54. package/dist/useColorContrast.js.map +1 -0
  55. package/dist/useDragScroll.d.ts +12 -0
  56. package/dist/useDragScroll.js +47 -0
  57. package/dist/useDragScroll.js.map +1 -0
  58. package/dist/version.d.ts +1 -1
  59. package/dist/version.js +1 -1
  60. package/dist/version.js.map +1 -1
  61. package/package.json +6 -6
  62. package/src/clustalX.test.ts +76 -0
  63. package/src/clustalX.ts +131 -0
  64. package/src/components/SequenceTextArea.tsx +2 -2
  65. package/src/components/TextTrack.tsx +3 -8
  66. package/src/components/Track.tsx +6 -9
  67. package/src/components/VerticalScrollbar.tsx +13 -40
  68. package/src/components/dialogs/InterProScanDialog.tsx +7 -1
  69. package/src/components/header/HeaderStatusArea.tsx +6 -1
  70. package/src/components/header/MSASettingsMenu.tsx +3 -27
  71. package/src/components/header/SettingsMenu.tsx +7 -79
  72. package/src/components/header/TreeSettingsMenu.tsx +4 -48
  73. package/src/components/header/settingsMenuItems.ts +68 -0
  74. package/src/components/minimap/Minimap.tsx +13 -38
  75. package/src/components/msa/MSACanvasBlock.tsx +53 -36
  76. package/src/components/msa/renderMSABlock.ts +16 -9
  77. package/src/components/tree/TreeCanvas.tsx +13 -35
  78. package/src/components/tree/renderTreeCanvas.ts +23 -38
  79. package/src/fetchUtils.ts +16 -2
  80. package/src/hierarchy.ts +27 -0
  81. package/src/launchInterProScan.ts +34 -10
  82. package/src/model.ts +32 -143
  83. package/src/useColorContrast.ts +18 -0
  84. package/src/useDragScroll.ts +55 -0
  85. package/src/version.ts +1 -1
package/src/model.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  } from 'msa-parsers'
21
21
 
22
22
  import { blocksX, blocksY } from './calculateBlocks.ts'
23
+ import { clustalXColumnColors } from './clustalX.ts'
23
24
  import colorSchemes from './colorSchemes.ts'
24
25
  import ConservationTrack from './components/ConservationTrack.tsx'
25
26
  import TextTrack from './components/TextTrack.tsx'
@@ -48,9 +49,11 @@ import {
48
49
  import { createPaletteMap } from './createPaletteMap.ts'
49
50
  import { flatToTree } from './flatToTree.ts'
50
51
  import {
52
+ calcDepthToLeaf,
51
53
  clusterLayout,
52
54
  collapse,
53
55
  find,
56
+ findMaxBranchLen,
54
57
  hierarchy,
55
58
  leaves,
56
59
  links,
@@ -90,9 +93,9 @@ import type { Theme } from '@mui/material'
90
93
  /**
91
94
  * #stateModel MsaView
92
95
  * extends
93
- * - DialogQueueSessionMixin
94
- * - MSAModel
95
- * - Tree
96
+ * - [DialogQueueSessionMixin](../dialogqueuesessionmixin)
97
+ * - [MSAModel](../msamodel)
98
+ * - [Tree](../tree)
96
99
  */
97
100
  function stateModelFactory() {
98
101
  return types
@@ -242,7 +245,9 @@ function stateModelFactory() {
242
245
  /**
243
246
  * #volatile
244
247
  */
245
- status: undefined as { msg: string; url?: string } | undefined,
248
+ status: undefined as
249
+ | { msg: string; url?: string; onCancel?: () => void }
250
+ | undefined,
246
251
  /**
247
252
  * #volatile
248
253
  * high resolution scale factor, helps make canvas look better on hi-dpi
@@ -922,13 +927,9 @@ function stateModelFactory() {
922
927
  const columns = this.columns2d
923
928
  for (const column of columns) {
924
929
  for (let j = 0; j < column.length; j++) {
925
- const l = r[j] || {}
930
+ const l = (r[j] ??= {})
926
931
  const cj = column[j]!
927
- if (!l[cj]) {
928
- l[cj] = 0
929
- }
930
- l[cj]++
931
- r[j] = l
932
+ l[cj] = (l[cj] ?? 0) + 1
932
933
  }
933
934
  }
934
935
  return r
@@ -1006,136 +1007,9 @@ function stateModelFactory() {
1006
1007
  */
1007
1008
  get colClustalX() {
1008
1009
  const { colStats, colStatsSums } = this
1009
- return colStats.map((stats, i) => {
1010
- const total = colStatsSums[i]!
1011
- const colors: Record<string, string> = {}
1012
-
1013
- const W = stats.W ?? 0
1014
- const L = stats.L ?? 0
1015
- const V = stats.V ?? 0
1016
- const I = stats.I ?? 0
1017
- const M = stats.M ?? 0
1018
- const A = stats.A ?? 0
1019
- const F = stats.F ?? 0
1020
- const C = stats.C ?? 0
1021
- const H = stats.H ?? 0
1022
- const P = stats.P ?? 0
1023
- const R = stats.R ?? 0
1024
- const K = stats.K ?? 0
1025
- const Q = stats.Q ?? 0
1026
- const E = stats.E ?? 0
1027
- const D = stats.D ?? 0
1028
- const T = stats.T ?? 0
1029
- const S = stats.S ?? 0
1030
- const G = stats.G ?? 0
1031
- const Y = stats.Y ?? 0
1032
- const N = stats.N ?? 0
1033
-
1034
- const WLVIMAFCHPY = W + L + V + I + M + A + F + C + H + P + Y
1035
- const KR = K + R
1036
- const QE = Q + E
1037
- const ED = E + D
1038
- const TS = T + S
1039
-
1040
- if (WLVIMAFCHPY / total > 0.6) {
1041
- colors.W = 'rgb(128,179,230)'
1042
- colors.L = 'rgb(128,179,230)'
1043
- colors.V = 'rgb(128,179,230)'
1044
- colors.A = 'rgb(128,179,230)'
1045
- colors.I = 'rgb(128,179,230)'
1046
- colors.M = 'rgb(128,179,230)'
1047
- colors.F = 'rgb(128,179,230)'
1048
- colors.C = 'rgb(128,179,230)'
1049
- }
1050
-
1051
- if (
1052
- KR / total > 0.6 ||
1053
- K / total > 0.8 ||
1054
- R / total > 0.8 ||
1055
- Q / total > 0.8
1056
- ) {
1057
- colors.K = '#d88'
1058
- colors.R = '#d88'
1059
- }
1060
-
1061
- if (
1062
- KR / total > 0.6 ||
1063
- QE / total > 0.5 ||
1064
- E / total > 0.8 ||
1065
- Q / total > 0.8 ||
1066
- D / total > 0.8
1067
- ) {
1068
- colors.E = 'rgb(192, 72, 192)'
1069
- }
1070
-
1071
- if (
1072
- KR / total > 0.6 ||
1073
- ED / total > 0.5 ||
1074
- K / total > 0.8 ||
1075
- R / total > 0.8 ||
1076
- Q / total > 0.8
1077
- ) {
1078
- colors.D = 'rgb(204, 77, 204)'
1079
- }
1080
-
1081
- if (N / total > 0.5 || Y / total > 0.85) {
1082
- colors.N = '#8f8'
1083
- }
1084
-
1085
- if (
1086
- KR / total > 0.6 ||
1087
- QE / total > 0.6 ||
1088
- Q / total > 0.85 ||
1089
- E / total > 0.85 ||
1090
- K / total > 0.85 ||
1091
- R / total > 0.85
1092
- ) {
1093
- colors.Q = '#8f8'
1094
- }
1095
-
1096
- if (
1097
- WLVIMAFCHPY / total > 0.6 ||
1098
- TS / total > 0.5 ||
1099
- S / total > 0.85 ||
1100
- T / total > 0.85
1101
- ) {
1102
- colors.S = 'rgb(26,204,26)'
1103
- colors.T = 'rgb(26,204,26)'
1104
- }
1105
-
1106
- if (C / total > 0.85) {
1107
- colors.C = 'rgb(240, 128, 128)'
1108
- }
1109
-
1110
- if (G / total > 0) {
1111
- colors.G = 'rgb(240, 144, 72)'
1112
- }
1113
-
1114
- if (P / total > 0) {
1115
- colors.P = 'rgb(204, 204, 0)'
1116
- }
1117
-
1118
- if (
1119
- WLVIMAFCHPY / total > 0.6 ||
1120
- W / total > 0.85 ||
1121
- Y / total > 0.85 ||
1122
- A / total > 0.85 ||
1123
- C / total > 0.85 ||
1124
- P / total > 0.85 ||
1125
- Q / total > 0.85 ||
1126
- F / total > 0.85 ||
1127
- H / total > 0.85 ||
1128
- I / total > 0.85 ||
1129
- L / total > 0.85 ||
1130
- M / total > 0.85 ||
1131
- V / total > 0.85
1132
- ) {
1133
- colors.H = 'rgb(26, 179, 179)'
1134
- colors.Y = 'rgb(26, 179, 179)'
1135
- }
1136
-
1137
- return colors
1138
- })
1010
+ return colStats.map((stats, i) =>
1011
+ clustalXColumnColors(stats, colStatsSums[i]!),
1012
+ )
1139
1013
  },
1140
1014
 
1141
1015
  /**
@@ -1209,6 +1083,22 @@ function stateModelFactory() {
1209
1083
  return leaves(this.hierarchy)
1210
1084
  },
1211
1085
 
1086
+ /**
1087
+ * #getter
1088
+ * max branch length across the tree, used to scale phylogram x-positions
1089
+ */
1090
+ get maxBranchLength() {
1091
+ return findMaxBranchLen(this.hierarchy)
1092
+ },
1093
+
1094
+ /**
1095
+ * #getter
1096
+ * max topological depth to a tip, used to scale cladogram x-positions
1097
+ */
1098
+ get maxDepthToLeaf() {
1099
+ return calcDepthToLeaf(this.hierarchy)
1100
+ },
1101
+
1212
1102
  /**
1213
1103
  * #getter
1214
1104
  */
@@ -1420,7 +1310,7 @@ function stateModelFactory() {
1420
1310
  /**
1421
1311
  * #action
1422
1312
  */
1423
- setStatus(status?: { msg: string; url?: string }) {
1313
+ setStatus(status?: { msg: string; url?: string; onCancel?: () => void }) {
1424
1314
  self.status = status
1425
1315
  },
1426
1316
  }))
@@ -1786,8 +1676,7 @@ function stateModelFactory() {
1786
1676
  },
1787
1677
 
1788
1678
  initFilter(arg: string) {
1789
- const ret = self.featureFilters.get(arg)
1790
- if (ret === undefined) {
1679
+ if (!self.featureFilters.has(arg)) {
1791
1680
  self.featureFilters.set(arg, true)
1792
1681
  }
1793
1682
  },
@@ -0,0 +1,18 @@
1
+ import { useMemo } from 'react'
2
+
3
+ import { useTheme } from '@mui/material'
4
+
5
+ import { colorContrast } from './util.ts'
6
+
7
+ /**
8
+ * Resolves the current theme and a memoized contrast-color scheme for a given
9
+ * color scheme. Shared by the MSA and text-track canvas blocks.
10
+ */
11
+ export function useColorContrast(colorScheme: Record<string, string>) {
12
+ const theme = useTheme()
13
+ const contrastScheme = useMemo(
14
+ () => colorContrast(colorScheme, theme),
15
+ [colorScheme, theme],
16
+ )
17
+ return { theme, contrastScheme }
18
+ }
@@ -0,0 +1,55 @@
1
+ import { useEffect, useRef, useState } from 'react'
2
+
3
+ /**
4
+ * Tracks a mouse drag along a single axis and reports the scroll delta on each
5
+ * animation frame. Shared by the horizontal Minimap and the VerticalScrollbar.
6
+ *
7
+ * `onScroll` is invoked with the pixel delta since drag start and the scroll
8
+ * offset captured when the drag began. Memoize it (useCallback) so the document
9
+ * listeners are not re-attached on every render.
10
+ */
11
+ export function useDragScroll(
12
+ axis: 'x' | 'y',
13
+ onScroll: (delta: number, startScroll: number) => void,
14
+ ) {
15
+ const scheduled = useRef(false)
16
+ const [mouseDown, setMouseDown] = useState<{
17
+ client: number
18
+ startScroll: number
19
+ }>()
20
+
21
+ useEffect(() => {
22
+ if (mouseDown !== undefined) {
23
+ const { client: startClient, startScroll } = mouseDown
24
+ function onMove(event: MouseEvent) {
25
+ if (!scheduled.current) {
26
+ scheduled.current = true
27
+ requestAnimationFrame(() => {
28
+ const client = axis === 'x' ? event.clientX : event.clientY
29
+ onScroll(client - startClient, startScroll)
30
+ scheduled.current = false
31
+ })
32
+ }
33
+ }
34
+ function onUp() {
35
+ setMouseDown(undefined)
36
+ }
37
+ document.addEventListener('mousemove', onMove)
38
+ document.addEventListener('mouseup', onUp)
39
+ return () => {
40
+ document.removeEventListener('mousemove', onMove)
41
+ document.removeEventListener('mouseup', onUp)
42
+ }
43
+ }
44
+ }, [axis, onScroll, mouseDown])
45
+
46
+ return {
47
+ dragging: mouseDown !== undefined,
48
+ startDrag: (event: React.MouseEvent, startScroll: number) => {
49
+ setMouseDown({
50
+ client: axis === 'x' ? event.clientX : event.clientY,
51
+ startScroll,
52
+ })
53
+ },
54
+ }
55
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '5.0.16'
1
+ export const version = '5.1.0'