@jbrowse/plugin-hic 3.6.5 → 4.0.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 (70) hide show
  1. package/esm/HicAdapter/HicAdapter.d.ts +9 -0
  2. package/esm/HicAdapter/HicAdapter.js +33 -2
  3. package/esm/HicAdapter/HicFilehandle.js +1 -0
  4. package/esm/HicAdapter/configSchema.d.ts +2 -2
  5. package/esm/HicAdapter/index.js +2 -2
  6. package/esm/HicRenderer/HicRenderer.d.ts +7 -36
  7. package/esm/HicRenderer/HicRenderer.js +19 -26
  8. package/esm/HicRenderer/components/HicColorLegend.d.ts +6 -0
  9. package/esm/HicRenderer/components/HicColorLegend.js +52 -0
  10. package/esm/HicRenderer/components/HicRendering.d.ts +1 -8
  11. package/esm/HicRenderer/components/HicRendering.js +3 -8
  12. package/esm/HicRenderer/configSchema.d.ts +2 -2
  13. package/esm/HicRenderer/index.js +4 -4
  14. package/esm/HicRenderer/makeImageData.d.ts +9 -2
  15. package/esm/HicRenderer/makeImageData.js +83 -58
  16. package/esm/HicRenderer/types.d.ts +7 -0
  17. package/esm/HicRenderer/types.js +1 -0
  18. package/esm/HicTrack/configSchema.d.ts +16 -11
  19. package/esm/HicTrack/index.js +1 -1
  20. package/esm/LinearHicDisplay/afterAttach.d.ts +2 -0
  21. package/esm/LinearHicDisplay/afterAttach.js +111 -0
  22. package/esm/LinearHicDisplay/components/BaseDisplayComponent.d.ts +2 -0
  23. package/esm/LinearHicDisplay/components/BaseDisplayComponent.js +1 -0
  24. package/esm/LinearHicDisplay/components/HicSVGColorLegend.d.ts +7 -0
  25. package/esm/LinearHicDisplay/components/HicSVGColorLegend.js +60 -0
  26. package/esm/LinearHicDisplay/components/ReactComponent.d.ts +5 -0
  27. package/esm/LinearHicDisplay/components/ReactComponent.js +83 -0
  28. package/esm/LinearHicDisplay/configSchema.d.ts +9 -4
  29. package/esm/LinearHicDisplay/configSchema.js +5 -0
  30. package/esm/LinearHicDisplay/index.js +4 -4
  31. package/esm/LinearHicDisplay/model.d.ts +180 -220
  32. package/esm/LinearHicDisplay/model.js +71 -34
  33. package/esm/LinearHicDisplay/renderSvg.d.ts +3 -0
  34. package/esm/LinearHicDisplay/renderSvg.js +32 -0
  35. package/esm/index.js +6 -9
  36. package/package.json +27 -32
  37. package/dist/GuessAdapter/index.d.ts +0 -2
  38. package/dist/GuessAdapter/index.js +0 -23
  39. package/dist/HicAdapter/HicAdapter.d.ts +0 -27
  40. package/dist/HicAdapter/HicAdapter.js +0 -63
  41. package/dist/HicAdapter/HicFilehandle.d.ts +0 -10
  42. package/dist/HicAdapter/HicFilehandle.js +0 -16
  43. package/dist/HicAdapter/configSchema.d.ts +0 -15
  44. package/dist/HicAdapter/configSchema.js +0 -32
  45. package/dist/HicAdapter/index.d.ts +0 -2
  46. package/dist/HicAdapter/index.js +0 -49
  47. package/dist/HicRenderer/HicRenderer.d.ts +0 -54
  48. package/dist/HicRenderer/HicRenderer.js +0 -87
  49. package/dist/HicRenderer/components/HicRendering.d.ts +0 -9
  50. package/dist/HicRenderer/components/HicRendering.js +0 -11
  51. package/dist/HicRenderer/configSchema.d.ts +0 -19
  52. package/dist/HicRenderer/configSchema.js +0 -23
  53. package/dist/HicRenderer/index.d.ts +0 -2
  54. package/dist/HicRenderer/index.js +0 -17
  55. package/dist/HicRenderer/makeImageData.d.ts +0 -11
  56. package/dist/HicRenderer/makeImageData.js +0 -81
  57. package/dist/HicRenderer/viridis.d.ts +0 -2
  58. package/dist/HicRenderer/viridis.js +0 -18
  59. package/dist/HicTrack/configSchema.d.ts +0 -80
  60. package/dist/HicTrack/configSchema.js +0 -9
  61. package/dist/HicTrack/index.d.ts +0 -2
  62. package/dist/HicTrack/index.js +0 -20
  63. package/dist/LinearHicDisplay/configSchema.d.ts +0 -35
  64. package/dist/LinearHicDisplay/configSchema.js +0 -14
  65. package/dist/LinearHicDisplay/index.d.ts +0 -2
  66. package/dist/LinearHicDisplay/index.js +0 -24
  67. package/dist/LinearHicDisplay/model.d.ts +0 -344
  68. package/dist/LinearHicDisplay/model.js +0 -205
  69. package/dist/index.d.ts +0 -7
  70. package/dist/index.js +0 -33
