@jbrowse/plugin-linear-comparative-view 4.0.2 → 4.0.4

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 (26) hide show
  1. package/esm/LGVSyntenyDisplay/model.d.ts +20 -1
  2. package/esm/LinearComparativeDisplay/stateModelFactory.d.ts +3 -0
  3. package/esm/LinearComparativeView/components/LinearComparativeRenderArea.js +3 -0
  4. package/esm/LinearComparativeView/components/OpacitySlider.js +7 -3
  5. package/esm/LinearComparativeView/components/useRangeSelect.js +3 -0
  6. package/esm/LinearComparativeView/model.d.ts +33 -6
  7. package/esm/LinearSyntenyDisplay/afterAttach.js +9 -0
  8. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +15 -15
  9. package/esm/LinearSyntenyDisplay/components/util.d.ts +1 -0
  10. package/esm/LinearSyntenyDisplay/components/util.js +23 -38
  11. package/esm/LinearSyntenyDisplay/drawCigarClickMap.d.ts +2 -0
  12. package/esm/LinearSyntenyDisplay/drawCigarClickMap.js +88 -0
  13. package/esm/LinearSyntenyDisplay/{drawMouseoverClickMap.js → drawMouseover.js} +9 -11
  14. package/esm/LinearSyntenyDisplay/drawRef.d.ts +2 -0
  15. package/esm/LinearSyntenyDisplay/drawRef.js +190 -0
  16. package/esm/LinearSyntenyDisplay/drawSynteny.d.ts +4 -6
  17. package/esm/LinearSyntenyDisplay/drawSynteny.js +4 -461
  18. package/esm/LinearSyntenyDisplay/drawSyntenyUtils.d.ts +58 -0
  19. package/esm/LinearSyntenyDisplay/drawSyntenyUtils.js +62 -0
  20. package/esm/LinearSyntenyDisplay/model.d.ts +47 -2
  21. package/esm/LinearSyntenyDisplay/model.js +50 -2
  22. package/esm/LinearSyntenyView/model.d.ts +54 -18
  23. package/esm/LinearSyntenyView/model.js +23 -24
  24. package/esm/SyntenyFeatureDetail/LinkToSyntenyView.js +4 -4
  25. package/package.json +4 -4
  26. /package/esm/LinearSyntenyDisplay/{drawMouseoverClickMap.d.ts → drawMouseover.d.ts} +0 -0
