@platforma-sdk/ui-vue 1.41.19 → 1.42.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/.turbo/turbo-build.log +19 -19
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +11 -0
- package/dist/components/PlMultiSequenceAlignment/Legend.vue.d.ts +2 -2
- package/dist/components/PlMultiSequenceAlignment/Legend.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/Legend.vue2.js +11 -11
- package/dist/components/PlMultiSequenceAlignment/Legend.vue3.js +8 -8
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts +12 -6
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue2.js +80 -65
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue2.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue3.js +14 -12
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue3.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.d.ts +36 -1
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js +146 -111
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts +2 -0
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js +71 -68
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.d.ts +42 -6
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.js +96 -130
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/data.d.ts +3 -9
- package/dist/components/PlMultiSequenceAlignment/data.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/data.js +198 -212
- package/dist/components/PlMultiSequenceAlignment/data.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/markup.d.ts +7 -5
- package/dist/components/PlMultiSequenceAlignment/markup.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/markup.js +47 -26
- package/dist/components/PlMultiSequenceAlignment/markup.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/types.d.ts +1 -1
- package/dist/components/PlMultiSequenceAlignment/types.d.ts.map +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAccordion/{ExpandTransition.vue.js → ExpandTransition.vue2.js} +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAccordion/ExpandTransition.vue2.js.map +1 -0
- package/dist/lib/ui/uikit/dist/components/PlAccordion/PlAccordionSection.vue2.js +1 -1
- package/dist/lib/ui/uikit/dist/lib/model/common/dist/index.js.map +1 -1
- package/dist/lib/ui/uikit/dist/sdk/model/dist/index.js +1 -1
- package/dist/node_modules/.pnpm/@vueuse_core@13.3.0_vue@3.5.13_typescript@5.6.3_/node_modules/@vueuse/core/index.js +111 -165
- package/dist/node_modules/.pnpm/@vueuse_core@13.3.0_vue@3.5.13_typescript@5.6.3_/node_modules/@vueuse/core/index.js.map +1 -1
- package/dist/node_modules/.pnpm/@vueuse_shared@13.3.0_vue@3.5.13_typescript@5.6.3_/node_modules/@vueuse/shared/index.js +1 -1
- package/dist/sdk/model/dist/index.js +1 -1
- package/package.json +5 -5
- package/src/components/PlMultiSequenceAlignment/Legend.vue +4 -3
- package/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue +66 -46
- package/src/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue +85 -34
- package/src/components/PlMultiSequenceAlignment/README.md +10 -8
- package/src/components/PlMultiSequenceAlignment/Toolbar.vue +4 -1
- package/src/components/PlMultiSequenceAlignment/chemical-properties.ts +154 -161
- package/src/components/PlMultiSequenceAlignment/data.ts +65 -85
- package/src/components/PlMultiSequenceAlignment/markup.ts +47 -15
- package/src/components/PlMultiSequenceAlignment/types.ts +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAccordion/ExpandTransition.vue.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { shallowRef as b, isRef as g, watch as p, shallowReadonly as T, onMounted as S, nextTick as j,
|
|
1
|
+
import { shallowRef as b, isRef as g, watch as p, shallowReadonly as T, onMounted as S, nextTick as j, getCurrentScope as A, onScopeDispose as C, toValue as m, getCurrentInstance as I } from "vue";
|
|
2
2
|
function d(e) {
|
|
3
3
|
return A() ? (C(e), !0) : !1;
|
|
4
4
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.42.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/lib.js",
|
|
6
6
|
"styles": "dist/lib.js",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"d3-format": "^3.1.0",
|
|
27
27
|
"zod": "~3.23.8",
|
|
28
28
|
"@milaboratories/biowasm-tools": "^1.1.0",
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
29
|
+
"@milaboratories/uikit": "2.3.24",
|
|
30
|
+
"@platforma-sdk/model": "~1.42.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"happy-dom": "^15.11.7",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"@faker-js/faker": "^9.2.0",
|
|
46
46
|
"@milaboratories/ts-configs": "1.0.5",
|
|
47
47
|
"@milaboratories/eslint-config": "^1.0.4",
|
|
48
|
-
"@milaboratories/
|
|
49
|
-
"@milaboratories/
|
|
48
|
+
"@milaboratories/helpers": "^1.6.19",
|
|
49
|
+
"@milaboratories/build-configs": "1.0.5"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"test": "vitest run --passWithNoTests",
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type {
|
|
2
|
+
import type { HighlightLegend } from './types';
|
|
3
3
|
|
|
4
4
|
defineProps<{
|
|
5
|
-
|
|
5
|
+
legend: HighlightLegend;
|
|
6
6
|
}>();
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
9
|
<template>
|
|
10
10
|
<div :class="$style.container">
|
|
11
11
|
<div
|
|
12
|
-
v-for="([key, { label, color }])
|
|
12
|
+
v-for="([key, { label, color }]) of Object.entries(legend)"
|
|
13
13
|
:key="key"
|
|
14
14
|
:class="$style.item"
|
|
15
15
|
>
|
|
@@ -27,6 +27,7 @@ defineProps<{
|
|
|
27
27
|
display: flex;
|
|
28
28
|
flex-wrap: wrap;
|
|
29
29
|
gap: 12px;
|
|
30
|
+
max-inline-size: fit-content;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
.item {
|
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import {
|
|
3
|
-
import { computed } from 'vue';
|
|
2
|
+
import { useObjectUrl } from '@vueuse/core';
|
|
3
|
+
import { computed, useTemplateRef } from 'vue';
|
|
4
4
|
import Consensus from './Consensus.vue';
|
|
5
|
+
import Legend from './Legend.vue';
|
|
5
6
|
import SeqLogo from './SeqLogo.vue';
|
|
6
|
-
import type { ResidueCounts } from './types';
|
|
7
|
+
import type { HighlightLegend, ResidueCounts } from './types';
|
|
7
8
|
|
|
8
|
-
const { sequences,
|
|
9
|
-
sequenceNames: string[];
|
|
9
|
+
const { sequences, highlightImage } = defineProps<{
|
|
10
10
|
sequences: string[];
|
|
11
|
+
sequenceNames: string[];
|
|
11
12
|
labelRows: string[][];
|
|
12
13
|
residueCounts: ResidueCounts;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
highlightImage: {
|
|
15
|
+
blob: Blob;
|
|
16
|
+
legend: HighlightLegend;
|
|
17
|
+
} | undefined;
|
|
18
|
+
widgets: ('consensus' | 'seqLogo' | 'legend')[];
|
|
16
19
|
}>();
|
|
17
20
|
|
|
18
|
-
const
|
|
21
|
+
const rootEl = useTemplateRef('rootRef');
|
|
22
|
+
defineExpose({ rootEl });
|
|
19
23
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
const highlightImageObjectUrl = useObjectUrl(() => highlightImage?.blob);
|
|
25
|
+
const highlightImageCssUrl = computed(() =>
|
|
26
|
+
highlightImageObjectUrl.value
|
|
27
|
+
? `url('${highlightImageObjectUrl.value}')`
|
|
23
28
|
: 'none',
|
|
24
29
|
);
|
|
25
30
|
|
|
@@ -29,55 +34,70 @@ const sequenceLengths = computed(() =>
|
|
|
29
34
|
</script>
|
|
30
35
|
|
|
31
36
|
<template>
|
|
32
|
-
<div :class="
|
|
33
|
-
<div :class="$style.
|
|
34
|
-
|
|
35
|
-
<div
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
inlineSize:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
<div ref="rootRef" :class="$style.root">
|
|
38
|
+
<div :class="['pl-scrollable', $style.table]">
|
|
39
|
+
<div :class="$style.corner" />
|
|
40
|
+
<div :class="$style.header">
|
|
41
|
+
<div v-if="sequenceNames.length > 1" :class="$style['sequence-names']">
|
|
42
|
+
<span
|
|
43
|
+
v-for="(name, index) of sequenceNames"
|
|
44
|
+
:key="index"
|
|
45
|
+
:style="{
|
|
46
|
+
inlineSize: ((sequenceLengths?.at(index) ?? 0) * 20)
|
|
47
|
+
+ 'px',
|
|
48
|
+
}"
|
|
49
|
+
>{{ name }}</span>
|
|
50
|
+
</div>
|
|
51
|
+
<Consensus v-if="widgets.includes('consensus')" :residue-counts />
|
|
52
|
+
<SeqLogo v-if="widgets.includes('seqLogo')" :residue-counts />
|
|
47
53
|
</div>
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
<div :class="$style.labels">
|
|
55
|
+
<template v-for="(labelRow, rowIndex) of labelRows">
|
|
56
|
+
<div
|
|
57
|
+
v-for="(label, labelIndex) of labelRow"
|
|
58
|
+
:key="labelIndex"
|
|
59
|
+
:style="{ gridRow: rowIndex + 1 }"
|
|
60
|
+
>
|
|
61
|
+
{{ label }}
|
|
62
|
+
</div>
|
|
63
|
+
</template>
|
|
64
|
+
</div>
|
|
65
|
+
<div :class="$style.sequences">
|
|
53
66
|
<div
|
|
54
|
-
v-for="(
|
|
55
|
-
:key="
|
|
56
|
-
:style="{ gridRow: rowIndex + 1 }"
|
|
67
|
+
v-for="(sequence, index) of sequences"
|
|
68
|
+
:key="index"
|
|
57
69
|
>
|
|
58
|
-
{{
|
|
70
|
+
{{ sequence }}
|
|
59
71
|
</div>
|
|
60
|
-
</template>
|
|
61
|
-
</div>
|
|
62
|
-
<div :class="$style.sequences">
|
|
63
|
-
<div
|
|
64
|
-
v-for="(sequence, index) of sequences"
|
|
65
|
-
:key="index"
|
|
66
|
-
>
|
|
67
|
-
{{ sequence }}
|
|
68
72
|
</div>
|
|
69
73
|
</div>
|
|
74
|
+
<Legend
|
|
75
|
+
v-if="widgets?.includes('legend') && highlightImage?.legend"
|
|
76
|
+
:legend="highlightImage.legend"
|
|
77
|
+
/>
|
|
70
78
|
</div>
|
|
71
79
|
</template>
|
|
72
80
|
|
|
73
81
|
<style module>
|
|
74
82
|
.root {
|
|
83
|
+
display: flex;
|
|
84
|
+
flex-direction: column;
|
|
85
|
+
gap: 12px;
|
|
86
|
+
min-block-size: 0;
|
|
87
|
+
-webkit-print-color-adjust: exact;
|
|
88
|
+
print-color-adjust: exact;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.table {
|
|
75
92
|
display: grid;
|
|
76
93
|
grid-template-areas:
|
|
77
94
|
"corner header"
|
|
78
95
|
"labels sequences";
|
|
79
96
|
text-wrap: nowrap;
|
|
80
97
|
justify-content: start;
|
|
98
|
+
@media print {
|
|
99
|
+
overflow: visible;
|
|
100
|
+
}
|
|
81
101
|
}
|
|
82
102
|
|
|
83
103
|
.corner {
|
|
@@ -128,9 +148,9 @@ const sequenceLengths = computed(() =>
|
|
|
128
148
|
line-height: 24px;
|
|
129
149
|
letter-spacing: 11.6px;
|
|
130
150
|
text-indent: 5.8px;
|
|
131
|
-
|
|
151
|
+
margin-inline-end: -5.8px;
|
|
152
|
+
background-image: v-bind(highlightImageCssUrl);
|
|
132
153
|
background-repeat: no-repeat;
|
|
133
154
|
background-size: calc(100% - 5.8px) 100%;
|
|
134
|
-
image-rendering: pixelated;
|
|
135
155
|
}
|
|
136
156
|
</style>
|
|
@@ -5,15 +5,22 @@ import {
|
|
|
5
5
|
PlAlert,
|
|
6
6
|
PlSplash,
|
|
7
7
|
} from '@milaboratories/uikit';
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
import {
|
|
9
|
+
getRawPlatformaInstance,
|
|
10
|
+
type PColumnPredicate,
|
|
11
|
+
type PFrameHandle,
|
|
12
|
+
type PlMultiSequenceAlignmentColorSchemeOption,
|
|
13
|
+
type PlMultiSequenceAlignmentModel,
|
|
14
|
+
type PlMultiSequenceAlignmentSettings,
|
|
15
|
+
type PlSelectionModel,
|
|
15
16
|
} from '@platforma-sdk/model';
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
computed,
|
|
19
|
+
onBeforeMount,
|
|
20
|
+
reactive,
|
|
21
|
+
useTemplateRef,
|
|
22
|
+
watchEffect,
|
|
23
|
+
} from 'vue';
|
|
17
24
|
import {
|
|
18
25
|
sequenceLimit,
|
|
19
26
|
useLabelColumnsOptions,
|
|
@@ -21,7 +28,6 @@ import {
|
|
|
21
28
|
useMultipleAlignmentData,
|
|
22
29
|
useSequenceColumnsOptions,
|
|
23
30
|
} from './data';
|
|
24
|
-
import Legend from './Legend.vue';
|
|
25
31
|
import { runMigrations } from './migrations';
|
|
26
32
|
import MultiSequenceAlignmentView from './MultiSequenceAlignmentView.vue';
|
|
27
33
|
import { defaultSettings } from './settings';
|
|
@@ -71,17 +77,10 @@ const markupColumns = reactive(useMarkupColumnsOptions(() => ({
|
|
|
71
77
|
sequenceColumnIds: settings.sequenceColumnIds,
|
|
72
78
|
})));
|
|
73
79
|
|
|
74
|
-
const markupColumnId = computed(() =>
|
|
75
|
-
settings.colorScheme?.type === 'markup'
|
|
76
|
-
? settings.colorScheme.columnId
|
|
77
|
-
: undefined,
|
|
78
|
-
);
|
|
79
|
-
|
|
80
80
|
const multipleAlignmentData = reactive(useMultipleAlignmentData(() => ({
|
|
81
81
|
pframe: props.pFrame,
|
|
82
82
|
sequenceColumnIds: settings.sequenceColumnIds,
|
|
83
83
|
labelColumnIds: settings.labelColumnIds,
|
|
84
|
-
markupColumnId: markupColumnId.value,
|
|
85
84
|
selection: props.selection,
|
|
86
85
|
colorScheme: settings.colorScheme,
|
|
87
86
|
alignmentParams: settings.alignmentParams,
|
|
@@ -165,10 +164,15 @@ watchEffect(() => {
|
|
|
165
164
|
) {
|
|
166
165
|
settingsToReset.push('labelColumnIds');
|
|
167
166
|
}
|
|
167
|
+
|
|
168
|
+
const markupColumnId = settings.colorScheme?.type === 'markup'
|
|
169
|
+
? settings.colorScheme.columnId
|
|
170
|
+
: undefined;
|
|
171
|
+
|
|
168
172
|
if (
|
|
169
|
-
markupColumnId
|
|
173
|
+
markupColumnId
|
|
170
174
|
&& !markupColumns.data?.some(
|
|
171
|
-
({ value }) => isJsonEqual(value, markupColumnId
|
|
175
|
+
({ value }) => isJsonEqual(value, markupColumnId),
|
|
172
176
|
)
|
|
173
177
|
) {
|
|
174
178
|
settingsToReset.push('colorScheme');
|
|
@@ -179,6 +183,61 @@ watchEffect(() => {
|
|
|
179
183
|
));
|
|
180
184
|
}
|
|
181
185
|
});
|
|
186
|
+
|
|
187
|
+
const msaEl = useTemplateRef('msa');
|
|
188
|
+
|
|
189
|
+
async function exportPdf() {
|
|
190
|
+
const exportToPdf = getRawPlatformaInstance()?.lsDriver
|
|
191
|
+
?.exportToPdf;
|
|
192
|
+
if (!exportToPdf) {
|
|
193
|
+
return console.error(
|
|
194
|
+
'API getPlatformaRawInstance().lsDriver.exportToPdf is not available',
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
const msaRoot = msaEl.value?.rootEl;
|
|
198
|
+
if (!msaRoot) {
|
|
199
|
+
throw new Error('MSA element is not available.');
|
|
200
|
+
}
|
|
201
|
+
const printTarget = document.createElement('div');
|
|
202
|
+
printTarget.id = `print-target-${crypto.randomUUID()}`;
|
|
203
|
+
const printStyleSheet = new CSSStyleSheet();
|
|
204
|
+
document.adoptedStyleSheets.push(printStyleSheet);
|
|
205
|
+
printStyleSheet.insertRule(`
|
|
206
|
+
@media screen {
|
|
207
|
+
#${printTarget.id} {
|
|
208
|
+
visibility: hidden;
|
|
209
|
+
position: fixed;
|
|
210
|
+
}
|
|
211
|
+
}`);
|
|
212
|
+
printTarget.replaceChildren(msaRoot.cloneNode(true));
|
|
213
|
+
document.body.appendChild(printTarget);
|
|
214
|
+
const { height, width } = printTarget.getBoundingClientRect();
|
|
215
|
+
const margin = CSS.cm(1);
|
|
216
|
+
const pageSize = [width, height]
|
|
217
|
+
.map((value) => CSS.px(value).add(margin.mul(2)))
|
|
218
|
+
.join(' ');
|
|
219
|
+
printStyleSheet.insertRule(`
|
|
220
|
+
@media print {
|
|
221
|
+
@page {
|
|
222
|
+
size: ${pageSize};
|
|
223
|
+
margin: ${margin};
|
|
224
|
+
}
|
|
225
|
+
body > :not(#${printTarget.id}) {
|
|
226
|
+
display: none;
|
|
227
|
+
}
|
|
228
|
+
}`);
|
|
229
|
+
try {
|
|
230
|
+
await exportToPdf();
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.error(error);
|
|
233
|
+
} finally {
|
|
234
|
+
document.body.removeChild(printTarget);
|
|
235
|
+
const index = document.adoptedStyleSheets.indexOf(printStyleSheet);
|
|
236
|
+
if (index >= 0) {
|
|
237
|
+
document.adoptedStyleSheets.splice(index, 1);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
182
241
|
</script>
|
|
183
242
|
|
|
184
243
|
<template>
|
|
@@ -188,15 +247,14 @@ watchEffect(() => {
|
|
|
188
247
|
:label-column-options="labelColumns.data?.options"
|
|
189
248
|
:color-scheme-options="colorSchemeOptions"
|
|
190
249
|
@update-settings="applySettings"
|
|
250
|
+
@export="exportPdf"
|
|
191
251
|
/>
|
|
192
252
|
<PlAlert v-if="error" type="error">
|
|
193
253
|
{{ error }}
|
|
194
254
|
</PlAlert>
|
|
195
255
|
<PlAlert
|
|
196
|
-
v-else-if="
|
|
197
|
-
|
|
198
|
-
&& (multipleAlignmentData.data?.sequences ?? []).length < 2
|
|
199
|
-
"
|
|
256
|
+
v-else-if="!multipleAlignmentData.isLoading
|
|
257
|
+
&& (multipleAlignmentData.data?.sequences ?? []).length < 2"
|
|
200
258
|
type="warn"
|
|
201
259
|
icon
|
|
202
260
|
>
|
|
@@ -221,20 +279,13 @@ watchEffect(() => {
|
|
|
221
279
|
>
|
|
222
280
|
<template v-if="multipleAlignmentData.data?.sequences.length">
|
|
223
281
|
<MultiSequenceAlignmentView
|
|
224
|
-
|
|
282
|
+
ref="msa"
|
|
225
283
|
:sequences="multipleAlignmentData.data.sequences"
|
|
226
|
-
:
|
|
284
|
+
:sequence-names="multipleAlignmentData.data.sequenceNames"
|
|
285
|
+
:label-rows="multipleAlignmentData.data.labelRows"
|
|
227
286
|
:residue-counts="multipleAlignmentData.data.residueCounts"
|
|
228
|
-
:highlight-image
|
|
229
|
-
:
|
|
230
|
-
:seq-logo="settings.widgets?.includes('seqLogo') ?? false"
|
|
231
|
-
/>
|
|
232
|
-
<Legend
|
|
233
|
-
v-if="
|
|
234
|
-
settings.widgets?.includes('legend')
|
|
235
|
-
&& multipleAlignmentData.data.highlightImage?.colorMap
|
|
236
|
-
"
|
|
237
|
-
:colors="multipleAlignmentData.data.highlightImage.colorMap"
|
|
287
|
+
:highlight-image="multipleAlignmentData.data.highlightImage"
|
|
288
|
+
:widgets="settings.widgets"
|
|
238
289
|
/>
|
|
239
290
|
</template>
|
|
240
291
|
</PlSplash>
|
|
@@ -13,7 +13,7 @@ Defined in `PlMultiSequenceAlignment.vue`.
|
|
|
13
13
|
|
|
14
14
|
This component is a "wrapper" that takes supplied data, runs data fetchers from
|
|
15
15
|
`data.ts` and draws `<MultiSequenceAlignmentView />`. It also draws a
|
|
16
|
-
`<Toolbar
|
|
16
|
+
`<Toolbar />` and is responsible for loading and error states.
|
|
17
17
|
|
|
18
18
|
The inputs are:
|
|
19
19
|
|
|
@@ -66,10 +66,9 @@ returns data in this format:
|
|
|
66
66
|
every row is the same length
|
|
67
67
|
- `sequenceNames`: list of sequence names, should match the names of the options
|
|
68
68
|
in a dropdown, which user selected
|
|
69
|
-
- `
|
|
69
|
+
- `labelRows`: list of lists of labels,
|
|
70
70
|
(`[["<r0l0>", "<r0l1>", ...], ["<r1l0>", "<r1l1>", ...]]`, "r"—row, "l"—label)
|
|
71
71
|
- `residueCounts`: see [Residue counts](#residue-counts)
|
|
72
|
-
- `markup`: optional, see [Markup](#markup)
|
|
73
72
|
- `highlightImage`: optional, see [Highlighting](#highlighting-color-scheme)
|
|
74
73
|
- `exceedsLimit`: see [Row limit](#row-limit)
|
|
75
74
|
|
|
@@ -79,10 +78,11 @@ Most of the data generated by it is in the format that is useful for
|
|
|
79
78
|
### Highlighting (Color Scheme)
|
|
80
79
|
|
|
81
80
|
There are two ways to colorize the MSA output. Both output a
|
|
82
|
-
[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that is
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that is an SVG
|
|
82
|
+
file which is later scaled up to fit the table layout. Current implementation
|
|
83
|
+
uses <path> tags to group multiple runs of the same color. The viewbox is
|
|
84
|
+
doubled in one of the directions to use SVG strokes without resorting to
|
|
85
|
+
fractional positions.
|
|
86
86
|
|
|
87
87
|
There's also an option to not colorize the output at all.
|
|
88
88
|
|
|
@@ -91,7 +91,9 @@ There's also an option to not colorize the output at all.
|
|
|
91
91
|
Defined in `chemical-properties.ts`.
|
|
92
92
|
|
|
93
93
|
This is an implementation of Clustal X color scheme. See
|
|
94
|
-
https://www.jalview.org/help/html/colourSchemes/clustal.html
|
|
94
|
+
https://www.jalview.org/help/html/colourSchemes/clustal.html and
|
|
95
|
+
https://www.rbvi.ucsf.edu/chimera/1.2065/docs/ContributedSoftware/multalignviewer/cxcolor.html
|
|
96
|
+
for reference.
|
|
95
97
|
|
|
96
98
|
#### Markup
|
|
97
99
|
|
|
@@ -29,6 +29,7 @@ const { settings } = defineProps<{
|
|
|
29
29
|
|
|
30
30
|
const emit = defineEmits<{
|
|
31
31
|
updateSettings: [Partial<Settings>];
|
|
32
|
+
export: [];
|
|
32
33
|
}>();
|
|
33
34
|
|
|
34
35
|
const settingsOpen = ref(false);
|
|
@@ -95,7 +96,9 @@ const canResetAlignmentParams = computed(() =>
|
|
|
95
96
|
<PlBtnGhost icon="settings" @click.stop="settingsOpen = true">
|
|
96
97
|
Settings
|
|
97
98
|
</PlBtnGhost>
|
|
98
|
-
<PlBtnGhost icon="export">
|
|
99
|
+
<PlBtnGhost icon="export" @click.stop="$emit('export')">
|
|
100
|
+
Export
|
|
101
|
+
</PlBtnGhost>
|
|
99
102
|
</div>
|
|
100
103
|
</div>
|
|
101
104
|
<div :class="$style.line">
|