@jbrowse/plugin-wiggle 2.6.3 → 2.7.1

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 (84) hide show
  1. package/dist/CreateMultiWiggleExtension/index.js +14 -11
  2. package/dist/DensityRenderer/DensityRenderer.js +2 -2
  3. package/dist/LinePlotRenderer/LinePlotRenderer.js +2 -2
  4. package/dist/LinearWiggleDisplay/components/SetColorDialog.d.ts +6 -7
  5. package/dist/LinearWiggleDisplay/components/SetColorDialog.js +3 -3
  6. package/dist/LinearWiggleDisplay/components/Tooltip.js +1 -1
  7. package/dist/MultiDensityRenderer/MultiDensityRenderer.js +5 -8
  8. package/dist/MultiLineRenderer/MultiLineRenderer.js +5 -9
  9. package/dist/MultiLinearWiggleDisplay/components/DraggableDialog.d.ts +3 -4
  10. package/dist/MultiLinearWiggleDisplay/components/DraggableDialog.js +3 -3
  11. package/dist/MultiLinearWiggleDisplay/components/SetColorDialog.js +2 -96
  12. package/dist/MultiLinearWiggleDisplay/components/SourcesGrid.d.ts +8 -0
  13. package/dist/MultiLinearWiggleDisplay/components/SourcesGrid.js +138 -0
  14. package/dist/MultiLinearWiggleDisplay/components/Tooltip.d.ts +3 -2
  15. package/dist/MultiLinearWiggleDisplay/components/Tooltip.js +1 -1
  16. package/dist/MultiLinearWiggleDisplay/components/WiggleDisplayComponent.d.ts +2 -3
  17. package/dist/MultiLinearWiggleDisplay/components/WiggleDisplayComponent.js +2 -4
  18. package/dist/MultiLinearWiggleDisplay/components/util.js +2 -4
  19. package/dist/MultiRowLineRenderer/MultiRowLineRenderer.js +5 -5
  20. package/dist/MultiRowXYPlotRenderer/MultiRowXYPlotRenderer.js +5 -34
  21. package/dist/MultiWiggleAddTrackWidget/AddTrackWorkflow.js +16 -12
  22. package/dist/MultiWiggleRendering.d.ts +3 -4
  23. package/dist/MultiWiggleRendering.js +7 -5
  24. package/dist/MultiXYPlotRenderer/MultiXYPlotRenderer.js +5 -33
  25. package/dist/Tooltip.d.ts +5 -6
  26. package/dist/Tooltip.js +3 -3
  27. package/dist/WiggleRendering.d.ts +3 -4
  28. package/dist/WiggleRendering.js +3 -3
  29. package/dist/XYPlotRenderer/XYPlotRenderer.js +2 -27
  30. package/dist/drawDensity.d.ts +17 -0
  31. package/dist/drawDensity.js +66 -0
  32. package/dist/drawLine.d.ts +19 -0
  33. package/dist/drawLine.js +73 -0
  34. package/dist/drawXY.d.ts +19 -0
  35. package/dist/drawXY.js +164 -0
  36. package/dist/shared/YScaleBar.d.ts +2 -2
  37. package/dist/shared/YScaleBar.js +2 -1
  38. package/dist/shared/modelShared.d.ts +4 -1
  39. package/dist/util.d.ts +1 -0
  40. package/dist/util.js +17 -1
  41. package/esm/CreateMultiWiggleExtension/index.js +14 -11
  42. package/esm/DensityRenderer/DensityRenderer.js +1 -1
  43. package/esm/LinePlotRenderer/LinePlotRenderer.js +1 -1
  44. package/esm/LinearWiggleDisplay/components/SetColorDialog.d.ts +6 -7
  45. package/esm/LinearWiggleDisplay/components/SetColorDialog.js +3 -3
  46. package/esm/LinearWiggleDisplay/components/Tooltip.js +1 -1
  47. package/esm/MultiDensityRenderer/MultiDensityRenderer.js +4 -7
  48. package/esm/MultiLineRenderer/MultiLineRenderer.js +4 -8
  49. package/esm/MultiLinearWiggleDisplay/components/DraggableDialog.d.ts +3 -4
  50. package/esm/MultiLinearWiggleDisplay/components/DraggableDialog.js +3 -3
  51. package/esm/MultiLinearWiggleDisplay/components/SetColorDialog.js +2 -96
  52. package/esm/MultiLinearWiggleDisplay/components/SourcesGrid.d.ts +8 -0
  53. package/esm/MultiLinearWiggleDisplay/components/SourcesGrid.js +110 -0
  54. package/esm/MultiLinearWiggleDisplay/components/Tooltip.d.ts +3 -2
  55. package/esm/MultiLinearWiggleDisplay/components/Tooltip.js +1 -1
  56. package/esm/MultiLinearWiggleDisplay/components/WiggleDisplayComponent.d.ts +2 -3
  57. package/esm/MultiLinearWiggleDisplay/components/WiggleDisplayComponent.js +2 -2
  58. package/esm/MultiLinearWiggleDisplay/components/util.js +2 -4
  59. package/esm/MultiRowLineRenderer/MultiRowLineRenderer.js +4 -4
  60. package/esm/MultiRowXYPlotRenderer/MultiRowXYPlotRenderer.js +4 -10
  61. package/esm/MultiWiggleAddTrackWidget/AddTrackWorkflow.js +17 -13
  62. package/esm/MultiWiggleRendering.d.ts +3 -4
  63. package/esm/MultiWiggleRendering.js +7 -5
  64. package/esm/MultiXYPlotRenderer/MultiXYPlotRenderer.js +4 -9
  65. package/esm/Tooltip.d.ts +5 -6
  66. package/esm/Tooltip.js +3 -3
  67. package/esm/WiggleRendering.d.ts +3 -4
  68. package/esm/WiggleRendering.js +3 -3
  69. package/esm/XYPlotRenderer/XYPlotRenderer.js +1 -3
  70. package/esm/drawDensity.d.ts +17 -0
  71. package/esm/drawDensity.js +62 -0
  72. package/esm/drawLine.d.ts +19 -0
  73. package/esm/drawLine.js +69 -0
  74. package/esm/drawXY.d.ts +19 -0
  75. package/esm/{drawxy.js → drawXY.js} +17 -140
  76. package/esm/shared/YScaleBar.d.ts +2 -2
  77. package/esm/shared/YScaleBar.js +2 -1
  78. package/esm/shared/modelShared.d.ts +4 -1
  79. package/esm/util.d.ts +1 -0
  80. package/esm/util.js +15 -0
  81. package/package.json +3 -4
  82. package/dist/drawxy.d.ts +0 -50
  83. package/dist/drawxy.js +0 -289
  84. package/esm/drawxy.d.ts +0 -50
