@jbrowse/plugin-wiggle 2.7.0 → 2.7.2

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 (43) hide show
  1. package/dist/DensityRenderer/DensityRenderer.js +2 -2
  2. package/dist/LinePlotRenderer/LinePlotRenderer.js +2 -2
  3. package/dist/MultiDensityRenderer/MultiDensityRenderer.js +5 -8
  4. package/dist/MultiLineRenderer/MultiLineRenderer.js +5 -9
  5. package/dist/MultiLinearWiggleDisplay/components/SetColorDialog.js +2 -102
  6. package/dist/MultiLinearWiggleDisplay/components/SourcesGrid.d.ts +8 -0
  7. package/dist/MultiLinearWiggleDisplay/components/SourcesGrid.js +138 -0
  8. package/dist/MultiRowLineRenderer/MultiRowLineRenderer.js +5 -5
  9. package/dist/MultiRowXYPlotRenderer/MultiRowXYPlotRenderer.js +5 -9
  10. package/dist/MultiXYPlotRenderer/MultiXYPlotRenderer.js +5 -8
  11. package/dist/Tooltip.js +4 -1
  12. package/dist/XYPlotRenderer/XYPlotRenderer.js +2 -2
  13. package/dist/drawDensity.d.ts +17 -0
  14. package/dist/drawDensity.js +66 -0
  15. package/dist/drawLine.d.ts +19 -0
  16. package/dist/drawLine.js +73 -0
  17. package/dist/drawXY.d.ts +19 -0
  18. package/dist/{drawxy.js → drawXY.js} +11 -147
  19. package/dist/util.d.ts +1 -0
  20. package/dist/util.js +17 -1
  21. package/esm/DensityRenderer/DensityRenderer.js +1 -1
  22. package/esm/LinePlotRenderer/LinePlotRenderer.js +1 -1
  23. package/esm/MultiDensityRenderer/MultiDensityRenderer.js +4 -7
  24. package/esm/MultiLineRenderer/MultiLineRenderer.js +4 -8
  25. package/esm/MultiLinearWiggleDisplay/components/SetColorDialog.js +2 -102
  26. package/esm/MultiLinearWiggleDisplay/components/SourcesGrid.d.ts +8 -0
  27. package/esm/MultiLinearWiggleDisplay/components/SourcesGrid.js +110 -0
  28. package/esm/MultiRowLineRenderer/MultiRowLineRenderer.js +4 -4
  29. package/esm/MultiRowXYPlotRenderer/MultiRowXYPlotRenderer.js +4 -8
  30. package/esm/MultiXYPlotRenderer/MultiXYPlotRenderer.js +4 -7
  31. package/esm/Tooltip.js +5 -2
  32. package/esm/XYPlotRenderer/XYPlotRenderer.js +1 -1
  33. package/esm/drawDensity.d.ts +17 -0
  34. package/esm/drawDensity.js +62 -0
  35. package/esm/drawLine.d.ts +19 -0
  36. package/esm/drawLine.js +69 -0
  37. package/esm/drawXY.d.ts +19 -0
  38. package/esm/{drawxy.js → drawXY.js} +2 -136
  39. package/esm/util.d.ts +1 -0
  40. package/esm/util.js +15 -0
  41. package/package.json +2 -2
  42. package/dist/drawxy.d.ts +0 -49
  43. package/esm/drawxy.d.ts +0 -49
@@ -1,12 +1,12 @@
1
1
  import { groupBy } from '@jbrowse/core/util';
2
- import { drawLine } from '../drawxy';
2
+ import { drawLine } from '../drawLine';
3
3
  import WiggleBaseRenderer from '../WiggleBaseRenderer';
