@jbrowse/plugin-hic 2.15.0 → 2.15.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.
- package/dist/HicRenderer/HicRenderer.d.ts +1 -2
- package/dist/HicRenderer/HicRenderer.js +26 -74
- package/dist/HicRenderer/makeImageData.d.ts +10 -0
- package/dist/HicRenderer/makeImageData.js +81 -0
- package/dist/LinearHicDisplay/model.d.ts +18 -14
- package/esm/HicRenderer/HicRenderer.d.ts +1 -2
- package/esm/HicRenderer/HicRenderer.js +3 -74
- package/esm/HicRenderer/makeImageData.d.ts +10 -0
- package/esm/HicRenderer/makeImageData.js +75 -0
- package/esm/LinearHicDisplay/model.d.ts +18 -14
- package/package.json +2 -2
|
@@ -28,7 +28,6 @@ export type ResultsSerialized = ServerSideResultsSerialized;
|
|
|
28
28
|
export type ResultsDeserialized = ServerSideResultsDeserialized;
|
|
29
29
|
export default class HicRenderer extends ServerSideRendererType {
|
|
30
30
|
supportsSVG: boolean;
|
|
31
|
-
makeImageData(ctx: CanvasRenderingContext2D, props: RenderArgsDeserializedWithFeatures): Promise<undefined>;
|
|
32
31
|
render(renderProps: RenderArgsDeserialized): Promise<{
|
|
33
32
|
height: any;
|
|
34
33
|
width: number;
|
|
@@ -38,7 +37,7 @@ export default class HicRenderer extends ServerSideRendererType {
|
|
|
38
37
|
} | {
|
|
39
38
|
height: any;
|
|
40
39
|
width: number;
|
|
41
|
-
reactElement:
|
|
40
|
+
reactElement: React.JSX.Element;
|
|
42
41
|
html?: string;
|
|
43
42
|
} | {
|
|
44
43
|
height: any;
|
|
@@ -1,101 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
29
|
const ServerSideRendererType_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType"));
|
|
7
|
-
const util_1 = require("@jbrowse/core/util");
|
|
8
30
|
const offscreenCanvasUtils_1 = require("@jbrowse/core/util/offscreenCanvasUtils");
|
|
9
31
|
const operators_1 = require("rxjs/operators");
|
|
10
32
|
const configuration_1 = require("@jbrowse/core/configuration");
|
|
11
33
|
const dataAdapterCache_1 = require("@jbrowse/core/data_adapters/dataAdapterCache");
|
|
12
|
-
const colord_1 = require("@jbrowse/core/util/colord");
|
|
13
34
|
const rxjs_1 = require("rxjs");
|
|
14
|
-
const d3_scale_1 = require("@mui/x-charts-vendor/d3-scale");
|
|
15
|
-
const viridis_1 = __importDefault(require("./viridis"));
|
|
16
|
-
const d3_interpolate_1 = require("@mui/x-charts-vendor/d3-interpolate");
|
|
17
35
|
class HicRenderer extends ServerSideRendererType_1.default {
|
|
18
36
|
constructor() {
|
|
19
37
|
super(...arguments);
|
|
20
38
|
this.supportsSVG = true;
|
|
21
39
|
}
|
|
22
|
-
async makeImageData(ctx, props) {
|
|
23
|
-
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, useLogScale, colorScheme, regions, } = props;
|
|
24
|
-
const region = regions[0];
|
|
25
|
-
const { dataAdapter } = await (0, dataAdapterCache_1.getAdapter)(this.pluginManager, sessionId, adapterConfig);
|
|
26
|
-
const res = await dataAdapter.getResolution(bpPerPx / resolution);
|
|
27
|
-
const width = (region.end - region.start) / bpPerPx;
|
|
28
|
-
const w = res / (bpPerPx * Math.sqrt(2));
|
|
29
|
-
const baseColor = (0, colord_1.colord)((0, configuration_1.readConfObject)(config, 'baseColor'));
|
|
30
|
-
const offset = Math.floor(region.start / res);
|
|
31
|
-
if (features.length) {
|
|
32
|
-
let maxScore = 0;
|
|
33
|
-
let minBin = 0;
|
|
34
|
-
let maxBin = 0;
|
|
35
|
-
await (0, util_1.abortBreakPoint)(signal);
|
|
36
|
-
for (const { bin1, bin2, counts } of features) {
|
|
37
|
-
maxScore = Math.max(counts, maxScore);
|
|
38
|
-
minBin = Math.min(Math.min(bin1, bin2), minBin);
|
|
39
|
-
maxBin = Math.max(Math.max(bin1, bin2), maxBin);
|
|
40
|
-
}
|
|
41
|
-
await (0, util_1.abortBreakPoint)(signal);
|
|
42
|
-
const colorSchemes = {
|
|
43
|
-
juicebox: ['rgba(0,0,0,0)', 'red'],
|
|
44
|
-
fall: (0, d3_interpolate_1.interpolateRgbBasis)([
|
|
45
|
-
'rgb(255, 255, 255)',
|
|
46
|
-
'rgb(255, 255, 204)',
|
|
47
|
-
'rgb(255, 237, 160)',
|
|
48
|
-
'rgb(254, 217, 118)',
|
|
49
|
-
'rgb(254, 178, 76)',
|
|
50
|
-
'rgb(253, 141, 60)',
|
|
51
|
-
'rgb(252, 78, 42)',
|
|
52
|
-
'rgb(227, 26, 28)',
|
|
53
|
-
'rgb(189, 0, 38)',
|
|
54
|
-
'rgb(128, 0, 38)',
|
|
55
|
-
'rgb(0, 0, 0)',
|
|
56
|
-
]),
|
|
57
|
-
viridis: viridis_1.default,
|
|
58
|
-
};
|
|
59
|
-
const m = useLogScale ? maxScore : maxScore / 20;
|
|
60
|
-
// @ts-expect-error
|
|
61
|
-
const x1 = colorSchemes[colorScheme] || colorSchemes.juicebox;
|
|
62
|
-
const scale = useLogScale
|
|
63
|
-
? (0, d3_scale_1.scaleSequentialLog)(x1).domain([1, m])
|
|
64
|
-
: (0, d3_scale_1.scaleSequential)(x1).domain([0, m]);
|
|
65
|
-
ctx.save();
|
|
66
|
-
if (region.reversed === true) {
|
|
67
|
-
ctx.scale(-1, 1);
|
|
68
|
-
ctx.translate(-width, 0);
|
|
69
|
-
}
|
|
70
|
-
ctx.rotate(-Math.PI / 4);
|
|
71
|
-
let start = Date.now();
|
|
72
|
-
for (const { bin1, bin2, counts } of features) {
|
|
73
|
-
ctx.fillStyle = (0, configuration_1.readConfObject)(config, 'color', {
|
|
74
|
-
count: counts,
|
|
75
|
-
maxScore,
|
|
76
|
-
baseColor,
|
|
77
|
-
scale,
|
|
78
|
-
useLogScale,
|
|
79
|
-
});
|
|
80
|
-
ctx.fillRect((bin1 - offset) * w, (bin2 - offset) * w, w, w);
|
|
81
|
-
if (+Date.now() - start > 400) {
|
|
82
|
-
await (0, util_1.abortBreakPoint)(signal);
|
|
83
|
-
start = +Date.now();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
ctx.restore();
|
|
87
|
-
}
|
|
88
|
-
return undefined;
|
|
89
|
-
}
|
|
90
40
|
async render(renderProps) {
|
|
91
41
|
const { config, regions, bpPerPx } = renderProps;
|
|
92
42
|
const region = regions[0];
|
|
93
43
|
const width = (region.end - region.start) / bpPerPx;
|
|
94
44
|
const height = (0, configuration_1.readConfObject)(config, 'maxHeight');
|
|
95
45
|
const features = await this.getFeatures(renderProps);
|
|
96
|
-
const
|
|
46
|
+
const { makeImageData } = await Promise.resolve().then(() => __importStar(require('./makeImageData')));
|
|
47
|
+
const res = await (0, offscreenCanvasUtils_1.renderToAbstractCanvas)(width, height, renderProps, ctx => makeImageData(ctx, {
|
|
97
48
|
...renderProps,
|
|
98
49
|
features,
|
|
50
|
+
pluginManager: this.pluginManager,
|
|
99
51
|
}));
|
|
100
52
|
const results = await super.render({
|
|
101
53
|
...renderProps,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RenderArgs as ServerSideRenderArgs } from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
|
|
2
|
+
import { Region } from '@jbrowse/core/util/types';
|
|
3
|
+
import PluginManager from '@jbrowse/core/PluginManager';
|
|
4
|
+
import { RenderArgsDeserializedWithFeatures } from './HicRenderer';
|
|
5
|
+
export interface RenderArgs extends ServerSideRenderArgs {
|
|
6
|
+
regions: Region[];
|
|
7
|
+
}
|
|
8
|
+
export declare function makeImageData(ctx: CanvasRenderingContext2D, props: RenderArgsDeserializedWithFeatures & {
|
|
9
|
+
pluginManager: PluginManager;
|
|
10
|
+
}): Promise<undefined>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.makeImageData = makeImageData;
|
|
7
|
+
const util_1 = require("@jbrowse/core/util");
|
|
8
|
+
const configuration_1 = require("@jbrowse/core/configuration");
|
|
9
|
+
const dataAdapterCache_1 = require("@jbrowse/core/data_adapters/dataAdapterCache");
|
|
10
|
+
const colord_1 = require("@jbrowse/core/util/colord");
|
|
11
|
+
const d3_scale_1 = require("@mui/x-charts-vendor/d3-scale");
|
|
12
|
+
const d3_interpolate_1 = require("@mui/x-charts-vendor/d3-interpolate");
|
|
13
|
+
const viridis_1 = __importDefault(require("./viridis"));
|
|
14
|
+
async function makeImageData(ctx, props) {
|
|
15
|
+
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, useLogScale, colorScheme, regions, pluginManager, } = props;
|
|
16
|
+
const region = regions[0];
|
|
17
|
+
const { dataAdapter } = await (0, dataAdapterCache_1.getAdapter)(pluginManager, sessionId, adapterConfig);
|
|
18
|
+
const res = await dataAdapter.getResolution(bpPerPx / resolution);
|
|
19
|
+
const width = (region.end - region.start) / bpPerPx;
|
|
20
|
+
const w = res / (bpPerPx * Math.sqrt(2));
|
|
21
|
+
const baseColor = (0, colord_1.colord)((0, configuration_1.readConfObject)(config, 'baseColor'));
|
|
22
|
+
const offset = Math.floor(region.start / res);
|
|
23
|
+
if (features.length) {
|
|
24
|
+
let maxScore = 0;
|
|
25
|
+
let minBin = 0;
|
|
26
|
+
let maxBin = 0;
|
|
27
|
+
await (0, util_1.abortBreakPoint)(signal);
|
|
28
|
+
for (const { bin1, bin2, counts } of features) {
|
|
29
|
+
maxScore = Math.max(counts, maxScore);
|
|
30
|
+
minBin = Math.min(Math.min(bin1, bin2), minBin);
|
|
31
|
+
maxBin = Math.max(Math.max(bin1, bin2), maxBin);
|
|
32
|
+
}
|
|
33
|
+
await (0, util_1.abortBreakPoint)(signal);
|
|
34
|
+
const colorSchemes = {
|
|
35
|
+
juicebox: ['rgba(0,0,0,0)', 'red'],
|
|
36
|
+
fall: (0, d3_interpolate_1.interpolateRgbBasis)([
|
|
37
|
+
'rgb(255, 255, 255)',
|
|
38
|
+
'rgb(255, 255, 204)',
|
|
39
|
+
'rgb(255, 237, 160)',
|
|
40
|
+
'rgb(254, 217, 118)',
|
|
41
|
+
'rgb(254, 178, 76)',
|
|
42
|
+
'rgb(253, 141, 60)',
|
|
43
|
+
'rgb(252, 78, 42)',
|
|
44
|
+
'rgb(227, 26, 28)',
|
|
45
|
+
'rgb(189, 0, 38)',
|
|
46
|
+
'rgb(128, 0, 38)',
|
|
47
|
+
'rgb(0, 0, 0)',
|
|
48
|
+
]),
|
|
49
|
+
viridis: viridis_1.default,
|
|
50
|
+
};
|
|
51
|
+
const m = useLogScale ? maxScore : maxScore / 20;
|
|
52
|
+
// @ts-expect-error
|
|
53
|
+
const x1 = colorSchemes[colorScheme] || colorSchemes.juicebox;
|
|
54
|
+
const scale = useLogScale
|
|
55
|
+
? (0, d3_scale_1.scaleSequentialLog)(x1).domain([1, m])
|
|
56
|
+
: (0, d3_scale_1.scaleSequential)(x1).domain([0, m]);
|
|
57
|
+
ctx.save();
|
|
58
|
+
if (region.reversed === true) {
|
|
59
|
+
ctx.scale(-1, 1);
|
|
60
|
+
ctx.translate(-width, 0);
|
|
61
|
+
}
|
|
62
|
+
ctx.rotate(-Math.PI / 4);
|
|
63
|
+
let start = Date.now();
|
|
64
|
+
for (const { bin1, bin2, counts } of features) {
|
|
65
|
+
ctx.fillStyle = (0, configuration_1.readConfObject)(config, 'color', {
|
|
66
|
+
count: counts,
|
|
67
|
+
maxScore,
|
|
68
|
+
baseColor,
|
|
69
|
+
scale,
|
|
70
|
+
useLogScale,
|
|
71
|
+
});
|
|
72
|
+
ctx.fillRect((bin1 - offset) * w, (bin2 - offset) * w, w, w);
|
|
73
|
+
if (+Date.now() - start > 400) {
|
|
74
|
+
await (0, util_1.abortBreakPoint)(signal);
|
|
75
|
+
start = +Date.now();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
ctx.restore();
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
@@ -33,7 +33,9 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
33
33
|
}, {
|
|
34
34
|
renderInProgress: AbortController | undefined;
|
|
35
35
|
filled: boolean;
|
|
36
|
-
reactElement:
|
|
36
|
+
reactElement: React.ReactElement /**
|
|
37
|
+
* #getter
|
|
38
|
+
*/ | undefined;
|
|
37
39
|
features: Map<string, import("@jbrowse/core/util").Feature> | undefined;
|
|
38
40
|
layout: any;
|
|
39
41
|
status: string;
|
|
@@ -46,10 +48,10 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
46
48
|
* #method
|
|
47
49
|
*/: unknown;
|
|
48
50
|
reload: () => void;
|
|
49
|
-
message:
|
|
51
|
+
message: React.ReactNode;
|
|
50
52
|
filled?: boolean;
|
|
51
53
|
status?: string;
|
|
52
|
-
reactElement?:
|
|
54
|
+
reactElement?: React.ReactElement;
|
|
53
55
|
};
|
|
54
56
|
}) => import("react").JSX.Element | undefined;
|
|
55
57
|
renderProps: any;
|
|
@@ -60,7 +62,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
60
62
|
setLoading(abortController: AbortController): void;
|
|
61
63
|
setMessage(messageText: string): void;
|
|
62
64
|
setRendered(props: {
|
|
63
|
-
reactElement:
|
|
65
|
+
reactElement: React.ReactElement;
|
|
64
66
|
features: Map<string, import("@jbrowse/core/util").Feature>;
|
|
65
67
|
layout: any;
|
|
66
68
|
maxHeightReached: boolean;
|
|
@@ -109,7 +111,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
109
111
|
error: unknown;
|
|
110
112
|
message: string | undefined;
|
|
111
113
|
} & {
|
|
112
|
-
readonly RenderingComponent:
|
|
114
|
+
readonly RenderingComponent: React.FC<{
|
|
113
115
|
model: {
|
|
114
116
|
id: string;
|
|
115
117
|
type: string;
|
|
@@ -132,7 +134,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
132
134
|
onHorizontalScroll?: () => void;
|
|
133
135
|
blockState?: Record<string, any>;
|
|
134
136
|
}>;
|
|
135
|
-
readonly DisplayBlurb:
|
|
137
|
+
readonly DisplayBlurb: React.FC<{
|
|
136
138
|
model: {
|
|
137
139
|
id: string;
|
|
138
140
|
type: string;
|
|
@@ -155,7 +157,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
155
157
|
readonly parentTrack: any;
|
|
156
158
|
renderProps(): any;
|
|
157
159
|
readonly rendererType: import("@jbrowse/core/pluggableElementTypes").RendererType;
|
|
158
|
-
readonly DisplayMessageComponent: undefined |
|
|
160
|
+
readonly DisplayMessageComponent: undefined | React.FC<any>;
|
|
159
161
|
trackMenuItems(): import("@jbrowse/core/ui").MenuItem[];
|
|
160
162
|
readonly viewMenuActions: import("@jbrowse/core/ui").MenuItem[];
|
|
161
163
|
regionCannotBeRendered(): null;
|
|
@@ -201,13 +203,13 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
201
203
|
featureIdUnderMouse: undefined | string;
|
|
202
204
|
contextMenuFeature: undefined | import("@jbrowse/core/util").Feature;
|
|
203
205
|
} & {
|
|
206
|
+
readonly DisplayMessageComponent: import("react").FC<any> | undefined;
|
|
204
207
|
readonly blockType: "dynamicBlocks" | "staticBlocks";
|
|
205
208
|
readonly blockDefinitions: import("@jbrowse/core/util/blockTypes").BlockSet;
|
|
206
209
|
} & {
|
|
207
210
|
readonly renderDelay: number;
|
|
208
|
-
readonly TooltipComponent: import("
|
|
211
|
+
readonly TooltipComponent: import("@jbrowse/core/util").AnyReactComponentType;
|
|
209
212
|
readonly selectedFeatureId: string | undefined;
|
|
210
|
-
readonly DisplayMessageComponent: undefined | import("react").FC<any>;
|
|
211
213
|
} & {
|
|
212
214
|
readonly features: import("@jbrowse/core/util/compositeMap").default<string, import("@jbrowse/core/util").Feature>;
|
|
213
215
|
readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
|
|
@@ -307,7 +309,9 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
307
309
|
}, {
|
|
308
310
|
renderInProgress: AbortController | undefined;
|
|
309
311
|
filled: boolean;
|
|
310
|
-
reactElement:
|
|
312
|
+
reactElement: React.ReactElement /**
|
|
313
|
+
* #getter
|
|
314
|
+
*/ | undefined;
|
|
311
315
|
features: Map<string, import("@jbrowse/core/util").Feature> | undefined;
|
|
312
316
|
layout: any;
|
|
313
317
|
status: string;
|
|
@@ -320,10 +324,10 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
320
324
|
* #method
|
|
321
325
|
*/: unknown;
|
|
322
326
|
reload: () => void;
|
|
323
|
-
message:
|
|
327
|
+
message: React.ReactNode;
|
|
324
328
|
filled?: boolean;
|
|
325
329
|
status?: string;
|
|
326
|
-
reactElement?:
|
|
330
|
+
reactElement?: React.ReactElement;
|
|
327
331
|
};
|
|
328
332
|
}) => import("react").JSX.Element | undefined;
|
|
329
333
|
renderProps: any;
|
|
@@ -334,7 +338,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
334
338
|
setLoading(abortController: AbortController): void;
|
|
335
339
|
setMessage(messageText: string): void;
|
|
336
340
|
setRendered(props: {
|
|
337
|
-
reactElement:
|
|
341
|
+
reactElement: React.ReactElement;
|
|
338
342
|
features: Map<string, import("@jbrowse/core/util").Feature>;
|
|
339
343
|
layout: any;
|
|
340
344
|
maxHeightReached: boolean;
|
|
@@ -376,8 +380,8 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
376
380
|
type: string;
|
|
377
381
|
id: string;
|
|
378
382
|
configuration: import("mobx-state-tree").ModelSnapshotType<Record<string, any>>;
|
|
379
|
-
rpcDriverName: string | undefined;
|
|
380
383
|
heightPreConfig: number | undefined;
|
|
384
|
+
rpcDriverName: string | undefined;
|
|
381
385
|
userBpPerPxLimit: number | undefined;
|
|
382
386
|
userByteSizeLimit: number | undefined;
|
|
383
387
|
} & import("mobx-state-tree")._NotCustomized>;
|
|
@@ -28,7 +28,6 @@ export type ResultsSerialized = ServerSideResultsSerialized;
|
|
|
28
28
|
export type ResultsDeserialized = ServerSideResultsDeserialized;
|
|
29
29
|
export default class HicRenderer extends ServerSideRendererType {
|
|
30
30
|
supportsSVG: boolean;
|
|
31
|
-
makeImageData(ctx: CanvasRenderingContext2D, props: RenderArgsDeserializedWithFeatures): Promise<undefined>;
|
|
32
31
|
render(renderProps: RenderArgsDeserialized): Promise<{
|
|
33
32
|
height: any;
|
|
34
33
|
width: number;
|
|
@@ -38,7 +37,7 @@ export default class HicRenderer extends ServerSideRendererType {
|
|
|
38
37
|
} | {
|
|
39
38
|
height: any;
|
|
40
39
|
width: number;
|
|
41
|
-
reactElement:
|
|
40
|
+
reactElement: React.JSX.Element;
|
|
42
41
|
html?: string;
|
|
43
42
|
} | {
|
|
44
43
|
height: any;
|
|
@@ -1,96 +1,25 @@
|
|
|
1
1
|
import ServerSideRendererType from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
|
|
2
|
-
import { abortBreakPoint } from '@jbrowse/core/util';
|
|
3
2
|
import { renderToAbstractCanvas } from '@jbrowse/core/util/offscreenCanvasUtils';
|
|
4
3
|
import { toArray } from 'rxjs/operators';
|
|
5
4
|
import { readConfObject } from '@jbrowse/core/configuration';
|
|
6
5
|
import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
|
|
7
|
-
import { colord } from '@jbrowse/core/util/colord';
|
|
8
6
|
import { firstValueFrom } from 'rxjs';
|
|
9
|
-
import { scaleSequential, scaleSequentialLog, } from '@mui/x-charts-vendor/d3-scale';
|
|
10
|
-
import interpolateViridis from './viridis';
|
|
11
|
-
import { interpolateRgbBasis } from '@mui/x-charts-vendor/d3-interpolate';
|
|
12
7
|
export default class HicRenderer extends ServerSideRendererType {
|
|
13
8
|
constructor() {
|
|
14
9
|
super(...arguments);
|
|
15
10
|
this.supportsSVG = true;
|
|
16
11
|
}
|
|
17
|
-
async makeImageData(ctx, props) {
|
|
18
|
-
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, useLogScale, colorScheme, regions, } = props;
|
|
19
|
-
const region = regions[0];
|
|
20
|
-
const { dataAdapter } = await getAdapter(this.pluginManager, sessionId, adapterConfig);
|
|
21
|
-
const res = await dataAdapter.getResolution(bpPerPx / resolution);
|
|
22
|
-
const width = (region.end - region.start) / bpPerPx;
|
|
23
|
-
const w = res / (bpPerPx * Math.sqrt(2));
|
|
24
|
-
const baseColor = colord(readConfObject(config, 'baseColor'));
|
|
25
|
-
const offset = Math.floor(region.start / res);
|
|
26
|
-
if (features.length) {
|
|
27
|
-
let maxScore = 0;
|
|
28
|
-
let minBin = 0;
|
|
29
|
-
let maxBin = 0;
|
|
30
|
-
await abortBreakPoint(signal);
|
|
31
|
-
for (const { bin1, bin2, counts } of features) {
|
|
32
|
-
maxScore = Math.max(counts, maxScore);
|
|
33
|
-
minBin = Math.min(Math.min(bin1, bin2), minBin);
|
|
34
|
-
maxBin = Math.max(Math.max(bin1, bin2), maxBin);
|
|
35
|
-
}
|
|
36
|
-
await abortBreakPoint(signal);
|
|
37
|
-
const colorSchemes = {
|
|
38
|
-
juicebox: ['rgba(0,0,0,0)', 'red'],
|
|
39
|
-
fall: interpolateRgbBasis([
|
|
40
|
-
'rgb(255, 255, 255)',
|
|
41
|
-
'rgb(255, 255, 204)',
|
|
42
|
-
'rgb(255, 237, 160)',
|
|
43
|
-
'rgb(254, 217, 118)',
|
|
44
|
-
'rgb(254, 178, 76)',
|
|
45
|
-
'rgb(253, 141, 60)',
|
|
46
|
-
'rgb(252, 78, 42)',
|
|
47
|
-
'rgb(227, 26, 28)',
|
|
48
|
-
'rgb(189, 0, 38)',
|
|
49
|
-
'rgb(128, 0, 38)',
|
|
50
|
-
'rgb(0, 0, 0)',
|
|
51
|
-
]),
|
|
52
|
-
viridis: interpolateViridis,
|
|
53
|
-
};
|
|
54
|
-
const m = useLogScale ? maxScore : maxScore / 20;
|
|
55
|
-
// @ts-expect-error
|
|
56
|
-
const x1 = colorSchemes[colorScheme] || colorSchemes.juicebox;
|
|
57
|
-
const scale = useLogScale
|
|
58
|
-
? scaleSequentialLog(x1).domain([1, m])
|
|
59
|
-
: scaleSequential(x1).domain([0, m]);
|
|
60
|
-
ctx.save();
|
|
61
|
-
if (region.reversed === true) {
|
|
62
|
-
ctx.scale(-1, 1);
|
|
63
|
-
ctx.translate(-width, 0);
|
|
64
|
-
}
|
|
65
|
-
ctx.rotate(-Math.PI / 4);
|
|
66
|
-
let start = Date.now();
|
|
67
|
-
for (const { bin1, bin2, counts } of features) {
|
|
68
|
-
ctx.fillStyle = readConfObject(config, 'color', {
|
|
69
|
-
count: counts,
|
|
70
|
-
maxScore,
|
|
71
|
-
baseColor,
|
|
72
|
-
scale,
|
|
73
|
-
useLogScale,
|
|
74
|
-
});
|
|
75
|
-
ctx.fillRect((bin1 - offset) * w, (bin2 - offset) * w, w, w);
|
|
76
|
-
if (+Date.now() - start > 400) {
|
|
77
|
-
await abortBreakPoint(signal);
|
|
78
|
-
start = +Date.now();
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
ctx.restore();
|
|
82
|
-
}
|
|
83
|
-
return undefined;
|
|
84
|
-
}
|
|
85
12
|
async render(renderProps) {
|
|
86
13
|
const { config, regions, bpPerPx } = renderProps;
|
|
87
14
|
const region = regions[0];
|
|
88
15
|
const width = (region.end - region.start) / bpPerPx;
|
|
89
16
|
const height = readConfObject(config, 'maxHeight');
|
|
90
17
|
const features = await this.getFeatures(renderProps);
|
|
91
|
-
const
|
|
18
|
+
const { makeImageData } = await import('./makeImageData');
|
|
19
|
+
const res = await renderToAbstractCanvas(width, height, renderProps, ctx => makeImageData(ctx, {
|
|
92
20
|
...renderProps,
|
|
93
21
|
features,
|
|
22
|
+
pluginManager: this.pluginManager,
|
|
94
23
|
}));
|
|
95
24
|
const results = await super.render({
|
|
96
25
|
...renderProps,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RenderArgs as ServerSideRenderArgs } from '@jbrowse/core/pluggableElementTypes/renderers/ServerSideRendererType';
|
|
2
|
+
import { Region } from '@jbrowse/core/util/types';
|
|
3
|
+
import PluginManager from '@jbrowse/core/PluginManager';
|
|
4
|
+
import { RenderArgsDeserializedWithFeatures } from './HicRenderer';
|
|
5
|
+
export interface RenderArgs extends ServerSideRenderArgs {
|
|
6
|
+
regions: Region[];
|
|
7
|
+
}
|
|
8
|
+
export declare function makeImageData(ctx: CanvasRenderingContext2D, props: RenderArgsDeserializedWithFeatures & {
|
|
9
|
+
pluginManager: PluginManager;
|
|
10
|
+
}): Promise<undefined>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { abortBreakPoint } from '@jbrowse/core/util';
|
|
2
|
+
import { readConfObject } from '@jbrowse/core/configuration';
|
|
3
|
+
import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
|
|
4
|
+
import { colord } from '@jbrowse/core/util/colord';
|
|
5
|
+
import { scaleSequential, scaleSequentialLog, } from '@mui/x-charts-vendor/d3-scale';
|
|
6
|
+
import { interpolateRgbBasis } from '@mui/x-charts-vendor/d3-interpolate';
|
|
7
|
+
import interpolateViridis from './viridis';
|
|
8
|
+
export async function makeImageData(ctx, props) {
|
|
9
|
+
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, useLogScale, colorScheme, regions, pluginManager, } = props;
|
|
10
|
+
const region = regions[0];
|
|
11
|
+
const { dataAdapter } = await getAdapter(pluginManager, sessionId, adapterConfig);
|
|
12
|
+
const res = await dataAdapter.getResolution(bpPerPx / resolution);
|
|
13
|
+
const width = (region.end - region.start) / bpPerPx;
|
|
14
|
+
const w = res / (bpPerPx * Math.sqrt(2));
|
|
15
|
+
const baseColor = colord(readConfObject(config, 'baseColor'));
|
|
16
|
+
const offset = Math.floor(region.start / res);
|
|
17
|
+
if (features.length) {
|
|
18
|
+
let maxScore = 0;
|
|
19
|
+
let minBin = 0;
|
|
20
|
+
let maxBin = 0;
|
|
21
|
+
await abortBreakPoint(signal);
|
|
22
|
+
for (const { bin1, bin2, counts } of features) {
|
|
23
|
+
maxScore = Math.max(counts, maxScore);
|
|
24
|
+
minBin = Math.min(Math.min(bin1, bin2), minBin);
|
|
25
|
+
maxBin = Math.max(Math.max(bin1, bin2), maxBin);
|
|
26
|
+
}
|
|
27
|
+
await abortBreakPoint(signal);
|
|
28
|
+
const colorSchemes = {
|
|
29
|
+
juicebox: ['rgba(0,0,0,0)', 'red'],
|
|
30
|
+
fall: interpolateRgbBasis([
|
|
31
|
+
'rgb(255, 255, 255)',
|
|
32
|
+
'rgb(255, 255, 204)',
|
|
33
|
+
'rgb(255, 237, 160)',
|
|
34
|
+
'rgb(254, 217, 118)',
|
|
35
|
+
'rgb(254, 178, 76)',
|
|
36
|
+
'rgb(253, 141, 60)',
|
|
37
|
+
'rgb(252, 78, 42)',
|
|
38
|
+
'rgb(227, 26, 28)',
|
|
39
|
+
'rgb(189, 0, 38)',
|
|
40
|
+
'rgb(128, 0, 38)',
|
|
41
|
+
'rgb(0, 0, 0)',
|
|
42
|
+
]),
|
|
43
|
+
viridis: interpolateViridis,
|
|
44
|
+
};
|
|
45
|
+
const m = useLogScale ? maxScore : maxScore / 20;
|
|
46
|
+
// @ts-expect-error
|
|
47
|
+
const x1 = colorSchemes[colorScheme] || colorSchemes.juicebox;
|
|
48
|
+
const scale = useLogScale
|
|
49
|
+
? scaleSequentialLog(x1).domain([1, m])
|
|
50
|
+
: scaleSequential(x1).domain([0, m]);
|
|
51
|
+
ctx.save();
|
|
52
|
+
if (region.reversed === true) {
|
|
53
|
+
ctx.scale(-1, 1);
|
|
54
|
+
ctx.translate(-width, 0);
|
|
55
|
+
}
|
|
56
|
+
ctx.rotate(-Math.PI / 4);
|
|
57
|
+
let start = Date.now();
|
|
58
|
+
for (const { bin1, bin2, counts } of features) {
|
|
59
|
+
ctx.fillStyle = readConfObject(config, 'color', {
|
|
60
|
+
count: counts,
|
|
61
|
+
maxScore,
|
|
62
|
+
baseColor,
|
|
63
|
+
scale,
|
|
64
|
+
useLogScale,
|
|
65
|
+
});
|
|
66
|
+
ctx.fillRect((bin1 - offset) * w, (bin2 - offset) * w, w, w);
|
|
67
|
+
if (+Date.now() - start > 400) {
|
|
68
|
+
await abortBreakPoint(signal);
|
|
69
|
+
start = +Date.now();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
ctx.restore();
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
@@ -33,7 +33,9 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
33
33
|
}, {
|
|
34
34
|
renderInProgress: AbortController | undefined;
|
|
35
35
|
filled: boolean;
|
|
36
|
-
reactElement:
|
|
36
|
+
reactElement: React.ReactElement /**
|
|
37
|
+
* #getter
|
|
38
|
+
*/ | undefined;
|
|
37
39
|
features: Map<string, import("@jbrowse/core/util").Feature> | undefined;
|
|
38
40
|
layout: any;
|
|
39
41
|
status: string;
|
|
@@ -46,10 +48,10 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
46
48
|
* #method
|
|
47
49
|
*/: unknown;
|
|
48
50
|
reload: () => void;
|
|
49
|
-
message:
|
|
51
|
+
message: React.ReactNode;
|
|
50
52
|
filled?: boolean;
|
|
51
53
|
status?: string;
|
|
52
|
-
reactElement?:
|
|
54
|
+
reactElement?: React.ReactElement;
|
|
53
55
|
};
|
|
54
56
|
}) => import("react").JSX.Element | undefined;
|
|
55
57
|
renderProps: any;
|
|
@@ -60,7 +62,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
60
62
|
setLoading(abortController: AbortController): void;
|
|
61
63
|
setMessage(messageText: string): void;
|
|
62
64
|
setRendered(props: {
|
|
63
|
-
reactElement:
|
|
65
|
+
reactElement: React.ReactElement;
|
|
64
66
|
features: Map<string, import("@jbrowse/core/util").Feature>;
|
|
65
67
|
layout: any;
|
|
66
68
|
maxHeightReached: boolean;
|
|
@@ -109,7 +111,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
109
111
|
error: unknown;
|
|
110
112
|
message: string | undefined;
|
|
111
113
|
} & {
|
|
112
|
-
readonly RenderingComponent:
|
|
114
|
+
readonly RenderingComponent: React.FC<{
|
|
113
115
|
model: {
|
|
114
116
|
id: string;
|
|
115
117
|
type: string;
|
|
@@ -132,7 +134,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
132
134
|
onHorizontalScroll?: () => void;
|
|
133
135
|
blockState?: Record<string, any>;
|
|
134
136
|
}>;
|
|
135
|
-
readonly DisplayBlurb:
|
|
137
|
+
readonly DisplayBlurb: React.FC<{
|
|
136
138
|
model: {
|
|
137
139
|
id: string;
|
|
138
140
|
type: string;
|
|
@@ -155,7 +157,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
155
157
|
readonly parentTrack: any;
|
|
156
158
|
renderProps(): any;
|
|
157
159
|
readonly rendererType: import("@jbrowse/core/pluggableElementTypes").RendererType;
|
|
158
|
-
readonly DisplayMessageComponent: undefined |
|
|
160
|
+
readonly DisplayMessageComponent: undefined | React.FC<any>;
|
|
159
161
|
trackMenuItems(): import("@jbrowse/core/ui").MenuItem[];
|
|
160
162
|
readonly viewMenuActions: import("@jbrowse/core/ui").MenuItem[];
|
|
161
163
|
regionCannotBeRendered(): null;
|
|
@@ -201,13 +203,13 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
201
203
|
featureIdUnderMouse: undefined | string;
|
|
202
204
|
contextMenuFeature: undefined | import("@jbrowse/core/util").Feature;
|
|
203
205
|
} & {
|
|
206
|
+
readonly DisplayMessageComponent: import("react").FC<any> | undefined;
|
|
204
207
|
readonly blockType: "dynamicBlocks" | "staticBlocks";
|
|
205
208
|
readonly blockDefinitions: import("@jbrowse/core/util/blockTypes").BlockSet;
|
|
206
209
|
} & {
|
|
207
210
|
readonly renderDelay: number;
|
|
208
|
-
readonly TooltipComponent: import("
|
|
211
|
+
readonly TooltipComponent: import("@jbrowse/core/util").AnyReactComponentType;
|
|
209
212
|
readonly selectedFeatureId: string | undefined;
|
|
210
|
-
readonly DisplayMessageComponent: undefined | import("react").FC<any>;
|
|
211
213
|
} & {
|
|
212
214
|
readonly features: import("@jbrowse/core/util/compositeMap").default<string, import("@jbrowse/core/util").Feature>;
|
|
213
215
|
readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
|
|
@@ -307,7 +309,9 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
307
309
|
}, {
|
|
308
310
|
renderInProgress: AbortController | undefined;
|
|
309
311
|
filled: boolean;
|
|
310
|
-
reactElement:
|
|
312
|
+
reactElement: React.ReactElement /**
|
|
313
|
+
* #getter
|
|
314
|
+
*/ | undefined;
|
|
311
315
|
features: Map<string, import("@jbrowse/core/util").Feature> | undefined;
|
|
312
316
|
layout: any;
|
|
313
317
|
status: string;
|
|
@@ -320,10 +324,10 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
320
324
|
* #method
|
|
321
325
|
*/: unknown;
|
|
322
326
|
reload: () => void;
|
|
323
|
-
message:
|
|
327
|
+
message: React.ReactNode;
|
|
324
328
|
filled?: boolean;
|
|
325
329
|
status?: string;
|
|
326
|
-
reactElement?:
|
|
330
|
+
reactElement?: React.ReactElement;
|
|
327
331
|
};
|
|
328
332
|
}) => import("react").JSX.Element | undefined;
|
|
329
333
|
renderProps: any;
|
|
@@ -334,7 +338,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
334
338
|
setLoading(abortController: AbortController): void;
|
|
335
339
|
setMessage(messageText: string): void;
|
|
336
340
|
setRendered(props: {
|
|
337
|
-
reactElement:
|
|
341
|
+
reactElement: React.ReactElement;
|
|
338
342
|
features: Map<string, import("@jbrowse/core/util").Feature>;
|
|
339
343
|
layout: any;
|
|
340
344
|
maxHeightReached: boolean;
|
|
@@ -376,8 +380,8 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
376
380
|
type: string;
|
|
377
381
|
id: string;
|
|
378
382
|
configuration: import("mobx-state-tree").ModelSnapshotType<Record<string, any>>;
|
|
379
|
-
rpcDriverName: string | undefined;
|
|
380
383
|
heightPreConfig: number | undefined;
|
|
384
|
+
rpcDriverName: string | undefined;
|
|
381
385
|
userBpPerPxLimit: number | undefined;
|
|
382
386
|
userByteSizeLimit: number | undefined;
|
|
383
387
|
} & import("mobx-state-tree")._NotCustomized>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-hic",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.2",
|
|
4
4
|
"description": "JBrowse 2 hic adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "8a58cefbfe39af4c97bcb6ead354d72c9fef9224"
|
|
59
59
|
}
|