@jbrowse/plugin-hic 2.10.3 → 2.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 length
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: b, bytesRead } = await this.filehandle.read(Buffer.allocUnsafe(length), 0, length, position);
20
- // xref https://stackoverflow.com/a/31394257/2129219
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
- records.forEach(record => {
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
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function HicAdapterF(pluginManager: PluginManager): void;
@@ -28,11 +28,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const pluggableElementTypes_1 = require("@jbrowse/core/pluggableElementTypes");
30
30
  const configSchema_1 = __importDefault(require("./configSchema"));
31
- exports.default = (pluginManager) => {
31
+ function HicAdapterF(pluginManager) {
32
32
  pluginManager.addAdapterType(() => new pluggableElementTypes_1.AdapterType({
33
33
  name: 'HicAdapter',
34
34
  displayName: 'Hi-C adapter',
35
35
  configSchema: configSchema_1.default,
36
36
  getAdapterClass: () => Promise.resolve().then(() => __importStar(require('./HicAdapter'))).then(r => r.default),
37
37
  }));
38
- };
38
+ }
39
+ exports.default = HicAdapterF;
@@ -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
- function horizontallyFlip() {
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:colorString(hsl(alpha(baseColor,min(1,count/(maxScore/20)))))`,
25
- contextVariable: ['count', 'maxScore', 'baseColor'],
24
+ defaultValue: `jexl:interpolate(count,scale)`,
25
+ contextVariable: ['count', 'maxScore', 'baseColor', 'scale'],
26
26
  },
27
27
  /**
28
28
  * #slot
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function HicRendererF(pluginManager: PluginManager): void;
@@ -6,11 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const HicRendering_1 = __importDefault(require("./components/HicRendering"));
7
7
  const configSchema_1 = __importDefault(require("./configSchema"));
8
8
  const HicRenderer_1 = __importDefault(require("./HicRenderer"));
9
- exports.default = (pluginManager) => {
9
+ function HicRendererF(pluginManager) {
10
10
  pluginManager.addRendererType(() => new HicRenderer_1.default({
11
11
  name: 'HicRenderer',
12
12
  ReactComponent: HicRendering_1.default,
13
13
  configSchema: configSchema_1.default,
14
14
  pluginManager,
15
15
  }));
16
- };
16
+ }
17
+ exports.default = HicRendererF;
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function HicTrackF(pluginManager: PluginManager): void;
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const TrackType_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/TrackType"));
7
7
  const models_1 = require("@jbrowse/core/pluggableElementTypes/models");
8
8
  const configSchema_1 = __importDefault(require("./configSchema"));
9
- exports.default = (pluginManager) => {
9
+ function HicTrackF(pluginManager) {
10
10
  pluginManager.addTrackType(() => {
11
11
  const configSchema = (0, configSchema_1.default)(pluginManager);
12
12
  return new TrackType_1.default({
@@ -16,4 +16,5 @@ exports.default = (pluginManager) => {
16
16
  stateModel: (0, models_1.createBaseTrackModel)(pluginManager, 'HicTrack', configSchema),
17
17
  });
18
18
  });
19
- };
19
+ }
20
+ exports.default = HicTrackF;
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function LinearHicDisplayF(pluginManager: PluginManager): void;
@@ -7,7 +7,7 @@ const pluggableElementTypes_1 = require("@jbrowse/core/pluggableElementTypes");
7
7
  const plugin_linear_genome_view_1 = require("@jbrowse/plugin-linear-genome-view");
8
8
  const configSchema_1 = __importDefault(require("./configSchema"));
9
9
  const model_1 = __importDefault(require("./model"));
10
- exports.default = (pluginManager) => {
10
+ function LinearHicDisplayF(pluginManager) {
11
11
  pluginManager.addDisplayType(() => {
12
12
  const configSchema = (0, configSchema_1.default)(pluginManager);
13
13
  return new pluggableElementTypes_1.DisplayType({
@@ -20,4 +20,5 @@ exports.default = (pluginManager) => {
20
20
  ReactComponent: plugin_linear_genome_view_1.BaseLinearDisplayComponent,
21
21
  });
22
22
  });
23
- };
23
+ }
24
+ exports.default = LinearHicDisplayF;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
3
- declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mobx-state-tree").IModelType<{
3
+ export default function stateModelFactory(configSchema: AnyConfigurationSchemaType): import("mobx-state-tree").IModelType<{
4
4
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
5
5
  type: import("mobx-state-tree").ISimpleType<string>;
6
6
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -67,6 +67,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
67
67
  maxFeatureScreenDensity: {
68
68
  type: string;
69
69
  description: string;
70
+ /**
71
+ * #property
72
+ */
70
73
  defaultValue: number;
71
74
  };
72
75
  fetchSizeLimit: {
@@ -80,39 +83,40 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
80
83
  description: string;
81
84
  };
82
85
  mouseover: {
83
- type: string;
86
+ type: string; /**
87
+ * #getter
88
+ */
84
89
  description: string;
85
90
  defaultValue: string;
86
91
  contextVariable: string[];
87
92
  };
88
93
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
89
94
  } & {
90
- /**
91
- * #property
92
- */
93
95
  type: import("mobx-state-tree").ISimpleType<"LinearHicDisplay">;
94
- /**
95
- * #property
96
- */
97
96
  configuration: AnyConfigurationSchemaType;
98
- /**
99
- * #property
100
- */
101
97
  resolution: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
98
+ useLogScale: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
99
+ colorScheme: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
102
100
  }, {
103
101
  rendererTypeName: string;
104
102
  error: unknown;
105
- message: string | undefined;
103
+ message: string | undefined; /**
104
+ * #property
105
+ */
106
106
  } & {
107
107
  readonly RenderingComponent: import("react").FC<{
108
108
  model: {
109
109
  id: string;
110
110
  type: string;
111
- rpcDriverName: string | undefined;
111
+ rpcDriverName: string | undefined; /**
112
+ * #property
113
+ */
112
114
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
113
115
  rendererTypeName: string;
114
116
  error: unknown;
115
- message: string | undefined;
117
+ message: string | undefined; /**
118
+ * #property
119
+ */
116
120
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
117
121
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
118
122
  type: import("mobx-state-tree").ISimpleType<string>;
@@ -170,7 +174,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
170
174
  featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
171
175
  currStatsBpPerPx: number;
172
176
  } & {
173
- readonly currentBytesRequested: number;
177
+ readonly currentBytesRequested: number; /**
178
+ * #method
179
+ */
174
180
  readonly currentFeatureScreenDensity: number;
175
181
  readonly maxFeatureScreenDensity: any;
176
182
  readonly featureDensityStatsReady: boolean;
@@ -241,11 +247,34 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
241
247
  * #action
242
248
  */
243
249
  setResolution(n: number): void;
250
+ /**
251
+ * #action
252
+ */
253
+ setUseLogScale(f: boolean): void;
254
+ /**
255
+ * #action
256
+ */
257
+ setColorScheme(f?: string): void;
244
258
  } & {
245
259
  /**
246
260
  * #getter
247
261
  */
248
- trackMenuItems(): import("@jbrowse/core/ui").MenuItem[];
262
+ 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 | {
263
+ label: string;
264
+ type: string;
265
+ checked: boolean;
266
+ onClick: () => void;
267
+ subMenu?: undefined;
268
+ } | {
269
+ label: string;
270
+ type: string;
271
+ subMenu: {
272
+ label: string;
273
+ onClick: () => void;
274
+ }[];
275
+ checked?: undefined;
276
+ onClick?: undefined;
277
+ })[];
249
278
  }, {
250
279
  type: string;
251
280
  } & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
@@ -315,6 +344,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
315
344
  maxFeatureScreenDensity: {
316
345
  type: string;
317
346
  description: string;
347
+ /**
348
+ * #property
349
+ */
318
350
  defaultValue: number;
319
351
  };
320
352
  fetchSizeLimit: {
@@ -328,7 +360,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
328
360
  description: string;
329
361
  };
330
362
  mouseover: {
331
- type: string;
363
+ type: string; /**
364
+ * #getter
365
+ */
332
366
  description: string;
333
367
  defaultValue: string;
334
368
  contextVariable: string[];
@@ -343,4 +377,3 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
343
377
  userBpPerPxLimit: number | undefined;
344
378
  userByteSizeLimit: number | undefined;
345
379
  } & import("mobx-state-tree")._NotCustomized>;
346
- export default _default;
@@ -9,86 +9,141 @@ const mobx_state_tree_1 = require("mobx-state-tree");
9
9
  * extends `BaseLinearDisplay`
10
10
  */
11
11
  function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
12
- exports.default = (configSchema) => mobx_state_tree_1.types
13
- .compose('LinearHicDisplay', plugin_linear_genome_view_1.BaseLinearDisplay, mobx_state_tree_1.types.model({
14
- /**
15
- * #property
16
- */
17
- type: mobx_state_tree_1.types.literal('LinearHicDisplay'),
18
- /**
19
- * #property
20
- */
21
- configuration: (0, configuration_1.ConfigurationReference)(configSchema),
22
- /**
23
- * #property
24
- */
25
- resolution: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.number, 1),
26
- }))
27
- .views(self => {
28
- const { renderProps: superRenderProps } = self;
29
- return {
12
+ function stateModelFactory(configSchema) {
13
+ return mobx_state_tree_1.types
14
+ .compose('LinearHicDisplay', plugin_linear_genome_view_1.BaseLinearDisplay, mobx_state_tree_1.types.model({
30
15
  /**
31
- * #getter
16
+ * #property
32
17
  */
33
- get blockType() {
34
- return 'dynamicBlocks';
35
- },
18
+ type: mobx_state_tree_1.types.literal('LinearHicDisplay'),
19
+ /**
20
+ * #property
21
+ */
22
+ configuration: (0, configuration_1.ConfigurationReference)(configSchema),
23
+ /**
24
+ * #property
25
+ */
26
+ resolution: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.number, 1),
27
+ /**
28
+ * #property
29
+ */
30
+ useLogScale: false,
36
31
  /**
37
- * #getter
32
+ * #property
38
33
  */
39
- get rendererTypeName() {
40
- return 'HicRenderer';
34
+ colorScheme: mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.string),
35
+ }))
36
+ .views(self => {
37
+ const { renderProps: superRenderProps } = self;
38
+ return {
39
+ /**
40
+ * #getter
41
+ */
42
+ get blockType() {
43
+ return 'dynamicBlocks';
44
+ },
45
+ /**
46
+ * #getter
47
+ */
48
+ get rendererTypeName() {
49
+ return 'HicRenderer';
50
+ },
51
+ /**
52
+ * #method
53
+ */
54
+ renderProps() {
55
+ const config = self.rendererType.configSchema.create({
56
+ ...(0, configuration_1.getConf)(self, 'renderer'),
57
+ // add specific jexl color callback when using pre-defined color schemes
58
+ ...(self.colorScheme
59
+ ? { color: 'jexl:interpolate(count,scale)' }
60
+ : {}),
61
+ }, (0, mobx_state_tree_1.getEnv)(self));
62
+ return {
63
+ ...superRenderProps(),
64
+ config,
65
+ rpcDriverName: self.rpcDriverName,
66
+ displayModel: self,
67
+ resolution: self.resolution,
68
+ useLogScale: self.useLogScale,
69
+ colorScheme: self.colorScheme,
70
+ };
71
+ },
72
+ };
73
+ })
74
+ .actions(self => ({
75
+ /**
76
+ * #action
77
+ */
78
+ setResolution(n) {
79
+ self.resolution = n;
41
80
  },
42
81
  /**
43
- * #method
82
+ * #action
44
83
  */
45
- renderProps() {
46
- const config = self.rendererType.configSchema.create((0, configuration_1.getConf)(self, 'renderer') || {}, (0, mobx_state_tree_1.getEnv)(self));
47
- return {
48
- ...superRenderProps(),
49
- config,
50
- rpcDriverName: self.rpcDriverName,
51
- displayModel: self,
52
- resolution: self.resolution,
53
- };
84
+ setUseLogScale(f) {
85
+ self.useLogScale = f;
54
86
  },
55
- };
56
- })
57
- .actions(self => ({
58
- /**
59
- * #action
60
- */
61
- setResolution(n) {
62
- self.resolution = n;
63
- },
64
- }))
65
- .views(self => {
66
- const { trackMenuItems: superTrackMenuItems } = self;
67
- return {
68
87
  /**
69
- * #getter
88
+ * #action
70
89
  */
71
- trackMenuItems() {
72
- return [
73
- ...superTrackMenuItems(),
74
- {
75
- label: 'Resolution',
76
- subMenu: [
77
- {
78
- label: 'Finer resolution',
79
- onClick: () => {
80
- self.setResolution(self.resolution * 2);
90
+ setColorScheme(f) {
91
+ self.colorScheme = f;
92
+ },
93
+ }))
94
+ .views(self => {
95
+ const { trackMenuItems: superTrackMenuItems } = self;
96
+ return {
97
+ /**
98
+ * #getter
99
+ */
100
+ trackMenuItems() {
101
+ return [
102
+ ...superTrackMenuItems(),
103
+ {
104
+ label: 'Use log scale',
105
+ type: 'checkbox',
106
+ checked: self.useLogScale,
107
+ onClick: () => self.setUseLogScale(!self.useLogScale),
108
+ },
109
+ {
110
+ label: 'Color scheme',
111
+ type: 'subMenu',
112
+ subMenu: [
113
+ {
114
+ label: 'Fall',
115
+ onClick: () => self.setColorScheme('fall'),
81
116
  },
82
- },
83
- {
84
- label: 'Coarser resolution',
85
- onClick: () => {
86
- self.setResolution(self.resolution / 2);
117
+ {
118
+ label: 'Viridis',
119
+ onClick: () => self.setColorScheme('viridis'),
87
120
  },
88
- },
89
- ],
90
- },
91
- ];
92
- },
93
- };
94
- });
121
+ {
122
+ label: 'Juicebox',
123
+ onClick: () => self.setColorScheme('juicebox'),
124
+ },
125
+ {
126
+ label: 'Clear',
127
+ onClick: () => self.setColorScheme(undefined),
128
+ },
129
+ ],
130
+ },
131
+ {
132
+ label: 'Resolution',
133
+ subMenu: [
134
+ {
135
+ label: 'Finer resolution',
136
+ onClick: () => self.setResolution(self.resolution * 2),
137
+ },
138
+ {
139
+ label: 'Coarser resolution',
140
+ onClick: () => self.setResolution(self.resolution / 2),
141
+ },
142
+ ],
143
+ },
144
+ ];
145
+ },
146
+ };
147
+ });
148
+ }
149
+ exports.default = stateModelFactory;
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
- return adapterGuesser(file, index, adapterHint);
39
+ else {
40
+ return adapterGuesser(file, index, adapterHint);
41
+ }
39
42
  };
40
43
  });
41
44
  pluginManager.addToExtensionPoint('Core-guessTrackTypeForLocation', (trackTypeGuesser) => {
42
- return (adapterName) => {
43
- if (adapterName === 'HicAdapter') {
44
- return 'HicTrack';
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 length
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: b, bytesRead } = await this.filehandle.read(Buffer.allocUnsafe(length), 0, length, position);
14
- // xref https://stackoverflow.com/a/31394257/2129219
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
- records.forEach(record => {
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
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function HicAdapterF(pluginManager: PluginManager): void;
@@ -1,10 +1,10 @@
1
1
  import { AdapterType } from '@jbrowse/core/pluggableElementTypes';
2
2
  import configSchema from './configSchema';
3
- export default (pluginManager) => {
3
+ export default function HicAdapterF(pluginManager) {
4
4
  pluginManager.addAdapterType(() => new AdapterType({
5
5
  name: 'HicAdapter',
6
6
  displayName: 'Hi-C adapter',
7
7
  configSchema,
8
8
  getAdapterClass: () => import('./HicAdapter').then(r => r.default),
9
9
  }));
10
- };
10
+ }
@@ -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
- function horizontallyFlip() {
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:colorString(hsl(alpha(baseColor,min(1,count/(maxScore/20)))))`,
23
- contextVariable: ['count', 'maxScore', 'baseColor'],
22
+ defaultValue: `jexl:interpolate(count,scale)`,
23
+ contextVariable: ['count', 'maxScore', 'baseColor', 'scale'],
24
24
  },
25
25
  /**
26
26
  * #slot
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function HicRendererF(pluginManager: PluginManager): void;
@@ -1,11 +1,11 @@
1
1
  import ReactComponent from './components/HicRendering';
2
2
  import configSchema from './configSchema';
3
3
  import HicRenderer from './HicRenderer';
4
- export default (pluginManager) => {
4
+ export default function HicRendererF(pluginManager) {
5
5
  pluginManager.addRendererType(() => new HicRenderer({
6
6
  name: 'HicRenderer',
7
7
  ReactComponent,
8
8
  configSchema,
9
9
  pluginManager,
10
10
  }));
11
- };
11
+ }
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function HicTrackF(pluginManager: PluginManager): void;
@@ -1,7 +1,7 @@
1
1
  import TrackType from '@jbrowse/core/pluggableElementTypes/TrackType';
2
2
  import { createBaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models';
3
3
  import configSchemaF from './configSchema';
4
- export default (pluginManager) => {
4
+ export default function HicTrackF(pluginManager) {
5
5
  pluginManager.addTrackType(() => {
6
6
  const configSchema = configSchemaF(pluginManager);
7
7
  return new TrackType({
@@ -11,4 +11,4 @@ export default (pluginManager) => {
11
11
  stateModel: createBaseTrackModel(pluginManager, 'HicTrack', configSchema),
12
12
  });
13
13
  });
14
- };
14
+ }
@@ -1,3 +1,2 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager';
2
- declare const _default: (pluginManager: PluginManager) => void;
3
- export default _default;
2
+ export default function LinearHicDisplayF(pluginManager: PluginManager): void;
@@ -2,7 +2,7 @@ import { DisplayType } from '@jbrowse/core/pluggableElementTypes';
2
2
  import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view';
3
3
  import configSchemaFactory from './configSchema';
4
4
  import stateModelFactory from './model';
5
- export default (pluginManager) => {
5
+ export default function LinearHicDisplayF(pluginManager) {
6
6
  pluginManager.addDisplayType(() => {
7
7
  const configSchema = configSchemaFactory(pluginManager);
8
8
  return new DisplayType({
@@ -15,4 +15,4 @@ export default (pluginManager) => {
15
15
  ReactComponent: BaseLinearDisplayComponent,
16
16
  });
17
17
  });
18
- };
18
+ }
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
3
- declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mobx-state-tree").IModelType<{
3
+ export default function stateModelFactory(configSchema: AnyConfigurationSchemaType): import("mobx-state-tree").IModelType<{
4
4
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
5
5
  type: import("mobx-state-tree").ISimpleType<string>;
6
6
  rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
@@ -67,6 +67,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
67
67
  maxFeatureScreenDensity: {
68
68
  type: string;
69
69
  description: string;
70
+ /**
71
+ * #property
72
+ */
70
73
  defaultValue: number;
71
74
  };
72
75
  fetchSizeLimit: {
@@ -80,39 +83,40 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
80
83
  description: string;
81
84
  };
82
85
  mouseover: {
83
- type: string;
86
+ type: string; /**
87
+ * #getter
88
+ */
84
89
  description: string;
85
90
  defaultValue: string;
86
91
  contextVariable: string[];
87
92
  };
88
93
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
89
94
  } & {
90
- /**
91
- * #property
92
- */
93
95
  type: import("mobx-state-tree").ISimpleType<"LinearHicDisplay">;
94
- /**
95
- * #property
96
- */
97
96
  configuration: AnyConfigurationSchemaType;
98
- /**
99
- * #property
100
- */
101
97
  resolution: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
98
+ useLogScale: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
99
+ colorScheme: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
102
100
  }, {
103
101
  rendererTypeName: string;
104
102
  error: unknown;
105
- message: string | undefined;
103
+ message: string | undefined; /**
104
+ * #property
105
+ */
106
106
  } & {
107
107
  readonly RenderingComponent: import("react").FC<{
108
108
  model: {
109
109
  id: string;
110
110
  type: string;
111
- rpcDriverName: string | undefined;
111
+ rpcDriverName: string | undefined; /**
112
+ * #property
113
+ */
112
114
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & {
113
115
  rendererTypeName: string;
114
116
  error: unknown;
115
- message: string | undefined;
117
+ message: string | undefined; /**
118
+ * #property
119
+ */
116
120
  } & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
117
121
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
118
122
  type: import("mobx-state-tree").ISimpleType<string>;
@@ -170,7 +174,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
170
174
  featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
171
175
  currStatsBpPerPx: number;
172
176
  } & {
173
- readonly currentBytesRequested: number;
177
+ readonly currentBytesRequested: number; /**
178
+ * #method
179
+ */
174
180
  readonly currentFeatureScreenDensity: number;
175
181
  readonly maxFeatureScreenDensity: any;
176
182
  readonly featureDensityStatsReady: boolean;
@@ -241,11 +247,34 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
241
247
  * #action
242
248
  */
243
249
  setResolution(n: number): void;
250
+ /**
251
+ * #action
252
+ */
253
+ setUseLogScale(f: boolean): void;
254
+ /**
255
+ * #action
256
+ */
257
+ setColorScheme(f?: string): void;
244
258
  } & {
245
259
  /**
246
260
  * #getter
247
261
  */
248
- trackMenuItems(): import("@jbrowse/core/ui").MenuItem[];
262
+ 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 | {
263
+ label: string;
264
+ type: string;
265
+ checked: boolean;
266
+ onClick: () => void;
267
+ subMenu?: undefined;
268
+ } | {
269
+ label: string;
270
+ type: string;
271
+ subMenu: {
272
+ label: string;
273
+ onClick: () => void;
274
+ }[];
275
+ checked?: undefined;
276
+ onClick?: undefined;
277
+ })[];
249
278
  }, {
250
279
  type: string;
251
280
  } & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
@@ -315,6 +344,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
315
344
  maxFeatureScreenDensity: {
316
345
  type: string;
317
346
  description: string;
347
+ /**
348
+ * #property
349
+ */
318
350
  defaultValue: number;
319
351
  };
320
352
  fetchSizeLimit: {
@@ -328,7 +360,9 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
328
360
  description: string;
329
361
  };
330
362
  mouseover: {
331
- type: string;
363
+ type: string; /**
364
+ * #getter
365
+ */
332
366
  description: string;
333
367
  defaultValue: string;
334
368
  contextVariable: string[];
@@ -343,4 +377,3 @@ declare const _default: (configSchema: AnyConfigurationSchemaType) => import("mo
343
377
  userBpPerPxLimit: number | undefined;
344
378
  userByteSizeLimit: number | undefined;
345
379
  } & import("mobx-state-tree")._NotCustomized>;
346
- export default _default;
@@ -7,86 +7,140 @@ import { types, getEnv } from 'mobx-state-tree';
7
7
  * extends `BaseLinearDisplay`
8
8
  */
9
9
  function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
10
- export default (configSchema) => types
11
- .compose('LinearHicDisplay', BaseLinearDisplay, types.model({
12
- /**
13
- * #property
14
- */
15
- type: types.literal('LinearHicDisplay'),
16
- /**
17
- * #property
18
- */
19
- configuration: ConfigurationReference(configSchema),
20
- /**
21
- * #property
22
- */
23
- resolution: types.optional(types.number, 1),
24
- }))
25
- .views(self => {
26
- const { renderProps: superRenderProps } = self;
27
- return {
10
+ export default function stateModelFactory(configSchema) {
11
+ return types
12
+ .compose('LinearHicDisplay', BaseLinearDisplay, types.model({
28
13
  /**
29
- * #getter
14
+ * #property
30
15
  */
31
- get blockType() {
32
- return 'dynamicBlocks';
33
- },
16
+ type: types.literal('LinearHicDisplay'),
17
+ /**
18
+ * #property
19
+ */
20
+ configuration: ConfigurationReference(configSchema),
21
+ /**
22
+ * #property
23
+ */
24
+ resolution: types.optional(types.number, 1),
25
+ /**
26
+ * #property
27
+ */
28
+ useLogScale: false,
34
29
  /**
35
- * #getter
30
+ * #property
36
31
  */
37
- get rendererTypeName() {
38
- return 'HicRenderer';
32
+ colorScheme: types.maybe(types.string),
33
+ }))
34
+ .views(self => {
35
+ const { renderProps: superRenderProps } = self;
36
+ return {
37
+ /**
38
+ * #getter
39
+ */
40
+ get blockType() {
41
+ return 'dynamicBlocks';
42
+ },
43
+ /**
44
+ * #getter
45
+ */
46
+ get rendererTypeName() {
47
+ return 'HicRenderer';
48
+ },
49
+ /**
50
+ * #method
51
+ */
52
+ renderProps() {
53
+ const config = self.rendererType.configSchema.create({
54
+ ...getConf(self, 'renderer'),
55
+ // add specific jexl color callback when using pre-defined color schemes
56
+ ...(self.colorScheme
57
+ ? { color: 'jexl:interpolate(count,scale)' }
58
+ : {}),
59
+ }, getEnv(self));
60
+ return {
61
+ ...superRenderProps(),
62
+ config,
63
+ rpcDriverName: self.rpcDriverName,
64
+ displayModel: self,
65
+ resolution: self.resolution,
66
+ useLogScale: self.useLogScale,
67
+ colorScheme: self.colorScheme,
68
+ };
69
+ },
70
+ };
71
+ })
72
+ .actions(self => ({
73
+ /**
74
+ * #action
75
+ */
76
+ setResolution(n) {
77
+ self.resolution = n;
39
78
  },
40
79
  /**
41
- * #method
80
+ * #action
42
81
  */
43
- renderProps() {
44
- const config = self.rendererType.configSchema.create(getConf(self, 'renderer') || {}, getEnv(self));
45
- return {
46
- ...superRenderProps(),
47
- config,
48
- rpcDriverName: self.rpcDriverName,
49
- displayModel: self,
50
- resolution: self.resolution,
51
- };
82
+ setUseLogScale(f) {
83
+ self.useLogScale = f;
52
84
  },
53
- };
54
- })
55
- .actions(self => ({
56
- /**
57
- * #action
58
- */
59
- setResolution(n) {
60
- self.resolution = n;
61
- },
62
- }))
63
- .views(self => {
64
- const { trackMenuItems: superTrackMenuItems } = self;
65
- return {
66
85
  /**
67
- * #getter
86
+ * #action
68
87
  */
69
- trackMenuItems() {
70
- return [
71
- ...superTrackMenuItems(),
72
- {
73
- label: 'Resolution',
74
- subMenu: [
75
- {
76
- label: 'Finer resolution',
77
- onClick: () => {
78
- self.setResolution(self.resolution * 2);
88
+ setColorScheme(f) {
89
+ self.colorScheme = f;
90
+ },
91
+ }))
92
+ .views(self => {
93
+ const { trackMenuItems: superTrackMenuItems } = self;
94
+ return {
95
+ /**
96
+ * #getter
97
+ */
98
+ trackMenuItems() {
99
+ return [
100
+ ...superTrackMenuItems(),
101
+ {
102
+ label: 'Use log scale',
103
+ type: 'checkbox',
104
+ checked: self.useLogScale,
105
+ onClick: () => self.setUseLogScale(!self.useLogScale),
106
+ },
107
+ {
108
+ label: 'Color scheme',
109
+ type: 'subMenu',
110
+ subMenu: [
111
+ {
112
+ label: 'Fall',
113
+ onClick: () => self.setColorScheme('fall'),
79
114
  },
80
- },
81
- {
82
- label: 'Coarser resolution',
83
- onClick: () => {
84
- self.setResolution(self.resolution / 2);
115
+ {
116
+ label: 'Viridis',
117
+ onClick: () => self.setColorScheme('viridis'),
85
118
  },
86
- },
87
- ],
88
- },
89
- ];
90
- },
91
- };
92
- });
119
+ {
120
+ label: 'Juicebox',
121
+ onClick: () => self.setColorScheme('juicebox'),
122
+ },
123
+ {
124
+ label: 'Clear',
125
+ onClick: () => self.setColorScheme(undefined),
126
+ },
127
+ ],
128
+ },
129
+ {
130
+ label: 'Resolution',
131
+ subMenu: [
132
+ {
133
+ label: 'Finer resolution',
134
+ onClick: () => self.setResolution(self.resolution * 2),
135
+ },
136
+ {
137
+ label: 'Coarser resolution',
138
+ onClick: () => self.setResolution(self.resolution / 2),
139
+ },
140
+ ],
141
+ },
142
+ ];
143
+ },
144
+ };
145
+ });
146
+ }
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
- return adapterGuesser(file, index, adapterHint);
34
+ else {
35
+ return adapterGuesser(file, index, adapterHint);
36
+ }
34
37
  };
35
38
  });
36
39
  pluginManager.addToExtensionPoint('Core-guessTrackTypeForLocation', (trackTypeGuesser) => {
37
- return (adapterName) => {
38
- if (adapterName === 'HicAdapter') {
39
- return 'HicTrack';
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.10.3",
3
+ "version": "2.11.1",
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": "c8fc800cd17decd72b2e971c7a6add3b95214e72"
59
+ "gitHead": "11b28d66d782eb06f92ccb993108bb6c3c82819e"
58
60
  }