@@ -0,0 +1,110 @@
1
+ import React, { useState } from 'react';
2
+ import { Button } from '@mui/material';
3
+ import { getStr, measureGridWidth } from '@jbrowse/core/util';
4
+ import { DataGrid } from '@mui/x-data-grid';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ // locals
7
+ import ColorPicker, { ColorPopover } from '@jbrowse/core/ui/ColorPicker';
8
+ import { moveUp, moveDown } from './util';
9
+ // icons
10
+ import KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp';
11
+ import KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrowDown';
12
+ import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
13
+ import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
14
+ import { SanitizedHTML } from '@jbrowse/core/ui';
15
+ const useStyles = makeStyles()({
16
+ cell: {
17
+ whiteSpace: 'nowrap',
18
+ overflow: 'hidden',
19
+ textOverflow: 'ellipsis',
20
+ },
21
+ });
22
+ function SourcesGrid({ rows, onChange, showTips, }) {
23
+ const { classes } = useStyles();
24
+ const [anchorEl, setAnchorEl] = useState(null);
25
+ const [selected, setSelected] = useState([]);
26
+ // @ts-expect-error
27
+ const { name: _name, color: _color, baseUri: _baseUri, ...rest } = rows[0];
28
+ const [widgetColor, setWidgetColor] = useState('blue');
29
+ const [currSort, setCurrSort] = useState({
30
+ idx: 0,
31
+ field: null,
32
+ });
33
+ return (React.createElement("div", null,
34
+ React.createElement(Button, { disabled: !selected.length, onClick: event => setAnchorEl(event.currentTarget) }, "Change color of selected items"),
35
+ React.createElement(Button, { onClick: () => onChange(moveUp([...rows], selected)), disabled: !selected.length },
36
+ React.createElement(KeyboardArrowUpIcon, null),
37
+ showTips ? 'Move selected items up' : null),
38
+ React.createElement(Button, { onClick: () => onChange(moveDown([...rows], selected)), disabled: !selected.length },
39
+ React.createElement(KeyboardArrowDownIcon, null),
40
+ showTips ? 'Move selected items down' : null),
41
+ React.createElement(Button, { onClick: () => onChange(moveUp([...rows], selected, rows.length)), disabled: !selected.length },
42
+ React.createElement(KeyboardDoubleArrowUpIcon, null),
43
+ showTips ? 'Move selected items to top' : null),
44
+ React.createElement(Button, { onClick: () => onChange(moveDown([...rows], selected, rows.length)), disabled: !selected.length },
45
+ React.createElement(KeyboardDoubleArrowDownIcon, null),
46
+ showTips ? 'Move selected items to bottom' : null),
47
+ React.createElement(ColorPopover, { anchorEl: anchorEl, color: widgetColor, onChange: c => {
48
+ setWidgetColor(c);
49
+ selected.forEach(id => {
50
+ const elt = rows.find(f => f.name === id);
51
+ if (elt) {
52
+ elt.color = c;
53
+ }
54
+ });
55
+ onChange([...rows]);
56
+ }, onClose: () => setAnchorEl(null) }),
57
+ React.createElement("div", { style: { height: 400, width: '100%' } },
58
+ React.createElement(DataGrid, { getRowId: row => row.name, checkboxSelection: true, disableRowSelectionOnClick: true, onRowSelectionModelChange: arg => setSelected(arg), rows: rows, rowHeight: 25, columnHeaderHeight: 33, columns: [
59
+ {
60
+ field: 'color',
61
+ headerName: 'Color',
62
+ renderCell: params => {
63
+ const { value, id } = params;
64
+ return (React.createElement(ColorPicker, { color: value || 'blue', onChange: c => {
65
+ const elt = rows.find(f => f.name === id);
66
+ if (elt) {
67
+ elt.color = c;
68
+ }
69
+ onChange([...rows]);
70
+ } }));
71
+ },
72
+ },
73
+ {
74
+ field: 'name',
75
+ sortingOrder: [null],
76
+ headerName: 'Name',
77
+ width: measureGridWidth(rows.map(r => r.name)),
78
+ },
79
+ ...Object.keys(rest).map(val => ({
80
+ field: val,
81
+ sortingOrder: [null],
82
+ renderCell: (params) => {
83
+ const { value } = params;
84
+ return (React.createElement("div", { className: classes.cell },
85
+ React.createElement(SanitizedHTML, { html: getStr(value) })));
86
+ },
87
+ // @ts-ignore
88
+ width: measureGridWidth(rows.map(r => r[val])),
89
+ })),
90
+ ], sortModel: [
91
+ /* we control the sort as a controlled component using onSortModelChange */
92
+ ], onSortModelChange: args => {
93
+ const sort = args[0];
94
+ const idx = (currSort.idx + 1) % 2;
95
+ const field = (sort === null || sort === void 0 ? void 0 : sort.field) || currSort.field;
96
+ setCurrSort({ idx, field });
97
+ onChange(field
98
+ ? [...rows].sort((a, b) => {
99
+ // @ts-expect-error
100
+ const aa = getStr(a[field]);
101
+ // @ts-expect-error
102
+ const bb = getStr(b[field]);
103
+ return idx === 1
104
+ ? aa.localeCompare(bb)
105
+ : bb.localeCompare(aa);
106
+ })
107
+ : rows);
108
+ } }))));
109
+ }
110
+ export default SourcesGrid;
@@ -2,12 +2,13 @@ import React from 'react';
2
2
  import { Feature } from '@jbrowse/core/util';
