react-msaview 5.1.0 → 5.2.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/bundle/index.js +35 -135
- package/bundle/index.js.map +1 -1
- package/dist/calculateBlocks.d.ts +4 -10
- package/dist/calculateBlocks.js +12 -20
- package/dist/calculateBlocks.js.map +1 -1
- package/dist/components/ConservationTrack.js +18 -24
- package/dist/components/ConservationTrack.js.map +1 -1
- package/dist/components/TextTrack.js +24 -34
- package/dist/components/TextTrack.js.map +1 -1
- package/dist/components/dialogs/ExportSVGDialog.js +20 -20
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/dialogs/InterProScanDialog.js +6 -1
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
- package/dist/components/header/FileMenu.js +2 -1
- package/dist/components/header/FileMenu.js.map +1 -1
- package/dist/components/header/Header.js +1 -1
- package/dist/components/header/settingsMenuItems.js +24 -8
- package/dist/components/header/settingsMenuItems.js.map +1 -1
- package/dist/components/minimap/Minimap.js +1 -6
- package/dist/components/minimap/Minimap.js.map +1 -1
- package/dist/components/minimap/MinimapSVG.js +4 -8
- package/dist/components/minimap/MinimapSVG.js.map +1 -1
- package/dist/components/msa/getVisibleLeaves.d.ts +6 -0
- package/dist/components/msa/getVisibleLeaves.js +9 -0
- package/dist/components/msa/getVisibleLeaves.js.map +1 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +2 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +5 -6
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.d.ts +2 -1
- package/dist/components/msa/renderMSABlock.js +98 -84
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/components/msa/renderMSAMouseover.js +3 -3
- package/dist/components/msa/renderMSAMouseover.js.map +1 -1
- package/dist/components/msa/visibleColRange.d.ts +8 -0
- package/dist/components/msa/visibleColRange.js +10 -0
- package/dist/components/msa/visibleColRange.js.map +1 -0
- package/dist/components/renderCtx.d.ts +7 -0
- package/dist/components/renderCtx.js +2 -0
- package/dist/components/renderCtx.js.map +1 -0
- package/dist/components/tracks/renderTracksSvg.d.ts +6 -5
- package/dist/components/tracks/renderTracksSvg.js +11 -4
- package/dist/components/tracks/renderTracksSvg.js.map +1 -1
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +2 -10
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.d.ts +5 -4
- package/dist/components/tree/renderTreeCanvas.js +16 -24
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/components/util.d.ts +0 -14
- package/dist/components/util.js +0 -58
- package/dist/components/util.js.map +1 -1
- package/dist/hierarchy.d.ts +2 -0
- package/dist/hierarchy.js +19 -0
- package/dist/hierarchy.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +26 -30
- package/dist/model.js +74 -82
- package/dist/model.js.map +1 -1
- package/dist/renderToSvg.d.ts +1 -1
- package/dist/renderToSvg.js +20 -26
- package/dist/renderToSvg.js.map +1 -1
- package/dist/rowCoordinateCalculations.d.ts +0 -9
- package/dist/rowCoordinateCalculations.js +0 -20
- package/dist/rowCoordinateCalculations.js.map +1 -1
- package/dist/util.d.ts +1 -0
- package/dist/util.js +23 -1
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
- package/src/calculateBlocks.ts +18 -51
- package/src/components/ConservationTrack.tsx +18 -27
- package/src/components/TextTrack.tsx +30 -38
- package/src/components/dialogs/ExportSVGDialog.tsx +27 -17
- package/src/components/dialogs/InterProScanDialog.tsx +6 -1
- package/src/components/header/FileMenu.tsx +2 -1
- package/src/components/header/Header.tsx +1 -1
- package/src/components/header/settingsMenuItems.ts +24 -8
- package/src/components/minimap/Minimap.tsx +1 -6
- package/src/components/minimap/MinimapSVG.tsx +4 -8
- package/src/components/msa/getVisibleLeaves.ts +21 -0
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +9 -9
- package/src/components/msa/renderMSABlock.ts +119 -118
- package/src/components/msa/renderMSAMouseover.ts +2 -3
- package/src/components/msa/visibleColRange.ts +17 -0
- package/src/components/renderCtx.ts +29 -0
- package/src/components/tracks/renderTracksSvg.ts +18 -9
- package/src/components/tree/TreeCanvas.tsx +3 -1
- package/src/components/tree/TreeCanvasBlock.tsx +2 -12
- package/src/components/tree/renderTreeCanvas.ts +25 -28
- package/src/components/util.ts +0 -81
- package/src/hierarchy.ts +27 -0
- package/src/index.ts +7 -0
- package/src/model.ts +81 -98
- package/src/renderToSvg.tsx +23 -31
- package/src/rowCoordinateCalculations.test.ts +0 -51
- package/src/rowCoordinateCalculations.ts +0 -23
- package/src/util.ts +25 -1
- package/src/version.ts +1 -1
package/src/renderToSvg.tsx
CHANGED
|
@@ -19,7 +19,7 @@ export interface ExportSvgOptions {
|
|
|
19
19
|
theme: Theme
|
|
20
20
|
includeMinimap?: boolean
|
|
21
21
|
includeTracks?: boolean
|
|
22
|
-
exportType:
|
|
22
|
+
exportType: 'entire' | 'viewport'
|
|
23
23
|
}
|
|
24
24
|
export async function renderToSvg(model: MsaViewModel, opts: ExportSvgOptions) {
|
|
25
25
|
await when(() => !!model.dataInitialized)
|
|
@@ -41,21 +41,18 @@ export async function renderToSvg(model: MsaViewModel, opts: ExportSvgOptions) {
|
|
|
41
41
|
includeTracks,
|
|
42
42
|
})
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
throw new Error('unknown export type')
|
|
44
|
+
return render({
|
|
45
|
+
width,
|
|
46
|
+
height: height + (includeMinimap ? model.minimapHeight : 0) + trackHeight,
|
|
47
|
+
contentHeight: height,
|
|
48
|
+
trackHeight,
|
|
49
|
+
theme,
|
|
50
|
+
model,
|
|
51
|
+
offsetY: -scrollY,
|
|
52
|
+
offsetX: -scrollX,
|
|
53
|
+
includeMinimap,
|
|
54
|
+
includeTracks,
|
|
55
|
+
})
|
|
59
56
|
}
|
|
60
57
|
|
|
61
58
|
async function render({
|
|
@@ -93,7 +90,7 @@ async function render({
|
|
|
93
90
|
model={model}
|
|
94
91
|
theme={theme}
|
|
95
92
|
offsetX={offsetX}
|
|
96
|
-
|
|
93
|
+
msaAreaWidth={width - model.treeAreaWidth}
|
|
97
94
|
trackHeight={trackHeight}
|
|
98
95
|
/>
|
|
99
96
|
) : null}
|
|
@@ -108,7 +105,7 @@ async function render({
|
|
|
108
105
|
theme={theme}
|
|
109
106
|
offsetX={offsetX}
|
|
110
107
|
offsetY={offsetY}
|
|
111
|
-
|
|
108
|
+
msaAreaWidth={width - model.treeAreaWidth}
|
|
112
109
|
contentHeight={contentHeight}
|
|
113
110
|
/>
|
|
114
111
|
</g>
|
|
@@ -120,7 +117,7 @@ async function render({
|
|
|
120
117
|
function CoreRendering({
|
|
121
118
|
model,
|
|
122
119
|
theme,
|
|
123
|
-
|
|
120
|
+
msaAreaWidth,
|
|
124
121
|
contentHeight,
|
|
125
122
|
offsetX,
|
|
126
123
|
offsetY,
|
|
@@ -128,7 +125,7 @@ function CoreRendering({
|
|
|
128
125
|
}: {
|
|
129
126
|
model: MsaViewModel
|
|
130
127
|
theme: Theme
|
|
131
|
-
|
|
128
|
+
msaAreaWidth: number
|
|
132
129
|
contentHeight: number
|
|
133
130
|
offsetX: number
|
|
134
131
|
offsetY: number
|
|
@@ -139,9 +136,8 @@ function CoreRendering({
|
|
|
139
136
|
const clipId2 = `msa-${id}`
|
|
140
137
|
const contrastScheme = colorContrast(colorScheme, theme)
|
|
141
138
|
|
|
142
|
-
const ctx1 = new Context(
|
|
143
|
-
|
|
144
|
-
const ctx2 = new Context(width, contentHeight) as any
|
|
139
|
+
const ctx1 = new Context(treeAreaWidth, contentHeight)
|
|
140
|
+
const ctx2 = new Context(msaAreaWidth, contentHeight)
|
|
145
141
|
renderBoxFeatureCanvasBlock({
|
|
146
142
|
ctx: ctx2,
|
|
147
143
|
offsetX,
|
|
@@ -150,7 +146,6 @@ function CoreRendering({
|
|
|
150
146
|
blockSizeYOverride: contentHeight,
|
|
151
147
|
highResScaleFactorOverride: 1,
|
|
152
148
|
})
|
|
153
|
-
const msaAreaWidth = width - treeAreaWidth
|
|
154
149
|
renderTreeCanvas({
|
|
155
150
|
model,
|
|
156
151
|
offsetY,
|
|
@@ -176,8 +171,6 @@ function CoreRendering({
|
|
|
176
171
|
<clipPath id={clipId1}>
|
|
177
172
|
<rect x={0} y={0} width={treeAreaWidth} height={contentHeight} />
|
|
178
173
|
</clipPath>
|
|
179
|
-
</defs>
|
|
180
|
-
<defs>
|
|
181
174
|
<clipPath id={clipId2}>
|
|
182
175
|
<rect x={0} y={0} width={msaAreaWidth} height={contentHeight} />
|
|
183
176
|
</clipPath>
|
|
@@ -199,14 +192,14 @@ function CoreRendering({
|
|
|
199
192
|
function TrackRendering({
|
|
200
193
|
model,
|
|
201
194
|
theme,
|
|
202
|
-
|
|
195
|
+
msaAreaWidth,
|
|
203
196
|
trackHeight,
|
|
204
197
|
offsetX,
|
|
205
198
|
Context,
|
|
206
199
|
}: {
|
|
207
200
|
model: MsaViewModel
|
|
208
201
|
theme: Theme
|
|
209
|
-
|
|
202
|
+
msaAreaWidth: number
|
|
210
203
|
trackHeight: number
|
|
211
204
|
offsetX: number
|
|
212
205
|
Context: typeof ContextType
|
|
@@ -214,9 +207,8 @@ function TrackRendering({
|
|
|
214
207
|
const { treeAreaWidth, colorScheme, id } = model
|
|
215
208
|
const clipId = `tracks-${id}`
|
|
216
209
|
const contrastScheme = colorContrast(colorScheme, theme)
|
|
217
|
-
const msaAreaWidth = width - treeAreaWidth
|
|
218
210
|
|
|
219
|
-
const ctx = new Context(msaAreaWidth, trackHeight)
|
|
211
|
+
const ctx = new Context(msaAreaWidth, trackHeight)
|
|
220
212
|
|
|
221
213
|
renderAllTracks({
|
|
222
214
|
model,
|
|
@@ -277,7 +269,7 @@ function SvgWrapper({
|
|
|
277
269
|
height={height}
|
|
278
270
|
xmlns="http://www.w3.org/2000/svg"
|
|
279
271
|
xmlnsXlink="http://www.w3.org/1999/xlink"
|
|
280
|
-
viewBox={
|
|
272
|
+
viewBox={`0 0 ${width} ${height}`}
|
|
281
273
|
>
|
|
282
274
|
{children}
|
|
283
275
|
</svg>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { expect, test } from 'vitest'
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
globalColToSeqPos,
|
|
5
4
|
globalColToVisibleCol,
|
|
6
5
|
visibleColToGlobalCol,
|
|
7
6
|
visibleColToSeqPos,
|
|
@@ -126,56 +125,6 @@ test('globalColToVisibleCol with consecutive blanks', () => {
|
|
|
126
125
|
expect(globalColToVisibleCol(blanks, 10)).toBe(5)
|
|
127
126
|
})
|
|
128
127
|
|
|
129
|
-
// Tests for globalColToSeqPos (global column → sequence position)
|
|
130
|
-
test('globalColToSeqPos with gaps in sequence', () => {
|
|
131
|
-
const sequence = 'AC-GT-A'
|
|
132
|
-
expect(globalColToSeqPos(sequence, 0)).toBe(0)
|
|
133
|
-
expect(globalColToSeqPos(sequence, 1)).toBe(1)
|
|
134
|
-
expect(globalColToSeqPos(sequence, 2)).toBe(2)
|
|
135
|
-
// Position 2 is a gap, so count before it is 2
|
|
136
|
-
expect(globalColToSeqPos(sequence, 3)).toBe(2)
|
|
137
|
-
expect(globalColToSeqPos(sequence, 4)).toBe(3)
|
|
138
|
-
expect(globalColToSeqPos(sequence, 5)).toBe(4)
|
|
139
|
-
// Position 5 is a gap, so count before it is 4
|
|
140
|
-
expect(globalColToSeqPos(sequence, 6)).toBe(4)
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
test('globalColToSeqPos with mixed gap characters (- and .)', () => {
|
|
144
|
-
const sequence = 'AC.GT-A'
|
|
145
|
-
expect(globalColToSeqPos(sequence, 0)).toBe(0)
|
|
146
|
-
expect(globalColToSeqPos(sequence, 1)).toBe(1)
|
|
147
|
-
// Position 2 is a gap (.), so count before it is 2
|
|
148
|
-
expect(globalColToSeqPos(sequence, 2)).toBe(2)
|
|
149
|
-
expect(globalColToSeqPos(sequence, 3)).toBe(2)
|
|
150
|
-
expect(globalColToSeqPos(sequence, 4)).toBe(3)
|
|
151
|
-
// Position 5 is a gap (-), so count before it is 4
|
|
152
|
-
expect(globalColToSeqPos(sequence, 5)).toBe(4)
|
|
153
|
-
expect(globalColToSeqPos(sequence, 6)).toBe(4)
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
test('globalColToSeqPos with no gaps in sequence', () => {
|
|
157
|
-
const sequence = 'ACGTA'
|
|
158
|
-
expect(globalColToSeqPos(sequence, 0)).toBe(0)
|
|
159
|
-
expect(globalColToSeqPos(sequence, 1)).toBe(1)
|
|
160
|
-
expect(globalColToSeqPos(sequence, 2)).toBe(2)
|
|
161
|
-
expect(globalColToSeqPos(sequence, 3)).toBe(3)
|
|
162
|
-
expect(globalColToSeqPos(sequence, 4)).toBe(4)
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
test('globalColToSeqPos with all gaps in sequence', () => {
|
|
166
|
-
const sequence = '-----'
|
|
167
|
-
expect(globalColToSeqPos(sequence, 0)).toBe(0)
|
|
168
|
-
expect(globalColToSeqPos(sequence, 1)).toBe(0)
|
|
169
|
-
expect(globalColToSeqPos(sequence, 2)).toBe(0)
|
|
170
|
-
expect(globalColToSeqPos(sequence, 3)).toBe(0)
|
|
171
|
-
expect(globalColToSeqPos(sequence, 4)).toBe(0)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
test('globalColToSeqPos with position exceeding sequence length', () => {
|
|
175
|
-
const sequence = 'AC-GT'
|
|
176
|
-
expect(globalColToSeqPos(sequence, 10)).toBe(4)
|
|
177
|
-
})
|
|
178
|
-
|
|
179
128
|
// Tests for visibleColToSeqPos (visible column → sequence position)
|
|
180
129
|
test('visibleColToSeqPos returns sequence position or undefined for gaps', () => {
|
|
181
130
|
const seq = 'AC--GT--CT'
|
|
@@ -88,29 +88,6 @@ export function globalColToVisibleCol(
|
|
|
88
88
|
return globalCol - blanksBefore
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
/**
|
|
92
|
-
* Convert a global column index to a row-specific sequence position.
|
|
93
|
-
* This counts non-gap characters up to the given global column.
|
|
94
|
-
*
|
|
95
|
-
* @param seq - The row's sequence string (including gaps)
|
|
96
|
-
* @param globalCol - The global column index
|
|
97
|
-
* @returns The sequence position (count of non-gap characters before this column)
|
|
98
|
-
*/
|
|
99
|
-
export function globalColToSeqPos(seq: string, globalCol: number) {
|
|
100
|
-
let seqPos = 0
|
|
101
|
-
let currentCol = 0
|
|
102
|
-
const seqLen = seq.length
|
|
103
|
-
|
|
104
|
-
while (currentCol < globalCol && currentCol < seqLen) {
|
|
105
|
-
if (!isBlank(seq[currentCol])) {
|
|
106
|
-
seqPos++
|
|
107
|
-
}
|
|
108
|
-
currentCol++
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return seqPos
|
|
112
|
-
}
|
|
113
|
-
|
|
114
91
|
/**
|
|
115
92
|
* Convert a visible column to a row-specific sequence position.
|
|
116
93
|
* Returns undefined if the position is a gap in the sequence.
|
package/src/util.ts
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
import { colord, extend } from 'colord'
|
|
2
|
+
import a11yPlugin from 'colord/plugins/a11y'
|
|
2
3
|
import namesPlugin from 'colord/plugins/names'
|
|
3
4
|
|
|
4
5
|
import type { Theme } from '@mui/material'
|
|
5
6
|
|
|
6
|
-
extend([namesPlugin])
|
|
7
|
+
extend([namesPlugin, a11yPlugin])
|
|
8
|
+
|
|
9
|
+
const contrastAdjustCache = new Map<string, string>()
|
|
10
|
+
|
|
11
|
+
// Adjusts a background-tile color until it meets WCAG AA (4.5:1) contrast
|
|
12
|
+
// against `bg`, so it can be used as letter text in letter-color mode.
|
|
13
|
+
// Darkens on light backgrounds, lightens on dark backgrounds.
|
|
14
|
+
export function adjustColorForContrast(color: string, bg: string): string {
|
|
15
|
+
const cacheKey = `${color}|${bg}`
|
|
16
|
+
const cached = contrastAdjustCache.get(cacheKey)
|
|
17
|
+
if (cached !== undefined) {
|
|
18
|
+
return cached
|
|
19
|
+
}
|
|
20
|
+
let c = colord(color)
|
|
21
|
+
if (!c.isReadable(bg)) {
|
|
22
|
+
const bgIsDark = colord(bg).luminance() < 0.5
|
|
23
|
+
for (let i = 0; i < 40 && !c.isReadable(bg); i++) {
|
|
24
|
+
c = bgIsDark ? c.lighten(0.05) : c.darken(0.05)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const result = c.toHex()
|
|
28
|
+
contrastAdjustCache.set(cacheKey, result)
|
|
29
|
+
return result
|
|
30
|
+
}
|
|
7
31
|
|
|
8
32
|
export function transform<T>(
|
|
9
33
|
obj: Record<string, T>,
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.2.0'
|