@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,12 +1,6 @@
1
1
  import { getContainingView } from '@jbrowse/core/util';
2
2
  import { drawMatchSimple } from "./components/util.js";
3
- const oobLimit = 1600;
4
- const fillCallback = (ctx) => {
5
- ctx.fill();
6
- };
7
- const strokeCallback = (ctx) => {
8
- ctx.stroke();
9
- };
3
+ import { oobLimit } from "./drawSyntenyUtils.js";
10
4
  export function drawMouseoverClickMap(model) {
11
5
  const { level, clickId, mouseoverId } = model;
12
6
  const view = getContainingView(model);
@@ -25,12 +19,14 @@ export function drawMouseoverClickMap(model) {
25
19
  const feature1 = model.featMap[mouseoverId || ''];
26
20
  if (feature1) {
27
21
  drawMatchSimple({
28
- cb: fillCallback,
22
+ cb: ctx => {
23
+ ctx.fill();
24
+ },
29
25
  feature: feature1,
30
26
  level,
31
27
  ctx,
32
28
  oobLimit,
33
- viewWidth: width,
29
+ viewWidth: view.width,
34
30
  drawCurves,
35
31
  offsets,
36
32
  height,
@@ -39,12 +35,14 @@ export function drawMouseoverClickMap(model) {
39
35
  const feature2 = model.featMap[clickId || ''];
40
36
  if (feature2) {
41
37
  drawMatchSimple({
42
- cb: strokeCallback,
38
+ cb: ctx => {
39
+ ctx.stroke();
40
+ },
43
41
  feature: feature2,
44
42
  ctx,
45
43
  level,
46
44
  oobLimit,
47
- viewWidth: width,
45
+ viewWidth: view.width,
48
46
  drawCurves,
49
47
  offsets,
50
48
  height,
@@ -0,0 +1,2 @@
1
+ import type { LinearSyntenyDisplayModel } from './model.ts';
2
+ export declare function drawRef(model: LinearSyntenyDisplayModel, mainCanvas: CanvasRenderingContext2D): void;
@@ -0,0 +1,190 @@
1
+ import { doesIntersect2, getContainingView } from '@jbrowse/core/util';
2
+ import { draw, drawLocationMarkers, drawMatchSimple, } from "./components/util.js";
3
+ import { MAX_COLOR_RANGE, lineLimit, makeColor, oobLimit, } from "./drawSyntenyUtils.js";
4
+ const fillCb = (ctx) => {
5
+ ctx.fill();
6
+ };
7
+ export function drawRef(model, mainCanvas) {
8
+ const view = getContainingView(model);
9
+ const drawCurves = view.drawCurves;
10
+ const drawCIGAR = view.drawCIGAR;
11
+ const drawCIGARMatchesOnly = view.drawCIGARMatchesOnly;
12
+ const drawLocationMarkersEnabled = view.drawLocationMarkers;
13
+ const { level, height, featPositions, minAlignmentLength, colorBy } = model;
14
+ const width = view.width;
15
+ const bpPerPxs = view.views.map(v => v.bpPerPx);
16
+ const colorMapWithAlpha = model.colorMapWithAlpha;
17
+ const posColorWithAlpha = model.posColorWithAlpha;
18
+ const negColorWithAlpha = model.negColorWithAlpha;
19
+ const getQueryColorWithAlpha = model.queryColorWithAlphaMap;
20
+ const queryTotalLengths = model.queryTotalLengths;
21
+ const offsets = view.views.map(v => v.offsetPx);
22
+ const offsetsL0 = offsets[level];
23
+ const offsetsL1 = offsets[level + 1];
24
+ const unitMultiplier = Math.floor(MAX_COLOR_RANGE / featPositions.length);
25
+ const y1 = 0;
26
+ const y2 = height;
27
+ const mid = (y2 - y1) / 2;
28
+ const useStrandColor = colorBy === 'strand';
29
+ const useQueryColor = colorBy === 'query';
30
+ const bpPerPx0 = bpPerPxs[level];
31
+ const bpPerPx1 = bpPerPxs[level + 1];
32
+ const bpPerPxInv0 = 1 / bpPerPx0;
33
+ const bpPerPxInv1 = 1 / bpPerPx1;
34
+ const clickMapCtx = model.clickMapCanvas?.getContext('2d');
35
+ if (clickMapCtx) {
36
+ clickMapCtx.imageSmoothingEnabled = false;
37
+ clickMapCtx.clearRect(0, 0, width, height);
38
+ }
39
+ mainCanvas.fillStyle = colorMapWithAlpha.M;
40
+ mainCanvas.strokeStyle = colorMapWithAlpha.M;
41
+ for (const [i, featPosition] of featPositions.entries()) {
42
+ const feature = featPosition;
43
+ const { p11, p12, p21, p22, f, cigar } = feature;
44
+ const strand = f.get('strand');
45
+ const refName = f.get('refName');
46
+ if (queryTotalLengths) {
47
+ const queryName = f.get('name') || f.get('id') || f.id();
48
+ const totalLength = queryTotalLengths.get(queryName) || 0;
49
+ if (totalLength < minAlignmentLength) {
50
+ continue;
51
+ }
52
+ }
53
+ const x11 = p11.offsetPx - offsetsL0;
54
+ const x12 = p12.offsetPx - offsetsL0;
55
+ const x21 = p21.offsetPx - offsetsL1;
56
+ const x22 = p22.offsetPx - offsetsL1;
57
+ const l1 = Math.abs(x12 - x11);
58
+ const l2 = Math.abs(x22 - x21);
59
+ const minX = Math.min(x21, x22);
60
+ const maxX = Math.max(x21, x22);
61
+ if (l1 <= lineLimit &&
62
+ l2 <= lineLimit &&
63
+ x21 < width + oobLimit &&
64
+ x21 > -oobLimit) {
65
+ if (useStrandColor) {
66
+ mainCanvas.strokeStyle =
67
+ strand === -1 ? negColorWithAlpha : posColorWithAlpha;
68
+ }
69
+ else if (useQueryColor) {
70
+ mainCanvas.strokeStyle = getQueryColorWithAlpha(refName);
71
+ }
72
+ else {
73
+ mainCanvas.strokeStyle = colorMapWithAlpha.M;
74
+ }
75
+ mainCanvas.beginPath();
76
+ mainCanvas.moveTo(x11, y1);
77
+ if (drawCurves) {
78
+ mainCanvas.bezierCurveTo(x11, mid, x21, mid, x21, y2);
79
+ }
80
+ else {
81
+ mainCanvas.lineTo(x21, y2);
82
+ }
83
+ mainCanvas.stroke();
84
+ }
85
+ else if (doesIntersect2(minX, maxX, -oobLimit, view.width + oobLimit)) {
86
+ const s1 = strand;
87
+ const k1 = s1 === -1 ? x12 : x11;
88
+ const k2 = s1 === -1 ? x11 : x12;
89
+ const rev1 = k1 < k2 ? 1 : -1;
90
+ const rev2 = (x21 < x22 ? 1 : -1) * s1;
91
+ let cx1 = k1;
92
+ let cx2 = s1 === -1 ? x22 : x21;
93
+ if (cigar.length && drawCIGAR) {
94
+ let continuingFlag = false;
95
+ let px1 = 0;
96
+ let px2 = 0;
97
+ for (let j = 0; j < cigar.length; j += 2) {
98
+ const len = +cigar[j];
99
+ const op = cigar[j + 1];
100
+ if (!continuingFlag) {
101
+ px1 = cx1;
102
+ px2 = cx2;
103
+ }
104
+ const d1 = len * bpPerPxInv0;
105
+ const d2 = len * bpPerPxInv1;
106
+ if (op === 'M' || op === '=' || op === 'X') {
107
+ cx1 += d1 * rev1;
108
+ cx2 += d2 * rev2;
109
+ }
110
+ else if (op === 'D' || op === 'N') {
111
+ cx1 += d1 * rev1;
112
+ }
113
+ else if (op === 'I') {
114
+ cx2 += d2 * rev2;
115
+ }
116
+ if (!(Math.max(px1, px2, cx1, cx2) < 0 ||
117
+ Math.min(px1, px2, cx1, cx2) > width)) {
118
+ const isNotLast = j < cigar.length - 2;
119
+ if (Math.abs(cx1 - px1) <= 1 &&
120
+ Math.abs(cx2 - px2) <= 1 &&
121
+ isNotLast) {
122
+ continuingFlag = true;
123
+ }
124
+ else {
125
+ const letter = (continuingFlag && d1 > 1) || d2 > 1 ? op : 'M';
126
+ const isInsertionOrDeletion = letter === 'I' || letter === 'D' || letter === 'N';
127
+ if (useStrandColor && !isInsertionOrDeletion) {
128
+ mainCanvas.fillStyle =
129
+ strand === -1 ? negColorWithAlpha : posColorWithAlpha;
130
+ }
131
+ else if (useQueryColor && !isInsertionOrDeletion) {
132
+ mainCanvas.fillStyle = getQueryColorWithAlpha(refName);
133
+ }
134
+ else {
135
+ mainCanvas.fillStyle = colorMapWithAlpha[letter];
136
+ }
137
+ continuingFlag = false;
138
+ if (drawCIGARMatchesOnly) {
139
+ if (letter === 'M') {
140
+ draw(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
141
+ mainCanvas.fill();
142
+ if (drawLocationMarkersEnabled) {
143
+ drawLocationMarkers(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, bpPerPx0, bpPerPx1, drawCurves);
144
+ }
145
+ }
146
+ }
147
+ else {
148
+ draw(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, drawCurves);
149
+ mainCanvas.fill();
150
+ if (drawLocationMarkersEnabled) {
151
+ drawLocationMarkers(mainCanvas, px1, cx1, y1, cx2, px2, y2, mid, bpPerPx0, bpPerPx1, drawCurves);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ else {
159
+ if (useStrandColor) {
160
+ mainCanvas.fillStyle =
161
+ strand === -1 ? negColorWithAlpha : posColorWithAlpha;
162
+ }
163
+ else if (useQueryColor) {
164
+ mainCanvas.fillStyle = getQueryColorWithAlpha(refName);
165
+ }
166
+ draw(mainCanvas, x11, x12, y1, x22, x21, y2, mid, drawCurves);
167
+ mainCanvas.fill();
168
+ if (useStrandColor || useQueryColor) {
169
+ mainCanvas.fillStyle = colorMapWithAlpha.M;
170
+ }
171
+ }
172
+ }
173
+ if (clickMapCtx) {
174
+ const idx = i * unitMultiplier + 1;
175
+ clickMapCtx.fillStyle = makeColor(idx);
176
+ drawMatchSimple({
177
+ cb: fillCb,
178
+ feature,
179
+ ctx: clickMapCtx,
180
+ drawCurves,
181
+ level,
182
+ offsets,
183
+ oobLimit,
184
+ viewWidth: view.width,
185
+ hideTiny: true,
186
+ height,
187
+ });
188
+ }
189
+ }
190
+ }
@@ -1,6 +1,4 @@
1
- import type { LinearSyntenyDisplayModel } from './model.ts';
2
- export declare const MAX_COLOR_RANGE: number;
3
- export declare function getId(r: number, g: number, b: number, unitMultiplier: number): number;
4
- export declare function drawCigarClickMap(model: LinearSyntenyDisplayModel, cigarClickMapCanvas: CanvasRenderingContext2D): void;
5
- export declare function drawRef(model: LinearSyntenyDisplayModel, mainCanvas: CanvasRenderingContext2D): void;
6
- export declare function drawMouseoverClickMap(model: LinearSyntenyDisplayModel): void;
1
+ export { drawCigarClickMap } from './drawCigarClickMap.ts';
2
+ export { drawMouseoverClickMap } from './drawMouseover.ts';
3
+ export { drawRef } from './drawRef.ts';
4
+ export { MAX_COLOR_RANGE, getId } from './drawSyntenyUtils.ts';