@@ -0,0 +1,111 @@
1
+ import { getContainingView, getRpcSessionId, getSession, isAbortException, } from '@jbrowse/core/util';
2
+ import { createStopToken, stopStopToken } from '@jbrowse/core/util/stopToken';
3
+ import { addDisposer, isAlive } from '@jbrowse/mobx-state-tree';
4
+ import { drawCanvasImageData } from '@jbrowse/plugin-linear-genome-view';
5
+ import { autorun, untracked } from 'mobx';
6
+ export function doAfterAttach(self) {
7
+ ;
8
+ (async () => {
9
+ try {
10
+ const { rpcManager } = getSession(self);
11
+ const rpcSessionId = getRpcSessionId(self);
12
+ const { norms } = (await rpcManager.call(rpcSessionId, 'CoreGetInfo', {
13
+ adapterConfig: self.adapterConfig,
14
+ }));
15
+ if (isAlive(self) && norms) {
16
+ self.setAvailableNormalizations(norms);
17
+ }
18
+ }
19
+ catch (e) {
20
+ console.error(e);
21
+ if (isAlive(self)) {
22
+ getSession(self).notifyError(`${e}`, e);
23
+ }
24
+ }
25
+ })();
26
+ const performRender = async () => {
27
+ const view = getContainingView(self);
28
+ const { bpPerPx, dynamicBlocks } = view;
29
+ const regions = dynamicBlocks.contentBlocks;
30
+ if (!regions.length) {
31
+ return;
32
+ }
33
+ const { adapterConfig } = self;
34
+ const renderProps = self.renderProps();
35
+ try {
36
+ const session = getSession(self);
37
+ const { rpcManager } = session;
38
+ const rpcSessionId = getRpcSessionId(self);
39
+ const previousToken = untracked(() => self.renderingStopToken);
40
+ if (previousToken) {
41
+ stopStopToken(previousToken);
42
+ }
43
+ const stopToken = createStopToken();
44
+ self.setRenderingStopToken(stopToken);
45
+ self.setLoading(true);
46
+ const result = (await rpcManager.call(rpcSessionId, 'CoreRender', {
47
+ sessionId: rpcSessionId,
48
+ rendererType: 'HicRenderer',
49
+ regions: [...regions],
50
+ adapterConfig,
51
+ bpPerPx,
52
+ stopToken,
53
+ ...renderProps,
54
+ }, {
55
+ statusCallback: (msg) => {
56
+ if (isAlive(self)) {
57
+ self.setStatusMessage(msg);
58
+ }
59
+ },
60
+ }));
61
+ if (result.imageData) {
62
+ self.setRenderingImageData(result.imageData);
63
+ self.setLastDrawnOffsetPx(view.offsetPx);
64
+ }
65
+ self.setFlatbushData(result.flatbush, result.items ?? [], result.maxScore ?? 0, result.yScalar ?? 1);
66
+ }
67
+ catch (error) {
68
+ if (!isAbortException(error)) {
69
+ if (isAlive(self)) {
70
+ self.setError(error);
71
+ }
72
+ }
73
+ }
74
+ finally {
75
+ if (isAlive(self)) {
76
+ self.setRenderingStopToken(undefined);
77
+ self.setLoading(false);
78
+ }
79
+ }
80
+ };
81
+ addDisposer(self, autorun(() => {
82
+ const view = getContainingView(self);
83
+ if (!view.initialized) {
84
+ return;
85
+ }
86
+ const { dynamicBlocks } = view;
87
+ const regions = dynamicBlocks.contentBlocks;
88
+ self.resolution;
89
+ self.useLogScale;
90
+ self.colorScheme;
91
+ self.activeNormalization;
92
+ self.mode;
93
+ self.height;
94
+ if (untracked(() => self.error) || !regions.length) {
95
+ return;
96
+ }
97
+ performRender();
98
+ }, {
99
+ delay: 1000,
100
+ name: 'LinearHicDisplayRender',
101
+ }));
102
+ addDisposer(self, autorun(() => {
103
+ const view = getContainingView(self);
104
+ if (!view.initialized) {
105
+ return;
106
+ }
107
+ drawCanvasImageData(self.ref, self.renderingImageData);
108
+ }, {
109
+ name: 'LinearHicDisplayCanvas',
110
+ }));
111
+ }
@@ -0,0 +1,2 @@
1
+ export { NonBlockCanvasDisplayComponent as default } from '@jbrowse/plugin-linear-genome-view';
2
+ export type { NonBlockCanvasDisplayModel } from '@jbrowse/plugin-linear-genome-view';
@@ -0,0 +1 @@
1
+ export { NonBlockCanvasDisplayComponent as default } from '@jbrowse/plugin-linear-genome-view';
@@ -0,0 +1,7 @@
1
+ export default function HicSVGColorLegend({ maxScore, colorScheme, useLogScale, width, legendAreaWidth, }: {
2
+ maxScore: number;
3
+ colorScheme?: string;
4
+ useLogScale?: boolean;
5
+ width: number;
6
+ legendAreaWidth?: number;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { toLocale } from '@jbrowse/core/util';
3
+ import { scaleLinear, scaleLog } from '@mui/x-charts-vendor/d3-scale';
4
+ const colorStops = {
5
+ juicebox: [
6
+ { offset: '0%', color: 'rgba(0,0,0,0)' },
7
+ { offset: '100%', color: 'red' },
8
+ ],
9
+ fall: [
10
+ { offset: '0%', color: 'rgb(255,255,255)' },
11
+ { offset: '10%', color: 'rgb(255,255,204)' },
12
+ { offset: '20%', color: 'rgb(255,237,160)' },
13
+ { offset: '30%', color: 'rgb(254,217,118)' },
14
+ { offset: '40%', color: 'rgb(254,178,76)' },
15
+ { offset: '50%', color: 'rgb(253,141,60)' },
16
+ { offset: '60%', color: 'rgb(252,78,42)' },
17
+ { offset: '70%', color: 'rgb(227,26,28)' },
18
+ { offset: '80%', color: 'rgb(189,0,38)' },
19
+ { offset: '90%', color: 'rgb(128,0,38)' },
20
+ { offset: '100%', color: 'rgb(0,0,0)' },
21
+ ],
22
+ viridis: [
23
+ { offset: '0%', color: '#440154' },
24
+ { offset: '11%', color: '#482878' },
25
+ { offset: '22%', color: '#3e4a89' },
26
+ { offset: '33%', color: '#31688e' },
27
+ { offset: '44%', color: '#26828e' },
28
+ { offset: '55%', color: '#1f9e89' },
29
+ { offset: '66%', color: '#35b779' },
30
+ { offset: '77%', color: '#6ece58' },
31
+ { offset: '88%', color: '#b5de2b' },
32
+ { offset: '100%', color: '#fde725' },
33
+ ],
34
+ };
35
+ function getNiceScale(maxScore, useLogScale) {
36
+ if (useLogScale) {
37
+ const scale = scaleLog().base(2).domain([1, maxScore]).nice();
38
+ const [min, max] = scale.domain();
39
+ return { min, max };
40
+ }
41
+ const scale = scaleLinear().domain([0, maxScore]).nice();
42
+ const [min, max] = scale.domain();
43
+ return { min, max };
44
+ }
45
+ export default function HicSVGColorLegend({ maxScore, colorScheme = 'juicebox', useLogScale, width, legendAreaWidth, }) {
46
+ const gradientId = `hic-gradient-${colorScheme}`;
47
+ const stops = colorStops[colorScheme] || colorStops.juicebox;
48
+ const { min, max } = getNiceScale(maxScore, useLogScale);
49
+ const minLabel = min !== undefined ? toLocale(min) : '';
50
+ const maxLabel = `${max !== undefined ? toLocale(max) : ''}${useLogScale ? ' (log)' : ''}`;
51
+ const legendWidth = 120;
52
+ const legendHeight = 40;
53
+ const barWidth = 100;
54
+ const barHeight = 12;
55
+ const padding = 8;
56
+ const fontSize = 10;
57
+ const x = legendAreaWidth ? width + 10 : width - legendWidth - 10;
58
+ const y = 10;
59
+ return (_jsxs("g", { transform: `translate(${x}, ${y})`, children: [_jsx("defs", { children: _jsx("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: stops.map((stop, idx) => (_jsx("stop", { offset: stop.offset, style: { stopColor: stop.color, stopOpacity: 1 } }, idx))) }) }), _jsx("rect", { x: 0, y: 0, width: legendWidth, height: legendHeight, fill: "rgba(255,255,255,0.9)", stroke: "#ccc", strokeWidth: 1, rx: 4 }), _jsx("rect", { x: padding, y: padding, width: barWidth, height: barHeight, fill: `url(#${gradientId})`, rx: 2 }), _jsx("text", { x: padding, y: padding + barHeight + fontSize + 2, fontSize: fontSize, fill: "black", children: minLabel }), _jsx("text", { x: padding + barWidth, y: padding + barHeight + fontSize + 2, fontSize: fontSize, fill: "black", textAnchor: "end", children: maxLabel })] }));
60
+ }
@@ -0,0 +1,5 @@
1
+ import type { LinearHicDisplayModel } from '../model.ts';
2
+ declare const LinearHicReactComponent: ({ model, }: {
3
+ model: LinearHicDisplayModel;
4
+ }) => import("react/jsx-runtime").JSX.Element;
5
+ export default LinearHicReactComponent;
@@ -0,0 +1,83 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback, useMemo, useRef, useState } from 'react';
3
+ import BaseTooltip from '@jbrowse/core/ui/BaseTooltip';
4
+ import { getContainingView, reducePrecision } from '@jbrowse/core/util';
5
+ import Flatbush from '@jbrowse/core/util/flatbush';
6
+ import { observer } from 'mobx-react';
7
+ import BaseDisplayComponent from "./BaseDisplayComponent.js";
8
+ import HicColorLegend from "../../HicRenderer/components/HicColorLegend.js";
9
+ const SQRT2 = Math.sqrt(2);
10
+ function HicTooltip({ item, x, y, }) {
11
+ return (_jsx(BaseTooltip, { clientPoint: { x: x + 15, y }, children: _jsxs("div", { children: ["Score: ", reducePrecision(item.counts)] }) }));
12
+ }
13
+ function Crosshairs({ x, y, yScalar, left, width, height, }) {
14
+ const dx = y / yScalar;
15
+ return (_jsx("svg", { style: {
16
+ position: 'absolute',
17
+ left,
18
+ top: 0,
19
+ width,
20
+ height,
21
+ pointerEvents: 'none',
22
+ }, children: _jsx("g", { stroke: "#000", strokeWidth: "1", fill: "none", children: _jsx("path", { d: `M ${x - dx} 0 L ${x} ${y} L ${x + dx} 0` }) }) }));
23
+ }
24
+ function screenToUnrotated(screenX, screenY, yScalar) {
25
+ const scaledY = screenY / yScalar;
26
+ const x = (screenX - scaledY) / SQRT2;
27
+ const y = (screenX + scaledY) / SQRT2;
28
+ return { x, y };
29
+ }
30
+ const HicCanvas = observer(function HicCanvas({ model, }) {
31
+ const view = getContainingView(model);
32
+ const width = Math.round(view.dynamicBlocks.totalWidthPx);
33
+ const { height, drawn, loading, flatbush, flatbushItems, yScalar, showLegend, maxScore, colorScheme, useLogScale, } = model;
34
+ const containerRef = useRef(null);
35
+ const [hoveredItem, setHoveredItem] = useState();
36
+ const [mousePosition, setMousePosition] = useState();
37
+ const [localMousePos, setLocalMousePos] = useState();
38
+ const flatbushIndex = useMemo(() => (flatbush ? Flatbush.from(flatbush) : null), [flatbush]);
39
+ const cb = useCallback((ref) => {
40
+ model.setRef(ref);
41
+ }, [model, width, height]);
42
+ const onMouseMove = useCallback((event) => {
43
+ if (!containerRef.current || !flatbushIndex || !flatbushItems.length) {
44
+ setHoveredItem(undefined);
45
+ setMousePosition(undefined);
46
+ return;
47
+ }
48
+ const rect = containerRef.current.getBoundingClientRect();
49
+ const screenX = event.clientX - rect.left;
50
+ const screenY = event.clientY - rect.top;
51
+ setMousePosition({ x: event.clientX, y: event.clientY });
52
+ setLocalMousePos({ x: screenX, y: screenY });
53
+ const { x, y } = screenToUnrotated(screenX, screenY, yScalar);
54
+ const results = flatbushIndex.search(x - 1, y - 1, x + 1, y + 1);
55
+ if (results.length > 0) {
56
+ const item = flatbushItems[results[0]];
57
+ setHoveredItem(item);
58
+ }
59
+ else {
60
+ setHoveredItem(undefined);
61
+ }
62
+ }, [flatbushIndex, flatbushItems, yScalar]);
63
+ const onMouseLeave = useCallback(() => {
64
+ setHoveredItem(undefined);
65
+ setMousePosition(undefined);
66
+ setLocalMousePos(undefined);
67
+ }, []);
68
+ return (_jsxs("div", { ref: containerRef, style: {
69
+ cursor: hoveredItem && mousePosition ? 'crosshair' : undefined,
70
+ position: 'relative',
71
+ width,
72
+ height,
73
+ }, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, children: [_jsx("canvas", { "data-testid": `hic_canvas${drawn && !loading ? '_done' : ''}`, ref: cb, style: {
74
+ width,
75
+ height,
76
+ position: 'absolute',
77
+ left: 0,
78
+ }, width: width * 2, height: height * 2 }), hoveredItem && localMousePos ? (_jsx(Crosshairs, { x: localMousePos.x, y: localMousePos.y, yScalar: yScalar, left: 0, width: width, height: height })) : null, hoveredItem && mousePosition ? (_jsx(HicTooltip, { item: hoveredItem, x: mousePosition.x, y: mousePosition.y })) : null, showLegend && maxScore > 0 ? (_jsx(HicColorLegend, { maxScore: maxScore, colorScheme: colorScheme, useLogScale: useLogScale })) : null] }));
79
+ });
80
+ const LinearHicReactComponent = observer(function LinearHicReactComponent({ model, }) {
81
+ return (_jsx(BaseDisplayComponent, { model: model, children: _jsx(HicCanvas, { model: model }) }));
82
+ });
83
+ export default LinearHicReactComponent;
@@ -1,8 +1,13 @@
1
1
  import type PluginManager from '@jbrowse/core/PluginManager';
2
- import type { Instance } from 'mobx-state-tree';
3
- declare const HicTrackConfigFactory: (pluginManager: PluginManager) => import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
+ import type { Instance } from '@jbrowse/mobx-state-tree';
3
+ declare const HicTrackConfigFactory: (pluginManager: PluginManager) => import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
4
4
  renderer: import("@jbrowse/core/configuration").AnyConfigurationSchemaType;
5
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
5
+ height: {
6
+ type: string;
7
+ defaultValue: number;
8
+ description: string;
9
+ };
10
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
6
11
  maxFeatureScreenDensity: {
7
12
  type: string;
8
13
  description: string;
@@ -29,7 +34,7 @@ declare const HicTrackConfigFactory: (pluginManager: PluginManager) => import("@
29
34
  description: string;
30
35
  defaultValue: never[];
31
36
  };
32
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>;
37
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>;
33
38
  export type HicTrackConfigModel = ReturnType<typeof HicTrackConfigFactory>;
34
39
  export type HicTrackConfig = Instance<HicTrackConfigModel>;
35
40
  export default HicTrackConfigFactory;
@@ -4,6 +4,11 @@ function x() { }
4
4
  const HicTrackConfigFactory = (pluginManager) => {
5
5
  return ConfigurationSchema('LinearHicDisplay', {
6
6
  renderer: pluginManager.getRendererType('HicRenderer').configSchema,
7
+ height: {
8
+ type: 'number',
9
+ defaultValue: 300,
10
+ description: 'default height for the Hi-C track',
11
+ },
7
12
  }, {
8
13
  baseConfiguration: baseLinearDisplayConfigSchema,
9
14
  explicitlyTyped: true,
@@ -1,7 +1,7 @@
1
+ import { lazy } from 'react';
1
2
  import { DisplayType } from '@jbrowse/core/pluggableElementTypes';
2
- import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view';
3
- import configSchemaFactory from './configSchema';
4
- import stateModelFactory from './model';
3
+ import configSchemaFactory from "./configSchema.js";
4
+ import stateModelFactory from "./model.js";
5
5
  export default function LinearHicDisplayF(pluginManager) {
6
6
  pluginManager.addDisplayType(() => {
7
7
  const configSchema = configSchemaFactory(pluginManager);
@@ -12,7 +12,7 @@ export default function LinearHicDisplayF(pluginManager) {
12
12
  stateModel: stateModelFactory(configSchema),
13
13
  trackType: 'HicTrack',
14
14
  viewType: 'LinearGenomeView',
15
- ReactComponent: BaseLinearDisplayComponent,
15
+ ReactComponent: lazy(() => import("./components/ReactComponent.js")),
16
16
  });
17
17
  });
18
18
  }