3
3
  import { Source } from '../../util';
4
4
  import { TooltipContentsComponent } from '../../Tooltip';
5
- declare const TooltipContents: React.ForwardRefExoticComponent<{
5
+ interface Props {
6
6
  model: {
7
7
  sources: Source[];
8
8
  };
9
9
  feature: Feature;
10
- } & React.RefAttributes<HTMLDivElement>>;
10
+ }
11
+ declare const TooltipContents: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLDivElement>>;
11
12
  type Coord = [number, number];
12
13
  declare const WiggleTooltip: (props: {
13
14
  model: {
@@ -4,7 +4,7 @@ import { observer } from 'mobx-react';
4
4
  import { toP } from '../../util';
5
5
  import Tooltip from '../../Tooltip';
6
6
  const en = (n) => n.toLocaleString('en-US');
7
- const TooltipContents = React.forwardRef(({ model, feature }, ref) => {
7
+ const TooltipContents = React.forwardRef(function TooltipContents2({ model, feature }, ref) {
8
8
  const start = feature.get('start');
9
9
  const end = feature.get('end');
10
10
  const refName = feature.get('refName');
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { WiggleDisplayModel } from '../models/model';
3
- declare const _default: (props: {
3
+ declare const MultiLinearWiggleDisplayComponent: (props: {
4
4
  model: WiggleDisplayModel;
5
5
  }) => React.JSX.Element;
6
- export default _default;
7
- export { default as YScaleBar } from '../../shared/YScaleBar';
6
+ export default MultiLinearWiggleDisplayComponent;
@@ -2,10 +2,10 @@ import React from 'react';
2
2
  import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view';
3
3
  import { observer } from 'mobx-react';
4
4
  import YScaleBars from './YScaleBars';
5
- export default observer((props) => {
5
+ const MultiLinearWiggleDisplayComponent = observer((props) => {
6
6
  const { model } = props;
7
7
  return (React.createElement("div", null,
8
8
  React.createElement(BaseLinearDisplayComponent, { ...props }),
9
9
  React.createElement(YScaleBars, { model: model })));
10
10
  });
11
- export { default as YScaleBar } from '../../shared/YScaleBar';
11
+ export default MultiLinearWiggleDisplayComponent;
@@ -5,8 +5,7 @@ export function moveUp(arr, sel, by = 1) {
5
5
  .map(l => arr.findIndex(v => v.name === l))
6
6
  .sort((a, b) => a - b);
7
7
  let lastIdx = 0;
8
- for (let i = 0; i < idxs.length; i++) {
9
- const old = idxs[i];
8
+ for (const old of idxs) {
10
9
  const idx = Math.max(lastIdx, old - by);
11
10
  if (idx >= lastIdx) {
12
11
  arr.splice(idx, 0, arr.splice(old, 1)[0]);
@@ -20,8 +19,7 @@ export function moveDown(arr, sel, by = 1) {
20
19
  .map(l => arr.findIndex(v => v.name === l))
21
20
  .sort((a, b) => b - a);
22
21
  let lastIdx = arr.length - 1;
23
- for (let i = 0; i < idxs.length; i++) {
24
- const old = idxs[i];
22
+ for (const old of idxs) {
25
23
  const idx = Math.min(lastIdx, old + by);
26
24
  if (idx <= lastIdx) {
27
25
  arr.splice(idx, 0, arr.splice(old, 1)[0]);
@@ -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,28 +1,22 @@
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
- const Color = await import('color').then(f => f.default);
13
12
  let feats = [];
14
13
  ctx.save();
15
14
  sources.forEach(source => {
16
- const features = groups[source.name];
17
- if (!features) {
18
- return;
19
- }
20
15
  const { reducedFeatures } = drawXY(ctx, {
21
16
  ...props,
22
- features,
17
+ features: groups[source.name] || [],
23
18
  height,
24
19
  colorCallback: () => source.color || 'blue',
25
- Color,
26
20
  });
27
21
  ctx.strokeStyle = 'rgba(200,200,200,0.8)';
28
22
  ctx.beginPath();
@@ -30,7 +24,7 @@ export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
30
24
  ctx.lineTo(width, height);
31
25
  ctx.stroke();
32
26
  ctx.translate(0, height);
33
- feats = [...feats, ...reducedFeatures];
27
+ feats = feats.concat(reducedFeatures);
34
28
  });
35
29
  ctx.restore();
36
30
  return { reducedFeatures: feats };
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { Button, Paper, TextField } from '@mui/material';
3
3
  import { makeStyles } from 'tss-react/mui';
4
- import { getSession, isElectron } from '@jbrowse/core/util';
4
+ import { getSession, isElectron, isSessionModelWithWidgets, isSessionWithAddTracks, } from '@jbrowse/core/util';
5
5
  import { storeBlobLocation } from '@jbrowse/core/util/tracks';
6
6
  const useStyles = makeStyles()(theme => ({
7
7
  textbox: {
@@ -60,19 +60,23 @@ export default function MultiWiggleWidget({ model }) {
60
60
  const obj = typeof bigWigs[0] === 'string'
61
61
  ? { bigWigs }
62
62
  : { subadapters: bigWigs };
63
- session.addTrackConf({
64
- trackId,
65
- type: 'MultiQuantitativeTrack',
66
- name: trackName,
67
- assemblyNames: [model.assembly],
68
- adapter: {
69
- type: 'MultiWiggleAdapter',
70
- ...obj,
71
- },
72
- });
73
- (_a = model.view) === null || _a === void 0 ? void 0 : _a.showTrack(trackId);
63
+ if (isSessionWithAddTracks(session)) {
64
+ session.addTrackConf({
65
+ trackId,
66
+ type: 'MultiQuantitativeTrack',
67
+ name: trackName,
68
+ assemblyNames: [model.assembly],
69
+ adapter: {
70
+ type: 'MultiWiggleAdapter',
71
+ ...obj,
72
+ },
73
+ });
74
+ (_a = model.view) === null || _a === void 0 ? void 0 : _a.showTrack(trackId);
75
+ }
74
76
  model.clearData();
75
- session.hideWidget(model);
77
+ if (isSessionModelWithWidgets(session)) {
78
+ session.hideWidget(model);
79
+ }
76
80
  } }, "Submit"),
77
81
  React.createElement("p", null, "Additional notes: "),
78
82
  React.createElement("ul", null,
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { Region } from '@jbrowse/core/util/types';
3
3
  import { Feature } from '@jbrowse/core/util';
4
4
  import { Source } from './util';
5
- declare function WiggleRendering(props: {
5
+ declare const MultiWiggleRendering: (props: {
6
6
  regions: Region[];
7
7
  features: Map<string, Feature>;
8
8
  bpPerPx: number;
@@ -16,6 +16,5 @@ declare function WiggleRendering(props: {
16
16
  displayModel: {
17
17
  isMultiRow: boolean;
18
18
  };
19
- }): React.JSX.Element;
20
- declare const _default: typeof WiggleRendering;
21
- export default _default;
19
+ }) => React.JSX.Element;
20
+ export default MultiWiggleRendering;
@@ -2,7 +2,7 @@ import { observer } from 'mobx-react';
2
2
  import React, { useRef } from 'react';
3
3
  import { SimpleFeature } from '@jbrowse/core/util';
4
4
  import { PrerenderedCanvas } from '@jbrowse/core/ui';
5
- function WiggleRendering(props) {
5
+ const MultiWiggleRendering = observer(function (props) {
6
6
  const { regions, features, bpPerPx, width, height, sources, onMouseLeave = () => { }, onMouseMove = () => { }, onFeatureClick = () => { }, displayModel, } = props;
7
7
  const [region] = regions;
8
8
  const ref = useRef(null);
@@ -59,10 +59,12 @@ function WiggleRendering(props) {
59
59
  return featureUnderMouse;
60
60
  }
61
61
  return (React.createElement("div", { ref: ref, onMouseMove: event => {
62
- const featureUnderMouse = getFeatureUnderMouse(event.clientX, event.clientY);
62
+ const { clientX, clientY } = event;
63
+ const featureUnderMouse = getFeatureUnderMouse(clientX, clientY);
63
64
  onMouseMove(event, featureUnderMouse);
64
65
  }, onClick: event => {
65
- const featureUnderMouse = getFeatureUnderMouse(event.clientX, event.clientY);
66
+ const { clientX, clientY } = event;
67
+ const featureUnderMouse = getFeatureUnderMouse(clientX, clientY);
66
68
  onFeatureClick(event, featureUnderMouse);
67
69
  }, onMouseLeave: event => onMouseLeave(event), style: {
68
70
  overflow: 'visible',
@@ -70,5 +72,5 @@ function WiggleRendering(props) {
70
72
  height,
71
73
  } },
72
74
  React.createElement(PrerenderedCanvas, { ...props })));
73
- }
74
- export default observer(WiggleRendering);
75
+ });
76
+ export default MultiWiggleRendering;
@@ -1,27 +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'));
10
- const Color = await import('color').then(f => f.default);
9
+ const groups = groupBy(features.values(), f => f.get('source'));
11
10
  let feats = [];
12
11
  for (const source of sources) {
13
- const features = groups[source.name];
14
- if (!features) {
15
- continue;
16
- }
12
+ const features = groups[source.name] || [];
17
13
  const { reducedFeatures } = drawXY(ctx, {
18
14
  ...props,
19
15
  features,
20
16
  offset: YSCALEBAR_LABEL_OFFSET,
21
17
  colorCallback: () => source.color || 'blue',
22
- Color,
23
18
  });
24
- feats = [...feats, ...reducedFeatures];
19
+ feats = feats.concat(reducedFeatures);
25
20
  }
26
21
  return { reducedFeatures: feats };
27
22
  }
package/esm/Tooltip.d.ts CHANGED
@@ -5,16 +5,15 @@ export type TooltipContentsComponent = React.ForwardRefExoticComponent<{
5
5
  feature: Feature;
6
6
  model: any;
7
7
  } & React.RefAttributes<HTMLDivElement>>;
8
- declare function Tooltip({ model, height, clientMouseCoord, offsetMouseCoord, clientRect, TooltipContents, useClientY, }: {
8
+ declare const Tooltip: ({ model, height, clientMouseCoord, offsetMouseCoord, clientRect, TooltipContents, useClientY, }: {
9
9
  model: {
10
10
  featureUnderMouse: Feature;
11
11
  };
12
- useClientY?: boolean;
12
+ useClientY?: boolean | undefined;
13
13
  height: number;
14
14
  clientMouseCoord: Coord;
15
15
  offsetMouseCoord: Coord;
16
- clientRect?: DOMRect;
16
+ clientRect?: DOMRect | undefined;
17
17
  TooltipContents: TooltipContentsComponent;
18
- }): React.JSX.Element | null;
19
- declare const _default: typeof Tooltip;
20
- export default _default;
18
+ }) => React.JSX.Element | null;
19
+ export default Tooltip;
package/esm/Tooltip.js CHANGED
@@ -32,7 +32,7 @@ const useStyles = makeStyles()(theme => ({
32
32
  pointerEvents: 'none',
33
33
  },
34
34
  }));
35
- function Tooltip({ model, height, clientMouseCoord, offsetMouseCoord, clientRect, TooltipContents, useClientY, }) {
35
+ const Tooltip = observer(function Tooltip({ model, height, clientMouseCoord, offsetMouseCoord, clientRect, TooltipContents, useClientY, }) {
36
36
  const { featureUnderMouse } = model;
37
37
  const [width, setWidth] = useState(0);
38
38
  const [anchorEl, setAnchorEl] = useState(null);
@@ -66,5 +66,5 @@ function Tooltip({ model, height, clientMouseCoord, offsetMouseCoord, clientRect
66
66
  left: offsetMouseCoord[0],
67
67
  height: height - YSCALEBAR_LABEL_OFFSET * 2,
68
68
  } }))) : null;
69
- }
70
- export default observer(Tooltip);
69
+ });
70
+ export default Tooltip;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Region } from '@jbrowse/core/util/types';
3
3
  import { Feature } from '@jbrowse/core/util';
4
- declare function WiggleRendering(props: {
4
+ declare const WiggleRendering: (props: {
5
5
  regions: Region[];
6
6
  features: Map<string, Feature>;
7
7
  bpPerPx: number;
@@ -11,6 +11,5 @@ declare function WiggleRendering(props: {
11
11
  onMouseMove: Function;
12
12
  onFeatureClick: Function;
13
13
  blockKey: string;
14
- }): React.JSX.Element;
15
- declare const _default: typeof WiggleRendering;
16
- export default _default;
14
+ }) => React.JSX.Element;
15
+ export default WiggleRendering;
@@ -1,7 +1,7 @@
1
1
  import { observer } from 'mobx-react';
2
2
  import React, { useRef } from 'react';
3
3
  import { PrerenderedCanvas } from '@jbrowse/core/ui';
4
- function WiggleRendering(props) {
4
+ const WiggleRendering = observer(function (props) {
5
5
  const { regions, features, bpPerPx, width, height, onMouseLeave = () => { }, onMouseMove = () => { }, onFeatureClick = () => { }, } = props;
6
6
  const [region] = regions;
7
7
  const ref = useRef(null);
@@ -31,5 +31,5 @@ function WiggleRendering(props) {
31
31
  height,
32
32
  } },
33
33
  React.createElement(PrerenderedCanvas, { ...props })));
34
- }
35
- export default observer(WiggleRendering);
34
+ });
35
+ export default WiggleRendering;
@@ -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 {
@@ -11,7 +11,6 @@ export default class XYPlotRenderer extends WiggleBaseRenderer {
11
11
  const pivotValue = readConfObject(config, 'bicolorPivotValue');
12
12
  const negColor = readConfObject(config, 'negColor');
13
13
  const posColor = readConfObject(config, 'posColor');
14
- const Color = await import('color').then(f => f.default);
15
14
  return drawXY(ctx, {
16
15
  ...props,
17
16
  colorCallback: readConfObject(config, 'color') === '#f0f'
@@ -19,7 +18,6 @@ export default class XYPlotRenderer extends WiggleBaseRenderer {
19
18
  : (feature, _score) => readConfObject(config, 'color', { feature }),
20
19
  offset: YSCALEBAR_LABEL_OFFSET,
21
20
  features: [...features.values()],
22
- Color,
23
21
  });
24
22
  }
25
23
  }
@@ -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
+ };