@@ -1,461 +1,4 @@
1
- import { category10 } from '@jbrowse/core/ui/colors';
2
- import { doesIntersect2, getContainingView } from '@jbrowse/core/util';
3
- import { colord } from '@jbrowse/core/util/colord';
4
- import { draw, drawLocationMarkers, drawMatchSimple, } from "./components/util.js";
5
- export const MAX_COLOR_RANGE = 255 * 255 * 255;
6
- function makeColor(idx) {
7
- const r = Math.floor(idx / (255 * 255)) % 255;
8
- const g = Math.floor(idx / 255) % 255;
9
- const b = idx % 255;
10
- return `rgb(${r},${g},${b})`;
11
- }
12
- function hashString(str) {
13
- let hash = 0;
14
- for (let i = 0; i < str.length; i++) {
15
- const char = str.charCodeAt(i);
16
- hash = (hash << 5) - hash + char;
17
- hash = hash & hash;
18
- }
19
- return Math.abs(hash);
20
- }
21
- function getQueryColor(queryName) {
22
- const hash = hashString(queryName);
23
- return category10[hash % category10.length];
24
- }
25
- const defaultCigarColors = {
26
- I: '#ff03',
27
- N: '#0a03',
28
- D: '#00f3',
29
- X: 'brown',
30
- M: '#f003',
31
- '=': '#f003',
32
- };
33
- const strandCigarColors = {
34
- I: '#ff03',
35
- N: '#a020f0',
36
- D: '#a020f0',
37
- X: 'brown',
38
- M: '#f003',
39
- '=': '#f003',
40
- };
41
- const colorSchemes = {
42
- default: {
43
- cigarColors: defaultCigarColors,
44
- },
45
- strand: {
46
- posColor: 'red',
47
- negColor: 'blue',
48
- cigarColors: strandCigarColors,
49
- },
50
- query: {
51
- cigarColors: defaultCigarColors,
52
- },
53
- };
54
- function applyAlpha(color, alpha) {
55
- if (alpha === 1) {
56
- return color;
57
- }
58
- return colord(color).alpha(alpha).toHex();
59
- }
60
- const lineLimit = 3;
61
- const oobLimit = 1600;
62
- export function getId(r, g, b, unitMultiplier) {
63
- return Math.floor((r * 255 * 255 + g * 255 + b - 1) / unitMultiplier);
64
- }
65
- export function drawCigarClickMap(model, cigarClickMapCanvas) {
66
- const view = getContainingView(model);
67
- const drawCurves = view.drawCurves;
68
- const drawCIGAR = view.drawCIGAR;
69
- const drawCIGARMatchesOnly = view.drawCIGARMatchesOnly;
70
- const { level, height, featPositions } = model;
71
- const width = view.width;
72
- const bpPerPxs = view.views.map(v => v.bpPerPx);
73
- cigarClickMapCanvas.imageSmoothingEnabled = false;
74
- cigarClickMapCanvas.clearRect(0, 0, width, height);
75
- const offsets = view.views.map(v => v.offsetPx);
76
- const bpPerPxInv0 = 1 / bpPerPxs[level];
77
- const bpPerPxInv1 = 1 / bpPerPxs[level + 1];
78
- for (const { p11, p12, p21, p22, f, cigar } of featPositions) {
79
- const x11 = p11.offsetPx - offsets[level];
80
- const x12 = p12.offsetPx - offsets[level];
81
- const x21 = p21.offsetPx - offsets[level + 1];
82
- const x22 = p22.offsetPx - offsets[level + 1];
83
- const l1 = Math.abs(x12 - x11);
84
- const l2 = Math.abs(x22 - x21);
85
- const minX = Math.min(x21, x22);
86
- const maxX = Math.max(x21, x22);
87
- const y1 = 0;
88
- const y2 = height;
89
- const mid = (y2 - y1) / 2;
90
- if (!(l1 <= lineLimit && l2 <= lineLimit) &&
91
- doesIntersect2(minX, maxX, -oobLimit, view.width + oobLimit)) {
92
- const s1 = f.get('strand');
93
- const k1 = s1 === -1 ? x12 : x11;
94
- const k2 = s1 === -1 ? x11 : x12;
95
- const rev1 = k1 < k2 ? 1 : -1;
96
- const rev2 = (x21 < x22 ? 1 : -1) * s1;
97
- let cx1 = k1;
98
- let cx2 = s1 === -1 ? x22 : x21;
99
- if (cigar.length && drawCIGAR) {
100
- let continuingFlag = false;
101
- let px1 = 0;
102
- let px2 = 0;
103
- const unitMultiplier2 = Math.floor(MAX_COLOR_RANGE / cigar.length);
104
- for (let j = 0; j < cigar.length; j += 2) {
105
- const len = +cigar[j];
106
- const op = cigar[j + 1];
107
- if (!continuingFlag) {
108
- px1 = cx1;
109
- px2 = cx2;
110
- }
111
- const d1 = len * bpPerPxInv0;
112
- const d2 = len * bpPerPxInv1;
113
- if (op === 'M' || op === '=' || op === 'X') {
114
- cx1 += d1 * rev1;
115
- cx2 += d2 * rev2;
116
- }
117
- else if (op === 'D' || op === 'N') {
118
- cx1 += d1 * rev1;
119
- }
120
- else if (op === 'I') {
121
- cx2 += d2 * rev2;
122
- }
123
- if (!(Math.max(px1, px2, cx1, cx2) < 0 ||
124
- Math.min(px1, px2, cx1, cx2) > width)) {
125
- const isNotLast = j < cigar.length - 2;
126
- if (Math.abs(cx1 - px1) <= 1 &&
127
- Math.abs(cx2 - px2) <= 1 &&
128
- isNotLast) {
129
- continuingFlag = true;
130
- }
131
- else {
132
- continuingFlag = false;
133
- const shouldDraw = !drawCIGARMatchesOnly ||
134
- ((op === 'M' || op === '=' || op === 'X') &&
135
- Math.abs(cx1 - px1) > 1 &&
136
- Math.abs(cx2 - px2) > 1);
137
- if (shouldDraw) {
138
- const idx = j * unitMultiplier2 + 1;
139
- cigarClickMapCanvas.fillStyle = makeColor(idx);
140
- draw(cigarClickMapCanvas, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
141
- cigarClickMapCanvas.fill();
142
- }
143
- }
144
- }
145
- }
146
- }
147
- }
148
- }
149
- }
150
- export function drawRef(model, mainCanvas) {
151
- const view = getContainingView(model);
152
- const drawCurves = view.drawCurves;
153
- const drawCIGAR = view.drawCIGAR;
154
- const drawCIGARMatchesOnly = view.drawCIGARMatchesOnly;
155
- const drawLocationMarkersEnabled = view.drawLocationMarkers;
156
- const { level, height, featPositions, alpha, minAlignmentLength, colorBy } = model;
157
- const width = view.width;
158
- const bpPerPxs = view.views.map(v => v.bpPerPx);
159
- const queryTotalLengths = new Map();
160
- if (minAlignmentLength > 0) {
161
- for (const { f } of featPositions) {
162
- const queryName = f.get('name') || f.get('id') || f.id();
163
- const alignmentLength = Math.abs(f.get('end') - f.get('start'));
164
- const currentTotal = queryTotalLengths.get(queryName) || 0;
165
- queryTotalLengths.set(queryName, currentTotal + alignmentLength);
166
- }
167
- }
168
- const schemeConfig = colorSchemes[colorBy] || colorSchemes.default;
169
- const activeColorMap = schemeConfig.cigarColors;
170
- const posColor = colorBy === 'strand' ? colorSchemes.strand.posColor : 'red';
171
- const negColor = colorBy === 'strand' ? colorSchemes.strand.negColor : 'blue';
172
- const colorMapWithAlpha = {
173
- I: applyAlpha(activeColorMap.I, alpha),
174
- N: applyAlpha(activeColorMap.N, alpha),
175
- D: applyAlpha(activeColorMap.D, alpha),
176
- X: applyAlpha(activeColorMap.X, alpha),
177
- M: applyAlpha(activeColorMap.M, alpha),
178
- '=': applyAlpha(activeColorMap['='], alpha),
179
- };
180
- const posColorWithAlpha = applyAlpha(posColor, alpha);
181
- const negColorWithAlpha = applyAlpha(negColor, alpha);
182
- const queryColorCache = new Map();
183
- const getQueryColorWithAlpha = (queryName) => {
184
- if (!queryColorCache.has(queryName)) {
185
- const color = getQueryColor(queryName);
186
- queryColorCache.set(queryName, applyAlpha(color, alpha));
187
- }
188
- return queryColorCache.get(queryName);
189
- };
190
- mainCanvas.beginPath();
191
- const offsets = view.views.map(v => v.offsetPx);
192
- const offsetsL0 = offsets[level];
193
- const offsetsL1 = offsets[level + 1];
194
- const unitMultiplier = Math.floor(MAX_COLOR_RANGE / featPositions.length);
195
- const y1 = 0;
196
- const y2 = height;
197
- const mid = (y2 - y1) / 2;
198
- const useStrandColorThin = colorBy === 'strand';
199
- const useQueryColorThin = colorBy === 'query';
200
- mainCanvas.fillStyle = colorMapWithAlpha.M;
201
- mainCanvas.strokeStyle = colorMapWithAlpha.M;
202
- const thinLinesByColor = new Map();
203
- for (const { p11, p12, p21, p22, f } of featPositions) {
204
- if (minAlignmentLength > 0) {
205
- const queryName = f.get('name') || f.get('id') || f.id();
206
- const totalLength = queryTotalLengths.get(queryName) || 0;
207
- if (totalLength < minAlignmentLength) {
208
- continue;
209
- }
210
- }
211
- const x11 = p11.offsetPx - offsetsL0;
212
- const x12 = p12.offsetPx - offsetsL0;
213
- const x21 = p21.offsetPx - offsetsL1;
214
- const x22 = p22.offsetPx - offsetsL1;
215
- const l1 = Math.abs(x12 - x11);
216
- const l2 = Math.abs(x22 - x21);
217
- if (l1 <= lineLimit &&
218
- l2 <= lineLimit &&
219
- x21 < width + oobLimit &&
220
- x21 > -oobLimit) {
221
- let colorKey = 'default';
222
- if (useStrandColorThin) {
223
- const strand = f.get('strand');
224
- colorKey = strand === -1 ? 'neg' : 'pos';
225
- }
226
- else if (useQueryColorThin) {
227
- colorKey = f.get('refName');
228
- }
229
- if (!thinLinesByColor.has(colorKey)) {
230
- thinLinesByColor.set(colorKey, []);
231
- }
232
- thinLinesByColor.get(colorKey).push({ x11, x21, y1, y2, mid });
233
- }
234
- }
235
- for (const [colorKey, lines] of thinLinesByColor) {
236
- if (colorKey === 'pos') {
237
- mainCanvas.strokeStyle = posColorWithAlpha;
238
- }
239
- else if (colorKey === 'neg') {
240
- mainCanvas.strokeStyle = negColorWithAlpha;
241
- }
242
- else if (colorKey !== 'default') {
243
- mainCanvas.strokeStyle = getQueryColorWithAlpha(colorKey);
244
- }
245
- else {
246
- mainCanvas.strokeStyle = colorMapWithAlpha.M;
247
- }
248
- mainCanvas.beginPath();
249
- if (drawCurves) {
250
- for (const { x11, x21, y1, y2, mid } of lines) {
251
- mainCanvas.moveTo(x11, y1);
252
- mainCanvas.bezierCurveTo(x11, mid, x21, mid, x21, y2);
253
- }
254
- }
255
- else {
256
- for (const { x11, x21, y1, y2 } of lines) {
257
- mainCanvas.moveTo(x11, y1);
258
- mainCanvas.lineTo(x21, y2);
259
- }
260
- }
261
- mainCanvas.stroke();
262
- }
263
- const bpPerPx0 = bpPerPxs[level];
264
- const bpPerPx1 = bpPerPxs[level + 1];
265
- const bpPerPxInv0 = 1 / bpPerPx0;
266
- const bpPerPxInv1 = 1 / bpPerPx1;
267
- const useStrandColor = colorBy === 'strand';
268
- const useQueryColor = colorBy === 'query';
269
- mainCanvas.fillStyle = colorMapWithAlpha.M;
270
- mainCanvas.strokeStyle = colorMapWithAlpha.M;
271
- for (const { p11, p12, p21, p22, f, cigar } of featPositions) {
272
- const strand = f.get('strand');
273
- const refName = f.get('refName');
274
- if (minAlignmentLength > 0) {
275
- const queryName = f.get('name') || f.get('id') || f.id();
276
- const totalLength = queryTotalLengths.get(queryName) || 0;
277
- if (totalLength < minAlignmentLength) {
278
- continue;
279
- }
280
- }
281
- const x11 = p11.offsetPx - offsetsL0;
282
- const x12 = p12.offsetPx - offsetsL0;
283
- const x21 = p21.offsetPx - offsetsL1;
284
- const x22 = p22.offsetPx - offsetsL1;
285
- const l1 = Math.abs(x12 - x11);
286
- const l2 = Math.abs(x22 - x21);
287
- const minX = Math.min(x21, x22);
288
- const maxX = Math.max(x21, x22);
289
- if (!(l1 <= lineLimit && l2 <= lineLimit) &&
290
- doesIntersect2(minX, maxX, -oobLimit, view.width + oobLimit)) {
291
- const s1 = strand;
292
- const k1 = s1 === -1 ? x12 : x11;
293
- const k2 = s1 === -1 ? x11 : x12;
294
- const rev1 = k1 < k2 ? 1 : -1;
295
- const rev2 = (x21 < x22 ? 1 : -1) * s1;
296
- let cx1 = k1;
297
- let cx2 = s1 === -1 ? x22 : x21;
298
- if (cigar.length && drawCIGAR) {
299
- let continuingFlag = false;
300
- let px1 = 0;
301
- let px2 = 0;
302
- for (let j = 0; j < cigar.length; j += 2) {
303
- const len = +cigar[j];
304
- const op = cigar[j + 1];
305
- if (!continuingFlag) {
306
- px1 = cx1;
307
- px2 = cx2;
308
- }
309
- const d1 = len * bpPerPxInv0;
310
- const d2 = len * bpPerPxInv1;
311
- if (op === 'M' || op === '=' || op === 'X') {
312
- cx1 += d1 * rev1;
313
- cx2 += d2 * rev2;
314
- }
315
- else if (op === 'D' || op === 'N') {
316
- cx1 += d1 * rev1;
317
- }
318
- else if (op === 'I') {
319
- cx2 += d2 * rev2;
320
- }
321
- if (!(Math.max(px1, px2, cx1, cx2) < 0 ||
322
- Math.min(px1, px2, cx1, cx2) > width)) {
323
- const isNotLast = j < cigar.length - 2;
324
- if (Math.abs(cx1 - px1) <= 1 &&
325
- Math.abs(cx2 - px2) <= 1 &&
326
- isNotLast) {
327
- continuingFlag = true;
328
- }
329
- else {
330
- const letter = (continuingFlag && d1 > 1) || d2 > 1 ? op : 'M';
331
- const isInsertionOrDeletion = letter === 'I' || letter === 'D' || letter === 'N';
332
- if (useStrandColor && !isInsertionOrDeletion) {
333
- mainCanvas.fillStyle =
334
- strand === -1 ? negColorWithAlpha : posColorWithAlpha;
335
- }
336
- else if (useQueryColor && !isInsertionOrDeletion) {
337
- mainCanvas.fillStyle = getQueryColorWithAlpha(refName);
338
- }
339
- else {
340
- mainCanvas.fillStyle = colorMapWithAlpha[letter];
341
- }
342
- continuingFlag = false;
343
- if (drawCIGARMatchesOnly) {
344
- if (letter === 'M') {
345
- draw(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
346
- mainCanvas.fill();
347
- if (drawLocationMarkersEnabled) {
348
- drawLocationMarkers(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, bpPerPx0, bpPerPx1, drawCurves);
349
- }
350
- }
351
- }
352
- else {
353
- draw(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
354
- mainCanvas.fill();
355
- if (drawLocationMarkersEnabled) {
356
- drawLocationMarkers(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, bpPerPx0, bpPerPx1, drawCurves);
357
- }
358
- }
359
- }
360
- }
361
- }
362
- }
363
- else {
364
- if (useStrandColor) {
365
- mainCanvas.fillStyle =
366
- strand === -1 ? negColorWithAlpha : posColorWithAlpha;
367
- }
368
- else if (useQueryColor) {
369
- mainCanvas.fillStyle = getQueryColorWithAlpha(refName);
370
- }
371
- draw(mainCanvas, x11, x12, y1, x22, x21, y2, mid, drawCurves);
372
- mainCanvas.fill();
373
- if (useStrandColor || useQueryColor) {
374
- mainCanvas.fillStyle = colorMapWithAlpha.M;
375
- }
376
- }
377
- }
378
- }
379
- const ctx2 = model.clickMapCanvas?.getContext('2d');
380
- if (!ctx2) {
381
- return;
382
- }
383
- ctx2.imageSmoothingEnabled = false;
384
- ctx2.clearRect(0, 0, width, height);
385
- for (let i = 0; i < featPositions.length; i++) {
386
- const feature = featPositions[i];
387
- if (minAlignmentLength > 0) {
388
- const queryName = feature.f.get('name') || feature.f.get('id') || feature.f.id();
389
- const totalLength = queryTotalLengths.get(queryName) || 0;
390
- if (totalLength < minAlignmentLength) {
391
- continue;
392
- }
393
- }
394
- const idx = i * unitMultiplier + 1;
395
- ctx2.fillStyle = makeColor(idx);
396
- drawMatchSimple({
397
- cb: ctx => {
398
- ctx.fill();
399
- },
400
- feature,
401
- ctx: ctx2,
402
- drawCurves,
403
- level,
404
- offsets,
405
- oobLimit,
406
- viewWidth: view.width,
407
- hideTiny: true,
408
- height,
409
- });
410
- }
411
- }
412
- export function drawMouseoverClickMap(model) {
413
- const { level, clickId, mouseoverId } = model;
414
- const highResolutionScaling = 1;
415
- const view = getContainingView(model);
416
- const drawCurves = view.drawCurves;
417
- const height = model.height;
418
- const width = view.width;
419
- const ctx = model.mouseoverCanvas?.getContext('2d');
420
- const offsets = view.views.map(v => v.offsetPx);
421
- if (!ctx) {
422
- return;
423
- }
424
- ctx.resetTransform();
425
- ctx.scale(highResolutionScaling, highResolutionScaling);
426
- ctx.clearRect(0, 0, width, height);
427
- ctx.strokeStyle = 'rgba(0, 0, 0, 0.9)';
428
- ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
429
- const feature1 = model.featMap[mouseoverId || ''];
430
- if (feature1) {
431
- drawMatchSimple({
432
- cb: ctx => {
433
- ctx.fill();
434
- },
435
- feature: feature1,
436
- level,
437
- ctx,
438
- oobLimit,
439
- viewWidth: view.width,
440
- drawCurves,
441
- offsets,
442
- height,
443
- });
444
- }
445
- const feature2 = model.featMap[clickId || ''];
446
- if (feature2) {
447
- drawMatchSimple({
448
- cb: ctx => {
449
- ctx.stroke();
450
- },
451
- feature: feature2,
452
- ctx,
453
- level,
454
- oobLimit,
455
- viewWidth: view.width,
456
- drawCurves,
457
- offsets,
458
- height,
459
- });
460
- }
461
- }
1
+ export { drawCigarClickMap } from "./drawCigarClickMap.js";
2
+ export { drawMouseoverClickMap } from "./drawMouseover.js";
3
+ export { drawRef } from "./drawRef.js";
4
+ export { MAX_COLOR_RANGE, getId } from "./drawSyntenyUtils.js";
@@ -0,0 +1,58 @@
1
+ export declare const MAX_COLOR_RANGE: number;
2
+ export declare const lineLimit = 3;
3
+ export declare const oobLimit = 1600;
4
+ export declare function makeColor(idx: number): string;
5
+ export declare function getId(r: number, g: number, b: number, unitMultiplier: number): number;
6
+ export declare function getQueryColor(queryName: string): string;
7
+ export declare const defaultCigarColors: {
8
+ I: string;
9
+ N: string;
10
+ D: string;
11
+ X: string;
12
+ M: string;
13
+ '=': string;
14
+ };
15
+ export declare const strandCigarColors: {
16
+ I: string;
17
+ N: string;
18
+ D: string;
19
+ X: string;
20
+ M: string;
21
+ '=': string;
22
+ };
23
+ export declare const colorSchemes: {
24
+ default: {
25
+ cigarColors: {
26
+ I: string;
27
+ N: string;
28
+ D: string;
29
+ X: string;
30
+ M: string;
31
+ '=': string;
32
+ };
33
+ };
34
+ strand: {
35
+ posColor: string;
36
+ negColor: string;
37
+ cigarColors: {
38
+ I: string;
39
+ N: string;
40
+ D: string;
41
+ X: string;
42
+ M: string;
43
+ '=': string;
44
+ };
45
+ };
46
+ query: {
47
+ cigarColors: {
48
+ I: string;
49
+ N: string;
50
+ D: string;
51
+ X: string;
52
+ M: string;
53
+ '=': string;
54
+ };
55
+ };
56
+ };
57
+ export type ColorScheme = keyof typeof colorSchemes;
58
+ export declare function applyAlpha(color: string, alpha: number): string;
@@ -0,0 +1,62 @@
1
+ import { category10 } from '@jbrowse/core/ui/colors';
2
+ import { colord } from '@jbrowse/core/util/colord';
3
+ export const MAX_COLOR_RANGE = 255 * 255 * 255;
4
+ export const lineLimit = 3;
5
+ export const oobLimit = 1600;
6
+ export function makeColor(idx) {
7
+ const r = Math.floor(idx / (255 * 255)) % 255;
8
+ const g = Math.floor(idx / 255) % 255;
9
+ const b = idx % 255;
10
+ return `rgb(${r},${g},${b})`;
11
+ }
12
+ export function getId(r, g, b, unitMultiplier) {
13
+ return Math.floor((r * 255 * 255 + g * 255 + b - 1) / unitMultiplier);
14
+ }
15
+ function hashString(str) {
16
+ let hash = 0;
17
+ for (let i = 0; i < str.length; i++) {
18
+ const char = str.charCodeAt(i);
19
+ hash = (hash << 5) - hash + char;
20
+ hash = hash & hash;
21
+ }
22
+ return Math.abs(hash);
23
+ }
24
+ export function getQueryColor(queryName) {
25
+ const hash = hashString(queryName);
26
+ return category10[hash % category10.length];
27
+ }
28
+ export const defaultCigarColors = {
29
+ I: '#ff03',
30
+ N: '#0a03',
31
+ D: '#00f3',
32
+ X: 'brown',
33
+ M: '#f003',
34
+ '=': '#f003',
35
+ };
36
+ export const strandCigarColors = {
37
+ I: '#ff03',
38
+ N: '#a020f0',
39
+ D: '#a020f0',
40
+ X: 'brown',
41
+ M: '#f003',
42
+ '=': '#f003',
43
+ };
44
+ export const colorSchemes = {
45
+ default: {
46
+ cigarColors: defaultCigarColors,
47
+ },
48
+ strand: {
49
+ posColor: 'red',
50
+ negColor: 'blue',
51
+ cigarColors: strandCigarColors,
52
+ },
53
+ query: {
54
+ cigarColors: defaultCigarColors,
55
+ },
56
+ };
57
+ export function applyAlpha(color, alpha) {
58
+ if (alpha === 1) {
59
+ return color;
60
+ }
61
+ return colord(color).alpha(alpha).toHex();
62
+ }
@@ -23,6 +23,8 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
23
23
  type: import("@jbrowse/mobx-state-tree").ISimpleType<"LinearSyntenyDisplay">;
24
24
  configuration: AnyConfigurationSchemaType;
25
25
  colorBy: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
26
+ alpha: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<number>, [undefined]>;
27
+ minAlignmentLength: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<number>, [undefined]>;
26
28
  }, {
27
29
  rendererTypeName: string;
28
30
  error: unknown;
@@ -70,6 +72,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
70
72
  }> | null;
71
73
  readonly adapterConfig: any;
72
74
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
75
+ readonly isMinimized: boolean;
73
76
  readonly parentDisplay: any;
74
77
  readonly effectiveRpcDriverName: any;
75
78
  } & {
@@ -126,6 +129,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
126
129
  }> | null;
127
130
  readonly adapterConfig: any;
128
131
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
132
+ readonly isMinimized: boolean;
129
133
  readonly parentDisplay: any;
130
134
  readonly effectiveRpcDriverName: any;
131
135
  } & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/mobx-state-tree").IModelType<{
