react-msaview 5.4.1 → 5.6.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 (180) hide show
  1. package/LICENSE +21 -0
  2. package/bundle/index.js +487 -149
  3. package/bundle/index.js.map +7 -1
  4. package/dist/colorSchemes.js +11 -7
  5. package/dist/colorSchemes.js.map +1 -1
  6. package/dist/components/ConservationTrack.js +20 -26
  7. package/dist/components/ConservationTrack.js.map +1 -1
  8. package/dist/components/MSAViewer.d.ts +13 -1
  9. package/dist/components/MSAViewer.js +13 -7
  10. package/dist/components/MSAViewer.js.map +1 -1
  11. package/dist/components/SequenceTextArea.js +1 -1
  12. package/dist/components/SequenceTextArea.js.map +1 -1
  13. package/dist/components/TextTrack.js +20 -27
  14. package/dist/components/TextTrack.js.map +1 -1
  15. package/dist/components/Track.js +9 -6
  16. package/dist/components/Track.js.map +1 -1
  17. package/dist/components/dialogs/FeatureDialog.js +27 -23
  18. package/dist/components/dialogs/FeatureDialog.js.map +1 -1
  19. package/dist/components/dialogs/TrackInfoDialog.js +1 -1
  20. package/dist/components/dialogs/TrackInfoDialog.js.map +1 -1
  21. package/dist/components/header/ColorSchemeMenu.js +1 -1
  22. package/dist/components/header/ColorSchemeMenu.js.map +1 -1
  23. package/dist/components/header/FileMenu.js +1 -16
  24. package/dist/components/header/FileMenu.js.map +1 -1
  25. package/dist/components/header/Header.js +6 -5
  26. package/dist/components/header/Header.js.map +1 -1
  27. package/dist/components/header/HeaderInfoArea.js +1 -1
  28. package/dist/components/header/HeaderInfoArea.js.map +1 -1
  29. package/dist/components/header/HeaderStatusArea.js +1 -1
  30. package/dist/components/header/HeaderStatusArea.js.map +1 -1
  31. package/dist/components/header/MSASettingsMenu.js +1 -1
  32. package/dist/components/header/MSASettingsMenu.js.map +1 -1
  33. package/dist/components/header/MultiAlignmentSelector.js +0 -0
  34. package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
  35. package/dist/components/header/TreeSettingsMenu.js +1 -1
  36. package/dist/components/header/TreeSettingsMenu.js.map +1 -1
  37. package/dist/components/header/ZoomControls.js +14 -12
  38. package/dist/components/header/ZoomControls.js.map +1 -1
  39. package/dist/components/header/ZoomMenu.js +1 -10
  40. package/dist/components/header/ZoomMenu.js.map +1 -1
  41. package/dist/components/header/settingsMenuItems.js +9 -1
  42. package/dist/components/header/settingsMenuItems.js.map +1 -1
  43. package/dist/components/{header/HeaderMenu.d.ts → msa/ColumnStats.d.ts} +3 -3
  44. package/dist/components/msa/ColumnStats.js +42 -0
  45. package/dist/components/msa/ColumnStats.js.map +1 -0
  46. package/dist/components/msa/DomainLegend.d.ts +6 -0
  47. package/dist/components/msa/DomainLegend.js +41 -0
  48. package/dist/components/msa/DomainLegend.js.map +1 -0
  49. package/dist/components/msa/MSACanvasBlock.js +41 -29
  50. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  51. package/dist/components/msa/MSAMouseoverCanvas.js +6 -12
  52. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  53. package/dist/components/msa/MSAPanel.js +3 -1
  54. package/dist/components/msa/MSAPanel.js.map +1 -1
  55. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +60 -14
  56. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  57. package/dist/components/msa/renderMSABlock.js +3 -3
  58. package/dist/components/msa/renderMSABlock.js.map +1 -1
  59. package/dist/components/msa/renderMSAMouseover.js +33 -6
  60. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  61. package/dist/components/overlayColors.d.ts +3 -0
  62. package/dist/components/overlayColors.js +11 -0
  63. package/dist/components/overlayColors.js.map +1 -0
  64. package/dist/components/renderCtx.d.ts +1 -1
  65. package/dist/components/tracks/renderTracksSvg.d.ts +6 -3
  66. package/dist/components/tracks/renderTracksSvg.js +20 -11
  67. package/dist/components/tracks/renderTracksSvg.js.map +1 -1
  68. package/dist/components/tree/TreeCanvas.js +31 -38
  69. package/dist/components/tree/TreeCanvas.js.map +1 -1
  70. package/dist/components/tree/TreeCanvasBlock.js +12 -47
  71. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  72. package/dist/components/tree/clickMap.d.ts +24 -0
  73. package/dist/components/tree/clickMap.js +33 -0
  74. package/dist/components/tree/clickMap.js.map +1 -0
  75. package/dist/components/tree/renderTreeCanvas.d.ts +1 -21
  76. package/dist/components/tree/renderTreeCanvas.js +8 -7
  77. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  78. package/dist/constants.d.ts +4 -0
  79. package/dist/constants.js +17 -0
  80. package/dist/constants.js.map +1 -1
  81. package/dist/createPaletteMap.d.ts +5 -2
  82. package/dist/createPaletteMap.js +15 -5
  83. package/dist/createPaletteMap.js.map +1 -1
  84. package/dist/fetchUtils.d.ts +2 -1
  85. package/dist/fetchUtils.js +3 -2
  86. package/dist/fetchUtils.js.map +1 -1
  87. package/dist/index.d.ts +1 -1
  88. package/dist/launchInterProScan.d.ts +2 -0
  89. package/dist/launchInterProScan.js.map +1 -1
  90. package/dist/model/msaModel.d.ts +25 -2
  91. package/dist/model/msaModel.js +15 -3
  92. package/dist/model/msaModel.js.map +1 -1
  93. package/dist/model/treeModel.d.ts +46 -5
  94. package/dist/model/treeModel.js +20 -7
  95. package/dist/model/treeModel.js.map +1 -1
  96. package/dist/model.d.ts +641 -133
  97. package/dist/model.js +191 -77
  98. package/dist/model.js.map +1 -1
  99. package/dist/propertyConservation.d.ts +7 -0
  100. package/dist/propertyConservation.js +66 -0
  101. package/dist/propertyConservation.js.map +1 -0
  102. package/dist/renderToSvg.js +104 -74
  103. package/dist/renderToSvg.js.map +1 -1
  104. package/dist/types.d.ts +4 -1
  105. package/dist/{webpack.js → umd.js} +1 -1
  106. package/dist/umd.js.map +1 -0
  107. package/dist/useCanvasAutorun.d.ts +2 -0
  108. package/dist/useCanvasAutorun.js +23 -0
  109. package/dist/useCanvasAutorun.js.map +1 -0
  110. package/dist/version.d.ts +1 -1
  111. package/dist/version.js +1 -1
  112. package/package.json +7 -8
  113. package/src/colorSchemes.docs.test.ts +55 -0
  114. package/src/colorSchemes.ts +12 -7
  115. package/src/columnStats.test.ts +94 -0
  116. package/src/components/ConservationTrack.tsx +17 -15
  117. package/src/components/MSAViewer.tsx +42 -18
  118. package/src/components/SequenceTextArea.tsx +1 -1
  119. package/src/components/TextTrack.tsx +7 -11
  120. package/src/components/Track.tsx +9 -6
  121. package/src/components/dialogs/FeatureDialog.tsx +62 -48
  122. package/src/components/dialogs/TrackInfoDialog.tsx +1 -1
  123. package/src/components/header/ColorSchemeMenu.tsx +1 -0
  124. package/src/components/header/FileMenu.tsx +1 -15
  125. package/src/components/header/Header.tsx +11 -8
  126. package/src/components/header/HeaderInfoArea.tsx +1 -1
  127. package/src/components/header/HeaderStatusArea.tsx +1 -1
  128. package/src/components/header/MSASettingsMenu.tsx +1 -0
  129. package/src/components/header/MultiAlignmentSelector.tsx +0 -0
  130. package/src/components/header/TreeSettingsMenu.tsx +1 -0
  131. package/src/components/header/ZoomControls.tsx +24 -17
  132. package/src/components/header/ZoomMenu.tsx +1 -10
  133. package/src/components/header/settingsMenuItems.ts +9 -1
  134. package/src/components/msa/ColumnStats.tsx +54 -0
  135. package/src/components/msa/DomainLegend.tsx +78 -0
  136. package/src/components/msa/MSACanvasBlock.tsx +46 -25
  137. package/src/components/msa/MSAMouseoverCanvas.tsx +10 -13
  138. package/src/components/msa/MSAPanel.tsx +2 -0
  139. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +75 -17
  140. package/src/components/msa/renderMSABlock.ts +3 -3
  141. package/src/components/msa/renderMSAMouseover.ts +34 -6
  142. package/src/components/overlayColors.ts +12 -0
  143. package/src/components/renderCtx.ts +1 -0
  144. package/src/components/tracks/renderTracksSvg.ts +25 -11
  145. package/src/components/tree/TreeCanvas.tsx +47 -54
  146. package/src/components/tree/TreeCanvasBlock.tsx +10 -68
  147. package/src/components/tree/clickMap.ts +55 -0
  148. package/src/components/tree/renderTreeCanvas.ts +10 -34
  149. package/src/constants.ts +19 -0
  150. package/src/createPaletteMap.ts +18 -5
  151. package/src/fetchUtils.ts +6 -3
  152. package/src/index.ts +1 -1
  153. package/src/launchInterProScan.ts +3 -1
  154. package/src/model/msaModel.ts +21 -3
  155. package/src/model/treeModel.ts +21 -7
  156. package/src/model.ts +221 -119
  157. package/src/propertyConservation.test.ts +47 -0
  158. package/src/propertyConservation.ts +73 -0
  159. package/src/renderDomainLegendSvg.test.tsx +134 -0
  160. package/src/renderToSvg.tsx +210 -147
  161. package/src/segmentOverlay.test.ts +70 -0
  162. package/src/stripDefaultSnapshot.test.ts +54 -0
  163. package/src/types.ts +7 -1
  164. package/src/useCanvasAutorun.ts +28 -0
  165. package/src/version.ts +1 -1
  166. package/bundle/index.js.LICENSE.txt +0 -100
  167. package/dist/components/dialogs/SettingsDialog.d.ts +0 -7
  168. package/dist/components/dialogs/SettingsDialog.js +0 -100
  169. package/dist/components/dialogs/SettingsDialog.js.map +0 -1
  170. package/dist/components/header/HeaderMenu.js +0 -27
  171. package/dist/components/header/HeaderMenu.js.map +0 -1
  172. package/dist/components/util.d.ts +0 -1
  173. package/dist/components/util.js +0 -7
  174. package/dist/components/util.js.map +0 -1
  175. package/dist/webpack.js.map +0 -1
  176. package/src/components/dialogs/SettingsDialog.tsx +0 -234
  177. package/src/components/header/HeaderMenu.tsx +0 -38
  178. package/src/components/util.ts +0 -9
  179. /package/dist/{webpack.d.ts → umd.d.ts} +0 -0
  180. /package/src/{webpack.ts → umd.ts} +0 -0
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Per-column property conservation using Shannon entropy over physicochemical
3
+ * classes rather than exact residues. Returns 0-1 where 1 = every non-gap
4
+ * residue shares one property class. Mirrors the identity-conservation formula
5
+ * so the two tracks are directly comparable: (1 - H/Hmax) * (1 - gapFraction).
6
+ */
7
+ export declare function calculatePropertyConservation(colStats: Record<string, number>[], colStatsSums: number[]): number[];
@@ -0,0 +1,66 @@
1
+ // Disjoint physicochemical classes for the 20 standard amino acids. Property
2
+ // conservation asks a different question than identity conservation: a column
3
+ // can vary in exact residue yet stay within one property class (a conservative
4
+ // substitution), which often marks a functionally constrained site that plain
5
+ // identity conservation reports as variable.
6
+ //
7
+ // Histidine is grouped with the aromatics (it is only weakly/conditionally
8
+ // positive at physiological pH); this mirrors common substitution-class schemes.
9
+ const aminoPropertyClass = {
10
+ A: 'hydrophobic',
11
+ V: 'hydrophobic',
12
+ L: 'hydrophobic',
13
+ I: 'hydrophobic',
14
+ M: 'hydrophobic',
15
+ C: 'hydrophobic',
16
+ F: 'aromatic',
17
+ W: 'aromatic',
18
+ Y: 'aromatic',
19
+ H: 'aromatic',
20
+ K: 'positive',
21
+ R: 'positive',
22
+ D: 'negative',
23
+ E: 'negative',
24
+ S: 'polar',
25
+ T: 'polar',
26
+ N: 'polar',
27
+ Q: 'polar',
28
+ G: 'special',
29
+ P: 'special',
30
+ };
31
+ const numPropertyClasses = new Set(Object.values(aminoPropertyClass)).size;
32
+ const maxPropertyEntropy = Math.log2(numPropertyClasses);
33
+ /**
34
+ * Per-column property conservation using Shannon entropy over physicochemical
35
+ * classes rather than exact residues. Returns 0-1 where 1 = every non-gap
36
+ * residue shares one property class. Mirrors the identity-conservation formula
37
+ * so the two tracks are directly comparable: (1 - H/Hmax) * (1 - gapFraction).
38
+ */
39
+ export function calculatePropertyConservation(colStats, colStatsSums) {
40
+ return colStats.map((stats, i) => {
41
+ const total = colStatsSums[i];
42
+ if (!total) {
43
+ return 0;
44
+ }
45
+ let nonGapTotal = 0;
46
+ const classCounts = {};
47
+ for (const [letter, count] of Object.entries(stats)) {
48
+ const cls = aminoPropertyClass[letter];
49
+ if (cls) {
50
+ classCounts[cls] = (classCounts[cls] ?? 0) + count;
51
+ nonGapTotal += count;
52
+ }
53
+ }
54
+ if (nonGapTotal === 0) {
55
+ return 0;
56
+ }
57
+ let entropy = 0;
58
+ for (const count of Object.values(classCounts)) {
59
+ const freq = count / nonGapTotal;
60
+ entropy -= freq * Math.log2(freq);
61
+ }
62
+ const gapFraction = (total - nonGapTotal) / total;
63
+ return Math.max(0, 1 - entropy / maxPropertyEntropy) * (1 - gapFraction);
64
+ });
65
+ }
66
+ //# sourceMappingURL=propertyConservation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"propertyConservation.js","sourceRoot":"","sources":["../src/propertyConservation.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAC9E,6CAA6C;AAC7C,EAAE;AACF,2EAA2E;AAC3E,iFAAiF;AACjF,MAAM,kBAAkB,GAA2B;IACjD,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,SAAS;IACZ,CAAC,EAAE,SAAS;CACb,CAAA;AAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAA;AAC1E,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;AAExD;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAAkC,EAClC,YAAsB;IAEtB,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;QAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,CAAA;QACV,CAAC;QAED,IAAI,WAAW,GAAG,CAAC,CAAA;QACnB,MAAM,WAAW,GAA2B,EAAE,CAAA;QAC9C,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,MAAM,GAAG,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;YACtC,IAAI,GAAG,EAAE,CAAC;gBACR,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAA;gBAClD,WAAW,IAAI,KAAK,CAAA;YACtB,CAAC;QACH,CAAC;QACD,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,CAAA;QACV,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,GAAG,KAAK,GAAG,WAAW,CAAA;YAChC,OAAO,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnC,CAAC;QAED,MAAM,WAAW,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,KAAK,CAAA;QACjD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,CAAA;IAC1E,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -8,123 +8,153 @@ import { renderMSABlock } from "./components/msa/renderMSABlock.js";
8
8
  import { renderAllTracks } from "./components/tracks/renderTracksSvg.js";
