@jbrowse/plugin-hic 3.7.0 → 4.0.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 (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 -235
  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 -359
  68. package/dist/LinearHicDisplay/model.js +0 -205
  69. package/dist/index.d.ts +0 -7
  70. package/dist/index.js +0 -33
@@ -4,6 +4,13 @@ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
4
  import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
5
5
  import type { getSubAdapterType } from '@jbrowse/core/data_adapters/dataAdapterCache';
6
6
  import type { Region } from '@jbrowse/core/util/types';
7
+ export interface MultiRegionContactRecord {
8
+ bin1: number;
9
+ bin2: number;
10
+ counts: number;
11
+ region1Idx: number;
12
+ region2Idx: number;
13
+ }
7
14
  interface HicOptions extends BaseOptions {
8
15
  resolution?: number;
9
16
  bpPerPx?: number;
@@ -15,11 +22,13 @@ export default class HicAdapter extends BaseFeatureDataAdapter {
15
22
  private setup;
16
23
  getHeader(opts?: BaseOptions): Promise<{
17
24
  norms: any;
25
+ hasInterChromosomalData: boolean;
18
26
  resolutions: number[];
19
27
  }>;
20
28
  getRefNames(opts?: BaseOptions): Promise<string[]>;
21
29
  getResolution(res: number, opts?: BaseOptions): Promise<number>;
22
30
  getFeatures(region: Region, opts?: HicOptions): any;
31
+ getMultiRegionContactRecords(regions: Region[], opts?: HicOptions): Promise<MultiRegionContactRecord[]>;
23
32
  getMultiRegionFeatureDensityStats(_regions: Region[]): Promise<{
24
33
  featureDensity: number;
25
34
  }>;
@@ -2,8 +2,9 @@ import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
2
2
  import { updateStatus } from '@jbrowse/core/util';
3
3
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
4
4
  import HicStraw from 'hic-straw';
5
- import { openHicFilehandle } from './HicFilehandle';
5
+ import { openHicFilehandle } from "./HicFilehandle.js";
6
6
  export default class HicAdapter extends BaseFeatureDataAdapter {
7
+ hic;
7
8
  constructor(config, getSubAdapter, pluginManager) {
8
9
  super(config, getSubAdapter, pluginManager);
9
10
  this.hic = new HicStraw({
@@ -17,7 +18,13 @@ export default class HicAdapter extends BaseFeatureDataAdapter {
17
18
  async getHeader(opts) {
18
19
  const { chromosomes, ...rest } = await this.setup(opts);
19
20
  const norms = await this.hic.getNormalizationOptions();
20
- return { ...rest, norms };
21
+ await this.hic.hicFile.init();
22
+ const { masterIndex } = this.hic.hicFile;
23
+ const hasInterChromosomalData = Object.keys(masterIndex).some(key => {
24
+ const [idx1, idx2] = key.split('_');
25
+ return idx1 !== idx2;
26
+ });
27
+ return { ...rest, norms, hasInterChromosomalData };
21
28
  }
22
29
  async getRefNames(opts) {
23
30
  const metadata = await this.setup(opts);
@@ -49,6 +56,30 @@ export default class HicAdapter extends BaseFeatureDataAdapter {
49
56
  observer.complete();
50
57
  }, opts.stopToken);
51
58
  }
59
+ async getMultiRegionContactRecords(regions, opts = {}) {
60
+ const { resolution, normalization = 'KR', bpPerPx = 1, statusCallback = () => { }, } = opts;
61
+ const res = await this.getResolution(bpPerPx / (resolution || 1000), opts);
62
+ const allRecords = [];
63
+ await updateStatus('Downloading .hic data', statusCallback, async () => {
64
+ for (let i = 0; i < regions.length; i++) {
65
+ for (let j = i; j < regions.length; j++) {
66
+ const region1 = regions[i];
67
+ const region2 = regions[j];
68
+ const records = await this.hic.getContactRecords(normalization, { chr: region1.refName, start: region1.start, end: region1.end }, { chr: region2.refName, start: region2.start, end: region2.end }, 'BP', res);
69
+ for (const { bin1, bin2, counts } of records) {
70
+ allRecords.push({
71
+ bin1,
72
+ bin2,
73
+ counts,
74
+ region1Idx: i,
75
+ region2Idx: j,
76
+ });
77
+ }
78
+ }
79
+ }
80
+ });
81
+ return allRecords;
82
+ }
52
83
  async getMultiRegionFeatureDensityStats(_regions) {
53
84
  return {
54
85
  featureDensity: 0,
@@ -1,5 +1,6 @@
1
1
  import { openLocation } from '@jbrowse/core/util/io';
2
2
  class HicFilehandle {
3
+ filehandle;
3
4
  constructor(filehandle) {
4
5
  this.filehandle = filehandle;
5
6
  }
@@ -1,4 +1,4 @@
1
- declare const HicAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
1
+ declare const HicAdapter: import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
2
2
  hicLocation: {
3
3
  type: string;
4
4
  defaultValue: {
@@ -11,5 +11,5 @@ declare const HicAdapter: import("@jbrowse/core/configuration/configurationSchem
11
11
  defaultValue: number;
12
12
  description: string;
13
13
  };
14
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
14
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
15
15
  export default HicAdapter;
@@ -1,10 +1,10 @@
1
1
  import { AdapterType } from '@jbrowse/core/pluggableElementTypes';
2
- import configSchema from './configSchema';
2
+ import configSchema from "./configSchema.js";
3
3
  export default function HicAdapterF(pluginManager) {
4
4
  pluginManager.addAdapterType(() => new AdapterType({
5
5
  name: 'HicAdapter',
6
6
  displayName: 'Hi-C adapter',
7
7
  configSchema,
8
- getAdapterClass: () => import('./HicAdapter').then(r => r.default),
8
+ getAdapterClass: () => import("./HicAdapter.js").then(r => r.default),
9
9
  }));
10
10
  }
@@ -1,54 +1,25 @@
1
1
  import ServerSideRendererType from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
2
+ import type { MultiRegionContactRecord } from '../HicAdapter/HicAdapter.ts';
2
3
  import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
- import type { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
4
- import type { RenderArgs as ServerSideRenderArgs, RenderArgsDeserialized as ServerSideRenderArgsDeserialized, ResultsDeserialized as ServerSideResultsDeserialized, ResultsSerialized as ServerSideResultsSerialized } from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
4
+ import type { RenderArgsDeserialized as ServerSideRenderArgsDeserialized } from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
5
5
  import type { Region } from '@jbrowse/core/util/types';
6
- interface HicFeature {
7
- bin1: number;
8
- bin2: number;
9
- counts: number;
10
- }
11
- interface HicDataAdapter extends BaseFeatureDataAdapter {
12
- getResolution: (bp: number) => Promise<number>;
13
- }
14
- export interface RenderArgs extends ServerSideRenderArgs {
15
- regions: Region[];
16
- }
6
+ export type HicFeature = MultiRegionContactRecord;
17
7
  export interface RenderArgsDeserialized extends ServerSideRenderArgsDeserialized {
18
8
  regions: Region[];
19
- dataAdapter: HicDataAdapter;
20
9
  bpPerPx: number;
21
10
  highResolutionScaling: number;
22
11
  resolution: number;
23
12
  adapterConfig: AnyConfigurationModel;
24
13
  displayHeight?: number;
14
+ useLogScale?: boolean;
15
+ colorScheme?: string;
25
16
  }
26
17
  export interface RenderArgsDeserializedWithFeatures extends RenderArgsDeserialized {
27
18
  features: HicFeature[];
28
19
  statusCallback?: (arg: string) => void;
29
20
  }
30
- export type ResultsSerialized = ServerSideResultsSerialized;
31
- export type ResultsDeserialized = ServerSideResultsDeserialized;
32
21
  export default class HicRenderer extends ServerSideRendererType {
33
22
  supportsSVG: boolean;
34
- render(renderProps: RenderArgsDeserialized): Promise<{
35
- height: number;
36
- width: number;
37
- canvasRecordedData: Record<string, unknown>;
38
- reactElement?: React.ReactElement;
39
- html?: string;
40
- } | {
41
- height: number;
42
- width: number;
43
- imageData: any;
44
- reactElement?: React.ReactElement;
45
- html?: string;
46
- } | {
47
- height: number;
48
- width: number;
49
- reactElement: React.ReactElement;
50
- html?: string;
51
- }>;
52
- getFeatures(args: RenderArgsDeserialized): Promise<any>;
23
+ render(renderProps: RenderArgsDeserialized): Promise<import("librpc-web-mod").RpcResult>;
24
+ getFeatures(args: RenderArgsDeserialized): Promise<MultiRegionContactRecord[]>;
53
25
  }
54
- export type { RenderArgsSerialized, RenderResults, } from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
@@ -1,48 +1,41 @@
1
1
  import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
2
2
  import ServerSideRendererType from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
3
+ import { rpcResult } from '@jbrowse/core/util/librpc';
4
+ import { collectTransferables } from '@jbrowse/core/util/offscreenCanvasPonyfill';
3
5
  import { renderToAbstractCanvas } from '@jbrowse/core/util/offscreenCanvasUtils';
4
- import { firstValueFrom } from 'rxjs';
5
- import { toArray } from 'rxjs/operators';
6
6
  export default class HicRenderer extends ServerSideRendererType {
7
- constructor() {
8
- super(...arguments);
9
- this.supportsSVG = true;
10
- }
7
+ supportsSVG = true;
11
8
  async render(renderProps) {
12
- const { displayHeight, regions, bpPerPx } = renderProps;
13
- const region = regions[0];
14
- const width = (region.end - region.start) / bpPerPx;
9
+ const { displayHeight, regions, bpPerPx, colorScheme, useLogScale } = renderProps;
10
+ let totalWidthBp = 0;
11
+ for (const region of regions) {
12
+ totalWidthBp += region.end - region.start;
13
+ }
14
+ const width = totalWidthBp / bpPerPx;
15
15
  const hyp = width / 2;
16
- const height = displayHeight !== null && displayHeight !== void 0 ? displayHeight : hyp;
16
+ const height = displayHeight ?? hyp;
17
17
  const features = await this.getFeatures(renderProps);
18
- const { makeImageData } = await import('./makeImageData');
18
+ const yScalar = height / Math.max(height, hyp);
19
+ const { makeImageData } = await import("./makeImageData.js");
19
20
  const res = await renderToAbstractCanvas(width, height, renderProps, ctx => makeImageData(ctx, {
20
21
  ...renderProps,
21
- yScalar: height / Math.max(height, hyp),
22
+ yScalar,
22
23
  features,
23
24
  pluginManager: this.pluginManager,
24
25
  }));
25
- const results = await super.render({
26
- ...renderProps,
27
- ...res,
28
- features,
29
- region: renderProps.regions[0],
30
- height,
31
- width,
32
- });
33
- return {
34
- ...results,
26
+ const serialized = {
35
27
  ...res,
36
28
  height,
37
29
  width,
30
+ yScalar,
31
+ colorScheme,
32
+ useLogScale,
38
33
  };
34
+ return rpcResult(serialized, collectTransferables(serialized));
39
35
  }
40
36
  async getFeatures(args) {
41
37
  const { regions, sessionId, adapterConfig } = args;
42
38
  const { dataAdapter } = await getAdapter(this.pluginManager, sessionId, adapterConfig);
43
- const features = await firstValueFrom(dataAdapter
44
- .getFeatures(regions[0], args)
45
- .pipe(toArray()));
46
- return features;
39
+ return dataAdapter.getMultiRegionContactRecords(regions, args);
47
40
  }
48
41
  }
@@ -0,0 +1,6 @@
1
+ declare const HicColorLegend: ({ maxScore, colorScheme, useLogScale, }: {
2
+ maxScore: number;
3
+ colorScheme?: string;
4
+ useLogScale?: boolean;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ export default HicColorLegend;
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { toLocale } from '@jbrowse/core/util';
3
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
4
+ import { scaleLinear, scaleLog } from '@mui/x-charts-vendor/d3-scale';
5
+ import { observer } from 'mobx-react';
6
+ const useStyles = makeStyles()({
7
+ legend: {
8
+ position: 'absolute',
9
+ right: 10,
10
+ top: 10,
11
+ background: 'rgba(255,255,255,0.9)',
12
+ border: '1px solid #ccc',
13
+ borderRadius: 4,
14
+ padding: 8,
15
+ fontSize: 11,
16
+ pointerEvents: 'none',
17
+ zIndex: 100,
18
+ },
19
+ gradientBar: {
20
+ width: 100,
21
+ height: 12,
22
+ marginBottom: 4,
23
+ borderRadius: 2,
24
+ },
25
+ labels: {
26
+ display: 'flex',
27
+ justifyContent: 'space-between',
28
+ fontSize: 10,
29
+ },
30
+ });
31
+ const colorGradients = {
32
+ juicebox: 'linear-gradient(to right, rgba(0,0,0,0), red)',
33
+ fall: 'linear-gradient(to right, rgb(255,255,255), rgb(255,255,204), rgb(255,237,160), rgb(254,217,118), rgb(254,178,76), rgb(253,141,60), rgb(252,78,42), rgb(227,26,28), rgb(189,0,38), rgb(128,0,38), rgb(0,0,0))',
34
+ viridis: 'linear-gradient(to right, #440154, #482878, #3e4a89, #31688e, #26828e, #1f9e89, #35b779, #6ece58, #b5de2b, #fde725)',
35
+ };
36
+ function getNiceScale(maxScore, useLogScale) {
37
+ if (useLogScale) {
38
+ const scale = scaleLog().base(2).domain([1, maxScore]).nice();
39
+ const [min, max] = scale.domain();
40
+ return { min, max };
41
+ }
42
+ const scale = scaleLinear().domain([0, maxScore]).nice();
43
+ const [min, max] = scale.domain();
44
+ return { min, max };
45
+ }
46
+ const HicColorLegend = observer(function HicColorLegend({ maxScore, colorScheme = 'juicebox', useLogScale, }) {
47
+ const { classes } = useStyles();
48
+ const gradient = colorGradients[colorScheme] || colorGradients.juicebox;
49
+ const { min, max } = getNiceScale(maxScore, useLogScale);
50
+ return (_jsxs("div", { className: classes.legend, children: [_jsx("div", { className: classes.gradientBar, style: { background: gradient } }), _jsxs("div", { className: classes.labels, children: [_jsx("span", { children: min !== undefined ? toLocale(min) : '' }), _jsxs("span", { children: [max !== undefined ? toLocale(max) : '', useLogScale ? ' (log)' : ''] })] })] }));
51
+ });
52
+ export default HicColorLegend;
@@ -1,9 +1,2 @@
1
- import type { Region } from '@jbrowse/core/util/types';
2
- declare const HicRendering: (props: {
3
- blockKey: string;
4
- width: number;
5
- height: number;
6
- regions: Region[];
7
- bpPerPx: number;
8
- }) => import("react/jsx-runtime").JSX.Element;
1
+ declare const HicRendering: () => null;
9
2
  export default HicRendering;
@@ -1,9 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { PrerenderedCanvas } from '@jbrowse/core/ui';
3
- import { observer } from 'mobx-react';
4
- const HicRendering = observer(function HicRendering(props) {
5
- const { width, height } = props;
6
- const canvasWidth = Math.ceil(width);
7
- return (_jsx("div", { style: { position: 'relative', width: canvasWidth, height }, children: _jsx(PrerenderedCanvas, { ...props, style: { position: 'absolute', left: 0, top: 0 } }) }));
8
- });
1
+ const HicRendering = function HicRendering() {
2
+ return null;
3
+ };
9
4
  export default HicRendering;
@@ -1,4 +1,4 @@
1
- declare const HicRenderer: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
1
+ declare const HicRenderer: import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
2
2
  baseColor: {
3
3
  type: string;
4
4
  description: string;
@@ -15,5 +15,5 @@ declare const HicRenderer: import("@jbrowse/core/configuration/configurationSche
15
15
  description: string;
16
16
  defaultValue: number;
17
17
  };
18
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
18
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
19
19
  export default HicRenderer;
@@ -1,10 +1,10 @@
1
- import HicRenderer from './HicRenderer';
2
- import ReactComponent from './components/HicRendering';
3
- import configSchema from './configSchema';
1
+ import { lazy } from 'react';
2
+ import HicRenderer from "./HicRenderer.js";
3
+ import configSchema from "./configSchema.js";
4
4
  export default function HicRendererF(pluginManager) {
5
5
  pluginManager.addRendererType(() => new HicRenderer({
6
6
  name: 'HicRenderer',
7
- ReactComponent,
7
+ ReactComponent: lazy(() => import("./components/HicRendering.js")),
8
8
  configSchema,
9
9
  pluginManager,
10
10
  }));
@@ -1,11 +1,18 @@
1
- import type { RenderArgsDeserializedWithFeatures } from './HicRenderer';
1
+ import type { RenderArgsDeserializedWithFeatures } from './HicRenderer.tsx';
2
+ import type { HicFlatbushItem } from './types.ts';
2
3
  import type PluginManager from '@jbrowse/core/PluginManager';
3
4
  import type { RenderArgs as ServerSideRenderArgs } from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
4
5
  import type { Region } from '@jbrowse/core/util/types';
6
+ export interface MakeImageDataResult {
7
+ flatbush: ArrayBufferLike;
8
+ items: HicFlatbushItem[];
9
+ maxScore: number;
10
+ w: number;
11
+ }
5
12
  export interface RenderArgs extends ServerSideRenderArgs {
6
13
  regions: Region[];
7
14
  }
8
15
  export declare function makeImageData(ctx: CanvasRenderingContext2D, props: RenderArgsDeserializedWithFeatures & {
9
16
  yScalar: number;
10
17
  pluginManager: PluginManager;
11
- }): Promise<undefined>;
18
+ }): Promise<MakeImageDataResult | undefined>;
@@ -1,75 +1,100 @@
1
1
  import { readConfObject } from '@jbrowse/core/configuration';
2
2
  import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
3
- import { forEachWithStopTokenCheck } from '@jbrowse/core/util';
4
3
  import { colord } from '@jbrowse/core/util/colord';
5
- import { checkStopToken } from '@jbrowse/core/util/stopToken';
4
+ import Flatbush from '@jbrowse/core/util/flatbush';
5
+ import { checkStopToken2, checkStopToken, createStopTokenChecker, } from '@jbrowse/core/util/stopToken';
6
6
  import { interpolateRgbBasis } from '@mui/x-charts-vendor/d3-interpolate';
7
7
  import { scaleSequential, scaleSequentialLog, } from '@mui/x-charts-vendor/d3-scale';
8
- import interpolateViridis from './viridis';
8
+ import interpolateViridis from "./viridis.js";
9
9
  export async function makeImageData(ctx, props) {
10
10
  const { features, config, bpPerPx, stopToken, resolution, sessionId, adapterConfig, useLogScale, colorScheme, regions, pluginManager, yScalar, } = props;
11
11
  const { statusCallback = () => { } } = props;
12
12
  statusCallback('Drawing Hi-C matrix');
13
- const region = regions[0];
14
13
  const { dataAdapter } = await getAdapter(pluginManager, sessionId, adapterConfig);
15
14
  const res = await dataAdapter.getResolution(bpPerPx / resolution);
16
- const width = (region.end - region.start) / bpPerPx;
15
+ const lastCheck = createStopTokenChecker(stopToken);
17
16
  const w = res / (bpPerPx * Math.sqrt(2));
18
17
  const baseColor = colord(readConfObject(config, 'baseColor'));
19
- const offset = Math.floor(region.start / res);
20
- if (features.length) {
21
- let maxScore = 0;
22
- let minBin = 0;
23
- let maxBin = 0;
24
- checkStopToken(stopToken);
25
- for (const { bin1, bin2, counts } of features) {
26
- maxScore = Math.max(counts, maxScore);
27
- minBin = Math.min(Math.min(bin1, bin2), minBin);
28
- maxBin = Math.max(Math.max(bin1, bin2), maxBin);
29
- }
30
- checkStopToken(stopToken);
31
- const colorSchemes = {
32
- juicebox: ['rgba(0,0,0,0)', 'red'],
33
- fall: interpolateRgbBasis([
34
- 'rgb(255, 255, 255)',
35
- 'rgb(255, 255, 204)',
36
- 'rgb(255, 237, 160)',
37
- 'rgb(254, 217, 118)',
38
- 'rgb(254, 178, 76)',
39
- 'rgb(253, 141, 60)',
40
- 'rgb(252, 78, 42)',
41
- 'rgb(227, 26, 28)',
42
- 'rgb(189, 0, 38)',
43
- 'rgb(128, 0, 38)',
44
- 'rgb(0, 0, 0)',
45
- ]),
46
- viridis: interpolateViridis,
47
- };
48
- const m = useLogScale ? maxScore : maxScore / 20;
49
- const x1 = colorSchemes[colorScheme] || colorSchemes.juicebox;
50
- const scale = useLogScale
51
- ? scaleSequentialLog(x1).domain([1, m])
52
- : scaleSequential(x1).domain([0, m]);
53
- if (yScalar) {
54
- ctx.scale(1, yScalar);
55
- }
56
- ctx.save();
57
- if (region.reversed === true) {
58
- ctx.scale(-1, 1);
59
- ctx.translate(-width, 0);
18
+ const regionPixelOffsets = [];
19
+ let cumulativePixelOffset = 0;
20
+ for (const region of regions) {
21
+ regionPixelOffsets.push(cumulativePixelOffset);
22
+ cumulativePixelOffset += (region.end - region.start) / bpPerPx;
23
+ }
24
+ const regionBinOffsets = regions.map(region => Math.floor(region.start / res));
25
+ if (!features.length) {
26
+ return undefined;
27
+ }
28
+ let maxScore = 0;
29
+ checkStopToken(stopToken);
30
+ for (const { counts } of features) {
31
+ if (counts > maxScore) {
32
+ maxScore = counts;
60
33
  }
61
- ctx.rotate(-Math.PI / 4);
62
- forEachWithStopTokenCheck(features, stopToken, ({ bin1, bin2, counts }) => {
63
- ctx.fillStyle = readConfObject(config, 'color', {
64
- count: counts,
65
- maxScore,
66
- baseColor,
67
- scale,
68
- useLogScale,
69
- });
70
- ctx.fillRect((bin1 - offset) * w, (bin2 - offset) * w, w, w);
34
+ }
35
+ checkStopToken(stopToken);
36
+ const colorSchemes = {
37
+ juicebox: ['rgba(0,0,0,0)', 'red'],
38
+ fall: interpolateRgbBasis([
39
+ 'rgb(255, 255, 255)',
40
+ 'rgb(255, 255, 204)',
41
+ 'rgb(255, 237, 160)',
42
+ 'rgb(254, 217, 118)',
43
+ 'rgb(254, 178, 76)',
44
+ 'rgb(253, 141, 60)',
45
+ 'rgb(252, 78, 42)',
46
+ 'rgb(227, 26, 28)',
47
+ 'rgb(189, 0, 38)',
48
+ 'rgb(128, 0, 38)',
49
+ 'rgb(0, 0, 0)',
50
+ ]),
51
+ viridis: interpolateViridis,
52
+ };
53
+ const m = useLogScale ? maxScore : maxScore / 20;
54
+ const x1 = colorSchemes[colorScheme] || colorSchemes.juicebox;
55
+ const scale = useLogScale
56
+ ? scaleSequentialLog(x1).domain([1, m])
57
+ : scaleSequential(x1).domain([0, m]);
58
+ if (yScalar) {
59
+ ctx.scale(1, yScalar);
60
+ }
61
+ ctx.save();
62
+ ctx.rotate(-Math.PI / 4);
63
+ const pxToBinFactor = bpPerPx / res;
64
+ const regionCombinedOffsets = regionBinOffsets.map((binOffset, i) => (regionPixelOffsets[i] ?? 0) * pxToBinFactor - binOffset);
65
+ const coords = [];
66
+ const items = [];
67
+ for (let i = 0, l = features.length; i < l; i++) {
68
+ const { bin1, bin2, counts, region1Idx, region2Idx } = features[i];
69
+ ctx.fillStyle = readConfObject(config, 'color', {
70
+ count: counts,
71
+ maxScore,
72
+ baseColor,
73
+ scale,
74
+ useLogScale,
71
75
  });
72
- ctx.restore();
76
+ const x = (bin1 + (regionCombinedOffsets[region1Idx] ?? 0)) * w;
77
+ const y = (bin2 + (regionCombinedOffsets[region2Idx] ?? 0)) * w;
78
+ ctx.fillRect(x, y, w, w);
79
+ coords.push(x, y, x + w, y + w);
80
+ items.push({ bin1, bin2, counts, region1Idx, region2Idx });
81
+ checkStopToken2(lastCheck);
82
+ }
83
+ ctx.restore();
84
+ const flatbush = new Flatbush(Math.max(items.length, 1));
85
+ if (coords.length) {
86
+ for (let i = 0; i < coords.length; i += 4) {
87
+ flatbush.add(coords[i], coords[i + 1], coords[i + 2], coords[i + 3]);
88
+ }
89
+ }
90
+ else {
91
+ flatbush.add(0, 0);
73
92
  }
74
- return undefined;
93
+ flatbush.finish();
94
+ return {
95
+ flatbush: flatbush.data,
96
+ items,
97
+ maxScore,
98
+ w,
99
+ };
75
100
  }
@@ -0,0 +1,7 @@
1
+ export interface HicFlatbushItem {
2
+ bin1: number;
3
+ bin2: number;
4
+ counts: number;
5
+ region1Idx: number;
6
+ region2Idx: number;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  import type PluginManager from '@jbrowse/core/PluginManager';
2
- declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
+ declare const configSchema: (pluginManager: PluginManager) => import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{}, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
3
3
  name: {
4
4
  description: string;
5
5
  type: string;
@@ -25,8 +25,13 @@ declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/c
25
25
  description: string;
26
26
  defaultValue: {};
27
27
  };
28
- adapter: import("mobx-state-tree").IAnyModelType;
29
- textSearching: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
28
+ rpcDriverName: {
29
+ type: string;
30
+ description: string;
31
+ defaultValue: string;
32
+ };
33
+ adapter: import("@jbrowse/mobx-state-tree").IAnyModelType;
34
+ textSearching: import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
30
35
  indexingAttributes: {
31
36
  type: string;
32
37
  description: string;
@@ -37,10 +42,10 @@ declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/c
37
42
  description: string;
38
43
  defaultValue: string[];
39
44
  };
40
- textSearchAdapter: import("mobx-state-tree").IAnyModelType;
41
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
42
- displays: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IAnyModelType>;
43
- formatDetails: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
45
+ textSearchAdapter: import("@jbrowse/mobx-state-tree").IAnyModelType;
46
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
47
+ displays: import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IAnyModelType>;
48
+ formatDetails: import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
44
49
  feature: {
45
50
  type: string;
46
51
  description: string;
@@ -63,8 +68,8 @@ declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/c
63
68
  defaultValue: number;
64
69
  description: string;
65
70
  };
66
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
67
- formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
71
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
72
+ formatAbout: import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
68
73
  config: {
69
74
  type: string;
70
75
  description: string;
@@ -75,6 +80,6 @@ declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/c
75
80
  type: string;
76
81
  defaultValue: boolean;
77
82
  };
78
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
79
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "trackId">>, undefined>>;
83
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
84
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "trackId">>, undefined>>;
80
85
  export default configSchema;
@@ -1,6 +1,6 @@
1
1
  import TrackType from '@jbrowse/core/pluggableElementTypes/TrackType';
2
2
  import { createBaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models';
3
- import configSchemaF from './configSchema';
3
+ import configSchemaF from "./configSchema.js";
4
4
  export default function HicTrackF(pluginManager) {
5
5
  pluginManager.addTrackType(() => {
6
6
  const configSchema = configSchemaF(pluginManager);
@@ -0,0 +1,2 @@
1
+ import type { LinearHicDisplayModel } from './model.ts';
2
+ export declare function doAfterAttach(self: LinearHicDisplayModel): void;