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.
- package/LICENSE +21 -0
- package/bundle/index.js +487 -149
- package/bundle/index.js.map +7 -1
- package/dist/colorSchemes.js +11 -7
- package/dist/colorSchemes.js.map +1 -1
- package/dist/components/ConservationTrack.js +20 -26
- package/dist/components/ConservationTrack.js.map +1 -1
- package/dist/components/MSAViewer.d.ts +13 -1
- package/dist/components/MSAViewer.js +13 -7
- package/dist/components/MSAViewer.js.map +1 -1
- package/dist/components/SequenceTextArea.js +1 -1
- package/dist/components/SequenceTextArea.js.map +1 -1
- package/dist/components/TextTrack.js +20 -27
- package/dist/components/TextTrack.js.map +1 -1
- package/dist/components/Track.js +9 -6
- package/dist/components/Track.js.map +1 -1
- package/dist/components/dialogs/FeatureDialog.js +27 -23
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/dialogs/TrackInfoDialog.js +1 -1
- package/dist/components/dialogs/TrackInfoDialog.js.map +1 -1
- package/dist/components/header/ColorSchemeMenu.js +1 -1
- package/dist/components/header/ColorSchemeMenu.js.map +1 -1
- package/dist/components/header/FileMenu.js +1 -16
- package/dist/components/header/FileMenu.js.map +1 -1
- package/dist/components/header/Header.js +6 -5
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderInfoArea.js +1 -1
- package/dist/components/header/HeaderInfoArea.js.map +1 -1
- package/dist/components/header/HeaderStatusArea.js +1 -1
- package/dist/components/header/HeaderStatusArea.js.map +1 -1
- package/dist/components/header/MSASettingsMenu.js +1 -1
- package/dist/components/header/MSASettingsMenu.js.map +1 -1
- package/dist/components/header/MultiAlignmentSelector.js +0 -0
- package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
- package/dist/components/header/TreeSettingsMenu.js +1 -1
- package/dist/components/header/TreeSettingsMenu.js.map +1 -1
- package/dist/components/header/ZoomControls.js +14 -12
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/header/ZoomMenu.js +1 -10
- package/dist/components/header/ZoomMenu.js.map +1 -1
- package/dist/components/header/settingsMenuItems.js +9 -1
- package/dist/components/header/settingsMenuItems.js.map +1 -1
- package/dist/components/{header/HeaderMenu.d.ts → msa/ColumnStats.d.ts} +3 -3
- package/dist/components/msa/ColumnStats.js +42 -0
- package/dist/components/msa/ColumnStats.js.map +1 -0
- package/dist/components/msa/DomainLegend.d.ts +6 -0
- package/dist/components/msa/DomainLegend.js +41 -0
- package/dist/components/msa/DomainLegend.js.map +1 -0
- package/dist/components/msa/MSACanvasBlock.js +41 -29
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js +6 -12
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/msa/MSAPanel.js +3 -1
- package/dist/components/msa/MSAPanel.js.map +1 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +60 -14
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.js +3 -3
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +33 -6
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/overlayColors.d.ts +3 -0
- package/dist/components/overlayColors.js +11 -0
- package/dist/components/overlayColors.js.map +1 -0
- package/dist/components/renderCtx.d.ts +1 -1
- package/dist/components/tracks/renderTracksSvg.d.ts +6 -3
- package/dist/components/tracks/renderTracksSvg.js +20 -11
- package/dist/components/tracks/renderTracksSvg.js.map +1 -1
- package/dist/components/tree/TreeCanvas.js +31 -38
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +12 -47
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/clickMap.d.ts +24 -0
- package/dist/components/tree/clickMap.js +33 -0
- package/dist/components/tree/clickMap.js.map +1 -0
- package/dist/components/tree/renderTreeCanvas.d.ts +1 -21
- package/dist/components/tree/renderTreeCanvas.js +8 -7
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +17 -0
- package/dist/constants.js.map +1 -1
- package/dist/createPaletteMap.d.ts +5 -2
- package/dist/createPaletteMap.js +15 -5
- package/dist/createPaletteMap.js.map +1 -1
- package/dist/fetchUtils.d.ts +2 -1
- package/dist/fetchUtils.js +3 -2
- package/dist/fetchUtils.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/launchInterProScan.d.ts +2 -0
- package/dist/launchInterProScan.js.map +1 -1
- package/dist/model/msaModel.d.ts +25 -2
- package/dist/model/msaModel.js +15 -3
- package/dist/model/msaModel.js.map +1 -1
- package/dist/model/treeModel.d.ts +46 -5
- package/dist/model/treeModel.js +20 -7
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +641 -133
- package/dist/model.js +191 -77
- package/dist/model.js.map +1 -1
- package/dist/propertyConservation.d.ts +7 -0
- package/dist/propertyConservation.js +66 -0
- package/dist/propertyConservation.js.map +1 -0
- package/dist/renderToSvg.js +104 -74
- package/dist/renderToSvg.js.map +1 -1
- package/dist/types.d.ts +4 -1
- package/dist/{webpack.js → umd.js} +1 -1
- package/dist/umd.js.map +1 -0
- package/dist/useCanvasAutorun.d.ts +2 -0
- package/dist/useCanvasAutorun.js +23 -0
- package/dist/useCanvasAutorun.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -8
- package/src/colorSchemes.docs.test.ts +55 -0
- package/src/colorSchemes.ts +12 -7
- package/src/columnStats.test.ts +94 -0
- package/src/components/ConservationTrack.tsx +17 -15
- package/src/components/MSAViewer.tsx +42 -18
- package/src/components/SequenceTextArea.tsx +1 -1
- package/src/components/TextTrack.tsx +7 -11
- package/src/components/Track.tsx +9 -6
- package/src/components/dialogs/FeatureDialog.tsx +62 -48
- package/src/components/dialogs/TrackInfoDialog.tsx +1 -1
- package/src/components/header/ColorSchemeMenu.tsx +1 -0
- package/src/components/header/FileMenu.tsx +1 -15
- package/src/components/header/Header.tsx +11 -8
- package/src/components/header/HeaderInfoArea.tsx +1 -1
- package/src/components/header/HeaderStatusArea.tsx +1 -1
- package/src/components/header/MSASettingsMenu.tsx +1 -0
- package/src/components/header/MultiAlignmentSelector.tsx +0 -0
- package/src/components/header/TreeSettingsMenu.tsx +1 -0
- package/src/components/header/ZoomControls.tsx +24 -17
- package/src/components/header/ZoomMenu.tsx +1 -10
- package/src/components/header/settingsMenuItems.ts +9 -1
- package/src/components/msa/ColumnStats.tsx +54 -0
- package/src/components/msa/DomainLegend.tsx +78 -0
- package/src/components/msa/MSACanvasBlock.tsx +46 -25
- package/src/components/msa/MSAMouseoverCanvas.tsx +10 -13
- package/src/components/msa/MSAPanel.tsx +2 -0
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +75 -17
- package/src/components/msa/renderMSABlock.ts +3 -3
- package/src/components/msa/renderMSAMouseover.ts +34 -6
- package/src/components/overlayColors.ts +12 -0
- package/src/components/renderCtx.ts +1 -0
- package/src/components/tracks/renderTracksSvg.ts +25 -11
- package/src/components/tree/TreeCanvas.tsx +47 -54
- package/src/components/tree/TreeCanvasBlock.tsx +10 -68
- package/src/components/tree/clickMap.ts +55 -0
- package/src/components/tree/renderTreeCanvas.ts +10 -34
- package/src/constants.ts +19 -0
- package/src/createPaletteMap.ts +18 -5
- package/src/fetchUtils.ts +6 -3
- package/src/index.ts +1 -1
- package/src/launchInterProScan.ts +3 -1
- package/src/model/msaModel.ts +21 -3
- package/src/model/treeModel.ts +21 -7
- package/src/model.ts +221 -119
- package/src/propertyConservation.test.ts +47 -0
- package/src/propertyConservation.ts +73 -0
- package/src/renderDomainLegendSvg.test.tsx +134 -0
- package/src/renderToSvg.tsx +210 -147
- package/src/segmentOverlay.test.ts +70 -0
- package/src/stripDefaultSnapshot.test.ts +54 -0
- package/src/types.ts +7 -1
- package/src/useCanvasAutorun.ts +28 -0
- package/src/version.ts +1 -1
- package/bundle/index.js.LICENSE.txt +0 -100
- package/dist/components/dialogs/SettingsDialog.d.ts +0 -7
- package/dist/components/dialogs/SettingsDialog.js +0 -100
- package/dist/components/dialogs/SettingsDialog.js.map +0 -1
- package/dist/components/header/HeaderMenu.js +0 -27
- package/dist/components/header/HeaderMenu.js.map +0 -1
- package/dist/components/util.d.ts +0 -1
- package/dist/components/util.js +0 -7
- package/dist/components/util.js.map +0 -1
- package/dist/webpack.js.map +0 -1
- package/src/components/dialogs/SettingsDialog.tsx +0 -234
- package/src/components/header/HeaderMenu.tsx +0 -38
- package/src/components/util.ts +0 -9
- /package/dist/{webpack.d.ts → umd.d.ts} +0 -0
- /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"}
|
package/dist/renderToSvg.js
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
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
|
|
50
|
-
|
|
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,
|
|
53
|
-
return
|
|
54
|
-
React.createElement("
|
|
55
|
-
|
|
56
|
-
|
|
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,
|
|
94
|
+
function CoreRendering({ model, theme, layout, Context, }) {
|
|
95
|
+
const { contentHeight, offsetX, offsetY, width } = layout;
|
|
59
96
|
const { treeAreaWidth, colorScheme, id } = model;
|
|
60
|
-
const
|
|
61
|
-
const clipId2 = `msa-${id}`;
|
|
97
|
+
const msaAreaWidth = width - treeAreaWidth;
|
|
62
98
|
const contrastScheme = colorContrast(colorScheme, theme);
|
|
63
|
-
const
|
|
64
|
-
|
|
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
|
-
|
|
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
|
-
|
|
85
|
-
offsetX,
|
|
120
|
+
ctx: msaCtx,
|
|
86
121
|
contrastScheme,
|
|
87
|
-
|
|
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(
|
|
94
|
-
|
|
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,
|
|
132
|
+
function TrackRendering({ model, theme, layout, Context, }) {
|
|
133
|
+
const { trackHeight, offsetX, width } = layout;
|
|
107
134
|
const { treeAreaWidth, colorScheme, id } = model;
|
|
108
|
-
const
|
|
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:
|
|
123
|
-
React.createElement(
|
|
124
|
-
|
|
125
|
-
|
|
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
|
package/dist/renderToSvg.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderToSvg.js","sourceRoot":"","sources":["../src/renderToSvg.tsx"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,UAAU,MAAM,oCAAqC,CAAA;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,iDAAiD,CAAA;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;
|
|
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[];
|
package/dist/umd.js.map
ADDED
|
@@ -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,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.
|
|
1
|
+
export declare const version = "5.6.0";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '5.
|
|
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
|
+
"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": "^
|
|
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
|
-
"
|
|
46
|
-
"
|
|
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:
|
|
54
|
-
"build": "pnpm clean && pnpm build:esm && pnpm build:
|
|
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
|
+
})
|
package/src/colorSchemes.ts
CHANGED
|
@@ -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',
|