@platforma-sdk/ui-vue 1.34.17 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/lib.css +1 -1
  3. package/dist/lib.js +7041 -6851
  4. package/dist/lib.js.map +1 -1
  5. package/dist/src/components/PlMultiSequenceAlignment/Consensus.vue.d.ts.map +1 -1
  6. package/dist/src/components/PlMultiSequenceAlignment/Legend.vue.d.ts +5 -1
  7. package/dist/src/components/PlMultiSequenceAlignment/Legend.vue.d.ts.map +1 -1
  8. package/dist/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts +5 -0
  9. package/dist/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts.map +1 -1
  10. package/dist/src/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.d.ts.map +1 -1
  11. package/dist/src/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts +4 -2
  12. package/dist/src/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts.map +1 -1
  13. package/dist/src/components/PlMultiSequenceAlignment/chemical-properties.d.ts +9 -0
  14. package/dist/src/components/PlMultiSequenceAlignment/chemical-properties.d.ts.map +1 -0
  15. package/dist/src/components/PlMultiSequenceAlignment/data.d.ts +32 -33
  16. package/dist/src/components/PlMultiSequenceAlignment/data.d.ts.map +1 -1
  17. package/dist/src/components/PlMultiSequenceAlignment/markup.d.ts +15 -0
  18. package/dist/src/components/PlMultiSequenceAlignment/markup.d.ts.map +1 -0
  19. package/dist/src/components/PlMultiSequenceAlignment/settings.d.ts +2 -2
  20. package/dist/src/components/PlMultiSequenceAlignment/settings.d.ts.map +1 -1
  21. package/dist/src/components/PlMultiSequenceAlignment/types.d.ts +17 -1
  22. package/dist/src/components/PlMultiSequenceAlignment/types.d.ts.map +1 -1
  23. package/dist/src/components/PlMultiSequenceAlignment/useMiPlots.d.ts.map +1 -1
  24. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  25. package/package.json +4 -4
  26. package/src/components/PlMultiSequenceAlignment/Consensus.vue +5 -5
  27. package/src/components/PlMultiSequenceAlignment/Legend.vue +9 -9
  28. package/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue +31 -40
  29. package/src/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue +110 -18
  30. package/src/components/PlMultiSequenceAlignment/Toolbar.vue +9 -10
  31. package/src/components/PlMultiSequenceAlignment/{highlight/chemical-properties.ts → chemical-properties.ts} +71 -68
  32. package/src/components/PlMultiSequenceAlignment/data.ts +159 -42
  33. package/src/components/PlMultiSequenceAlignment/markup.ts +107 -0
  34. package/src/components/PlMultiSequenceAlignment/settings.ts +2 -2
  35. package/src/components/PlMultiSequenceAlignment/types.ts +13 -1
  36. package/src/components/PlMultiSequenceAlignment/useMiPlots.ts +1 -2
  37. package/dist/src/components/PlMultiSequenceAlignment/highlight/chemical-properties.d.ts +0 -20
  38. package/dist/src/components/PlMultiSequenceAlignment/highlight/chemical-properties.d.ts.map +0 -1
  39. package/dist/src/components/PlMultiSequenceAlignment/highlight/index.d.ts +0 -7
  40. package/dist/src/components/PlMultiSequenceAlignment/highlight/index.d.ts.map +0 -1
  41. package/dist/src/components/PlMultiSequenceAlignment/highlight/types.d.ts +0 -8
  42. package/dist/src/components/PlMultiSequenceAlignment/highlight/types.d.ts.map +0 -1
  43. package/src/components/PlMultiSequenceAlignment/highlight/index.ts +0 -33
  44. package/src/components/PlMultiSequenceAlignment/highlight/types.ts +0 -7