4
4
  export default class MultiRowLineRenderer extends WiggleBaseRenderer {
5
5
  // @ts-expect-error
6
6
  async draw(ctx, props) {
7
7
  const { bpPerPx, sources, regions, features } = props;
8
8
  const [region] = regions;
9
- const groups = groupBy([...features.values()], f => f.get('source'));
9
+ const groups = groupBy(features.values(), f => f.get('source'));
10
10
  const height = props.height / sources.length;
11
11
  const width = (region.end - region.start) / bpPerPx;
12
12
  let feats = [];
@@ -14,7 +14,7 @@ export default class MultiRowLineRenderer extends WiggleBaseRenderer {
14
14
  sources.forEach(source => {
15
15
  const { reducedFeatures } = drawLine(ctx, {
16
16
  ...props,
17
- features: groups[source.name],
17
+ features: groups[source.name] || [],
18
18
  height,
19
19
  colorCallback: () => source.color || 'blue',
20
20
  });
@@ -24,7 +24,7 @@ export default class MultiRowLineRenderer extends WiggleBaseRenderer {
24
24
  ctx.lineTo(width, height);
25
25
  ctx.stroke();
26
26
  ctx.translate(0, height);
27
- feats = [...feats, ...reducedFeatures];
27
+ feats = feats.concat(reducedFeatures);
28
28
  });
29
29
  ctx.restore();
30
30
  return { reducedFeatures: feats };
@@ -1,24 +1,20 @@
1
1
  import { groupBy } from '@jbrowse/core/util';
2
- import { drawXY } from '../drawxy';
2
+ import { drawXY } from '../drawXY';
3
3
  import WiggleBaseRenderer from '../WiggleBaseRenderer';
4
4
  export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
5
5
  // @ts-expect-error
6
6
  async draw(ctx, props) {
7
7
  const { bpPerPx, sources, regions, features } = props;
8
8
  const [region] = regions;
9
- const groups = groupBy([...features.values()], f => f.get('source'));
9
+ const groups = groupBy(features.values(), f => f.get('source'));
10
10
  const height = props.height / sources.length;
11
11
  const width = (region.end - region.start) / bpPerPx;
12
12
  let feats = [];
13
13
  ctx.save();
14
14
  sources.forEach(source => {
15
- const features = groups[source.name];
16
- if (!features) {
17
- return;
18
- }
19
15
  const { reducedFeatures } = drawXY(ctx, {
20
16
  ...props,
21
- features,
17
+ features: groups[source.name] || [],
22
18
  height,
23
19
  colorCallback: () => source.color || 'blue',
24
20
  });
@@ -28,7 +24,7 @@ export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
28
24
  ctx.lineTo(width, height);
29
25
  ctx.stroke();
30
26
  ctx.translate(0, height);
31
- feats = [...feats, ...reducedFeatures];
27
+ feats = feats.concat(reducedFeatures);
32
28
  });
33
29
  ctx.restore();
34
30
  return { reducedFeatures: feats };
@@ -1,25 +1,22 @@
1
1
  import { groupBy } from '@jbrowse/core/util';
2
- import { drawXY } from '../drawxy';
2
+ import { drawXY } from '../drawXY';
3
3
  import { YSCALEBAR_LABEL_OFFSET } from '../util';
4
4
  import WiggleBaseRenderer from '../WiggleBaseRenderer';
5
5
  export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
6
6
  // @ts-expect-error
7
7
  async draw(ctx, props) {
8
8
  const { sources, features } = props;
9
- const groups = groupBy([...features.values()], f => f.get('source'));
9
+ const groups = groupBy(features.values(), f => f.get('source'));
10
10
  let feats = [];
11
11
  for (const source of sources) {
12
- const features = groups[source.name];
13
- if (!features) {
14
- continue;
15
- }
12
+ const features = groups[source.name] || [];
16
13
  const { reducedFeatures } = drawXY(ctx, {
17
14
  ...props,
18
15
  features,
19
16
  offset: YSCALEBAR_LABEL_OFFSET,
20
17
  colorCallback: () => source.color || 'blue',
21
18
  });
22
- feats = [...feats, ...reducedFeatures];
19
+ feats = feats.concat(reducedFeatures);
23
20
  }
24
21
  return { reducedFeatures: feats };
25
22
  }
package/esm/Tooltip.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo, useState } from 'react';
2
2
  import { observer } from 'mobx-react';
3
- import { alpha, Portal } from '@mui/material';
3
+ import { alpha, Portal, useTheme } from '@mui/material';
4
4
  import { makeStyles } from 'tss-react/mui';
5
5
  // locals
6
6
  import { YSCALEBAR_LABEL_OFFSET, round } from './util';
@@ -33,6 +33,8 @@ const useStyles = makeStyles()(theme => ({
33
33
  },
34
34
  }));
35
35
  const Tooltip = observer(function Tooltip({ model, height, clientMouseCoord, offsetMouseCoord, clientRect, TooltipContents, useClientY, }) {
36
+ var _a, _b;
37
+ const theme = useTheme();
36
38
  const { featureUnderMouse } = model;
37
39
  const [width, setWidth] = useState(0);
38
40
  const [anchorEl, setAnchorEl] = useState(null);
@@ -56,8 +58,9 @@ const Tooltip = observer(function Tooltip({ model, height, clientMouseCoord, off
56
58
  },
57
59
  }), [clientRect === null || clientRect === void 0 ? void 0 : clientRect.top, clientMouseCoord, width, useClientY]);
58
60
  const { styles, attributes } = usePopper(virtElement, anchorEl);
61
+ const popperTheme = (_a = theme === null || theme === void 0 ? void 0 : theme.components) === null || _a === void 0 ? void 0 : _a.MuiPopper;
59
62
  return featureUnderMouse ? (React.createElement(React.Fragment, null,
60
- React.createElement(Portal, null,
63
+ React.createElement(Portal, { container: (_b = popperTheme === null || popperTheme === void 0 ? void 0 : popperTheme.defaultProps) === null || _b === void 0 ? void 0 : _b.container },
61
64
  React.createElement("div", { ref: setAnchorEl, className: classes.tooltip,
62
65
  // zIndex needed to go over widget drawer
63
66
  style: { ...styles.popper, zIndex: 100000 }, ...attributes.popper },
@@ -1,5 +1,5 @@
1
1
  import { readConfObject } from '@jbrowse/core/configuration';
2
- import { drawXY } from '../drawxy';
2
+ import { drawXY } from '../drawXY';
3
3
  import WiggleBaseRenderer from '../WiggleBaseRenderer';
4
4
  import { YSCALEBAR_LABEL_OFFSET } from '../util';
5
5
  export default class XYPlotRenderer extends WiggleBaseRenderer {
@@ -0,0 +1,17 @@
1
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
+ import { Feature, Region } from '@jbrowse/core/util';
3
+ import { ScaleOpts } from './util';
4
+ export declare function drawDensity(ctx: CanvasRenderingContext2D, props: {
5
+ features: Map<string, Feature> | Feature[];
6
+ regions: Region[];
7
+ bpPerPx: number;
8
+ scaleOpts: ScaleOpts;
9
+ height: number;
10
+ ticks: {
11
+ values: number[];
12
+ };
13
+ displayCrossHatches: boolean;
14
+ config: AnyConfigurationModel;
15
+ }): {
16
+ reducedFeatures: Feature[];
17
+ };
@@ -0,0 +1,62 @@
1
+ import { readConfObject, } from '@jbrowse/core/configuration';
2
+ import { featureSpanPx } from '@jbrowse/core/util';
3
+ // locals
4
+ import { fillRectCtx, getScale } from './util';
5
+ const fudgeFactor = 0.3;
6
+ const clipHeight = 2;
7
+ export function drawDensity(ctx, props) {
8
+ const { features, regions, bpPerPx, scaleOpts, height, config } = props;
9
+ const [region] = regions;
10
+ const pivot = readConfObject(config, 'bicolorPivot');
11
+ const pivotValue = readConfObject(config, 'bicolorPivotValue');
12
+ const negColor = readConfObject(config, 'negColor');
13
+ const posColor = readConfObject(config, 'posColor');
14
+ const color = readConfObject(config, 'color');
15
+ const clipColor = readConfObject(config, 'clipColor');
16
+ const crossing = pivot !== 'none' && scaleOpts.scaleType !== 'log';
17
+ const scale = getScale({
18
+ ...scaleOpts,
19
+ pivotValue: crossing ? pivotValue : undefined,
20
+ range: crossing ? [negColor, 'white', posColor] : ['white', posColor],
21
+ });
22
+ const scale2 = getScale({ ...scaleOpts, range: [0, height] });
23
+ const cb = color === '#f0f'
24
+ ? (_, score) => scale(score)
25
+ : (feature, score) => readConfObject(config, 'color', { feature, score });
26
+ const [niceMin, niceMax] = scale2.domain();
27
+ let prevLeftPx = -Infinity;
28
+ let hasClipping = false;
29
+ const reducedFeatures = [];
30
+ for (const feature of features.values()) {
31
+ const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
32
+ // create reduced features, avoiding multiple features per px
33
+ if (Math.floor(leftPx) !== Math.floor(prevLeftPx)) {
34
+ reducedFeatures.push(feature);
35
+ prevLeftPx = leftPx;
36
+ }
37
+ const score = feature.get('score');
38
+ hasClipping = hasClipping || score > niceMax || score < niceMin;
39
+ const w = rightPx - leftPx + fudgeFactor;
40
+ ctx.fillStyle = cb(feature, score);
41
+ ctx.fillRect(leftPx, 0, w, height);
42
+ }
43
+ // second pass: draw clipping
44
+ // avoid persisting the red fillstyle with save/restore
45
+ ctx.save();
46
+ if (hasClipping) {
47
+ ctx.fillStyle = clipColor;
48
+ for (const feature of features.values()) {
49
+ const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
50
+ const w = rightPx - leftPx + fudgeFactor;
51
+ const score = feature.get('score');
52
+ if (score > niceMax) {
53
+ fillRectCtx(leftPx, 0, w, clipHeight, ctx);
54
+ }
55
+ else if (score < niceMin && scaleOpts.scaleType !== 'log') {
56
+ fillRectCtx(leftPx, 0, w, clipHeight, ctx);
57
+ }
58
+ }
59
+ }
60
+ ctx.restore();
61
+ return { reducedFeatures };
62
+ }
@@ -0,0 +1,19 @@
1
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
+ import { Feature, Region } from '@jbrowse/core/util';
3
+ import { ScaleOpts } from './util';
4
+ export declare function drawLine(ctx: CanvasRenderingContext2D, props: {
5
+ features: Map<string, Feature> | Feature[];
6
+ regions: Region[];
7
+ bpPerPx: number;
8
+ scaleOpts: ScaleOpts;
9
+ height: number;
10
+ ticks: {
11
+ values: number[];
12
+ };
13
+ displayCrossHatches: boolean;
14
+ colorCallback: (f: Feature, score: number) => string;
15
+ config: AnyConfigurationModel;
16
+ offset?: number;
17
+ }): {
18
+ reducedFeatures: Feature[];
19
+ };
@@ -0,0 +1,69 @@
1
+ import { readConfObject, } from '@jbrowse/core/configuration';
2
+ import { clamp, featureSpanPx } from '@jbrowse/core/util';
3
+ // locals
4
+ import { getScale } from './util';
5
+ const fudgeFactor = 0.3;
6
+ const clipHeight = 2;
7
+ export function drawLine(ctx, props) {
8
+ const { features, regions, bpPerPx, scaleOpts, height: unadjustedHeight, ticks: { values }, displayCrossHatches, colorCallback, config, offset = 0, } = props;
9
+ const [region] = regions;
10
+ const width = (region.end - region.start) / bpPerPx;
11
+ // the adjusted height takes into account YSCALEBAR_LABEL_OFFSET from the
12
+ // wiggle display, and makes the height of the actual drawn area add
13
+ // "padding" to the top and bottom of the display
14
+ const height = unadjustedHeight - offset * 2;
15
+ const clipColor = readConfObject(config, 'clipColor');
16
+ const scale = getScale({ ...scaleOpts, range: [0, height] });
17
+ const [niceMin, niceMax] = scale.domain();
18
+ const toY = (n) => clamp(height - (scale(n) || 0), 0, height) + offset;
19
+ let lastVal;
20
+ let prevLeftPx = -Infinity;
21
+ const reducedFeatures = [];
22
+ for (const feature of features.values()) {
23
+ const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
24
+ // create reduced features, avoiding multiple features per px
25
+ if (Math.floor(leftPx) !== Math.floor(prevLeftPx)) {
26
+ reducedFeatures.push(feature);
27
+ prevLeftPx = leftPx;
28
+ }
29
+ const score = feature.get('score');
30
+ const lowClipping = score < niceMin;
31
+ const highClipping = score > niceMax;
32
+ const w = rightPx - leftPx + fudgeFactor;
33
+ const c = colorCallback(feature, score);
34
+ ctx.beginPath();
35
+ ctx.strokeStyle = c;
36
+ const startPos = lastVal !== undefined ? lastVal : score;
37
+ if (!region.reversed) {
38
+ ctx.moveTo(leftPx, toY(startPos));
39
+ ctx.lineTo(leftPx, toY(score));
40
+ ctx.lineTo(rightPx, toY(score));
41
+ }
42
+ else {
43
+ ctx.moveTo(rightPx, toY(startPos));
44
+ ctx.lineTo(rightPx, toY(score));
45
+ ctx.lineTo(leftPx, toY(score));
46
+ }
47
+ ctx.stroke();
48
+ lastVal = score;
49
+ if (highClipping) {
50
+ ctx.fillStyle = clipColor;
51
+ ctx.fillRect(leftPx, offset, w, clipHeight);
52
+ }
53
+ else if (lowClipping && scaleOpts.scaleType !== 'log') {
54
+ ctx.fillStyle = clipColor;
55
+ ctx.fillRect(leftPx, height - clipHeight, w, height);
56
+ }
57
+ }
58
+ if (displayCrossHatches) {
59
+ ctx.lineWidth = 1;
60
+ ctx.strokeStyle = 'rgba(200,200,200,0.5)';
61
+ values.forEach(tick => {
62
+ ctx.beginPath();
63
+ ctx.moveTo(0, Math.round(toY(tick)));
64
+ ctx.lineTo(width, Math.round(toY(tick)));
65
+ ctx.stroke();
66
+ });
67
+ }
68
+ return { reducedFeatures };
69
+ }
@@ -0,0 +1,19 @@
1
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
+ import { Feature, Region } from '@jbrowse/core/util';
3
+ import { ScaleOpts } from './util';
4
+ export declare function drawXY(ctx: CanvasRenderingContext2D, props: {
5
+ features: Map<string, Feature> | Feature[];
6
+ bpPerPx: number;
7
+ regions: Region[];
8
+ scaleOpts: ScaleOpts;
9
+ height: number;
10
+ ticks: {
11
+ values: number[];
12
+ };
13
+ config: AnyConfigurationModel;
14
+ displayCrossHatches: boolean;
15
+ offset?: number;
16
+ colorCallback: (f: Feature, score: number) => string;
17
+ }): {
18
+ reducedFeatures: Feature[];
19
+ };
@@ -1,6 +1,8 @@
1
1
  import { readConfObject, } from '@jbrowse/core/configuration';
2
2
  import { colord } from '@jbrowse/core/util/colord';
3
3
  import { clamp, featureSpanPx } from '@jbrowse/core/util';
4
+ // locals
5
+ import { fillRectCtx, getOrigin, getScale } from './util';
4
6
  function lighten(color, amount) {
5
7
  const hslColor = color.toHsl();
6
8
  const l = hslColor.l * (1 + amount);
@@ -11,23 +13,6 @@ function darken(color, amount) {
11
13
  const l = hslColor.l * (1 - amount);
12
14
  return colord({ ...hslColor, l: clamp(l, 0, 100) });
13
15
  }
14
- // locals
15
- import { getOrigin, getScale } from './util';
16
- // avoid drawing negative width features for SVG exports
17
- function fillRectCtx(x, y, width, height, ctx, color) {
18
- if (width < 0) {
19
- x += width;
20
- width = -width;
21
- }
22
- if (height < 0) {
23
- y += height;
24
- height = -height;
25
- }
26
- if (color) {
27
- ctx.fillStyle = color;
28
- }
29
- ctx.fillRect(x, y, width, height);
30
- }
31
16
  const fudgeFactor = 0.3;
32
17
  const clipHeight = 2;
33
18
  export function drawXY(ctx, props) {
@@ -173,122 +158,3 @@ export function drawXY(ctx, props) {
173
158
  }
174
159
  return { reducedFeatures };
175
160
  }
176
- export function drawLine(ctx, props) {
177
- const { features, regions, bpPerPx, scaleOpts, height: unadjustedHeight, ticks: { values }, displayCrossHatches, colorCallback, config, offset = 0, } = props;
178
- const [region] = regions;
179
- const width = (region.end - region.start) / bpPerPx;
180
- // the adjusted height takes into account YSCALEBAR_LABEL_OFFSET from the
181
- // wiggle display, and makes the height of the actual drawn area add
182
- // "padding" to the top and bottom of the display
183
- const height = unadjustedHeight - offset * 2;
184
- const clipColor = readConfObject(config, 'clipColor');
185
- const scale = getScale({ ...scaleOpts, range: [0, height] });
186
- const [niceMin, niceMax] = scale.domain();
187
- const toY = (n) => clamp(height - (scale(n) || 0), 0, height) + offset;
188
- let lastVal;
189
- let prevLeftPx = -Infinity;
190
- const reducedFeatures = [];
191
- for (const feature of features.values()) {
192
- const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
193
- // create reduced features, avoiding multiple features per px
194
- if (Math.floor(leftPx) !== Math.floor(prevLeftPx)) {
195
- reducedFeatures.push(feature);
196
- prevLeftPx = leftPx;
197
- }
198
- const score = feature.get('score');
199
- const lowClipping = score < niceMin;
200
- const highClipping = score > niceMax;
201
- const w = rightPx - leftPx + fudgeFactor;
202
- const c = colorCallback(feature, score);
203
- ctx.beginPath();
204
- ctx.strokeStyle = c;
205
- const startPos = lastVal !== undefined ? lastVal : score;
206
- if (!region.reversed) {
207
- ctx.moveTo(leftPx, toY(startPos));
208
- ctx.lineTo(leftPx, toY(score));
209
- ctx.lineTo(rightPx, toY(score));
210
- }
211
- else {
212
- ctx.moveTo(rightPx, toY(startPos));
213
- ctx.lineTo(rightPx, toY(score));
214
- ctx.lineTo(leftPx, toY(score));
215
- }
216
- ctx.stroke();
217
- lastVal = score;
218
- if (highClipping) {
219
- ctx.fillStyle = clipColor;
220
- ctx.fillRect(leftPx, offset, w, clipHeight);
221
- }
222
- else if (lowClipping && scaleOpts.scaleType !== 'log') {
223
- ctx.fillStyle = clipColor;
224
- ctx.fillRect(leftPx, height - clipHeight, w, height);
225
- }
226
- }
227
- if (displayCrossHatches) {
228
- ctx.lineWidth = 1;
229
- ctx.strokeStyle = 'rgba(200,200,200,0.5)';
230
- values.forEach(tick => {
231
- ctx.beginPath();
232
- ctx.moveTo(0, Math.round(toY(tick)));
233
- ctx.lineTo(width, Math.round(toY(tick)));
234
- ctx.stroke();
235
- });
236
- }
237
- return { reducedFeatures };
238
- }
239
- export function drawDensity(ctx, props) {
240
- const { features, regions, bpPerPx, scaleOpts, height, config } = props;
241
- const [region] = regions;
242
- const pivot = readConfObject(config, 'bicolorPivot');
243
- const pivotValue = readConfObject(config, 'bicolorPivotValue');
244
- const negColor = readConfObject(config, 'negColor');
245
- const posColor = readConfObject(config, 'posColor');
246
- const color = readConfObject(config, 'color');
247
- const clipColor = readConfObject(config, 'clipColor');
248
- const crossing = pivot !== 'none' && scaleOpts.scaleType !== 'log';
249
- const scale = getScale({
250
- ...scaleOpts,
251
- pivotValue: crossing ? pivotValue : undefined,
252
- range: crossing ? [negColor, 'white', posColor] : ['white', posColor],
253
- });
254
- const scale2 = getScale({ ...scaleOpts, range: [0, height] });
255
- const cb = color === '#f0f'
256
- ? (_, score) => scale(score)
257
- : (feature, score) => readConfObject(config, 'color', { feature, score });
258
- const [niceMin, niceMax] = scale2.domain();
259
- let prevLeftPx = -Infinity;
260
- let hasClipping = false;
261
- const reducedFeatures = [];
262
- for (const feature of features.values()) {
263
- const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
264
- // create reduced features, avoiding multiple features per px
265
- if (Math.floor(leftPx) !== Math.floor(prevLeftPx)) {
266
- reducedFeatures.push(feature);
267
- prevLeftPx = leftPx;
268
- }
269
- const score = feature.get('score');
270
- hasClipping = hasClipping || score > niceMax || score < niceMin;
271
- const w = rightPx - leftPx + fudgeFactor;
272
- ctx.fillStyle = cb(feature, score);
273
- ctx.fillRect(leftPx, 0, w, height);
274
- }
275
- // second pass: draw clipping
276
- // avoid persisting the red fillstyle with save/restore
277
- ctx.save();
278
- if (hasClipping) {
279
- ctx.fillStyle = clipColor;
280
- for (const feature of features.values()) {
281
- const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
282
- const w = rightPx - leftPx + fudgeFactor;
283
- const score = feature.get('score');
284
- if (score > niceMax) {
285
- fillRectCtx(leftPx, 0, w, clipHeight, ctx);
286
- }
287
- else if (score < niceMin && scaleOpts.scaleType !== 'log') {
288
- fillRectCtx(leftPx, 0, w, clipHeight, ctx);
289
- }
290
- }
291
- }
292
- ctx.restore();
293
- return { reducedFeatures };
294
- }
package/esm/util.d.ts CHANGED
@@ -72,3 +72,4 @@ export declare function quantitativeStatsAutorun(self: {
72
72
  }): void;
73
73
  export declare function toP(s?: number): number;
74
74
  export declare function round(value: number): number;
75
+ export declare function fillRectCtx(x: number, y: number, width: number, height: number, ctx: CanvasRenderingContext2D, color?: string): void;
package/esm/util.js CHANGED
@@ -221,3 +221,18 @@ export function toP(s = 0) {
221
221
  export function round(value) {
222
222
  return Math.round(value * 1e5) / 1e5;
223
223
  }
224
+ // avoid drawing negative width features for SVG exports
225
+ export function fillRectCtx(x, y, width, height, ctx, color) {
226
+ if (width < 0) {
227
+ x += width;
228
+ width = -width;
229
+ }
230
+ if (height < 0) {
231
+ y += height;
232
+ height = -height;
233
+ }
234
+ if (color) {
235
+ ctx.fillStyle = color;
236
+ }
237
+ ctx.fillRect(x, y, width, height);
238
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-wiggle",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "JBrowse 2 wiggle adapters, tracks, etc.",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -67,5 +67,5 @@
67
67
  "distModule": "esm/index.js",
68
68
  "srcModule": "src/index.ts",
69
69
  "module": "esm/index.js",
70
- "gitHead": "dbe7fb1af01fc89f833d2744635eb44a17365b41"
70
+ "gitHead": "9052b295f2d322e729254457ed9fe2231fb22cce"
71
71
  }
package/dist/drawxy.d.ts DELETED
@@ -1,49 +0,0 @@
1
- import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
- import { Feature, Region } from '@jbrowse/core/util';
3
- import { ScaleOpts } from './util';
4
- export declare function drawXY(ctx: CanvasRenderingContext2D, props: {
5
- features: Map<string, Feature> | Feature[];
6
- bpPerPx: number;
7
- regions: Region[];
8
- scaleOpts: ScaleOpts;
9
- height: number;
10
- ticks: {
11
- values: number[];
12
- };
13
- config: AnyConfigurationModel;
14
- displayCrossHatches: boolean;
15
- offset?: number;
16
- colorCallback: (f: Feature, score: number) => string;
17
- }): {
18
- reducedFeatures: Feature[];
19
- };
20
- export declare function drawLine(ctx: CanvasRenderingContext2D, props: {
21
- features: Map<string, Feature> | Feature[];
22
- regions: Region[];
23
- bpPerPx: number;
24
- scaleOpts: ScaleOpts;
25
- height: number;
26
- ticks: {
27
- values: number[];
28
- };
29
- displayCrossHatches: boolean;
30
- colorCallback: (f: Feature, score: number) => string;
31
- config: AnyConfigurationModel;
32
- offset?: number;
33
- }): {
34
- reducedFeatures: Feature[];
35
- };
36
- export declare function drawDensity(ctx: CanvasRenderingContext2D, props: {
37
- features: Map<string, Feature> | Feature[];
38
- regions: Region[];
39
- bpPerPx: number;
40
- scaleOpts: ScaleOpts;
41
- height: number;
42
- ticks: {
43
- values: number[];
44
- };
45
- displayCrossHatches: boolean;
46
- config: AnyConfigurationModel;
47
- }): {
48
- reducedFeatures: Feature[];
49
- };
package/esm/drawxy.d.ts DELETED
@@ -1,49 +0,0 @@
1
- import { AnyConfigurationModel } from '@jbrowse/core/configuration';
2
- import { Feature, Region } from '@jbrowse/core/util';
3
- import { ScaleOpts } from './util';
4
- export declare function drawXY(ctx: CanvasRenderingContext2D, props: {
5
- features: Map<string, Feature> | Feature[];
6
- bpPerPx: number;
7
- regions: Region[];
8
- scaleOpts: ScaleOpts;
9
- height: number;
10
- ticks: {
11
- values: number[];
12
- };
13
- config: AnyConfigurationModel;
14
- displayCrossHatches: boolean;
15
- offset?: number;
16
- colorCallback: (f: Feature, score: number) => string;
17
- }): {
18
- reducedFeatures: Feature[];
19
- };
20
- export declare function drawLine(ctx: CanvasRenderingContext2D, props: {
21
- features: Map<string, Feature> | Feature[];
22
- regions: Region[];
23
- bpPerPx: number;
24
- scaleOpts: ScaleOpts;
25
- height: number;
26
- ticks: {
27
- values: number[];
28
- };
29
- displayCrossHatches: boolean;
30
- colorCallback: (f: Feature, score: number) => string;
31
- config: AnyConfigurationModel;
32
- offset?: number;
33
- }): {
34
- reducedFeatures: Feature[];
35
- };
36
- export declare function drawDensity(ctx: CanvasRenderingContext2D, props: {
37
- features: Map<string, Feature> | Feature[];
38
- regions: Region[];
39
- bpPerPx: number;
40
- scaleOpts: ScaleOpts;
41
- height: number;
42
- ticks: {
43
- values: number[];
44
- };
45
- displayCrossHatches: boolean;
46
- config: AnyConfigurationModel;
47
- }): {
48
- reducedFeatures: Feature[];
49
- };