react-msaview 4.3.0 → 4.4.1
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 +15 -15
- package/bundle/index.js.LICENSE.txt +1 -9
- package/bundle/index.js.map +1 -1
- package/dist/colorSchemes.js +2 -2
- package/dist/colorSchemes.js.map +1 -1
- package/dist/components/VerticalScrollbar.js +2 -2
- package/dist/components/VerticalScrollbar.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.js +1 -1
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/header/{SettingsMenu.d.ts → ColorMenu.d.ts} +2 -2
- package/dist/components/header/ColorMenu.js +19 -0
- package/dist/components/header/ColorMenu.js.map +1 -0
- package/dist/components/header/Header.js +6 -2
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderInfoArea.js +3 -2
- package/dist/components/header/HeaderInfoArea.js.map +1 -1
- package/dist/components/header/HeaderMenu.js +15 -97
- package/dist/components/header/HeaderMenu.js.map +1 -1
- package/dist/components/header/MSAMenu.d.ts +6 -0
- package/dist/components/header/MSAMenu.js +44 -0
- package/dist/components/header/MSAMenu.js.map +1 -0
- package/dist/components/header/TreeMenu.d.ts +6 -0
- package/dist/components/header/TreeMenu.js +64 -0
- package/dist/components/header/TreeMenu.js.map +1 -0
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js +4 -4
- package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
- package/dist/components/msa/renderMSABlock.js +13 -9
- package/dist/components/msa/renderMSABlock.js.map +1 -1
- package/dist/model.d.ts +7 -1
- package/dist/model.js +54 -53
- package/dist/model.js.map +1 -1
- package/dist/rowCoordinateCalculations.d.ts +13 -2
- package/dist/rowCoordinateCalculations.js +60 -17
- package/dist/rowCoordinateCalculations.js.map +1 -1
- package/dist/rowCoordinateCalculations.test.js +96 -2
- package/dist/rowCoordinateCalculations.test.js.map +1 -1
- package/dist/seqCoordToRowSpecificGlobalCoord.d.ts +4 -0
- package/dist/seqCoordToRowSpecificGlobalCoord.js +15 -0
- package/dist/seqCoordToRowSpecificGlobalCoord.js.map +1 -0
- package/dist/seqCoordToRowSpecificGlobalCoord.test.d.ts +1 -0
- package/dist/seqCoordToRowSpecificGlobalCoord.test.js +42 -0
- package/dist/seqCoordToRowSpecificGlobalCoord.test.js.map +1 -0
- package/dist/util.d.ts +1 -6
- package/dist/util.js +5 -22
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/colorSchemes.ts +2 -2
- package/src/components/VerticalScrollbar.tsx +2 -3
- package/src/components/dialogs/SettingsDialog.tsx +1 -1
- package/src/components/header/ColorMenu.tsx +33 -0
- package/src/components/header/Header.tsx +6 -2
- package/src/components/header/HeaderInfoArea.tsx +5 -2
- package/src/components/header/HeaderMenu.tsx +15 -110
- package/src/components/header/MSAMenu.tsx +55 -0
- package/src/components/header/TreeMenu.tsx +82 -0
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +4 -4
- package/src/components/msa/renderMSABlock.ts +26 -22
- package/src/model.ts +73 -61
- package/src/rowCoordinateCalculations.test.ts +138 -2
- package/src/rowCoordinateCalculations.ts +95 -18
- package/src/seqCoordToRowSpecificGlobalCoord.test.ts +53 -0
- package/src/seqCoordToRowSpecificGlobalCoord.ts +20 -0
- package/src/util.ts +5 -28
- package/src/version.ts +1 -1
- package/dist/components/header/SettingsMenu.js +0 -141
- package/dist/components/header/SettingsMenu.js.map +0 -1
- package/src/components/header/SettingsMenu.tsx +0 -169
|
@@ -1,26 +1,103 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { isBlank } from './util'
|
|
2
|
+
|
|
3
|
+
export function mouseOverCoordToGlobalCoord(
|
|
4
|
+
blanks: number[],
|
|
5
|
+
position: number,
|
|
6
|
+
) {
|
|
7
|
+
let mousePosition = 0 // Current position in mouse coordinates
|
|
8
|
+
let blankArrayIndex = 0 // Current index in the blanks array
|
|
9
|
+
let globalPosition = 0 // Position in global coordinates (return value)
|
|
10
|
+
const blanksLen = blanks.length
|
|
11
|
+
|
|
12
|
+
// Iterate until we reach the target mouse position
|
|
13
|
+
while (mousePosition < position) {
|
|
14
|
+
// Skip any blank positions in the sequence
|
|
15
|
+
while (
|
|
16
|
+
blankArrayIndex < blanksLen &&
|
|
17
|
+
blanks[blankArrayIndex]! - 1 === globalPosition
|
|
18
|
+
) {
|
|
19
|
+
blankArrayIndex++
|
|
20
|
+
globalPosition++
|
|
11
21
|
}
|
|
22
|
+
|
|
23
|
+
// Move to next position
|
|
24
|
+
mousePosition++
|
|
25
|
+
globalPosition++
|
|
12
26
|
}
|
|
13
|
-
|
|
27
|
+
|
|
28
|
+
return globalPosition
|
|
14
29
|
}
|
|
15
30
|
|
|
16
|
-
export function globalCoordToRowSpecificCoord(seq: string,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
export function globalCoordToRowSpecificCoord(seq: string, position: number) {
|
|
32
|
+
// Initialize counter for non-gap characters
|
|
33
|
+
let nonGapCount = 0
|
|
34
|
+
// Initialize position counter
|
|
35
|
+
let currentPosition = 0
|
|
36
|
+
const sequenceLength = seq.length
|
|
37
|
+
|
|
38
|
+
// Iterate until we reach the target position or end of sequence
|
|
39
|
+
while (currentPosition < position && currentPosition < sequenceLength) {
|
|
40
|
+
// If current character is not a gap, increment the non-gap counter
|
|
41
|
+
if (seq[currentPosition] !== '-') {
|
|
42
|
+
nonGapCount++
|
|
43
|
+
}
|
|
44
|
+
// If we've reached the target position in non-gap coordinates, break
|
|
45
|
+
else if (nonGapCount >= position) {
|
|
22
46
|
break
|
|
23
47
|
}
|
|
48
|
+
currentPosition++
|
|
24
49
|
}
|
|
25
|
-
|
|
50
|
+
|
|
51
|
+
return nonGapCount
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function mouseOverCoordToGapRemovedRowCoord({
|
|
55
|
+
rowName,
|
|
56
|
+
position,
|
|
57
|
+
rowMap,
|
|
58
|
+
blanks,
|
|
59
|
+
}: {
|
|
60
|
+
rowName: string
|
|
61
|
+
position: number
|
|
62
|
+
rowMap: Map<string, string>
|
|
63
|
+
blanks: number[]
|
|
64
|
+
}) {
|
|
65
|
+
const seq = rowMap.get(rowName)
|
|
66
|
+
return seq !== undefined
|
|
67
|
+
? mouseOverCoordToGapRemovedCoord({
|
|
68
|
+
seq,
|
|
69
|
+
position,
|
|
70
|
+
blanks,
|
|
71
|
+
})
|
|
72
|
+
: undefined
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function mouseOverCoordToGapRemovedCoord({
|
|
76
|
+
seq,
|
|
77
|
+
blanks,
|
|
78
|
+
position,
|
|
79
|
+
}: {
|
|
80
|
+
seq: string
|
|
81
|
+
blanks: number[]
|
|
82
|
+
position: number
|
|
83
|
+
}) {
|
|
84
|
+
// First convert the mouse position to global coordinates
|
|
85
|
+
const globalPos = mouseOverCoordToGlobalCoord(blanks, position)
|
|
86
|
+
const seqLen = seq.length
|
|
87
|
+
|
|
88
|
+
// Check if the position in the sequence is a gap
|
|
89
|
+
if (globalPos < seqLen && isBlank(seq[globalPos])) {
|
|
90
|
+
return undefined
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Count non-gap characters up to the global position
|
|
94
|
+
let nonGapCount = 0
|
|
95
|
+
for (let i = 0; i < globalPos && i < seqLen; i++) {
|
|
96
|
+
if (!isBlank(seq[i])) {
|
|
97
|
+
nonGapCount++
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// If we're at a valid position, return the count of non-gap characters
|
|
102
|
+
return globalPos < seqLen ? nonGapCount : undefined
|
|
26
103
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { seqCoordToRowSpecificGlobalCoord } from './seqCoordToRowSpecificGlobalCoord'
|
|
4
|
+
|
|
5
|
+
describe('seqCoordToRowSpecificGlobalCoord', () => {
|
|
6
|
+
test('converts sequence coordinate to global coordinate with no gaps', () => {
|
|
7
|
+
const row = 'ATGCATGC'
|
|
8
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 3 })).toBe(3)
|
|
9
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 0 })).toBe(0)
|
|
10
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 8 })).toBe(8)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
test('converts sequence coordinate to global coordinate with gaps', () => {
|
|
14
|
+
const row = 'A-TG-CA-TGC'
|
|
15
|
+
// A(0) -(1) T(2) G(3) -(4) C(5) A(6) -(7) T(8) G(9) C(10)
|
|
16
|
+
// Sequence positions: A(0) T(1) G(2) C(3) A(4) T(5) G(6) C(7)
|
|
17
|
+
|
|
18
|
+
// Position 0 (first A) -> Global index 0
|
|
19
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 0 })).toBe(0)
|
|
20
|
+
|
|
21
|
+
// Position 1 (T after first gap) -> Global index 2
|
|
22
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 1 })).toBe(1)
|
|
23
|
+
|
|
24
|
+
// Position 3 (C after second gap) -> Global index 5
|
|
25
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 3 })).toBe(4)
|
|
26
|
+
|
|
27
|
+
// Position 5 (T after third gap) -> Global index 8
|
|
28
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 5 })).toBe(7)
|
|
29
|
+
|
|
30
|
+
// Position 8 (end of sequence) -> Global index 11
|
|
31
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 8 })).toBe(11)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('handles empty row', () => {
|
|
35
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row: '', position: 0 })).toBe(0)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('handles row with only gaps', () => {
|
|
39
|
+
const row = '---..--'
|
|
40
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 0 })).toBe(0)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('handles mixed gap characters', () => {
|
|
44
|
+
const row = 'A-.G-C.'
|
|
45
|
+
// A(0) -(1) .(2) G(3) -(4) C(5) .(6)
|
|
46
|
+
// Sequence positions: A(0) G(1) C(2)
|
|
47
|
+
|
|
48
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 0 })).toBe(0)
|
|
49
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 1 })).toBe(1)
|
|
50
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 2 })).toBe(4)
|
|
51
|
+
expect(seqCoordToRowSpecificGlobalCoord({ row, position: 3 })).toBe(6)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isBlank } from './util'
|
|
2
|
+
|
|
3
|
+
export function seqCoordToRowSpecificGlobalCoord({
|
|
4
|
+
row,
|
|
5
|
+
position,
|
|
6
|
+
}: {
|
|
7
|
+
row: string
|
|
8
|
+
position: number
|
|
9
|
+
}) {
|
|
10
|
+
let k = 0
|
|
11
|
+
let i = 0
|
|
12
|
+
for (; k < position; i++) {
|
|
13
|
+
if (!isBlank(row[i])) {
|
|
14
|
+
k++
|
|
15
|
+
} else if (k >= position) {
|
|
16
|
+
break
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return i
|
|
20
|
+
}
|
package/src/util.ts
CHANGED
|
@@ -46,7 +46,7 @@ export function colorContrast(
|
|
|
46
46
|
export function skipBlanks(blanks: number[], arg: string | string[]) {
|
|
47
47
|
let s = ''
|
|
48
48
|
let b = 0
|
|
49
|
-
for (let j = 0
|
|
49
|
+
for (let j = 0, l = arg.length; j < l; j++) {
|
|
50
50
|
if (j === blanks[b]) {
|
|
51
51
|
b++
|
|
52
52
|
} else {
|
|
@@ -90,35 +90,12 @@ export function collapse(d: HierarchyNode<NodeWithIds>) {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
export function clamp(min: number, num: number, max: number) {
|
|
94
|
-
return Math.min(Math.max(num, min), max)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
93
|
export function len(a: { end: number; start: number }) {
|
|
98
94
|
return a.end - a.start
|
|
99
95
|
}
|
|
100
96
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function localStorageGetBoolean(key: string, defaultVal: boolean) {
|
|
108
|
-
return Boolean(
|
|
109
|
-
JSON.parse(localStorageGetItem(key) || JSON.stringify(defaultVal)),
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function localStorageSetItem(str: string, item: string) {
|
|
114
|
-
if (typeof localStorage !== 'undefined') {
|
|
115
|
-
localStorage.setItem(str, item)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
export function localStorageSetBoolean(key: string, value: boolean) {
|
|
119
|
-
localStorageSetItem(key, JSON.stringify(value))
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export function isGzip(buf: Uint8Array) {
|
|
123
|
-
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8
|
|
97
|
+
// https://sonnhammer.sbc.su.se/Stockholm.html
|
|
98
|
+
// gaps can be a . or - in stockholm
|
|
99
|
+
export function isBlank(s?: string) {
|
|
100
|
+
return s === '-' || s === '.'
|
|
124
101
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '4.
|
|
1
|
+
export const version = '4.4.1'
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import React, { lazy } from 'react';
|
|
2
|
-
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
|
|
3
|
-
import AccountTreeIcon from '@mui/icons-material/AccountTree';
|
|
4
|
-
import ColorLensIcon from '@mui/icons-material/ColorLens';
|
|
5
|
-
import GridOn from '@mui/icons-material/GridOn';
|
|
6
|
-
import Settings from '@mui/icons-material/Settings';
|
|
7
|
-
import { observer } from 'mobx-react';
|
|
8
|
-
import colorSchemes from '../../colorSchemes';
|
|
9
|
-
// lazies
|
|
10
|
-
const SettingsDialog = lazy(() => import('../dialogs/SettingsDialog'));
|
|
11
|
-
const SettingsMenu = observer(({ model }) => {
|
|
12
|
-
const { drawTree, showBranchLen, labelsAlignRight, drawNodeBubbles, drawLabels, treeWidthMatchesArea, drawMsaLetters, noTree, bgColor, hideGaps, contrastLettering, colorSchemeName, } = model;
|
|
13
|
-
return (React.createElement(CascadingMenuButton, { menuItems: [
|
|
14
|
-
{
|
|
15
|
-
label: 'Tree settings',
|
|
16
|
-
type: 'subMenu',
|
|
17
|
-
icon: AccountTreeIcon,
|
|
18
|
-
subMenu: [
|
|
19
|
-
{
|
|
20
|
-
label: 'Show branch length',
|
|
21
|
-
type: 'checkbox',
|
|
22
|
-
checked: showBranchLen,
|
|
23
|
-
onClick: () => {
|
|
24
|
-
model.setShowBranchLen(!showBranchLen);
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
label: 'Show tree',
|
|
29
|
-
type: 'checkbox',
|
|
30
|
-
checked: drawTree,
|
|
31
|
-
onClick: () => {
|
|
32
|
-
model.setDrawTree(!drawTree);
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
label: 'Draw clickable bubbles on tree branches',
|
|
37
|
-
type: 'checkbox',
|
|
38
|
-
checked: drawNodeBubbles,
|
|
39
|
-
onClick: () => {
|
|
40
|
-
model.setDrawNodeBubbles(!drawNodeBubbles);
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
label: 'Tree labels align right',
|
|
45
|
-
type: 'checkbox',
|
|
46
|
-
checked: labelsAlignRight,
|
|
47
|
-
onClick: () => {
|
|
48
|
-
model.setLabelsAlignRight(!labelsAlignRight);
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
label: 'Draw labels',
|
|
53
|
-
type: 'checkbox',
|
|
54
|
-
checked: drawLabels,
|
|
55
|
-
onClick: () => {
|
|
56
|
-
model.setDrawLabels(!drawLabels);
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
...(noTree
|
|
60
|
-
? []
|
|
61
|
-
: [
|
|
62
|
-
{
|
|
63
|
-
label: 'Make tree width fit to tree area',
|
|
64
|
-
type: 'checkbox',
|
|
65
|
-
checked: treeWidthMatchesArea,
|
|
66
|
-
onClick: () => {
|
|
67
|
-
model.setTreeWidthMatchesArea(!treeWidthMatchesArea);
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
]),
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
label: 'MSA settings',
|
|
75
|
-
type: 'subMenu',
|
|
76
|
-
icon: GridOn,
|
|
77
|
-
subMenu: [
|
|
78
|
-
{
|
|
79
|
-
label: 'Draw letters',
|
|
80
|
-
type: 'checkbox',
|
|
81
|
-
checked: drawMsaLetters,
|
|
82
|
-
onClick: () => {
|
|
83
|
-
model.setDrawMsaLetters(!drawMsaLetters);
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
label: 'Color background tiles of MSA?',
|
|
88
|
-
type: 'checkbox',
|
|
89
|
-
checked: bgColor,
|
|
90
|
-
onClick: () => {
|
|
91
|
-
model.setBgColor(!bgColor);
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
label: 'Use contrast lettering',
|
|
96
|
-
type: 'checkbox',
|
|
97
|
-
checked: contrastLettering,
|
|
98
|
-
onClick: () => {
|
|
99
|
-
model.setContrastLettering(!contrastLettering);
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
label: 'Enable hiding gappy columns?',
|
|
104
|
-
type: 'checkbox',
|
|
105
|
-
checked: hideGaps,
|
|
106
|
-
onClick: () => {
|
|
107
|
-
model.setHideGaps(!hideGaps);
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
],
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
label: 'Color scheme',
|
|
114
|
-
type: 'subMenu',
|
|
115
|
-
icon: ColorLensIcon,
|
|
116
|
-
subMenu: Object.keys(colorSchemes).map(option => ({
|
|
117
|
-
label: option,
|
|
118
|
-
type: 'radio',
|
|
119
|
-
checked: colorSchemeName === option,
|
|
120
|
-
onClick: () => {
|
|
121
|
-
model.setColorSchemeName(option);
|
|
122
|
-
},
|
|
123
|
-
})),
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
label: 'More settings',
|
|
127
|
-
onClick: () => {
|
|
128
|
-
model.queueDialog(onClose => [
|
|
129
|
-
SettingsDialog,
|
|
130
|
-
{
|
|
131
|
-
model,
|
|
132
|
-
onClose,
|
|
133
|
-
},
|
|
134
|
-
]);
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
] },
|
|
138
|
-
React.createElement(Settings, null)));
|
|
139
|
-
});
|
|
140
|
-
export default SettingsMenu;
|
|
141
|
-
//# sourceMappingURL=SettingsMenu.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsMenu.js","sourceRoot":"","sources":["../../../src/components/header/SettingsMenu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import React, { lazy } from 'react'
|
|
2
|
-
|
|
3
|
-
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
|
|
4
|
-
import AccountTreeIcon from '@mui/icons-material/AccountTree'
|
|
5
|
-
import ColorLensIcon from '@mui/icons-material/ColorLens'
|
|
6
|
-
import GridOn from '@mui/icons-material/GridOn'
|
|
7
|
-
import Settings from '@mui/icons-material/Settings'
|
|
8
|
-
import { observer } from 'mobx-react'
|
|
9
|
-
|
|
10
|
-
import colorSchemes from '../../colorSchemes'
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import type { MsaViewModel } from '../../model'
|
|
14
|
-
|
|
15
|
-
// lazies
|
|
16
|
-
const SettingsDialog = lazy(() => import('../dialogs/SettingsDialog'))
|
|
17
|
-
|
|
18
|
-
const SettingsMenu = observer(({ model }: { model: MsaViewModel }) => {
|
|
19
|
-
const {
|
|
20
|
-
drawTree,
|
|
21
|
-
showBranchLen,
|
|
22
|
-
labelsAlignRight,
|
|
23
|
-
drawNodeBubbles,
|
|
24
|
-
drawLabels,
|
|
25
|
-
treeWidthMatchesArea,
|
|
26
|
-
drawMsaLetters,
|
|
27
|
-
noTree,
|
|
28
|
-
bgColor,
|
|
29
|
-
hideGaps,
|
|
30
|
-
contrastLettering,
|
|
31
|
-
colorSchemeName,
|
|
32
|
-
} = model
|
|
33
|
-
return (
|
|
34
|
-
<CascadingMenuButton
|
|
35
|
-
menuItems={[
|
|
36
|
-
{
|
|
37
|
-
label: 'Tree settings',
|
|
38
|
-
type: 'subMenu',
|
|
39
|
-
icon: AccountTreeIcon,
|
|
40
|
-
subMenu: [
|
|
41
|
-
{
|
|
42
|
-
label: 'Show branch length',
|
|
43
|
-
type: 'checkbox',
|
|
44
|
-
checked: showBranchLen,
|
|
45
|
-
onClick: () => {
|
|
46
|
-
model.setShowBranchLen(!showBranchLen)
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
label: 'Show tree',
|
|
51
|
-
type: 'checkbox',
|
|
52
|
-
checked: drawTree,
|
|
53
|
-
onClick: () => {
|
|
54
|
-
model.setDrawTree(!drawTree)
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
label: 'Draw clickable bubbles on tree branches',
|
|
59
|
-
type: 'checkbox',
|
|
60
|
-
checked: drawNodeBubbles,
|
|
61
|
-
onClick: () => {
|
|
62
|
-
model.setDrawNodeBubbles(!drawNodeBubbles)
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
label: 'Tree labels align right',
|
|
67
|
-
type: 'checkbox',
|
|
68
|
-
checked: labelsAlignRight,
|
|
69
|
-
onClick: () => {
|
|
70
|
-
model.setLabelsAlignRight(!labelsAlignRight)
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
label: 'Draw labels',
|
|
75
|
-
type: 'checkbox',
|
|
76
|
-
checked: drawLabels,
|
|
77
|
-
onClick: () => {
|
|
78
|
-
model.setDrawLabels(!drawLabels)
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
...(noTree
|
|
82
|
-
? []
|
|
83
|
-
: [
|
|
84
|
-
{
|
|
85
|
-
label: 'Make tree width fit to tree area',
|
|
86
|
-
type: 'checkbox' as const,
|
|
87
|
-
checked: treeWidthMatchesArea,
|
|
88
|
-
onClick: () => {
|
|
89
|
-
model.setTreeWidthMatchesArea(!treeWidthMatchesArea)
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
]),
|
|
93
|
-
],
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
label: 'MSA settings',
|
|
97
|
-
type: 'subMenu',
|
|
98
|
-
icon: GridOn,
|
|
99
|
-
subMenu: [
|
|
100
|
-
{
|
|
101
|
-
label: 'Draw letters',
|
|
102
|
-
type: 'checkbox',
|
|
103
|
-
checked: drawMsaLetters,
|
|
104
|
-
onClick: () => {
|
|
105
|
-
model.setDrawMsaLetters(!drawMsaLetters)
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
label: 'Color background tiles of MSA?',
|
|
110
|
-
type: 'checkbox',
|
|
111
|
-
checked: bgColor,
|
|
112
|
-
onClick: () => {
|
|
113
|
-
model.setBgColor(!bgColor)
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
label: 'Use contrast lettering',
|
|
118
|
-
type: 'checkbox',
|
|
119
|
-
checked: contrastLettering,
|
|
120
|
-
onClick: () => {
|
|
121
|
-
model.setContrastLettering(!contrastLettering)
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
label: 'Enable hiding gappy columns?',
|
|
126
|
-
type: 'checkbox',
|
|
127
|
-
checked: hideGaps,
|
|
128
|
-
onClick: () => {
|
|
129
|
-
model.setHideGaps(!hideGaps)
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
label: 'Color scheme',
|
|
136
|
-
type: 'subMenu',
|
|
137
|
-
icon: ColorLensIcon,
|
|
138
|
-
subMenu: Object.keys(colorSchemes).map(
|
|
139
|
-
option =>
|
|
140
|
-
({
|
|
141
|
-
label: option,
|
|
142
|
-
type: 'radio',
|
|
143
|
-
checked: colorSchemeName === option,
|
|
144
|
-
onClick: () => {
|
|
145
|
-
model.setColorSchemeName(option)
|
|
146
|
-
},
|
|
147
|
-
}) as const,
|
|
148
|
-
),
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
label: 'More settings',
|
|
152
|
-
onClick: () => {
|
|
153
|
-
model.queueDialog(onClose => [
|
|
154
|
-
SettingsDialog,
|
|
155
|
-
{
|
|
156
|
-
model,
|
|
157
|
-
onClose,
|
|
158
|
-
},
|
|
159
|
-
])
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
]}
|
|
163
|
-
>
|
|
164
|
-
<Settings />
|
|
165
|
-
</CascadingMenuButton>
|
|
166
|
-
)
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
export default SettingsMenu
|