@@ -179,6 +183,7 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
179
183
  }> | null;
180
184
  readonly adapterConfig: any;
181
185
  readonly parentTrack: import("@jbrowse/core/util").AbstractTrackModel;
186
+ readonly isMinimized: boolean;
182
187
  readonly parentDisplay: any;
183
188
  readonly effectiveRpcDriverName: any;
184
189
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>;
@@ -221,8 +226,6 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
221
226
  mouseoverId: string | undefined;
222
227
  clickId: string | undefined;
223
228
  cigarMouseoverId: number;
224
- alpha: number;
225
- minAlignmentLength: number;
226
229
  } & {
227
230
  setFeatPositions(arg: FeatPos[]): void;
228
231
  setMainCanvasRef(ref: HTMLCanvasElement | null): void;
@@ -243,6 +246,48 @@ declare function stateModelFactory(configSchema: AnyConfigurationSchemaType): im
243
246
  readonly featMap: {
244
247
  [k: string]: FeatPos;
245
248
  };
249
+ readonly colorSchemeConfig: {
250
+ cigarColors: {
251
+ I: string;
252
+ N: string;
253
+ D: string;
254
+ X: string;
255
+ M: string;
256
+ '=': string;
257
+ };
258
+ } | {
259
+ posColor: string;
260
+ negColor: string;
261
+ cigarColors: {
262
+ I: string;
263
+ N: string;
264
+ D: string;
265
+ X: string;
266
+ M: string;
267
+ '=': string;
268
+ };
269
+ } | {
270
+ cigarColors: {
271
+ I: string;
272
+ N: string;
273
+ D: string;
274
+ X: string;
275
+ M: string;
276
+ '=': string;
277
+ };
278
+ };
279
+ readonly colorMapWithAlpha: {
280
+ I: string;
281
+ N: string;
282
+ D: string;
283
+ X: string;
284
+ M: string;
285
+ '=': string;
286
+ };
287
+ readonly posColorWithAlpha: string;
288
+ readonly negColorWithAlpha: string;
289
+ readonly queryColorWithAlphaMap: (queryName: string) => string;
290
+ readonly queryTotalLengths: Map<string, number> | undefined;
246
291
  } & {
247
292
  afterAttach(): void;
248
293
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;