9
9
  import { renderTreeCanvas } from "./components/tree/renderTreeCanvas.js";
10
10
  import { colorContrast } from "./util.js";
11
- export async function renderToSvg(model, opts) {
12
- await when(() => model.dataInitialized);
13
- const { width, height, scrollX, scrollY, totalTrackAreaHeight, minimapHeight, } = model;
14
- const { exportType, theme, includeTracks } = opts;
15
- const trackHeight = includeTracks ? totalTrackAreaHeight : 0;
11
+ // domain-legend geometry, shared by the width calculation and the renderer so
12
+ // the reserved column on the right exactly fits the drawn legend
13
+ const LEGEND_PAD = 8;
14
+ const LEGEND_ROW_H = 16;
15
+ const LEGEND_SWATCH = 12;
16
+ const LEGEND_FONT = 12;
17
+ const LEGEND_CHAR_W = 7;
18
+ function getLegendWidth(model) {
19
+ const names = model.visibleDomainTypes.map(d => d.name);
20
+ const maxLen = Math.max(0, ...names.map(n => n.length));
21
+ const w = LEGEND_PAD * 2 + LEGEND_SWATCH + 6 + maxLen * LEGEND_CHAR_W;
22
+ return Math.min(360, Math.max(120, w));
23
+ }
24
+ function getLayout(model, opts) {
25
+ const { width, height, scrollX, scrollY, totalWidth, totalHeight, treeAreaWidth, totalTrackAreaHeight, minimapHeight, } = model;
26
+ const trackHeight = opts.includeTracks ? totalTrackAreaHeight : 0;
16
27
  // the minimap reflects the live viewport scroll position, so it's only
17
28
  // meaningful for a viewport export, never for the entire alignment
18
- const includeMinimap = exportType === 'viewport' && !!opts.includeMinimap;
19
- if (exportType === 'entire') {
20
- return render({
21
- width: model.totalWidth + model.treeAreaWidth,
22
- height: model.totalHeight + trackHeight,
23
- contentHeight: model.totalHeight,
29
+ const includeMinimap = opts.exportType === 'viewport' && !!opts.includeMinimap;
30
+ const legendWidth = model.actuallyShowDomains && model.visibleDomainTypes.length > 0
31
+ ? getLegendWidth(model)
32
+ : 0;
33
+ // width stays content-only (the renderers derive msaAreaWidth from it); the
34
+ // legend occupies an extra column added at the svg root in MsaSvg
35
+ return opts.exportType === 'entire'
36
+ ? {
37
+ width: totalWidth + treeAreaWidth,
38
+ height: totalHeight + trackHeight,
39
+ contentHeight: totalHeight,
24
40
  trackHeight,
25
- theme,
26
- model,
27
- offsetY: 0,
28
41
  offsetX: 0,
42
+ offsetY: 0,
29
43
  includeMinimap,
30
- includeTracks,
31
- });
32
- }
33
- return render({
34
- width,
35
- height: height + (includeMinimap ? minimapHeight : 0) + trackHeight,
36
- contentHeight: height,
37
- trackHeight,
38
- theme,
39
- model,
40
- offsetY: -scrollY,
41
- offsetX: -scrollX,
42
- includeMinimap,
43
- includeTracks,
44
- });
44
+ legendWidth,
45
+ }
46
+ : {
47
+ width,
48
+ height: height + (includeMinimap ? minimapHeight : 0) + trackHeight,
49
+ contentHeight: height,
50
+ trackHeight,
51
+ offsetX: -scrollX,
52
+ offsetY: -scrollY,
53
+ includeMinimap,
54
+ legendWidth,
55
+ };
45
56
  }
46
- async function render({ width, height, contentHeight, trackHeight, offsetX, offsetY, theme, model, includeMinimap, includeTracks, }) {
57
+ export async function renderToSvg(model, opts) {
58
+ await when(() => model.dataInitialized);
47
59
  const { Context } = await import('@jbrowse/svgcanvas');
60
+ return renderToStaticMarkup(React.createElement(MsaSvg, { model: model, theme: opts.theme, Context: Context, layout: getLayout(model, opts) }));
61
+ }
62
+ function MsaSvg({ model, theme, Context, layout, }) {
63
+ const { width, height, trackHeight, includeMinimap, legendWidth } = layout;
48
64
  const { treeAreaWidth, minimapHeight } = model;
49
- const content = (React.createElement(React.Fragment, null,
50
- includeTracks && trackHeight > 0 ? (React.createElement(TrackRendering, { Context: Context, model: model, theme: theme, offsetX: offsetX, msaAreaWidth: width - treeAreaWidth, trackHeight: trackHeight })) : null,
65
+ const totalWidth = width + legendWidth;
66
+ const legendTop = includeMinimap ? minimapHeight : 0;
67
+ const body = (React.createElement(React.Fragment, null,
68
+ trackHeight > 0 ? (React.createElement(TrackRendering, { Context: Context, model: model, theme: theme, layout: layout })) : null,
51
69
  React.createElement("g", { transform: trackHeight > 0 ? `translate(0 ${trackHeight})` : undefined },
52
- React.createElement(CoreRendering, { Context: Context, model: model, theme: theme, offsetX: offsetX, offsetY: offsetY, msaAreaWidth: width - treeAreaWidth, contentHeight: contentHeight }))));
53
- return renderToStaticMarkup(React.createElement(SvgWrapper, { width: width, height: height }, includeMinimap ? (React.createElement(React.Fragment, null,
54
- React.createElement("g", { transform: `translate(${treeAreaWidth} 0)` },
55
- React.createElement(MinimapSVG, { model: model })),
56
- React.createElement("g", { transform: `translate(0 ${minimapHeight})` }, content))) : (content)));
70
+ React.createElement(CoreRendering, { Context: Context, model: model, theme: theme, layout: layout }))));
71
+ return (React.createElement("svg", { width: totalWidth, height: height, xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", viewBox: `0 0 ${totalWidth} ${height}` },
72
+ React.createElement("rect", { width: "100%", height: "100%", fill: "white" }),
73
+ includeMinimap ? (React.createElement(React.Fragment, null,
74
+ React.createElement("g", { transform: `translate(${treeAreaWidth} 0)` },
75
+ React.createElement(MinimapSVG, { model: model })),
76
+ React.createElement("g", { transform: `translate(0 ${minimapHeight})` }, body))) : (body),
77
+ legendWidth > 0 ? (React.createElement("g", { transform: `translate(${width} ${legendTop})` },
78
+ React.createElement(LegendSVG, { model: model, width: legendWidth }))) : null));
79
+ }
80
+ // the domain color key drawn as a reserved column to the right of the
81
+ // alignment, mirroring the on-screen DomainLegend overlay
82
+ function LegendSVG({ model, width }) {
83
+ const { visibleDomainTypes, fillPalette, strokePalette } = model;
84
+ const boxHeight = LEGEND_PAD * 2 + visibleDomainTypes.length * LEGEND_ROW_H;
85
+ return (React.createElement("g", null,
86
+ React.createElement("rect", { x: 0, y: 0, width: width - 4, height: boxHeight, fill: "white", stroke: "#ccc", rx: 2 }),
87
+ visibleDomainTypes.map((d, i) => {
88
+ const y = LEGEND_PAD + i * LEGEND_ROW_H;
89
+ return (React.createElement("g", { key: d.accession },
90
+ React.createElement("rect", { x: LEGEND_PAD, y: y, width: LEGEND_SWATCH, height: LEGEND_SWATCH, fill: fillPalette[d.accession], stroke: strokePalette[d.accession] }),
91
+ React.createElement("text", { x: LEGEND_PAD + LEGEND_SWATCH + 6, y: y + LEGEND_SWATCH - 1, fontSize: LEGEND_FONT }, d.name)));
92
+ })));
57
93
  }
58
- function CoreRendering({ model, theme, msaAreaWidth, contentHeight, offsetX, offsetY, Context, }) {
94
+ function CoreRendering({ model, theme, layout, Context, }) {
95
+ const { contentHeight, offsetX, offsetY, width } = layout;
59
96
  const { treeAreaWidth, colorScheme, id } = model;
60
- const clipId1 = `tree-${id}`;
61
- const clipId2 = `msa-${id}`;
97
+ const msaAreaWidth = width - treeAreaWidth;
62
98
  const contrastScheme = colorContrast(colorScheme, theme);
63
- const ctx1 = new Context(treeAreaWidth, contentHeight);
64
- const ctx2 = new Context(msaAreaWidth, contentHeight);
65
- renderBoxFeatureCanvasBlock({
66
- ctx: ctx2,
67
- offsetX,
68
- offsetY,
99
+ const treeCtx = new Context(treeAreaWidth, contentHeight);
100
+ renderTreeCanvas({
69
101
  model,
102
+ theme,
103
+ ctx: treeCtx,
104
+ offsetY,
70
105
  blockSizeYOverride: contentHeight,
71
106
  highResScaleFactorOverride: 1,
72
107
  });
73
- renderTreeCanvas({
108
+ const msaCtx = new Context(msaAreaWidth, contentHeight);
109
+ renderBoxFeatureCanvasBlock({
74
110
  model,
111
+ ctx: msaCtx,
112
+ offsetX,
75
113
  offsetY,
76
- ctx: ctx1,
77
- theme,
78
114
  blockSizeYOverride: contentHeight,
79
115
  highResScaleFactorOverride: 1,
80
116
  });
81
117
  renderMSABlock({
82
118
  model,
83
119
  theme,
84
- offsetY,
85
- offsetX,
120
+ ctx: msaCtx,
86
121
  contrastScheme,
87
- ctx: ctx2,
122
+ offsetX,
123
+ offsetY,
88
124
  blockSizeXOverride: msaAreaWidth,
89
125
  blockSizeYOverride: contentHeight,
90
126
  highResScaleFactorOverride: 1,
91
127
  });
92
128
  return (React.createElement(React.Fragment, null,
93
- React.createElement("defs", null,
94
- React.createElement("clipPath", { id: clipId1 },
95
- React.createElement("rect", { x: 0, y: 0, width: treeAreaWidth, height: contentHeight })),
96
- React.createElement("clipPath", { id: clipId2 },
97
- React.createElement("rect", { x: 0, y: 0, width: msaAreaWidth, height: contentHeight }))),
98
- React.createElement(ClipGroup, { clipId: clipId1, html: ctx1.getSvg().innerHTML }),
99
- React.createElement(ClipGroup, { clipId: clipId2, transform: `translate(${treeAreaWidth} 0)`, html: ctx2.getSvg().innerHTML })));
100
- }
101
- // Wraps SVG markup produced by a svgcanvas Context in a clipped group. The
102
- // markup is injected verbatim since it's already serialized SVG, not React.
103
- function ClipGroup({ clipId, html, transform, }) {
104
- return (React.createElement("g", { clipPath: `url(#${clipId})`, transform: transform, dangerouslySetInnerHTML: { __html: html } }));
129
+ React.createElement(ClipGroup, { clipId: `tree-${id}`, width: treeAreaWidth, height: contentHeight, ctx: treeCtx }),
130
+ React.createElement(ClipGroup, { clipId: `msa-${id}`, width: msaAreaWidth, height: contentHeight, transform: `translate(${treeAreaWidth} 0)`, ctx: msaCtx })));
105
131
  }
106
- function TrackRendering({ model, theme, msaAreaWidth, trackHeight, offsetX, Context, }) {
132
+ function TrackRendering({ model, theme, layout, Context, }) {
133
+ const { trackHeight, offsetX, width } = layout;
107
134
  const { treeAreaWidth, colorScheme, id } = model;
108
- const clipId = `tracks-${id}`;
135
+ const msaAreaWidth = width - treeAreaWidth;
109
136
  const contrastScheme = colorContrast(colorScheme, theme);
110
137
  const ctx = new Context(msaAreaWidth, trackHeight);
111
138
  renderAllTracks({
112
139
  model,
113
140
  ctx,
114
- offsetX,
115
141
  contrastScheme,
142
+ offsetX,
116
143
  blockSizeXOverride: msaAreaWidth,
117
144
  highResScaleFactorOverride: 1,
118
145
  });
119
146
  return (React.createElement("g", { transform: `translate(${treeAreaWidth} 0)` },
147
+ React.createElement(ClipGroup, { clipId: `tracks-${id}`, width: msaAreaWidth, height: trackHeight, ctx: ctx })));
148
+ }
149
+ // Clips a svgcanvas Context to its box and injects its markup verbatim (it is
150
+ // already serialized SVG, not React).
151
+ function ClipGroup({ clipId, width, height, transform, ctx, }) {
152
+ return (React.createElement(React.Fragment, null,
120
153
  React.createElement("defs", null,
121
154
  React.createElement("clipPath", { id: clipId },
122
- React.createElement("rect", { x: 0, y: 0, width: msaAreaWidth, height: trackHeight }))),
123
- React.createElement(ClipGroup, { clipId: clipId, html: ctx.getSvg().innerHTML })));
124
- }
125
- function SvgWrapper({ width, height, children, }) {
126
- return (React.createElement("svg", { width: width, height: height, xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", viewBox: `0 0 ${width} ${height}` },
127
- React.createElement("rect", { width: "100%", height: "100%", fill: "white" }),
128
- children));
155
+ React.createElement("rect", { x: 0, y: 0, width: width, height: height }))),
156
+ React.createElement("g", { clipPath: `url(#${clipId})`, transform: transform,
157
+ // eslint-disable-next-line @eslint-react/dom-no-dangerously-set-innerhtml
158
+ dangerouslySetInnerHTML: { __html: ctx.getSvg().innerHTML } })));
129
159
  }
130
160
  //# sourceMappingURL=renderToSvg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderToSvg.js","sourceRoot":"","sources":["../src/renderToSvg.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderToSvg.js","sourceRoot":"","sources":["../src/renderToSvg.tsx"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -13,9 +13,12 @@ export interface TextTrackModel extends BasicTrackModel {
13
13
  customColorScheme?: Record<string, string>;
14
14
  data?: string;
15
15
  }
16
+ export interface BarTrackModel extends BasicTrackModel {
17
+ barColor?: string;
18
+ }
16
19
  export interface BasicTrack {
17
20
  ReactComponent: React.FC<any>;
18
- model: TextTrackModel;
21
+ model: TextTrackModel & BarTrackModel;
19
22
  }
20
23
  export interface Node {
21
24
  children?: Node[];
@@ -3,4 +3,4 @@ export { default as MSAView } from "./components/Loading.js";
3
3
  export { default as MSAModelF } from "./model.js";
4
4
  export * from 'react-dom/client';
5
5
  export { React };
6
- //# sourceMappingURL=webpack.js.map
6
+ //# sourceMappingURL=umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"umd.js","sourceRoot":"","sources":["../src/umd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAA0B,CAAA;AAC7D,OAAO,EAAqB,OAAO,IAAI,SAAS,EAAE,MAAM,YAAY,CAAA;AAEpE,cAAc,kBAAkB,CAAA;AAEhC,OAAO,EAAE,KAAK,EAAE,CAAA"}
@@ -0,0 +1,2 @@
1
+ import type React from 'react';
2
+ export declare function useCanvasAutorun(draw: (ctx: CanvasRenderingContext2D) => void, deps: React.DependencyList): React.RefObject<HTMLCanvasElement | null>;
@@ -0,0 +1,23 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { autorun } from 'mobx';
3
+ // Wires a canvas ref to a mobx autorun: grabs the 2d context once the canvas
4
+ // mounts and re-runs `draw` whenever any observable it reads changes. Collapses
5
+ // the getContext/null-guard/autorun-dispose boilerplate repeated by every
6
+ // canvas block host. `deps` controls when the effect (and thus the context
7
+ // lookup) is torn down and re-created, matching a normal useEffect dep array.
8
+ export function useCanvasAutorun(draw, deps) {
9
+ const ref = useRef(null);
10
+ // the autorun tracks its own observable reads, so `draw` is intentionally not
11
+ // a dependency; `deps` alone controls when the effect re-subscribes
12
+ useEffect(() => {
13
+ const ctx = ref.current?.getContext('2d');
14
+ return ctx
15
+ ? autorun(() => {
16
+ draw(ctx);
17
+ })
18
+ : undefined;
19
+ // eslint-disable-next-line @eslint-react/exhaustive-deps
20
+ }, deps);
21
+ return ref;
22
+ }
23
+ //# sourceMappingURL=useCanvasAutorun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCanvasAutorun.js","sourceRoot":"","sources":["../src/useCanvasAutorun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE9B,6EAA6E;AAC7E,gFAAgF;AAChF,0EAA0E;AAC1E,2EAA2E;AAC3E,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAC9B,IAA6C,EAC7C,IAA0B;IAE1B,MAAM,GAAG,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IAC3C,8EAA8E;IAC9E,oEAAoE;IACpE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAA;QACzC,OAAO,GAAG;YACR,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;gBACX,IAAI,CAAC,GAAG,CAAC,CAAA;YACX,CAAC,CAAC;YACJ,CAAC,CAAC,SAAS,CAAA;QACb,yDAAyD;IAC3D,CAAC,EAAE,IAAI,CAAC,CAAA;IACR,OAAO,GAAG,CAAA;AACZ,CAAC"}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.4.1";
1
+ export declare const version = "5.6.0";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '5.4.1';
1
+ export const version = '5.6.0';
2
2
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-msaview",
3
3
  "author": "Colin",
4
- "version": "5.4.1",
4
+ "version": "5.6.0",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "repository": {
@@ -35,23 +35,22 @@
35
35
  "react-dom": ">=16.8.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@types/node": "^25.9.4"
38
+ "@types/node": "^26.1.1",
39
+ "esbuild": "^0.28.1"
39
40
  },
40
41
  "dependencies": {
41
- "@mui/icons-material": "^7.3.11",
42
- "@mui/material": "^7.3.11",
43
42
  "colord": "^2.9.3",
44
43
  "flatbush": "^4.6.2",
45
- "@jbrowse/svgcanvas": "5.4.1",
46
- "msa-parsers": "5.4.1"
44
+ "msa-parsers": "5.6.0",
45
+ "@jbrowse/svgcanvas": "5.6.0"
47
46
  },
48
47
  "scripts": {
49
48
  "clean": "rimraf dist bundle",
50
49
  "watch": "pnpm build:esm --watch",
51
50
  "format": "prettier --write .",
52
51
  "build:esm": "tsc --project tsconfig.build.json",
53
- "build:bundle": "webpack",
54
- "build": "pnpm clean && pnpm build:esm && pnpm build:bundle",
52
+ "build:umd": "node esbuild.mjs",
53
+ "build": "pnpm clean && pnpm build:esm && pnpm build:umd",
55
54
  "statedocs": "rm -rf apidocs && mkdir apidocs && node --experimental-strip-types docgen/generateStateModelDocs.ts",
56
55
  "poststatedocs": "pnpm format",
57
56
  "test": "vitest"
@@ -0,0 +1,55 @@
1
+ import { readFileSync } from 'node:fs'
2
+
3
+ import { expect, test } from 'vitest'
4
+
5
+ import colorSchemes from './colorSchemes.ts'
6
+
7
+ // Guard against doc drift: every color-scheme name listed in the JS embedding
8
+ // docs (USAGE.md) must be a real registered scheme, so a rename or removal in
9
+ // colorSchemes.ts can't silently leave a dead name in the docs that users copy.
10
+ // (Subset check only — a registered scheme may intentionally go undocumented.)
11
+ test('color schemes listed in USAGE.md all exist', () => {
12
+ const registered = new Set(Object.keys(colorSchemes))
13
+ const usage = readFileSync(
14
+ new URL('../../../USAGE.md', import.meta.url),
15
+ 'utf8',
16
+ )
17
+
18
+ const section = /## Color schemes\n([\s\S]*?)\n## /.exec(usage)?.[1]
19
+ expect(section, 'could not find the "## Color schemes" section').toBeTruthy()
20
+
21
+ // drop the bold labels (**Protein:**, **Dynamic (per-column):**, …), leaving
22
+ // just the comma-separated scheme names
23
+ const names = section!.replace(/\*\*[^*]+\*\*/g, '').match(/[a-z][a-z0-9_]+/g)
24
+ expect(names?.length).toBeGreaterThan(0)
25
+
26
+ const unknown = names!.filter(name => !registered.has(name))
27
+ expect(
28
+ unknown,
29
+ `documented but not registered: ${unknown.join(', ')}`,
30
+ ).toEqual([])
31
+ })
32
+
33
+ // Same guard for the R package docs, whose color_scheme names pass straight
34
+ // through as colorSchemeName with no remapping — a name that isn't registered
35
+ // silently renders with no coloring.
36
+ test('color schemes listed in the R README all exist', () => {
37
+ const registered = new Set(Object.keys(colorSchemes))
38
+ const readme = readFileSync(
39
+ new URL('../../r-msaview/README.md', import.meta.url),
40
+ 'utf8',
41
+ )
42
+
43
+ const section = /## Color schemes\n([\s\S]*?)\n## /.exec(readme)?.[1]
44
+ expect(section, 'could not find the "## Color schemes" section').toBeTruthy()
45
+
46
+ // names are backtick-quoted, e.g. `jalview_taylor`
47
+ const names = [...section!.matchAll(/`([a-z][a-z0-9_]+)`/g)].map(m => m[1])
48
+ expect(names.length).toBeGreaterThan(0)
49
+
50
+ const unknown = names.filter(name => !registered.has(name))
51
+ expect(
52
+ unknown,
53
+ `documented but not registered: ${unknown.join(', ')}`,
54
+ ).toEqual([])
55
+ })
@@ -6,8 +6,19 @@ import { transform } from './util.ts'
6
6
 
7
7
  extend([namesPlugin])
8
8
 
9
+ // standard A/C/G/T(/U) coloring, shared by the `jbrowse_dna` and `nucleotide`
10
+ // scheme names
11
+ const dna = {
12
+ A: green[500],
13
+ C: blue[500],
14
+ G: orange[500],
15
+ T: red[500],
16
+ U: red[500],
17
+ }
18
+
9
19
  const colorSchemes = {
10
20
  none: {},
21
+ nucleotide: dna,
11
22
  clustal: {
12
23
  G: 'orange',
13
24
  P: 'orange',
@@ -135,13 +146,7 @@ const colorSchemes = {
135
146
  T: '#19cc19',
136
147
  U: '#19cc19',
137
148
  },
138
- jbrowse_dna: {
139
- A: green[500],
140
- C: blue[500],
141
- G: orange[500],
142
- T: red[500],
143
- U: red[500],
144
- },
149
+ jbrowse_dna: dna,
145
150
  jalview_buried: {
146
151
  A: '#00a35c',
147
152
  R: '#00fc03',