@jbrowse/plugin-hic 2.10.2 → 2.11.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.
- package/dist/HicAdapter/HicAdapter.js +6 -7
- package/dist/HicRenderer/HicRenderer.js +37 -10
- package/dist/HicRenderer/configSchema.js +2 -2
- package/dist/LinearHicDisplay/model.d.ts +65 -21
- package/dist/LinearHicDisplay/model.js +59 -7
- package/dist/index.js +9 -8
- package/esm/HicAdapter/HicAdapter.js +6 -7
- package/esm/HicRenderer/HicRenderer.js +37 -10
- package/esm/HicRenderer/configSchema.js +2 -2
- package/esm/LinearHicDisplay/model.d.ts +65 -21
- package/esm/LinearHicDisplay/model.js +59 -7
- package/esm/index.js +9 -8
- package/package.json +4 -2
|
@@ -8,17 +8,16 @@ const BaseAdapter_1 = require("@jbrowse/core/data_adapters/BaseAdapter");
|
|
|
8
8
|
const rxjs_1 = require("@jbrowse/core/util/rxjs");
|
|
9
9
|
const io_1 = require("@jbrowse/core/util/io");
|
|
10
10
|
const hic_straw_1 = __importDefault(require("hic-straw"));
|
|
11
|
-
// wraps generic-filehandle so the read function only takes a position and
|
|
12
|
-
// in some ways, generic-filehandle wishes it was just this but it has
|
|
11
|
+
// wraps generic-filehandle so the read function only takes a position and
|
|
12
|
+
// length in some ways, generic-filehandle wishes it was just this but it has
|
|
13
13
|
// to adapt to the node.js fs promises API
|
|
14
14
|
class GenericFilehandleWrapper {
|
|
15
15
|
constructor(filehandle) {
|
|
16
16
|
this.filehandle = filehandle;
|
|
17
17
|
}
|
|
18
18
|
async read(position, length) {
|
|
19
|
-
const { buffer
|
|
20
|
-
|
|
21
|
-
return b.buffer.slice(b.byteOffset, b.byteOffset + bytesRead);
|
|
19
|
+
const { buffer } = await this.filehandle.read(Buffer.alloc(length), 0, length, position);
|
|
20
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
function openFilehandleWrapper(location, pluginManager) {
|
|
@@ -67,9 +66,9 @@ class HicAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
67
66
|
const res = await this.getResolution(bpPerPx / (resolution || 1000), opts);
|
|
68
67
|
statusCallback('Downloading .hic data');
|
|
69
68
|
const records = await this.hic.getContactRecords('KR', { start, chr, end }, { start, chr, end }, 'BP', res);
|
|
70
|
-
|
|
69
|
+
for (const record of records) {
|
|
71
70
|
observer.next(record);
|
|
72
|
-
}
|
|
71
|
+
}
|
|
73
72
|
statusCallback('');
|
|
74
73
|
observer.complete();
|
|
75
74
|
}, opts.signal); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
@@ -10,20 +10,25 @@ const operators_1 = require("rxjs/operators");
|
|
|
10
10
|
const configuration_1 = require("@jbrowse/core/configuration");
|
|
11
11
|
const dataAdapterCache_1 = require("@jbrowse/core/data_adapters/dataAdapterCache");
|
|
12
12
|
const colord_1 = require("@jbrowse/core/util/colord");
|
|
13
|
+
const rxjs_1 = require("rxjs");
|
|
14
|
+
const d3_scale_1 = require("d3-scale");
|
|
15
|
+
const d3_scale_chromatic_1 = require("d3-scale-chromatic");
|
|
16
|
+
const d3_interpolate_1 = require("d3-interpolate");
|
|
13
17
|
class HicRenderer extends ServerSideRendererType_1.default {
|
|
14
18
|
constructor() {
|
|
15
19
|
super(...arguments);
|
|
16
20
|
this.supportsSVG = true;
|
|
17
21
|
}
|
|
18
22
|
async makeImageData(ctx, props) {
|
|
19
|
-
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, regions, } = props;
|
|
23
|
+
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, useLogScale, colorScheme, regions, } = props;
|
|
20
24
|
const [region] = regions;
|
|
21
25
|
const { dataAdapter } = await (0, dataAdapterCache_1.getAdapter)(this.pluginManager, sessionId, adapterConfig);
|
|
22
26
|
const res = await dataAdapter.getResolution(bpPerPx / resolution);
|
|
27
|
+
const width = (region.end - region.start) / bpPerPx;
|
|
23
28
|
const w = res / (bpPerPx * Math.sqrt(2));
|
|
24
29
|
const baseColor = (0, colord_1.colord)((0, configuration_1.readConfObject)(config, 'baseColor'));
|
|
30
|
+
const offset = Math.floor(region.start / res);
|
|
25
31
|
if (features.length) {
|
|
26
|
-
const offset = features[0].bin1;
|
|
27
32
|
let maxScore = 0;
|
|
28
33
|
let minBin = 0;
|
|
29
34
|
let maxBin = 0;
|
|
@@ -34,14 +39,34 @@ class HicRenderer extends ServerSideRendererType_1.default {
|
|
|
34
39
|
maxBin = Math.max(Math.max(bin1, bin2), maxBin);
|
|
35
40
|
}
|
|
36
41
|
await (0, util_1.abortBreakPoint)(signal);
|
|
37
|
-
|
|
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: d3_scale_chromatic_1.interpolateViridis,
|
|
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) {
|
|
38
67
|
ctx.scale(-1, 1);
|
|
39
|
-
const width = (region.end - region.start) / bpPerPx;
|
|
40
68
|
ctx.translate(-width, 0);
|
|
41
69
|
}
|
|
42
|
-
if (region.reversed === true) {
|
|
43
|
-
horizontallyFlip();
|
|
44
|
-
}
|
|
45
70
|
ctx.rotate(-Math.PI / 4);
|
|
46
71
|
let start = Date.now();
|
|
47
72
|
for (const { bin1, bin2, counts } of features) {
|
|
@@ -49,6 +74,8 @@ class HicRenderer extends ServerSideRendererType_1.default {
|
|
|
49
74
|
count: counts,
|
|
50
75
|
maxScore,
|
|
51
76
|
baseColor,
|
|
77
|
+
scale,
|
|
78
|
+
useLogScale,
|
|
52
79
|
});
|
|
53
80
|
ctx.fillRect((bin1 - offset) * w, (bin2 - offset) * w, w, w);
|
|
54
81
|
if (+Date.now() - start > 400) {
|
|
@@ -56,6 +83,7 @@ class HicRenderer extends ServerSideRendererType_1.default {
|
|
|
56
83
|
start = +Date.now();
|
|
57
84
|
}
|
|
58
85
|
}
|
|
86
|
+
ctx.restore();
|
|
59
87
|
}
|
|
60
88
|
}
|
|
61
89
|
async render(renderProps) {
|
|
@@ -86,10 +114,9 @@ class HicRenderer extends ServerSideRendererType_1.default {
|
|
|
86
114
|
async getFeatures(args) {
|
|
87
115
|
const { regions, sessionId, adapterConfig } = args;
|
|
88
116
|
const { dataAdapter } = await (0, dataAdapterCache_1.getAdapter)(this.pluginManager, sessionId, adapterConfig);
|
|
89
|
-
const features = await dataAdapter
|
|
117
|
+
const features = await (0, rxjs_1.firstValueFrom)(dataAdapter
|
|
90
118
|
.getFeatures(regions[0], args)
|
|
91
|
-
.pipe((0, operators_1.toArray)())
|
|
92
|
-
.toPromise();
|
|
119
|
+
.pipe((0, operators_1.toArray)()));
|
|
93
120
|
// cast to any to avoid return-type conflict, because the
|
|
94
121
|
// types of features returned by our getFeatures are quite
|
|
95
122
|
// different from the base interface
|
|
@@ -21,8 +21,8 @@ const HicRenderer = (0, configuration_1.ConfigurationSchema)('HicRenderer', {
|
|
|
21
21
|
color: {
|
|
22
22
|
type: 'color',
|
|
23
23
|
description: 'the color of each feature in a hic alignment',
|
|
24
|
-
defaultValue: `jexl:
|
|
25
|
-
contextVariable: ['count', 'maxScore', 'baseColor'],
|
|
24
|
+
defaultValue: `jexl:interpolate(count,scale)`,
|
|
25
|
+
contextVariable: ['count', 'maxScore', 'baseColor', 'scale'],
|
|
26
26
|
},
|
|
27
27
|
/**
|
|
28
28
|
* #slot
|
|
@@ -36,8 +36,15 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
36
36
|
message: string | undefined;
|
|
37
37
|
maxHeightReached: boolean;
|
|
38
38
|
ReactComponent: ({ model, }: {
|
|
39
|
-
model:
|
|
40
|
-
|
|
39
|
+
model: {
|
|
40
|
+
error?: unknown;
|
|
41
|
+
reload: () => void;
|
|
42
|
+
message: import("react").ReactNode;
|
|
43
|
+
filled?: boolean | undefined;
|
|
44
|
+
status?: string | undefined;
|
|
45
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
46
|
+
};
|
|
47
|
+
}) => import("react").JSX.Element | undefined;
|
|
41
48
|
renderProps: any;
|
|
42
49
|
} & {
|
|
43
50
|
doReload(): void;
|
|
@@ -74,24 +81,19 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
74
81
|
};
|
|
75
82
|
mouseover: {
|
|
76
83
|
type: string;
|
|
77
|
-
description: string;
|
|
84
|
+
description: string; /**
|
|
85
|
+
* #getter
|
|
86
|
+
*/
|
|
78
87
|
defaultValue: string;
|
|
79
88
|
contextVariable: string[];
|
|
80
89
|
};
|
|
81
90
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
82
91
|
} & {
|
|
83
|
-
/**
|
|
84
|
-
* #property
|
|
85
|
-
*/
|
|
86
92
|
type: import("mobx-state-tree").ISimpleType<"LinearHicDisplay">;
|
|
87
|
-
/**
|
|
88
|
-
* #property
|
|
89
|
-
*/
|
|
90
93
|
configuration: AnyConfigurationSchemaType;
|
|
91
|
-
/**
|
|
92
|
-
* #property
|
|
93
|
-
*/
|
|
94
94
|
resolution: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
95
|
+
useLogScale: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
96
|
+
colorScheme: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
95
97
|
}, {
|
|
96
98
|
rendererTypeName: string;
|
|
97
99
|
error: unknown;
|
|
@@ -104,11 +106,17 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
104
106
|
rpcDriverName: string | undefined;
|
|
105
107
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
106
108
|
rendererTypeName: string;
|
|
107
|
-
error: unknown;
|
|
109
|
+
error: unknown; /**
|
|
110
|
+
* #property
|
|
111
|
+
*/
|
|
108
112
|
message: string | undefined;
|
|
109
113
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
110
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
111
|
-
|
|
114
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>; /**
|
|
115
|
+
* #getter
|
|
116
|
+
*/
|
|
117
|
+
type: import("mobx-state-tree").ISimpleType<string>; /**
|
|
118
|
+
* #method
|
|
119
|
+
*/
|
|
112
120
|
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
113
121
|
}, {
|
|
114
122
|
rendererTypeName: string;
|
|
@@ -124,7 +132,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
124
132
|
type: string;
|
|
125
133
|
rpcDriverName: string | undefined;
|
|
126
134
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
127
|
-
rendererTypeName: string;
|
|
135
|
+
rendererTypeName: string; /**
|
|
136
|
+
* #action
|
|
137
|
+
*/
|
|
128
138
|
error: unknown;
|
|
129
139
|
message: string | undefined;
|
|
130
140
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
@@ -159,7 +169,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
159
169
|
setHeight(displayHeight: number): number;
|
|
160
170
|
resizeHeight(distance: number): number;
|
|
161
171
|
} & {
|
|
162
|
-
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined;
|
|
172
|
+
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined; /**
|
|
173
|
+
* #getter
|
|
174
|
+
*/
|
|
163
175
|
featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
|
|
164
176
|
currStatsBpPerPx: number;
|
|
165
177
|
} & {
|
|
@@ -234,11 +246,34 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
234
246
|
* #action
|
|
235
247
|
*/
|
|
236
248
|
setResolution(n: number): void;
|
|
249
|
+
/**
|
|
250
|
+
* #action
|
|
251
|
+
*/
|
|
252
|
+
setUseLogScale(f: boolean): void;
|
|
253
|
+
/**
|
|
254
|
+
* #action
|
|
255
|
+
*/
|
|
256
|
+
setColorScheme(f?: string): void;
|
|
237
257
|
} & {
|
|
238
258
|
/**
|
|
239
259
|
* #getter
|
|
240
260
|
*/
|
|
241
|
-
trackMenuItems(): import("@jbrowse/core/ui").
|
|
261
|
+
trackMenuItems(): (import("@jbrowse/core/ui").MenuDivider | import("@jbrowse/core/ui").MenuSubHeader | import("@jbrowse/core/ui").NormalMenuItem | import("@jbrowse/core/ui").CheckboxMenuItem | import("@jbrowse/core/ui").RadioMenuItem | import("@jbrowse/core/ui").SubMenuItem | {
|
|
262
|
+
label: string;
|
|
263
|
+
type: string;
|
|
264
|
+
checked: boolean;
|
|
265
|
+
onClick: () => void;
|
|
266
|
+
subMenu?: undefined;
|
|
267
|
+
} | {
|
|
268
|
+
label: string;
|
|
269
|
+
type: string;
|
|
270
|
+
subMenu: {
|
|
271
|
+
label: string;
|
|
272
|
+
onClick: () => void;
|
|
273
|
+
}[];
|
|
274
|
+
checked?: undefined;
|
|
275
|
+
onClick?: undefined;
|
|
276
|
+
})[];
|
|
242
277
|
}, {
|
|
243
278
|
type: string;
|
|
244
279
|
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
@@ -277,8 +312,15 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
277
312
|
message: string | undefined;
|
|
278
313
|
maxHeightReached: boolean;
|
|
279
314
|
ReactComponent: ({ model, }: {
|
|
280
|
-
model:
|
|
281
|
-
|
|
315
|
+
model: {
|
|
316
|
+
error?: unknown;
|
|
317
|
+
reload: () => void;
|
|
318
|
+
message: import("react").ReactNode;
|
|
319
|
+
filled?: boolean | undefined;
|
|
320
|
+
status?: string | undefined;
|
|
321
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
322
|
+
};
|
|
323
|
+
}) => import("react").JSX.Element | undefined;
|
|
282
324
|
renderProps: any;
|
|
283
325
|
} & {
|
|
284
326
|
doReload(): void;
|
|
@@ -315,7 +357,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
315
357
|
};
|
|
316
358
|
mouseover: {
|
|
317
359
|
type: string;
|
|
318
|
-
description: string;
|
|
360
|
+
description: string; /**
|
|
361
|
+
* #getter
|
|
362
|
+
*/
|
|
319
363
|
defaultValue: string;
|
|
320
364
|
contextVariable: string[];
|
|
321
365
|
};
|
|
@@ -23,6 +23,14 @@ exports.default = (configSchema) => mobx_state_tree_1.types
|
|
|
23
23
|
* #property
|
|
24
24
|
*/
|
|
25
25
|
resolution: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.number, 1),
|
|
26
|
+
/**
|
|
27
|
+
* #property
|
|
28
|
+
*/
|
|
29
|
+
useLogScale: false,
|
|
30
|
+
/**
|
|
31
|
+
* #property
|
|
32
|
+
*/
|
|
33
|
+
colorScheme: mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.string),
|
|
26
34
|
}))
|
|
27
35
|
.views(self => {
|
|
28
36
|
const { renderProps: superRenderProps } = self;
|
|
@@ -43,13 +51,21 @@ exports.default = (configSchema) => mobx_state_tree_1.types
|
|
|
43
51
|
* #method
|
|
44
52
|
*/
|
|
45
53
|
renderProps() {
|
|
46
|
-
const config = self.rendererType.configSchema.create(
|
|
54
|
+
const config = self.rendererType.configSchema.create({
|
|
55
|
+
...(0, configuration_1.getConf)(self, 'renderer'),
|
|
56
|
+
// add specific jexl color callback when using pre-defined color schemes
|
|
57
|
+
...(self.colorScheme
|
|
58
|
+
? { color: 'jexl:interpolate(count,scale)' }
|
|
59
|
+
: {}),
|
|
60
|
+
}, (0, mobx_state_tree_1.getEnv)(self));
|
|
47
61
|
return {
|
|
48
62
|
...superRenderProps(),
|
|
49
63
|
config,
|
|
50
64
|
rpcDriverName: self.rpcDriverName,
|
|
51
65
|
displayModel: self,
|
|
52
66
|
resolution: self.resolution,
|
|
67
|
+
useLogScale: self.useLogScale,
|
|
68
|
+
colorScheme: self.colorScheme,
|
|
53
69
|
};
|
|
54
70
|
},
|
|
55
71
|
};
|
|
@@ -61,6 +77,18 @@ exports.default = (configSchema) => mobx_state_tree_1.types
|
|
|
61
77
|
setResolution(n) {
|
|
62
78
|
self.resolution = n;
|
|
63
79
|
},
|
|
80
|
+
/**
|
|
81
|
+
* #action
|
|
82
|
+
*/
|
|
83
|
+
setUseLogScale(f) {
|
|
84
|
+
self.useLogScale = f;
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* #action
|
|
88
|
+
*/
|
|
89
|
+
setColorScheme(f) {
|
|
90
|
+
self.colorScheme = f;
|
|
91
|
+
},
|
|
64
92
|
}))
|
|
65
93
|
.views(self => {
|
|
66
94
|
const { trackMenuItems: superTrackMenuItems } = self;
|
|
@@ -71,20 +99,44 @@ exports.default = (configSchema) => mobx_state_tree_1.types
|
|
|
71
99
|
trackMenuItems() {
|
|
72
100
|
return [
|
|
73
101
|
...superTrackMenuItems(),
|
|
102
|
+
{
|
|
103
|
+
label: 'Use log scale',
|
|
104
|
+
type: 'checkbox',
|
|
105
|
+
checked: self.useLogScale,
|
|
106
|
+
onClick: () => self.setUseLogScale(!self.useLogScale),
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
label: 'Color scheme',
|
|
110
|
+
type: 'subMenu',
|
|
111
|
+
subMenu: [
|
|
112
|
+
{
|
|
113
|
+
label: 'Fall',
|
|
114
|
+
onClick: () => self.setColorScheme('fall'),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
label: 'Viridis',
|
|
118
|
+
onClick: () => self.setColorScheme('viridis'),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
label: 'Juicebox',
|
|
122
|
+
onClick: () => self.setColorScheme('juicebox'),
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
label: 'Clear',
|
|
126
|
+
onClick: () => self.setColorScheme(undefined),
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
74
130
|
{
|
|
75
131
|
label: 'Resolution',
|
|
76
132
|
subMenu: [
|
|
77
133
|
{
|
|
78
134
|
label: 'Finer resolution',
|
|
79
|
-
onClick: () =>
|
|
80
|
-
self.setResolution(self.resolution * 2);
|
|
81
|
-
},
|
|
135
|
+
onClick: () => self.setResolution(self.resolution * 2),
|
|
82
136
|
},
|
|
83
137
|
{
|
|
84
138
|
label: 'Coarser resolution',
|
|
85
|
-
onClick: () =>
|
|
86
|
-
self.setResolution(self.resolution / 2);
|
|
87
|
-
},
|
|
139
|
+
onClick: () => self.setResolution(self.resolution / 2),
|
|
88
140
|
},
|
|
89
141
|
],
|
|
90
142
|
},
|
package/dist/index.js
CHANGED
|
@@ -5,11 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const Plugin_1 = __importDefault(require("@jbrowse/core/Plugin"));
|
|
7
7
|
const colord_1 = require("@jbrowse/core/util/colord");
|
|
8
|
+
const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
9
|
+
// locals
|
|
8
10
|
const HicRenderer_1 = __importDefault(require("./HicRenderer"));
|
|
9
11
|
const HicTrack_1 = __importDefault(require("./HicTrack"));
|
|
10
12
|
const LinearHicDisplay_1 = __importDefault(require("./LinearHicDisplay"));
|
|
11
13
|
const HicAdapter_1 = __importDefault(require("./HicAdapter"));
|
|
12
|
-
const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
13
14
|
class HicPlugin extends Plugin_1.default {
|
|
14
15
|
constructor() {
|
|
15
16
|
super(...arguments);
|
|
@@ -35,16 +36,15 @@ class HicPlugin extends Plugin_1.default {
|
|
|
35
36
|
else if (adapterHint === adapterName) {
|
|
36
37
|
return obj;
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
+
else {
|
|
40
|
+
return adapterGuesser(file, index, adapterHint);
|
|
41
|
+
}
|
|
39
42
|
};
|
|
40
43
|
});
|
|
41
44
|
pluginManager.addToExtensionPoint('Core-guessTrackTypeForLocation', (trackTypeGuesser) => {
|
|
42
|
-
return (adapterName) =>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
return trackTypeGuesser(adapterName);
|
|
47
|
-
};
|
|
45
|
+
return (adapterName) => adapterName === 'HicAdapter'
|
|
46
|
+
? 'HicTrack'
|
|
47
|
+
: trackTypeGuesser(adapterName);
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
configure(pluginManager) {
|
|
@@ -52,6 +52,7 @@ class HicPlugin extends Plugin_1.default {
|
|
|
52
52
|
jexl.addFunction('alpha', (color, n) => color.alpha(n));
|
|
53
53
|
jexl.addFunction('hsl', (color) => (0, colord_1.colord)(color.toHsl()));
|
|
54
54
|
jexl.addFunction('colorString', (color) => color.toHex());
|
|
55
|
+
jexl.addFunction('interpolate', (count, scale) => scale(count));
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
exports.default = HicPlugin;
|
|
@@ -2,17 +2,16 @@ import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter
|
|
|
2
2
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
3
3
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
4
4
|
import HicStraw from 'hic-straw';
|
|
5
|
-
// wraps generic-filehandle so the read function only takes a position and
|
|
6
|
-
// in some ways, generic-filehandle wishes it was just this but it has
|
|
5
|
+
// wraps generic-filehandle so the read function only takes a position and
|
|
6
|
+
// length in some ways, generic-filehandle wishes it was just this but it has
|
|
7
7
|
// to adapt to the node.js fs promises API
|
|
8
8
|
class GenericFilehandleWrapper {
|
|
9
9
|
constructor(filehandle) {
|
|
10
10
|
this.filehandle = filehandle;
|
|
11
11
|
}
|
|
12
12
|
async read(position, length) {
|
|
13
|
-
const { buffer
|
|
14
|
-
|
|
15
|
-
return b.buffer.slice(b.byteOffset, b.byteOffset + bytesRead);
|
|
13
|
+
const { buffer } = await this.filehandle.read(Buffer.alloc(length), 0, length, position);
|
|
14
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
17
|
export function openFilehandleWrapper(location, pluginManager) {
|
|
@@ -60,9 +59,9 @@ export default class HicAdapter extends BaseFeatureDataAdapter {
|
|
|
60
59
|
const res = await this.getResolution(bpPerPx / (resolution || 1000), opts);
|
|
61
60
|
statusCallback('Downloading .hic data');
|
|
62
61
|
const records = await this.hic.getContactRecords('KR', { start, chr, end }, { start, chr, end }, 'BP', res);
|
|
63
|
-
|
|
62
|
+
for (const record of records) {
|
|
64
63
|
observer.next(record);
|
|
65
|
-
}
|
|
64
|
+
}
|
|
66
65
|
statusCallback('');
|
|
67
66
|
observer.complete();
|
|
68
67
|
}, opts.signal); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
@@ -5,20 +5,25 @@ import { toArray } from 'rxjs/operators';
|
|
|
5
5
|
import { readConfObject } from '@jbrowse/core/configuration';
|
|
6
6
|
import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
|
|
7
7
|
import { colord } from '@jbrowse/core/util/colord';
|
|
8
|
+
import { firstValueFrom } from 'rxjs';
|
|
9
|
+
import { scaleSequential, scaleSequentialLog } from 'd3-scale';
|
|
10
|
+
import { interpolateViridis } from 'd3-scale-chromatic';
|
|
11
|
+
import { interpolateRgbBasis } from 'd3-interpolate';
|
|
8
12
|
export default class HicRenderer extends ServerSideRendererType {
|
|
9
13
|
constructor() {
|
|
10
14
|
super(...arguments);
|
|
11
15
|
this.supportsSVG = true;
|
|
12
16
|
}
|
|
13
17
|
async makeImageData(ctx, props) {
|
|
14
|
-
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, regions, } = props;
|
|
18
|
+
const { features, config, bpPerPx, signal, resolution, sessionId, adapterConfig, useLogScale, colorScheme, regions, } = props;
|
|
15
19
|
const [region] = regions;
|
|
16
20
|
const { dataAdapter } = await getAdapter(this.pluginManager, sessionId, adapterConfig);
|
|
17
21
|
const res = await dataAdapter.getResolution(bpPerPx / resolution);
|
|
22
|
+
const width = (region.end - region.start) / bpPerPx;
|
|
18
23
|
const w = res / (bpPerPx * Math.sqrt(2));
|
|
19
24
|
const baseColor = colord(readConfObject(config, 'baseColor'));
|
|
25
|
+
const offset = Math.floor(region.start / res);
|
|
20
26
|
if (features.length) {
|
|
21
|
-
const offset = features[0].bin1;
|
|
22
27
|
let maxScore = 0;
|
|
23
28
|
let minBin = 0;
|
|
24
29
|
let maxBin = 0;
|
|
@@ -29,14 +34,34 @@ export default class HicRenderer extends ServerSideRendererType {
|
|
|
29
34
|
maxBin = Math.max(Math.max(bin1, bin2), maxBin);
|
|
30
35
|
}
|
|
31
36
|
await abortBreakPoint(signal);
|
|
32
|
-
|
|
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) {
|
|
33
62
|
ctx.scale(-1, 1);
|
|
34
|
-
const width = (region.end - region.start) / bpPerPx;
|
|
35
63
|
ctx.translate(-width, 0);
|
|
36
64
|
}
|
|
37
|
-
if (region.reversed === true) {
|
|
38
|
-
horizontallyFlip();
|
|
39
|
-
}
|
|
40
65
|
ctx.rotate(-Math.PI / 4);
|
|
41
66
|
let start = Date.now();
|
|
42
67
|
for (const { bin1, bin2, counts } of features) {
|
|
@@ -44,6 +69,8 @@ export default class HicRenderer extends ServerSideRendererType {
|
|
|
44
69
|
count: counts,
|
|
45
70
|
maxScore,
|
|
46
71
|
baseColor,
|
|
72
|
+
scale,
|
|
73
|
+
useLogScale,
|
|
47
74
|
});
|
|
48
75
|
ctx.fillRect((bin1 - offset) * w, (bin2 - offset) * w, w, w);
|
|
49
76
|
if (+Date.now() - start > 400) {
|
|
@@ -51,6 +78,7 @@ export default class HicRenderer extends ServerSideRendererType {
|
|
|
51
78
|
start = +Date.now();
|
|
52
79
|
}
|
|
53
80
|
}
|
|
81
|
+
ctx.restore();
|
|
54
82
|
}
|
|
55
83
|
}
|
|
56
84
|
async render(renderProps) {
|
|
@@ -81,10 +109,9 @@ export default class HicRenderer extends ServerSideRendererType {
|
|
|
81
109
|
async getFeatures(args) {
|
|
82
110
|
const { regions, sessionId, adapterConfig } = args;
|
|
83
111
|
const { dataAdapter } = await getAdapter(this.pluginManager, sessionId, adapterConfig);
|
|
84
|
-
const features = await dataAdapter
|
|
112
|
+
const features = await firstValueFrom(dataAdapter
|
|
85
113
|
.getFeatures(regions[0], args)
|
|
86
|
-
.pipe(toArray())
|
|
87
|
-
.toPromise();
|
|
114
|
+
.pipe(toArray()));
|
|
88
115
|
// cast to any to avoid return-type conflict, because the
|
|
89
116
|
// types of features returned by our getFeatures are quite
|
|
90
117
|
// different from the base interface
|
|
@@ -19,8 +19,8 @@ const HicRenderer = ConfigurationSchema('HicRenderer', {
|
|
|
19
19
|
color: {
|
|
20
20
|
type: 'color',
|
|
21
21
|
description: 'the color of each feature in a hic alignment',
|
|
22
|
-
defaultValue: `jexl:
|
|
23
|
-
contextVariable: ['count', 'maxScore', 'baseColor'],
|
|
22
|
+
defaultValue: `jexl:interpolate(count,scale)`,
|
|
23
|
+
contextVariable: ['count', 'maxScore', 'baseColor', 'scale'],
|
|
24
24
|
},
|
|
25
25
|
/**
|
|
26
26
|
* #slot
|
|
@@ -36,8 +36,15 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
36
36
|
message: string | undefined;
|
|
37
37
|
maxHeightReached: boolean;
|
|
38
38
|
ReactComponent: ({ model, }: {
|
|
39
|
-
model:
|
|
40
|
-
|
|
39
|
+
model: {
|
|
40
|
+
error?: unknown;
|
|
41
|
+
reload: () => void;
|
|
42
|
+
message: import("react").ReactNode;
|
|
43
|
+
filled?: boolean | undefined;
|
|
44
|
+
status?: string | undefined;
|
|
45
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
46
|
+
};
|
|
47
|
+
}) => import("react").JSX.Element | undefined;
|
|
41
48
|
renderProps: any;
|
|
42
49
|
} & {
|
|
43
50
|
doReload(): void;
|
|
@@ -74,24 +81,19 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
74
81
|
};
|
|
75
82
|
mouseover: {
|
|
76
83
|
type: string;
|
|
77
|
-
description: string;
|
|
84
|
+
description: string; /**
|
|
85
|
+
* #getter
|
|
86
|
+
*/
|
|
78
87
|
defaultValue: string;
|
|
79
88
|
contextVariable: string[];
|
|
80
89
|
};
|
|
81
90
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
82
91
|
} & {
|
|
83
|
-
/**
|
|
84
|
-
* #property
|
|
85
|
-
*/
|
|
86
92
|
type: import("mobx-state-tree").ISimpleType<"LinearHicDisplay">;
|
|
87
|
-
/**
|
|
88
|
-
* #property
|
|
89
|
-
*/
|
|
90
93
|
configuration: AnyConfigurationSchemaType;
|
|
91
|
-
/**
|
|
92
|
-
* #property
|
|
93
|
-
*/
|
|
94
94
|
resolution: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
95
|
+
useLogScale: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
96
|
+
colorScheme: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
95
97
|
}, {
|
|
96
98
|
rendererTypeName: string;
|
|
97
99
|
error: unknown;
|
|
@@ -104,11 +106,17 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
104
106
|
rpcDriverName: string | undefined;
|
|
105
107
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
106
108
|
rendererTypeName: string;
|
|
107
|
-
error: unknown;
|
|
109
|
+
error: unknown; /**
|
|
110
|
+
* #property
|
|
111
|
+
*/
|
|
108
112
|
message: string | undefined;
|
|
109
113
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
110
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
111
|
-
|
|
114
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>; /**
|
|
115
|
+
* #getter
|
|
116
|
+
*/
|
|
117
|
+
type: import("mobx-state-tree").ISimpleType<string>; /**
|
|
118
|
+
* #method
|
|
119
|
+
*/
|
|
112
120
|
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
113
121
|
}, {
|
|
114
122
|
rendererTypeName: string;
|
|
@@ -124,7 +132,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
124
132
|
type: string;
|
|
125
133
|
rpcDriverName: string | undefined;
|
|
126
134
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
127
|
-
rendererTypeName: string;
|
|
135
|
+
rendererTypeName: string; /**
|
|
136
|
+
* #action
|
|
137
|
+
*/
|
|
128
138
|
error: unknown;
|
|
129
139
|
message: string | undefined;
|
|
130
140
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
@@ -159,7 +169,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
159
169
|
setHeight(displayHeight: number): number;
|
|
160
170
|
resizeHeight(distance: number): number;
|
|
161
171
|
} & {
|
|
162
|
-
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined;
|
|
172
|
+
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined; /**
|
|
173
|
+
* #getter
|
|
174
|
+
*/
|
|
163
175
|
featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
|
|
164
176
|
currStatsBpPerPx: number;
|
|
165
177
|
} & {
|
|
@@ -234,11 +246,34 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
234
246
|
* #action
|
|
235
247
|
*/
|
|
236
248
|
setResolution(n: number): void;
|
|
249
|
+
/**
|
|
250
|
+
* #action
|
|
251
|
+
*/
|
|
252
|
+
setUseLogScale(f: boolean): void;
|
|
253
|
+
/**
|
|
254
|
+
* #action
|
|
255
|
+
*/
|
|
256
|
+
setColorScheme(f?: string): void;
|
|
237
257
|
} & {
|
|
238
258
|
/**
|
|
239
259
|
* #getter
|
|
240
260
|
*/
|
|
241
|
-
trackMenuItems(): import("@jbrowse/core/ui").
|
|
261
|
+
trackMenuItems(): (import("@jbrowse/core/ui").MenuDivider | import("@jbrowse/core/ui").MenuSubHeader | import("@jbrowse/core/ui").NormalMenuItem | import("@jbrowse/core/ui").CheckboxMenuItem | import("@jbrowse/core/ui").RadioMenuItem | import("@jbrowse/core/ui").SubMenuItem | {
|
|
262
|
+
label: string;
|
|
263
|
+
type: string;
|
|
264
|
+
checked: boolean;
|
|
265
|
+
onClick: () => void;
|
|
266
|
+
subMenu?: undefined;
|
|
267
|
+
} | {
|
|
268
|
+
label: string;
|
|
269
|
+
type: string;
|
|
270
|
+
subMenu: {
|
|
271
|
+
label: string;
|
|
272
|
+
onClick: () => void;
|
|
273
|
+
}[];
|
|
274
|
+
checked?: undefined;
|
|
275
|
+
onClick?: undefined;
|
|
276
|
+
})[];
|
|
242
277
|
}, {
|
|
243
278
|
type: string;
|
|
244
279
|
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
@@ -277,8 +312,15 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
277
312
|
message: string | undefined;
|
|
278
313
|
maxHeightReached: boolean;
|
|
279
314
|
ReactComponent: ({ model, }: {
|
|
280
|
-
model:
|
|
281
|
-
|
|
315
|
+
model: {
|
|
316
|
+
error?: unknown;
|
|
317
|
+
reload: () => void;
|
|
318
|
+
message: import("react").ReactNode;
|
|
319
|
+
filled?: boolean | undefined;
|
|
320
|
+
status?: string | undefined;
|
|
321
|
+
reactElement?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
322
|
+
};
|
|
323
|
+
}) => import("react").JSX.Element | undefined;
|
|
282
324
|
renderProps: any;
|
|
283
325
|
} & {
|
|
284
326
|
doReload(): void;
|
|
@@ -315,7 +357,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
315
357
|
};
|
|
316
358
|
mouseover: {
|
|
317
359
|
type: string;
|
|
318
|
-
description: string;
|
|
360
|
+
description: string; /**
|
|
361
|
+
* #getter
|
|
362
|
+
*/
|
|
319
363
|
defaultValue: string;
|
|
320
364
|
contextVariable: string[];
|
|
321
365
|
};
|
|
@@ -21,6 +21,14 @@ export default (configSchema) => types
|
|
|
21
21
|
* #property
|
|
22
22
|
*/
|
|
23
23
|
resolution: types.optional(types.number, 1),
|
|
24
|
+
/**
|
|
25
|
+
* #property
|
|
26
|
+
*/
|
|
27
|
+
useLogScale: false,
|
|
28
|
+
/**
|
|
29
|
+
* #property
|
|
30
|
+
*/
|
|
31
|
+
colorScheme: types.maybe(types.string),
|
|
24
32
|
}))
|
|
25
33
|
.views(self => {
|
|
26
34
|
const { renderProps: superRenderProps } = self;
|
|
@@ -41,13 +49,21 @@ export default (configSchema) => types
|
|
|
41
49
|
* #method
|
|
42
50
|
*/
|
|
43
51
|
renderProps() {
|
|
44
|
-
const config = self.rendererType.configSchema.create(
|
|
52
|
+
const config = self.rendererType.configSchema.create({
|
|
53
|
+
...getConf(self, 'renderer'),
|
|
54
|
+
// add specific jexl color callback when using pre-defined color schemes
|
|
55
|
+
...(self.colorScheme
|
|
56
|
+
? { color: 'jexl:interpolate(count,scale)' }
|
|
57
|
+
: {}),
|
|
58
|
+
}, getEnv(self));
|
|
45
59
|
return {
|
|
46
60
|
...superRenderProps(),
|
|
47
61
|
config,
|
|
48
62
|
rpcDriverName: self.rpcDriverName,
|
|
49
63
|
displayModel: self,
|
|
50
64
|
resolution: self.resolution,
|
|
65
|
+
useLogScale: self.useLogScale,
|
|
66
|
+
colorScheme: self.colorScheme,
|
|
51
67
|
};
|
|
52
68
|
},
|
|
53
69
|
};
|
|
@@ -59,6 +75,18 @@ export default (configSchema) => types
|
|
|
59
75
|
setResolution(n) {
|
|
60
76
|
self.resolution = n;
|
|
61
77
|
},
|
|
78
|
+
/**
|
|
79
|
+
* #action
|
|
80
|
+
*/
|
|
81
|
+
setUseLogScale(f) {
|
|
82
|
+
self.useLogScale = f;
|
|
83
|
+
},
|
|
84
|
+
/**
|
|
85
|
+
* #action
|
|
86
|
+
*/
|
|
87
|
+
setColorScheme(f) {
|
|
88
|
+
self.colorScheme = f;
|
|
89
|
+
},
|
|
62
90
|
}))
|
|
63
91
|
.views(self => {
|
|
64
92
|
const { trackMenuItems: superTrackMenuItems } = self;
|
|
@@ -69,20 +97,44 @@ export default (configSchema) => types
|
|
|
69
97
|
trackMenuItems() {
|
|
70
98
|
return [
|
|
71
99
|
...superTrackMenuItems(),
|
|
100
|
+
{
|
|
101
|
+
label: 'Use log scale',
|
|
102
|
+
type: 'checkbox',
|
|
103
|
+
checked: self.useLogScale,
|
|
104
|
+
onClick: () => self.setUseLogScale(!self.useLogScale),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
label: 'Color scheme',
|
|
108
|
+
type: 'subMenu',
|
|
109
|
+
subMenu: [
|
|
110
|
+
{
|
|
111
|
+
label: 'Fall',
|
|
112
|
+
onClick: () => self.setColorScheme('fall'),
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
label: 'Viridis',
|
|
116
|
+
onClick: () => self.setColorScheme('viridis'),
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
label: 'Juicebox',
|
|
120
|
+
onClick: () => self.setColorScheme('juicebox'),
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
label: 'Clear',
|
|
124
|
+
onClick: () => self.setColorScheme(undefined),
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
72
128
|
{
|
|
73
129
|
label: 'Resolution',
|
|
74
130
|
subMenu: [
|
|
75
131
|
{
|
|
76
132
|
label: 'Finer resolution',
|
|
77
|
-
onClick: () =>
|
|
78
|
-
self.setResolution(self.resolution * 2);
|
|
79
|
-
},
|
|
133
|
+
onClick: () => self.setResolution(self.resolution * 2),
|
|
80
134
|
},
|
|
81
135
|
{
|
|
82
136
|
label: 'Coarser resolution',
|
|
83
|
-
onClick: () =>
|
|
84
|
-
self.setResolution(self.resolution / 2);
|
|
85
|
-
},
|
|
137
|
+
onClick: () => self.setResolution(self.resolution / 2),
|
|
86
138
|
},
|
|
87
139
|
],
|
|
88
140
|
},
|
package/esm/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import Plugin from '@jbrowse/core/Plugin';
|
|
2
2
|
import { colord } from '@jbrowse/core/util/colord';
|
|
3
|
+
import { getFileName, } from '@jbrowse/core/util/tracks';
|
|
4
|
+
// locals
|
|
3
5
|
import HicRendererF from './HicRenderer';
|
|
4
6
|
import HicTrackF from './HicTrack';
|
|
5
7
|
import LinearHicDisplayF from './LinearHicDisplay';
|
|
6
8
|
import HicAdapterF from './HicAdapter';
|
|
7
|
-
import { getFileName, } from '@jbrowse/core/util/tracks';
|
|
8
9
|
export default class HicPlugin extends Plugin {
|
|
9
10
|
constructor() {
|
|
10
11
|
super(...arguments);
|
|
@@ -30,16 +31,15 @@ export default class HicPlugin extends Plugin {
|
|
|
30
31
|
else if (adapterHint === adapterName) {
|
|
31
32
|
return obj;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
else {
|
|
35
|
+
return adapterGuesser(file, index, adapterHint);
|
|
36
|
+
}
|
|
34
37
|
};
|
|
35
38
|
});
|
|
36
39
|
pluginManager.addToExtensionPoint('Core-guessTrackTypeForLocation', (trackTypeGuesser) => {
|
|
37
|
-
return (adapterName) =>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
return trackTypeGuesser(adapterName);
|
|
42
|
-
};
|
|
40
|
+
return (adapterName) => adapterName === 'HicAdapter'
|
|
41
|
+
? 'HicTrack'
|
|
42
|
+
: trackTypeGuesser(adapterName);
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
configure(pluginManager) {
|
|
@@ -47,5 +47,6 @@ export default class HicPlugin extends Plugin {
|
|
|
47
47
|
jexl.addFunction('alpha', (color, n) => color.alpha(n));
|
|
48
48
|
jexl.addFunction('hsl', (color) => colord(color.toHsl()));
|
|
49
49
|
jexl.addFunction('colorString', (color) => color.toHex());
|
|
50
|
+
jexl.addFunction('interpolate', (count, scale) => scale(count));
|
|
50
51
|
}
|
|
51
52
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-hic",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "JBrowse 2 hic adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"clean": "rimraf dist esm *.tsbuildinfo"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"d3-interpolate": "^2.0.1",
|
|
40
|
+
"d3-scale-chromatic": "^2.0.0",
|
|
39
41
|
"hic-straw": "^2.0.3"
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
@@ -54,5 +56,5 @@
|
|
|
54
56
|
"publishConfig": {
|
|
55
57
|
"access": "public"
|
|
56
58
|
},
|
|
57
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "3d43a820b9274a6160aa4dc15616147f390d9094"
|
|
58
60
|
}
|