@jbrowse/plugin-hic 2.10.3 → 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 +47 -17
- 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 +47 -17
- 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
|
|
@@ -81,24 +81,19 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
81
81
|
};
|
|
82
82
|
mouseover: {
|
|
83
83
|
type: string;
|
|
84
|
-
description: string;
|
|
84
|
+
description: string; /**
|
|
85
|
+
* #getter
|
|
86
|
+
*/
|
|
85
87
|
defaultValue: string;
|
|
86
88
|
contextVariable: string[];
|
|
87
89
|
};
|
|
88
90
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
89
91
|
} & {
|
|
90
|
-
/**
|
|
91
|
-
* #property
|
|
92
|
-
*/
|
|
93
92
|
type: import("mobx-state-tree").ISimpleType<"LinearHicDisplay">;
|
|
94
|
-
/**
|
|
95
|
-
* #property
|
|
96
|
-
*/
|
|
97
93
|
configuration: AnyConfigurationSchemaType;
|
|
98
|
-
/**
|
|
99
|
-
* #property
|
|
100
|
-
*/
|
|
101
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>>;
|
|
102
97
|
}, {
|
|
103
98
|
rendererTypeName: string;
|
|
104
99
|
error: unknown;
|
|
@@ -111,11 +106,17 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
111
106
|
rpcDriverName: string | undefined;
|
|
112
107
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
113
108
|
rendererTypeName: string;
|
|
114
|
-
error: unknown;
|
|
109
|
+
error: unknown; /**
|
|
110
|
+
* #property
|
|
111
|
+
*/
|
|
115
112
|
message: string | undefined;
|
|
116
113
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
117
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
118
|
-
|
|
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
|
+
*/
|
|
119
120
|
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
120
121
|
}, {
|
|
121
122
|
rendererTypeName: string;
|
|
@@ -131,7 +132,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
131
132
|
type: string;
|
|
132
133
|
rpcDriverName: string | undefined;
|
|
133
134
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
134
|
-
rendererTypeName: string;
|
|
135
|
+
rendererTypeName: string; /**
|
|
136
|
+
* #action
|
|
137
|
+
*/
|
|
135
138
|
error: unknown;
|
|
136
139
|
message: string | undefined;
|
|
137
140
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
@@ -166,7 +169,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
166
169
|
setHeight(displayHeight: number): number;
|
|
167
170
|
resizeHeight(distance: number): number;
|
|
168
171
|
} & {
|
|
169
|
-
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined;
|
|
172
|
+
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined; /**
|
|
173
|
+
* #getter
|
|
174
|
+
*/
|
|
170
175
|
featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
|
|
171
176
|
currStatsBpPerPx: number;
|
|
172
177
|
} & {
|
|
@@ -241,11 +246,34 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
241
246
|
* #action
|
|
242
247
|
*/
|
|
243
248
|
setResolution(n: number): void;
|
|
249
|
+
/**
|
|
250
|
+
* #action
|
|
251
|
+
*/
|
|
252
|
+
setUseLogScale(f: boolean): void;
|
|
253
|
+
/**
|
|
254
|
+
* #action
|
|
255
|
+
*/
|
|
256
|
+
setColorScheme(f?: string): void;
|
|
244
257
|
} & {
|
|
245
258
|
/**
|
|
246
259
|
* #getter
|
|
247
260
|
*/
|
|
248
|
-
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
|
+
})[];
|
|
249
277
|
}, {
|
|
250
278
|
type: string;
|
|
251
279
|
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
@@ -329,7 +357,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
329
357
|
};
|
|
330
358
|
mouseover: {
|
|
331
359
|
type: string;
|
|
332
|
-
description: string;
|
|
360
|
+
description: string; /**
|
|
361
|
+
* #getter
|
|
362
|
+
*/
|
|
333
363
|
defaultValue: string;
|
|
334
364
|
contextVariable: string[];
|
|
335
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
|
|
@@ -81,24 +81,19 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
81
81
|
};
|
|
82
82
|
mouseover: {
|
|
83
83
|
type: string;
|
|
84
|
-
description: string;
|
|
84
|
+
description: string; /**
|
|
85
|
+
* #getter
|
|
86
|
+
*/
|
|
85
87
|
defaultValue: string;
|
|
86
88
|
contextVariable: string[];
|
|
87
89
|
};
|
|
88
90
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
89
91
|
} & {
|
|
90
|
-
/**
|
|
91
|
-
* #property
|
|
92
|
-
*/
|
|
93
92
|
type: import("mobx-state-tree").ISimpleType<"LinearHicDisplay">;
|
|
94
|
-
/**
|
|
95
|
-
* #property
|
|
96
|
-
*/
|
|
97
93
|
configuration: AnyConfigurationSchemaType;
|
|
98
|
-
/**
|
|
99
|
-
* #property
|
|
100
|
-
*/
|
|
101
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>>;
|
|
102
97
|
}, {
|
|
103
98
|
rendererTypeName: string;
|
|
104
99
|
error: unknown;
|
|
@@ -111,11 +106,17 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
111
106
|
rpcDriverName: string | undefined;
|
|
112
107
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
113
108
|
rendererTypeName: string;
|
|
114
|
-
error: unknown;
|
|
109
|
+
error: unknown; /**
|
|
110
|
+
* #property
|
|
111
|
+
*/
|
|
115
112
|
message: string | undefined;
|
|
116
113
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
117
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
118
|
-
|
|
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
|
+
*/
|
|
119
120
|
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
120
121
|
}, {
|
|
121
122
|
rendererTypeName: string;
|
|
@@ -131,7 +132,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
131
132
|
type: string;
|
|
132
133
|
rpcDriverName: string | undefined;
|
|
133
134
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
134
|
-
rendererTypeName: string;
|
|
135
|
+
rendererTypeName: string; /**
|
|
136
|
+
* #action
|
|
137
|
+
*/
|
|
135
138
|
error: unknown;
|
|
136
139
|
message: string | undefined;
|
|
137
140
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
@@ -166,7 +169,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
166
169
|
setHeight(displayHeight: number): number;
|
|
167
170
|
resizeHeight(distance: number): number;
|
|
168
171
|
} & {
|
|
169
|
-
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined;
|
|
172
|
+
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined; /**
|
|
173
|
+
* #getter
|
|
174
|
+
*/
|
|
170
175
|
featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
|
|
171
176
|
currStatsBpPerPx: number;
|
|
172
177
|
} & {
|
|
@@ -241,11 +246,34 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
241
246
|
* #action
|
|
242
247
|
*/
|
|
243
248
|
setResolution(n: number): void;
|
|
249
|
+
/**
|
|
250
|
+
* #action
|
|
251
|
+
*/
|
|
252
|
+
setUseLogScale(f: boolean): void;
|
|
253
|
+
/**
|
|
254
|
+
* #action
|
|
255
|
+
*/
|
|
256
|
+
setColorScheme(f?: string): void;
|
|
244
257
|
} & {
|
|
245
258
|
/**
|
|
246
259
|
* #getter
|
|
247
260
|
*/
|
|
248
|
-
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
|
+
})[];
|
|
249
277
|
}, {
|
|
250
278
|
type: string;
|
|
251
279
|
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
@@ -329,7 +357,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
|
|
|
329
357
|
};
|
|
330
358
|
mouseover: {
|
|
331
359
|
type: string;
|
|
332
|
-
description: string;
|
|
360
|
+
description: string; /**
|
|
361
|
+
* #getter
|
|
362
|
+
*/
|
|
333
363
|
defaultValue: string;
|
|
334
364
|
contextVariable: string[];
|
|
335
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
|
}
|