@@ -5,6 +5,7 @@ import {
5
5
  type CanonicalizedJson,
6
6
  canonicalizeJson,
7
7
  createRowSelectionColumn,
8
+ ensureError,
8
9
  getAxisId,
9
10
  getRawPlatformaInstance,
10
11
  isLabelColumn,
@@ -20,13 +21,12 @@ import {
20
21
  pTableValue,
21
22
  } from '@platforma-sdk/model';
22
23
  import { computedAsync } from '@vueuse/core';
23
- import { type MaybeRefOrGetter, ref, toValue } from 'vue';
24
+ import { type MaybeRefOrGetter, ref, shallowRef, toValue } from 'vue';
25
+ import { type Markup, markupAlignedSequence, parseMarkup } from './markup';
24
26
  import { multiSequenceAlignment } from './multi-sequence-alignment';
25
27
 
26
28
  const getPFrameDriver = () => getRawPlatformaInstance().pFrameDriver;
27
29
 
28
- const getEmptyOptions = () => ({ defaults: [], options: [] });
29
-
30
30
  export const sequenceLimit = 1000;
31
31
 
32
32
  export function useSequenceColumnsOptions(
@@ -35,10 +35,20 @@ export function useSequenceColumnsOptions(
35
35
  sequenceColumnPredicate: PColumnPredicate;
36
36
  }>,
37
37
  ) {
38
- return computedAsync(
39
- () => getSequenceColumnsOptions(toValue(params)).catch(getEmptyOptions),
40
- getEmptyOptions(),
38
+ const error = shallowRef<Error>();
39
+ const data = computedAsync(
40
+ async () => {
41
+ try {
42
+ error.value = undefined;
43
+ return await getSequenceColumnsOptions(toValue(params));
44
+ } catch (err) {
45
+ error.value = ensureError(err);
46
+ return { options: [], defaults: [] };
47
+ }
48
+ },
49
+ { options: [], defaults: [] },
41
50
  );
51
+ return { data, error };
42
52
  }
43
53
 
44
54
  export function useLabelColumnsOptions(
@@ -50,10 +60,42 @@ export function useLabelColumnsOptions(
50
60
  | undefined;
51
61
  }>,
52
62
  ) {
53
- return computedAsync(
54
- () => getLabelColumnsOptions(toValue(params)).catch(getEmptyOptions),
55
- getEmptyOptions(),
63
+ const error = shallowRef<Error>();
64
+ const data = computedAsync(
65
+ async () => {
66
+ try {
67
+ error.value = undefined;
68
+ return await getLabelColumnsOptions(toValue(params));
69
+ } catch (err) {
70
+ error.value = ensureError(err);
71
+ return { options: [], defaults: [] };
72
+ }
73
+ },
74
+ { options: [], defaults: [] },
56
75
  );
76
+ return { data, error };
77
+ }
78
+
79
+ export function useMarkupColumnsOptions(
80
+ params: MaybeRefOrGetter<{
81
+ pFrame: PFrameHandle | undefined;
82
+ sequenceColumnIds: PObjectId[];
83
+ }>,
84
+ ) {
85
+ const error = shallowRef<Error>();
86
+ const data = computedAsync(
87
+ async () => {
88
+ try {
89
+ error.value = undefined;
90
+ return await getMarkupColumnsOptions(toValue(params));
91
+ } catch (err) {
92
+ error.value = ensureError(err);
93
+ return [];
94
+ }
95
+ },
96
+ [],
97
+ );
98
+ return { data, error };
57
99
  }
58
100
 
59
101
  export function useMultipleAlignmentData(
@@ -61,17 +103,27 @@ export function useMultipleAlignmentData(
61
103
  pframe: PFrameHandle | undefined;
62
104
  sequenceColumnIds: PObjectId[];
63
105
  labelColumnIds: PTableColumnId[];
106
+ markupColumnId: PObjectId | undefined;
64
107
  linkerColumnPredicate: PColumnPredicate | undefined;
65
108
  selection: PlSelectionModel | undefined;
66
109
  }>,
67
110
  ) {
68
111
  const loading = ref(true);
69
- const result = computedAsync(
70
- () => getMultipleAlignmentData(toValue(params)).catch(() => ({ sequences: [], labels: [] })),
112
+ const error = shallowRef<Error>();
113
+ const data = computedAsync(
114
+ async () => {
115
+ try {
116
+ error.value = undefined;
117
+ return await getMultipleAlignmentData(toValue(params));
118
+ } catch (err) {
119
+ error.value = ensureError(err);
120
+ return { sequences: [], labels: [] };
121
+ }
122
+ },
71
123
  { sequences: [], labels: [] },
72
124
  { evaluating: loading },
73
125
  );
74
- return { data: result, loading };
126
+ return { data, error, loading };
75
127
  }
76
128
 
77
129
  async function getSequenceColumnsOptions({
@@ -80,11 +132,8 @@ async function getSequenceColumnsOptions({
80
132
  }: {
81
133
  pFrame: PFrameHandle | undefined;
82
134
  sequenceColumnPredicate: (column: PColumnIdAndSpec) => boolean;
83
- }): Promise<{
84
- options: ListOptionNormalized<PObjectId>[];
85
- defaults: PObjectId[];
86
- }> {
87
- if (!pFrame) return getEmptyOptions();
135
+ }): Promise<OptionsWithDefaults<PObjectId>> {
136
+ if (!pFrame) return { options: [], defaults: [] };
88
137
  const pFrameDriver = getPFrameDriver();
89
138
  const columns = await pFrameDriver.listColumns(pFrame);
90
139
  const options = columns
@@ -107,11 +156,8 @@ async function getLabelColumnsOptions({
107
156
  labelColumnOptionPredicate:
108
157
  | ((column: PColumnIdAndSpec) => boolean)
109
158
  | undefined;
110
- }): Promise<{
111
- options: ListOptionNormalized<PTableColumnId>[];
112
- defaults: PTableColumnId[];
113
- }> {
114
- if (!pFrame) return getEmptyOptions();
159
+ }): Promise<OptionsWithDefaults<PTableColumnId>> {
160
+ if (!pFrame) return { options: [], defaults: [] };
115
161
  const pFrameDriver = getPFrameDriver();
116
162
  const columns = await pFrameDriver.listColumns(pFrame);
117
163
  const optionMap = new Map<CanonicalizedJson<PTableColumnId>, string>();
@@ -154,24 +200,52 @@ async function getLabelColumnsOptions({
154
200
  return { options, defaults };
155
201
  }
156
202
 
157
- async function getMultipleAlignmentData(
158
- {
159
- pframe,
160
- sequenceColumnIds,
161
- labelColumnIds,
162
- linkerColumnPredicate,
163
- selection,
164
- }: {
165
- pframe: PFrameHandle | undefined;
166
- sequenceColumnIds: PObjectId[];
167
- labelColumnIds: PTableColumnId[];
168
- linkerColumnPredicate: PColumnPredicate | undefined;
169
- selection: PlSelectionModel | undefined;
170
- },
171
- ): Promise<{
172
- sequences: string[][];
173
- labels: string[][];
174
- }> {
203
+ async function getMarkupColumnsOptions({
204
+ pFrame,
205
+ sequenceColumnIds,
206
+ }: {
207
+ pFrame: PFrameHandle | undefined;
208
+ sequenceColumnIds: PObjectId[];
209
+ }): Promise<ListOptionNormalized<PObjectId>[]> {
210
+ if (!pFrame || sequenceColumnIds.length !== 1) return [];
211
+ const pFrameDriver = getPFrameDriver();
212
+ const columns = await pFrameDriver.listColumns(pFrame);
213
+ const sequenceColumn = columns.find((column) =>
214
+ column.columnId === sequenceColumnIds[0],
215
+ );
216
+ if (!sequenceColumn) {
217
+ throw new Error(
218
+ `Couldn't find sequence column (ID: ${sequenceColumnIds[0]})`,
219
+ );
220
+ }
221
+ return columns
222
+ .filter((column) =>
223
+ column.spec.annotations?.['pl7.app/sequence/isAnnotation'] === 'true'
224
+ && isJsonEqual(sequenceColumn.spec.axesSpec, column.spec.axesSpec)
225
+ && Object.entries(sequenceColumn.spec.domain ?? {}).every((
226
+ [key, value],
227
+ ) => column.spec.domain?.[key] === value),
228
+ ).map(({ columnId, spec }) => ({
229
+ value: columnId,
230
+ label: spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',
231
+ }));
232
+ }
233
+
234
+ async function getMultipleAlignmentData({
235
+ pframe,
236
+ sequenceColumnIds,
237
+ labelColumnIds,
238
+ markupColumnId,
239
+ linkerColumnPredicate,
240
+ selection,
241
+ }: {
242
+ pframe: PFrameHandle | undefined;
243
+ sequenceColumnIds: PObjectId[];
244
+ labelColumnIds: PTableColumnId[];
245
+ markupColumnId: PObjectId | undefined;
246
+ linkerColumnPredicate: PColumnPredicate | undefined;
247
+ selection: PlSelectionModel | undefined;
248
+ }): Promise<MultipleAlignmentData> {
175
249
  if (!pframe || sequenceColumnIds.length === 0) {
176
250
  return { sequences: [], labels: [] };
177
251
  }
@@ -219,13 +293,18 @@ async function getMultipleAlignmentData(
219
293
  };
220
294
  }
221
295
 
296
+ // left join with labels
222
297
  const secondaryEntry: JoinEntry<PObjectId>[] = labelColumnIds
223
298
  .flatMap((column) => {
224
299
  if (column.type !== 'column') return [];
225
300
  return { type: 'column', column: column.id };
226
301
  });
227
302
 
228
- // left join with labels
303
+ // and markup
304
+ if (markupColumnId) {
305
+ secondaryEntry.push({ type: 'column', column: markupColumnId });
306
+ }
307
+
229
308
  const request: CalculateTableDataRequest<PObjectId> = {
230
309
  src: {
231
310
  type: 'outer',
@@ -281,6 +360,9 @@ async function getMultipleAlignmentData(
281
360
  return column;
282
361
  });
283
362
 
363
+ const markupColumn = markupColumnId
364
+ && table.find(({ spec }) => spec.id === markupColumnId);
365
+
284
366
  const alignedSequences = await Promise.all(
285
367
  sequenceColumns.map((column) =>
286
368
  multiSequenceAlignment(Array.from(
@@ -305,5 +387,40 @@ async function getMultipleAlignmentData(
305
387
  ),
306
388
  );
307
389
 
308
- return { sequences, labels };
390
+ const result: MultipleAlignmentData = { sequences, labels };
391
+
392
+ if (markupColumn) {
393
+ const labels = JSON.parse(
394
+ markupColumn.spec.spec.annotations
395
+ ?.['pl7.app/sequence/annotation/mapping'] ?? '{}',
396
+ );
397
+ const data = Array.from(
398
+ { length: rowCount },
399
+ (_, row) => {
400
+ const markup = parseMarkup(
401
+ pTableValue(markupColumn.data, row, { na: '', absent: '' })
402
+ ?.toString()
403
+ ?? '',
404
+ );
405
+ return markupAlignedSequence(sequences[row][0], markup);
406
+ },
407
+ );
408
+ result.markup = { labels, data };
409
+ }
410
+
411
+ return result;
309
412
  }
413
+
414
+ type MultipleAlignmentData = {
415
+ sequences: string[][];
416
+ labels: string[][];
417
+ markup?: {
418
+ labels: Record<string, string>;
419
+ data: Markup[];
420
+ };
421
+ };
422
+
423
+ type OptionsWithDefaults<T> = {
424
+ options: ListOptionNormalized<T>[];
425
+ defaults: T[];
426
+ };
@@ -0,0 +1,107 @@
1
+ import type { ColorMap } from './types';
2
+
3
+ export type Markup = { id: string; start: number; length: number }[];
4
+
5
+ export function parseMarkup(row: string): Markup {
6
+ return Array.from(row.matchAll(
7
+ /(?<id>[^:]*):(?<start>[0-9A-Za-z]*)(?:\+(?<length>[0-9A-Za-z]*))?\|?/g,
8
+ )).map((match) => {
9
+ const matchGroups = match.groups as {
10
+ id: string;
11
+ start: string;
12
+ length: string | undefined;
13
+ };
14
+ const start = Number.parseInt(matchGroups.start, 36);
15
+ const length = matchGroups.length
16
+ ? Number.parseInt(matchGroups.length, 36)
17
+ : 0;
18
+ return {
19
+ id: matchGroups.id,
20
+ start,
21
+ length,
22
+ };
23
+ });
24
+ }
25
+
26
+ export function markupAlignedSequence(
27
+ alignedSequence: string,
28
+ markup: Markup,
29
+ ): Markup {
30
+ const indexMap = alignedSequence.split('').reduce<number[]>(
31
+ (acc, char, index) => {
32
+ if (char !== '-') acc.push(index);
33
+ return acc;
34
+ },
35
+ [],
36
+ );
37
+ const adjusted = markup.map((segment) => {
38
+ const start = indexMap[segment.start];
39
+ const end = indexMap[segment.start + segment.length - 1] + 1;
40
+ return {
41
+ id: segment.id,
42
+ start: start,
43
+ length: end - start,
44
+ };
45
+ });
46
+ return adjusted;
47
+ }
48
+
49
+ export function colorizeSequencesByMarkup(
50
+ { markupRows, columnCount, colorMap }: {
51
+ markupRows: Markup[];
52
+ columnCount: number;
53
+ colorMap: ColorMap;
54
+ },
55
+ ): Promise<Blob> {
56
+ const canvas = new OffscreenCanvas(columnCount, markupRows.length);
57
+ const context = canvas.getContext('2d')!;
58
+ for (const [rowIndex, markup] of markupRows.entries()) {
59
+ for (const segment of markup) {
60
+ const color = colorMap[segment.id]?.color;
61
+ if (!color) continue;
62
+ context.fillStyle = color;
63
+ context.fillRect(segment.start, rowIndex, segment.length, 1);
64
+ }
65
+ }
66
+ return canvas.convertToBlob();
67
+ }
68
+
69
+ export const markupColors = [
70
+ '#E5F2FF',
71
+ '#FFE8E8',
72
+ '#F0EBFF',
73
+ '#FFFFE3',
74
+ '#E5F7E5',
75
+ '#FEEAFE',
76
+ '#FDEED6',
77
+ '#E8FDFE',
78
+ '#CCDFF2',
79
+ '#F2CCCD',
80
+ '#D5CCF2',
81
+ '#F2F2CC',
82
+ '#CCF2CC',
83
+ '#F2CCF2',
84
+ '#EFDDBF',
85
+ '#DEEEEF',
86
+ ];
87
+
88
+ if (import.meta.vitest) {
89
+ const { test, expect } = import.meta.vitest;
90
+ test('annotateAlignedRow', () => {
91
+ const alignedSequence
92
+ = 'EVRLVESGGALVQPGGSLRLSCVAASGFTFINNWVTWVRQAPGKGLEWVANIKEDGSQKYYVDSVKGRFTISRDNAEKSVYLQMSSLRVDDTAVYYCAR------------GRAV----D---QWGQGTLVTVSS';
93
+ // 0 10 20 30 40 50 60 70 80 90 100 110 120 130
94
+ // EVRLVESGGALVQPGGSLRLSCVAASGFTFINNWVTWVRQAPGKGLEWVANIKEDGSQKYYVDSVKGRFTISRDNAEKSVYLQMSSLRVDDTAVYYCARGRAVDQWGQGTLVTVSS
95
+ const markup = [
96
+ { id: '1', start: 0, length: 99 },
97
+ { id: '2', start: 99, length: 3 },
98
+ { id: '3', start: 102, length: 14 },
99
+ ];
100
+ const alignedMarkup = markupAlignedSequence(alignedSequence, markup);
101
+ expect(alignedMarkup).toEqual([
102
+ { id: '1', start: 0, length: 99 },
103
+ { id: '2', start: 111, length: 3 },
104
+ { id: '3', start: 114, length: 21 },
105
+ ]);
106
+ });
107
+ }
@@ -1,7 +1,7 @@
1
- import type { ColorScheme } from './types';
1
+ import type { ColorSchemeOption } from './types';
2
2
 
3
3
  export const defaultSettings = {
4
- colorScheme: 'chemical-properties' as ColorScheme,
4
+ colorScheme: { type: 'chemical-properties' } as ColorSchemeOption,
5
5
  consensus: true,
6
6
  seqLogo: true,
7
7
  legend: true,
@@ -1,3 +1,15 @@
1
- export type ColorScheme = 'chemical-properties' | 'no-color';
1
+ import type { PObjectId } from '@platforma-sdk/model';
2
+
3
+ export type ColorSchemeOption =
4
+ | { type: 'no-color' }
5
+ | { type: 'chemical-properties' }
6
+ | { type: 'markup'; columnId: PObjectId };
7
+
8
+ export type ColorScheme = {
9
+ type: ColorSchemeOption['type'];
10
+ colors: ColorMap;
11
+ };
12
+
13
+ export type ColorMap = Record<string, { label: string; color: string }>;
2
14
 
3
15
  export type ResidueCounts = Record<string, number>[];
@@ -1,6 +1,5 @@
1
- import { shallowRef } from 'vue';
2
- import { onMounted } from 'vue';
3
1
  import { ensureError } from '@platforma-sdk/model';
2
+ import { onMounted, shallowRef } from 'vue';
4
3
 
5
4
  export function useMiPlots() {
6
5
  const load = async () => {
@@ -1,20 +0,0 @@
1
- import type { ResidueCounts } from '../types';
2
- import type { SegmentedColumn } from './types';
3
- export declare const chemicalCategories: readonly ["hydrophobic", "positiveCharge", "negativeCharge", "polar", "cysteine", "glycine", "proline", "aromatic"];
4
- export type ChemicalCategory = typeof chemicalCategories[number];
5
- export declare const chemicalPropertiesLabels: Record<ChemicalCategory, string>;
6
- export declare const chemicalPropertiesColors: Record<ChemicalCategory, string>;
7
- type ColumnChemicalProperties = {
8
- residues: string;
9
- category: ChemicalCategory;
10
- }[];
11
- export declare const getColumnChemicalProperties: ({ residueCounts, rowCount }: {
12
- residueCounts: ResidueCounts;
13
- rowCount: number;
14
- }) => ColumnChemicalProperties[];
15
- export declare function alignedSequencesToSegmentedColumns({ alignedSequences, consensuses }: {
16
- alignedSequences: string[];
17
- consensuses: ColumnChemicalProperties[];
18
- }): SegmentedColumn<ChemicalCategory>[];
19
- export {};
20
- //# sourceMappingURL=chemical-properties.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chemical-properties.d.ts","sourceRoot":"","sources":["../../../../../src/components/PlMultiSequenceAlignment/highlight/chemical-properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,eAAO,MAAM,kBAAkB,qHASrB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAEjE,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CASrE,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CASrE,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,EAAE,CAAC;AAEJ,eAAO,MAAM,2BAA2B,gCACT;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB,KACA,wBAAwB,EAsBvB,CAAC;AAEL,wBAAgB,kCAAkC,CAChD,EAAE,gBAAgB,EAAE,WAAW,EAAE,EAAE;IACjC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,wBAAwB,EAAE,CAAC;CACzC,GACA,eAAe,CAAC,gBAAgB,CAAC,EAAE,CAuBrC"}
@@ -1,7 +0,0 @@
1
- import type { SegmentedColumn } from './types';
2
- export declare const colorizeSegmentedColumns: <T extends string>({ columns, rowCount, colors }: {
3
- columns: SegmentedColumn<T>[];
4
- rowCount: number;
5
- colors: Record<T, string>;
6
- }) => Blob;
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/PlMultiSequenceAlignment/highlight/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,MAAM,iCACxB;IAC7B,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;CAC3B,KACA,IAwBF,CAAC"}
@@ -1,8 +0,0 @@
1
- type ColumnSegment<T> = {
2
- category: T;
3
- start: number;
4
- end: number;
5
- };
6
- export type SegmentedColumn<T> = ColumnSegment<T>[];
7
- export {};
8
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/components/PlMultiSequenceAlignment/highlight/types.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,CAAC,CAAC,IAAI;IACtB,QAAQ,EAAE,CAAC,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC"}
@@ -1,33 +0,0 @@
1
- import type { SegmentedColumn } from './types';
2
-
3
- export const colorizeSegmentedColumns = <T extends string>(
4
- { columns, rowCount, colors }: {
5
- columns: SegmentedColumn<T>[];
6
- rowCount: number;
7
- colors: Record<T, string>;
8
- },
9
- ): Blob => {
10
- const pathsByColor: Record<string, string> = {};
11
- for (const [columnIndex, column] of columns.entries()) {
12
- for (const { category, start, end } of column) {
13
- const color = colors[category];
14
- pathsByColor[color] = (pathsByColor[color] ?? '').concat(
15
- [
16
- `M${columnIndex},${start}`,
17
- 'h1',
18
- `v${end - start + 1}`,
19
- 'h-1',
20
- 'z',
21
- ].join(''),
22
- );
23
- }
24
- }
25
- return new Blob([
26
- `<svg viewBox="0 0 ${columns.length} ${rowCount}" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">`,
27
- ...Object.entries(pathsByColor).map(
28
- ([color, pathDefinition]) =>
29
- `<path d="${pathDefinition}" fill="${color}" />`,
30
- ),
31
- `</svg>`,
32
- ], { type: 'image/svg+xml' });
33
- };
@@ -1,7 +0,0 @@
1
- type ColumnSegment<T> = {
2
- category: T;
3
- start: number;
4
- end: number;
5
- };
6
-
7
- export type SegmentedColumn<T> = ColumnSegment<T>[];