@jbrowse/img 1.3.4 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # v1.3.5
2
+
3
+ - Add pdf export functionality
4
+
1
5
  # v1.3.4
2
6
 
3
7
  - Update to @jbrowse/react-linear-genome-view@1.3.5
package/LICENSE CHANGED
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [2021] [Evolutionary Software Foundation]
189
+ Copyright [2020] [Evolutionary Software Foundation]
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -8,7 +8,6 @@ You don't need to have JBrowse 2 installed to use this tool. The tool can genera
8
8
 
9
9
  - NodeJS v12+
10
10
 
11
-
12
11
  ## Screenshot
13
12
 
14
13
  ![](img/1.png)
@@ -20,7 +19,7 @@ More examples [EXAMPLES.md](EXAMPLES.md)
20
19
  You can install the `@jbrowse/img` package from npm, which, if your node is configured in a typical configuration, will then have a command `jb2export` in your path
21
20
 
22
21
  ```bash
23
- npm install -g @jbrowse/img
22
+ npm install -g @jbrowse/img
24
23
  ```
25
24
 
26
25
  If you are using npm version 7+ (released 2021) you may also need to add `--legacy-peer-deps`
@@ -47,14 +46,21 @@ samtools index yourfile.bam
47
46
 
48
47
 
49
48
  ## simple rendering of a your local files
50
- jb2export --fasta yourfile.fa --bam yourfile.bam --loc chr1:1,000,000-1,001,000
49
+ jb2export --fasta yourfile.fa --bam yourfile.bam --loc chr1:1,000,000-1,001,000 --out file.svg
51
50
  ```
52
51
 
53
- ### Generate PNG instead of SVG
52
+ If `--out` is not specified it writes to out.svg
53
+
54
+ ### Generate PDF of PNG instead of SVG
55
+
56
+ If a filename with a `pdf` or `png` extension is supplied to `--out` then the
57
+ tool tries to convert from svg to pdf/png using rsvg-convert (you will need to
58
+ install rsvg-convert to your system e.g. with `sudo apt install librsvg2-bin`)
54
59
 
55
- The file out.svg is created by default, or whatever is passed to --out flag. If a filename
56
- with a png extension is supplied to --out then the tool tries to convert to png
57
- automatically using rsvg-convert (can be installed on some systems with `sudo apt install librsvg2-bin`)
60
+ ```
61
+ jb2export --fasta yourfile.fa --bam yourfile.bam --loc chr1:1,000,000-1,001,000 --out file.png
62
+ jb2export --fasta yourfile.fa --bam yourfile.bam --loc chr1:1,000,000-1,001,000 --out file.pdf
63
+ ```
58
64
 
59
65
  ### Use with remote files
60
66
 
package/dist/bin.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
 
4
- require("./index.js");
4
+ require('./index.js');
package/dist/index.js CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
- require("abortcontroller-polyfill/dist/abortcontroller-polyfill-only");
6
-
7
5
  var _fs = _interopRequireDefault(require("fs"));
8
6
 
9
7
  var _yargs = _interopRequireDefault(require("yargs"));
@@ -16,74 +14,76 @@ var _tmp = _interopRequireDefault(require("tmp"));
16
14
 
17
15
  var _child_process = require("child_process");
18
16
 
19
- _yargs.default.command("jb2export", "Creates a jbrowse 2 image snapshot").option("config", {
20
- description: "Path to config file",
21
- type: "string"
22
- }).option("session", {
23
- description: "Path to session file",
24
- type: "string"
25
- }).option("assembly", {
26
- description: "Path to an assembly configuration, or a name of an assembly in the configFile",
27
- type: "string"
28
- }).option("tracks", {
29
- description: "Path to tracks portion of a session",
30
- type: "string"
31
- }).option("loc", {
32
- description: "A locstring to navigate to, or --loc all to view the whole genome",
33
- type: "string"
34
- }).option("fasta", {
35
- description: "Supply a fasta for the assembly",
36
- type: "string"
37
- }).option("aliases", {
38
- description: "Supply aliases for the assembly, e.g. mapping of 1 to chr1. Tab separated file where column 1 matches the names from the FASTA",
39
- type: "string"
40
- }).option("width", {
41
- description: "Set the width of the window that jbrowse renders to, default: 1500px",
42
- type: "number"
43
- }).option("pngwidth", {
44
- description: "Set the width of the png canvas if using png output, default 2048px",
45
- type: "number",
17
+ /* eslint-disable no-console */
18
+ // eslint-disable-next-line no-unused-expressions
19
+ _yargs.default.command('jb2export', 'Creates a jbrowse 2 image snapshot').option('config', {
20
+ description: 'Path to config file',
21
+ type: 'string'
22
+ }).option('session', {
23
+ description: 'Path to session file',
24
+ type: 'string'
25
+ }).option('assembly', {
26
+ description: 'Path to an assembly configuration, or a name of an assembly in the configFile',
27
+ type: 'string'
28
+ }).option('tracks', {
29
+ description: 'Path to tracks portion of a session',
30
+ type: 'string'
31
+ }).option('loc', {
32
+ description: 'A locstring to navigate to, or --loc all to view the whole genome',
33
+ type: 'string'
34
+ }).option('fasta', {
35
+ description: 'Supply a fasta for the assembly',
36
+ type: 'string'
37
+ }).option('aliases', {
38
+ description: 'Supply aliases for the assembly, e.g. mapping of 1 to chr1. Tab separated file where column 1 matches the names from the FASTA',
39
+ type: 'string'
40
+ }).option('width', {
41
+ description: 'Set the width of the window that jbrowse renders to, default: 1500px',
42
+ type: 'number'
43
+ }).option('pngwidth', {
44
+ description: 'Set the width of the png canvas if using png output, default 2048px',
45
+ type: 'number',
46
46
  default: 2048
47
47
  }) // track types
48
- .option("configtracks", {
49
- description: "A list of track labels from a config file",
50
- type: "array"
51
- }).option("bam", {
52
- description: "A bam file, flag --bam can be used multiple times to specify multiple bam files",
53
- type: "array"
54
- }).option("bigwig", {
55
- description: "A bigwig file, the --bigwig flag can be used multiple times to specify multiple bigwig files",
56
- type: "array"
57
- }).option("cram", {
58
- description: "A cram file, the --cram flag can be used multiple times to specify multiple cram files",
59
- type: "array"
60
- }).option("vcfgz", {
61
- description: "A tabixed VCF, the --vcfgz flag can be used multiple times to specify multiple vcfgz files",
62
- type: "array"
63
- }).option("gffgz", {
64
- description: "A tabixed GFF, the --gffgz can be used multiple times to specify multiple gffgz files",
65
- type: "array"
66
- }).option("hic", {
67
- description: "A .hic file, the --hic can be used multiple times to specify multiple hic files",
68
- type: "array"
69
- }).option("bigbed", {
70
- description: "A .bigBed file, the --bigbed can be used multiple times to specify multiple bigbed files",
71
- type: "array"
72
- }).option("bedgz", {
73
- description: "A bed tabix file, the --bedgz can be used multiple times to specify multiple bedtabix files",
74
- type: "array"
48
+ .option('configtracks', {
49
+ description: 'A list of track labels from a config file',
50
+ type: 'array'
51
+ }).option('bam', {
52
+ description: 'A bam file, flag --bam can be used multiple times to specify multiple bam files',
53
+ type: 'array'
54
+ }).option('bigwig', {
55
+ description: 'A bigwig file, the --bigwig flag can be used multiple times to specify multiple bigwig files',
56
+ type: 'array'
57
+ }).option('cram', {
58
+ description: 'A cram file, the --cram flag can be used multiple times to specify multiple cram files',
59
+ type: 'array'
60
+ }).option('vcfgz', {
61
+ description: 'A tabixed VCF, the --vcfgz flag can be used multiple times to specify multiple vcfgz files',
62
+ type: 'array'
63
+ }).option('gffgz', {
64
+ description: 'A tabixed GFF, the --gffgz can be used multiple times to specify multiple gffgz files',
65
+ type: 'array'
66
+ }).option('hic', {
67
+ description: 'A .hic file, the --hic can be used multiple times to specify multiple hic files',
68
+ type: 'array'
69
+ }).option('bigbed', {
70
+ description: 'A .bigBed file, the --bigbed can be used multiple times to specify multiple bigbed files',
71
+ type: 'array'
72
+ }).option('bedgz', {
73
+ description: 'A bed tabix file, the --bedgz can be used multiple times to specify multiple bedtabix files',
74
+ type: 'array'
75
75
  }) // other
76
- .option("out", {
77
- description: "File to output to. Default: out.svg. If a filename with extension .png is supplied the program will try to automatically execute rsvg-convert to convert it to png",
78
- type: "string",
79
- default: "out.svg"
80
- }).option("noRasterize", {
81
- description: "Use full SVG rendering with no rasterized layers, this can substantially increase filesize",
82
- type: "boolean"
83
- }).option("defaultSession", {
84
- description: "Use the defaultSession from config.json",
85
- type: "boolean"
86
- }).help().alias("help", "h").alias("width", "w").argv; //prints to stderr the time it takes to execute cb
76
+ .option('out', {
77
+ description: 'File to output to. Default: out.svg. If a filename with extension .png is supplied the program will try to automatically execute rsvg-convert to convert it to png',
78
+ type: 'string',
79
+ default: 'out.svg'
80
+ }).option('noRasterize', {
81
+ description: 'Use full SVG rendering with no rasterized layers, this can substantially increase filesize',
82
+ type: 'boolean'
83
+ }).option('defaultSession', {
84
+ description: 'Use the defaultSession from config.json',
85
+ type: 'boolean'
86
+ }).help().alias('help', 'h').alias('width', 'w').argv; // prints to stderr the time it takes to execute cb
87
87
 
88
88
  async function time(cb) {
89
89
  const start = +Date.now();
@@ -92,20 +92,34 @@ async function time(cb) {
92
92
  return ret;
93
93
  }
94
94
 
95
- const args = (0, _parseArgv.standardizeArgv)((0, _parseArgv.parseArgv)(process.argv.slice(2)), ["bam", "cram", "vcfgz", "hic", "bigwig", "bigbed", "bedgz", "gffgz", "configtracks"]);
95
+ const args = (0, _parseArgv.standardizeArgv)((0, _parseArgv.parseArgv)(process.argv.slice(2)), ['bam', 'cram', 'vcfgz', 'hic', 'bigwig', 'bigbed', 'bedgz', 'gffgz', 'configtracks']);
96
96
  time(() => (0, _renderRegion.renderRegion)(args).then(result => {
97
- const outfile = args.out || "out.svg";
97
+ const outfile = args.out || 'out.svg';
98
+
99
+ if (outfile.endsWith('.png')) {
100
+ const tmpobj = _tmp.default.fileSync({
101
+ mode: 0o644,
102
+ prefix: 'prefix-',
103
+ postfix: '.svg'
104
+ });
98
105
 
99
- if (outfile.endsWith(".png")) {
106
+ _fs.default.writeFileSync(tmpobj.name, result);
107
+
108
+ const ls = (0, _child_process.spawnSync)('rsvg-convert', ['-w', args.pngwidth || 2048, tmpobj.name, '-o', outfile]);
109
+ console.log(`rsvg-convert stderr: ${ls.stderr.toString()}`);
110
+ console.log(`rsvg-convert stdout: ${ls.stdout.toString()}`);
111
+
112
+ _fs.default.unlinkSync(tmpobj.name);
113
+ } else if (outfile.endsWith('.pdf')) {
100
114
  const tmpobj = _tmp.default.fileSync({
101
115
  mode: 0o644,
102
- prefix: "prefix-",
103
- postfix: ".svg"
116
+ prefix: 'prefix-',
117
+ postfix: '.svg'
104
118
  });
105
119
 
106
120
  _fs.default.writeFileSync(tmpobj.name, result);
107
121
 
108
- const ls = (0, _child_process.spawnSync)("rsvg-convert", ["-w", args.pngwidth || 2048, tmpobj.name, "-o", outfile]);
122
+ const ls = (0, _child_process.spawnSync)('rsvg-convert', ['-w', args.pngwidth || 2048, tmpobj.name, '-f', 'pdf', '-o', outfile]);
109
123
  console.log(`rsvg-convert stderr: ${ls.stderr.toString()}`);
110
124
  console.log(`rsvg-convert stdout: ${ls.stdout.toString()}`);
111
125
 
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _renderRegion = require("./renderRegion");
6
+
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+
9
+ function hashCode(str) {
10
+ let hash = 0;
11
+ let chr;
12
+
13
+ if (str.length === 0) {
14
+ return hash;
15
+ }
16
+
17
+ for (let i = 0; i < str.length; i++) {
18
+ chr = str.charCodeAt(i);
19
+ hash = (hash << 5) - hash + chr;
20
+ hash |= 0; // Convert to 32bit integer
21
+ }
22
+
23
+ return hash;
24
+ }
25
+
26
+ const timeout = 20000; // commented out for using remote files currently
27
+
28
+ xtest('renders a region with --session and --config args', async () => {
29
+ const result = await (0, _renderRegion.renderRegion)({
30
+ session: require.resolve('../test/clingen_session.json'),
31
+ config: require.resolve('../data/config.json')
32
+ });
33
+
34
+ _fs.default.writeFileSync('svg_from_config_and_session_param.svg', result);
35
+
36
+ expect(hashCode(result)).toMatchSnapshot();
37
+ }, timeout); // commented out for using remote files currently
38
+
39
+ xtest('renders a region with --session, --tracks, and --assembly args', async () => {
40
+ const result = await (0, _renderRegion.renderRegion)({
41
+ session: require.resolve('../test/clingen_session.json'),
42
+ tracks: require.resolve('../data/tracks.json'),
43
+ assembly: require.resolve('../data/assembly.json')
44
+ });
45
+
46
+ _fs.default.writeFileSync('svg_from_separate_session_and_tracks.svg', result);
47
+
48
+ expect(hashCode(result)).toMatchSnapshot();
49
+ }, timeout);
50
+ test('renders volvox with variety of args', async () => {
51
+ console.error = jest.fn();
52
+ const result = await (0, _renderRegion.renderRegion)({
53
+ fasta: require.resolve('../data/volvox/volvox.fa'),
54
+ trackList: [['bam', [require.resolve('../data/volvox/volvox-sorted.bam')]], ['cram', [require.resolve('../data/volvox/volvox-sorted.cram')]], ['bigwig', [require.resolve('../data/volvox/volvox-sorted.bam.coverage.bw')]], ['vcfgz', [require.resolve('../data/volvox/volvox.filtered.vcf.gz')]], ['gffgz', [require.resolve('../data/volvox/volvox.sort.gff3.gz')]], ['bigbed', [require.resolve('../data/volvox/volvox.bb')]], ['bedgz', [require.resolve('../data/volvox/volvox-bed12.bed.gz')]]],
55
+ loc: 'ctgA:1000-2000'
56
+ }); // can't do a snapshot test here, slightly inconsistent results(?)
57
+
58
+ _fs.default.writeFileSync(require.resolve('../test/svg_from_volvox_fasta_and_bam.svg'), result);
59
+
60
+ expect(result).toBeTruthy();
61
+ }, timeout); // commented out for using remote files currently
62
+
63
+ xtest('configtracks arg with urls', async () => {
64
+ const result = await (0, _renderRegion.renderRegion)({
65
+ config: 'data/config.json',
66
+ trackList: [['configtracks', ['ncbi_refseq_109_hg38']]],
67
+ assembly: 'GRCh38',
68
+ loc: 'chr1:50,000-60,000'
69
+ }); // can't do a snapshot test here, slightly inconsistent results(?)
70
+
71
+ _fs.default.writeFileSync('svg_configtracks_simple.svg', result);
72
+
73
+ expect(result).toBeTruthy();
74
+ }, timeout * 3);
75
+ test('configtracks arg with local files', async () => {
76
+ const result = await (0, _renderRegion.renderRegion)({
77
+ config: require.resolve('../data/volvox/config.json'),
78
+ trackList: [['configtracks', ['volvox_sv']]],
79
+ assembly: 'volvox',
80
+ loc: 'ctgA:1-50,000'
81
+ }); // can't do a snapshot test here, slightly inconsistent results(?)
82
+
83
+ _fs.default.writeFileSync(require.resolve('../test/svg_configtracks_local.svg'), result);
84
+
85
+ expect(result).toBeTruthy();
86
+ }, timeout * 3);
87
+ xtest('renders --hic', async () => {
88
+ const result = await (0, _renderRegion.renderRegion)({
89
+ fasta: 'https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz',
90
+ trackList: [['hic', ['https://s3.amazonaws.com/igv.broadinstitute.org/data/hic/intra_nofrag_30.hic']]],
91
+ loc: '1:2,000,000-10,000,000'
92
+ });
93
+
94
+ _fs.default.writeFileSync(require.resolve('../test/svg_from_human_hic.svg'), result);
95
+
96
+ expect(result).toBeTruthy();
97
+ }, 20000);
package/dist/parseArgv.js CHANGED
@@ -12,7 +12,7 @@ function parseArgv(argv) {
12
12
  while (argv.length) {
13
13
  const val = argv[0].slice(2);
14
14
  argv = argv.slice(1);
15
- const next = argv.findIndex(arg => arg.startsWith("-"));
15
+ const next = argv.findIndex(arg => arg.startsWith('-'));
16
16
 
17
17
  if (next !== -1) {
18
18
  map.push([val, argv.slice(0, next)]);
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ var _parseArgv = require("./parseArgv");
4
+
5
+ test('parse', () => {
6
+ const args = '--bam dad.bam color:red --vcf variants.vcf --bam mom.bam --defaultSession --out out.svg --noRasterize';
7
+ expect((0, _parseArgv.parseArgv)(args.split(' '))).toEqual([['bam', ['dad.bam', 'color:red']], ['vcf', ['variants.vcf']], ['bam', ['mom.bam']], ['defaultSession', []], ['out', ['out.svg']], ['noRasterize', []]]);
8
+ });
@@ -8,12 +8,8 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.readData = readData;
9
9
  exports.renderRegion = renderRegion;
10
10
 
11
- require("regenerator-runtime/runtime");
12
-
13
11
  var _reactLinearGenomeView = require("@jbrowse/react-linear-genome-view");
14
12
 
15
- var _mobxStateTree = require("mobx-state-tree");
16
-
17
13
  var _pluginLinearGenomeView = require("@jbrowse/plugin-linear-genome-view");
18
14
 
19
15
  var _mobx = require("mobx");
@@ -37,7 +33,7 @@ function read(file) {
37
33
  }
38
34
 
39
35
  function makeLocation(file) {
40
- return file.startsWith("http") ? {
36
+ return file.startsWith('http') ? {
41
37
  uri: file
42
38
  } : {
43
39
  localPath: file
@@ -45,11 +41,11 @@ function makeLocation(file) {
45
41
  }
46
42
 
47
43
  function addRelativePaths(config, configPath) {
48
- if (typeof config === "object") {
44
+ if (typeof config === 'object') {
49
45
  for (const key of Object.keys(config)) {
50
- if (typeof config[key] === "object") {
46
+ if (typeof config[key] === 'object') {
51
47
  addRelativePaths(config[key], configPath);
52
- } else if (key === "localPath") {
48
+ } else if (key === 'localPath') {
53
49
  config.localPath = _path.default.resolve(configPath, config.localPath);
54
50
  }
55
51
  }
@@ -95,37 +91,37 @@ function readData(opts) {
95
91
  configData.assembly = assemblyData;
96
92
  } // else check if it was an assembly name in a config file
97
93
  else if ((_configData$assemblie = configData.assemblies) !== null && _configData$assemblie !== void 0 && _configData$assemblie.length) {
98
- configData.assembly = asm ? configData.assemblies.find(entry => entry.name === asm) : configData.assemblies[0];
99
- } // else load fasta from command line
100
- else if (fasta) {
101
- const bgzip = fasta.endsWith("gz");
102
- configData.assembly = {
103
- name: _path.default.basename(fasta),
104
- sequence: {
105
- type: "ReferenceSequenceTrack",
106
- trackId: "refseq",
107
- adapter: {
108
- type: bgzip ? "BgzipFastaAdapter" : "IndexedFastaAdapter",
109
- fastaLocation: makeLocation(fasta),
110
- faiLocation: makeLocation(fasta + ".fai"),
111
- gziLocation: bgzip ? makeLocation(fasta + ".gzi") : undefined
112
- }
113
- }
114
- };
115
-
116
- if (aliases) {
117
- configData.assembly.refNameAliases = {
118
- adapter: {
119
- type: "RefNameAliasAdapter",
120
- location: makeLocation(aliases)
121
- }
122
- };
94
+ configData.assembly = asm ? configData.assemblies.find(entry => entry.name === asm) : configData.assemblies[0];
95
+ } // else load fasta from command line
96
+ else if (fasta) {
97
+ const bgzip = fasta.endsWith('gz');
98
+ configData.assembly = {
99
+ name: _path.default.basename(fasta),
100
+ sequence: {
101
+ type: 'ReferenceSequenceTrack',
102
+ trackId: 'refseq',
103
+ adapter: {
104
+ type: bgzip ? 'BgzipFastaAdapter' : 'IndexedFastaAdapter',
105
+ fastaLocation: makeLocation(fasta),
106
+ faiLocation: makeLocation(fasta + '.fai'),
107
+ gziLocation: bgzip ? makeLocation(fasta + '.gzi') : undefined
108
+ }
109
+ }
110
+ };
111
+
112
+ if (aliases) {
113
+ configData.assembly.refNameAliases = {
114
+ adapter: {
115
+ type: 'RefNameAliasAdapter',
116
+ location: makeLocation(aliases)
123
117
  }
124
- } // throw if still no assembly
118
+ };
119
+ }
120
+ } // throw if still no assembly
125
121
 
126
122
 
127
123
  if (!configData.assembly) {
128
- throw new Error("no assembly specified, use --fasta to supply an indexed FASTA file (generated with samtools faidx yourfile.fa). see README for alternatives with --assembly and --config");
124
+ throw new Error('no assembly specified, use --fasta to supply an indexed FASTA file (generated with samtools faidx yourfile.fa). see README for alternatives with --assembly and --config');
129
125
  }
130
126
 
131
127
  if (tracksData) {
@@ -135,122 +131,122 @@ function readData(opts) {
135
131
  }
136
132
 
137
133
  trackList.forEach(track => {
138
- const [type, [file, opts]] = track;
134
+ const [type, [file]] = track;
139
135
 
140
- if (type === "bam") {
136
+ if (type === 'bam') {
141
137
  configData.tracks = [...configData.tracks, {
142
- type: "AlignmentsTrack",
138
+ type: 'AlignmentsTrack',
143
139
  trackId: _path.default.basename(file),
144
140
  name: _path.default.basename(file),
145
141
  assemblyNames: [configData.assembly.name],
146
142
  adapter: {
147
- type: "BamAdapter",
143
+ type: 'BamAdapter',
148
144
  bamLocation: makeLocation(file),
149
145
  index: {
150
- location: makeLocation(file + ".bai")
146
+ location: makeLocation(file + '.bai')
151
147
  },
152
148
  sequenceAdapter: configData.assembly.sequence.adapter
153
149
  }
154
150
  }];
155
151
  }
156
152
 
157
- if (type === "cram") {
153
+ if (type === 'cram') {
158
154
  configData.tracks = [...configData.tracks, {
159
- type: "AlignmentsTrack",
155
+ type: 'AlignmentsTrack',
160
156
  trackId: _path.default.basename(file),
161
157
  name: _path.default.basename(file),
162
158
  assemblyNames: [configData.assembly.name],
163
159
  adapter: {
164
- type: "CramAdapter",
160
+ type: 'CramAdapter',
165
161
  cramLocation: makeLocation(file),
166
- craiLocation: makeLocation(file + ".crai"),
162
+ craiLocation: makeLocation(file + '.crai'),
167
163
  sequenceAdapter: configData.assembly.sequence.adapter
168
164
  }
169
165
  }];
170
166
  }
171
167
 
172
- if (type === "bigwig") {
168
+ if (type === 'bigwig') {
173
169
  configData.tracks = [...configData.tracks, {
174
- type: "QuantitativeTrack",
170
+ type: 'QuantitativeTrack',
175
171
  trackId: _path.default.basename(file),
176
172
  name: _path.default.basename(file),
177
173
  assemblyNames: [configData.assembly.name],
178
174
  adapter: {
179
- type: "BigWigAdapter",
175
+ type: 'BigWigAdapter',
180
176
  bigWigLocation: makeLocation(file)
181
177
  }
182
178
  }];
183
179
  }
184
180
 
185
- if (type === "vcfgz") {
181
+ if (type === 'vcfgz') {
186
182
  configData.tracks = [...configData.tracks, {
187
- type: "VariantTrack",
183
+ type: 'VariantTrack',
188
184
  trackId: _path.default.basename(file),
189
185
  name: _path.default.basename(file),
190
186
  assemblyNames: [configData.assembly.name],
191
187
  adapter: {
192
- type: "VcfTabixAdapter",
188
+ type: 'VcfTabixAdapter',
193
189
  vcfGzLocation: makeLocation(file),
194
190
  index: {
195
- location: makeLocation(file + ".tbi")
191
+ location: makeLocation(file + '.tbi')
196
192
  }
197
193
  }
198
194
  }];
199
195
  }
200
196
 
201
- if (type === "gffgz") {
197
+ if (type === 'gffgz') {
202
198
  configData.tracks = [...configData.tracks, {
203
- type: "FeatureTrack",
199
+ type: 'FeatureTrack',
204
200
  trackId: _path.default.basename(file),
205
201
  name: _path.default.basename(file),
206
202
  assemblyNames: [configData.assembly.name],
207
203
  adapter: {
208
- type: "Gff3TabixAdapter",
204
+ type: 'Gff3TabixAdapter',
209
205
  gffGzLocation: makeLocation(file),
210
206
  index: {
211
- location: makeLocation(file + ".tbi")
207
+ location: makeLocation(file + '.tbi')
212
208
  }
213
209
  }
214
210
  }];
215
211
  }
216
212
 
217
- if (type === "hic") {
213
+ if (type === 'hic') {
218
214
  configData.tracks = [...configData.tracks, {
219
- type: "HicTrack",
215
+ type: 'HicTrack',
220
216
  trackId: _path.default.basename(file),
221
217
  name: _path.default.basename(file),
222
218
  assemblyNames: [configData.assembly.name],
223
219
  adapter: {
224
- type: "HicAdapter",
220
+ type: 'HicAdapter',
225
221
  hicLocation: makeLocation(file)
226
222
  }
227
223
  }];
228
224
  }
229
225
 
230
- if (type === "bigbed") {
226
+ if (type === 'bigbed') {
231
227
  configData.tracks = [...configData.tracks, {
232
- type: "FeatureTrack",
228
+ type: 'FeatureTrack',
233
229
  trackId: _path.default.basename(file),
234
230
  name: _path.default.basename(file),
235
231
  assemblyNames: [configData.assembly.name],
236
232
  adapter: {
237
- type: "BigBedAdapter",
233
+ type: 'BigBedAdapter',
238
234
  bigBedLocation: makeLocation(file)
239
235
  }
240
236
  }];
241
237
  }
242
238
 
243
- if (type === "bedgz") {
239
+ if (type === 'bedgz') {
244
240
  configData.tracks = [...configData.tracks, {
245
- type: "FeatureTrack",
241
+ type: 'FeatureTrack',
246
242
  trackId: _path.default.basename(file),
247
243
  name: _path.default.basename(file),
248
244
  assemblyNames: [configData.assembly.name],
249
245
  adapter: {
250
- type: "BedTabixAdapter",
246
+ type: 'BedTabixAdapter',
251
247
  bedGzLocation: makeLocation(file),
252
248
  index: {
253
- location: makeLocation(file + ".tbi")
249
+ location: makeLocation(file + '.tbi')
254
250
  }
255
251
  }
256
252
  }];
@@ -291,7 +287,9 @@ async function renderRegion(opts = {}) {
291
287
  } = model;
292
288
  view.setWidth(width);
293
289
  await (0, _mobx.when)(() => {
294
- return assemblyManager.allPossibleRefNames && assemblyManager.allPossibleRefNames.length && model.session.view.initialized;
290
+ var _assemblyManager$allP;
291
+
292
+ return ((_assemblyManager$allP = assemblyManager.allPossibleRefNames) === null || _assemblyManager$allP === void 0 ? void 0 : _assemblyManager$allP.length) && model.session.view.initialized;
295
293
  });
296
294
 
297
295
  if (loc) {
@@ -302,13 +300,13 @@ async function renderRegion(opts = {}) {
302
300
  view.setDisplayedRegions([region]);
303
301
  }
304
302
 
305
- if (loc === "all") {
303
+ if (loc === 'all') {
306
304
  view.showAllRegionsInAssembly(assembly.name);
307
305
  } else {
308
306
  view.navToLocString(loc);
309
307
  }
310
308
  } else if (!sessionParam && !defaultSession) {
311
- console.warn("No loc specified");
309
+ console.warn('No loc specified');
312
310
  }
313
311
 
314
312
  function process(trackEntry, extra = () => {}) {
@@ -317,65 +315,65 @@ async function renderRegion(opts = {}) {
317
315
  const display = currentTrack.displays[0];
318
316
  opts.forEach(opt => {
319
317
  // apply height to any track
320
- if (opt.startsWith("height:")) {
321
- const [, height] = opt.split(":");
318
+ if (opt.startsWith('height:')) {
319
+ const [, height] = opt.split(':');
322
320
  display.setHeight(+height);
323
321
  } // apply sort to pileup
324
- else if (opt.startsWith("sort:")) {
325
- const [, type, tag] = opt.split(":");
326
- display.PileupDisplay.setSortedBy(type, tag);
327
- } // apply color scheme to pileup
328
- else if (opt.startsWith("color:")) {
329
- const [, type, tag] = opt.split(":");
330
-
331
- if (display.PileupDisplay) {
332
- display.PileupDisplay.setColorScheme({
333
- type,
334
- tag
335
- });
336
- } else {
337
- display.setColor(type);
338
- }
339
- } // force track to render even if maxbpperpx limit hit...
340
- else if (opt.startsWith("force:")) {
341
- const [, force] = opt.split(":");
342
-
343
- if (Boolean(force)) {
344
- display.setUserBpPerPxLimit(Number.MAX_VALUE);
345
- }
346
- } // apply wiggle autoscale
347
- else if (opt.startsWith("autoscale:")) {
348
- const [, autoscale] = opt.split(":");
349
- display.setAutoscale(autoscale);
350
- } // apply min and max score to wiggle
351
- else if (opt.startsWith("minmax:")) {
352
- const [, min, max] = opt.split(":");
353
- display.setMinScore(+min);
354
- display.setMaxScore(+max);
355
- } // apply linear or log scale to wiggle
356
- else if (opt.startsWith("scaletype:")) {
357
- const [, scaletype] = opt.split(":");
358
- display.setScaleType(scaletype);
359
- } // draw crosshatches on wiggle
360
- else if (opt.startsWith("crosshatch:")) {
361
- const [, val] = opt.split(":");
362
- display.setCrossHatches((0, _util.booleanize)(val));
363
- } // turn off fill on bigwig with fill:false
364
- else if (opt.startsWith("fill:")) {
365
- const [, val] = opt.split(":");
366
- display.setFill((0, _util.booleanize)(val));
367
- } // set resolution:superfine to use finer bigwig bin size
368
- else if (opt.startsWith("resolution:")) {
369
- let [, val] = opt.split(":");
370
-
371
- if (val === "fine") {
372
- val = 10;
373
- } else if (val === "superfine") {
374
- val = 100;
375
- }
376
-
377
- display.setResolution(val);
378
- }
322
+ else if (opt.startsWith('sort:')) {
323
+ const [, type, tag] = opt.split(':');
324
+ display.PileupDisplay.setSortedBy(type, tag);
325
+ } // apply color scheme to pileup
326
+ else if (opt.startsWith('color:')) {
327
+ const [, type, tag] = opt.split(':');
328
+
329
+ if (display.PileupDisplay) {
330
+ display.PileupDisplay.setColorScheme({
331
+ type,
332
+ tag
333
+ });
334
+ } else {
335
+ display.setColor(type);
336
+ }
337
+ } // force track to render even if maxbpperpx limit hit...
338
+ else if (opt.startsWith('force:')) {
339
+ const [, force] = opt.split(':');
340
+
341
+ if (Boolean(force)) {
342
+ display.setUserBpPerPxLimit(Number.MAX_VALUE);
343
+ }
344
+ } // apply wiggle autoscale
345
+ else if (opt.startsWith('autoscale:')) {
346
+ const [, autoscale] = opt.split(':');
347
+ display.setAutoscale(autoscale);
348
+ } // apply min and max score to wiggle
349
+ else if (opt.startsWith('minmax:')) {
350
+ const [, min, max] = opt.split(':');
351
+ display.setMinScore(+min);
352
+ display.setMaxScore(+max);
353
+ } // apply linear or log scale to wiggle
354
+ else if (opt.startsWith('scaletype:')) {
355
+ const [, scaletype] = opt.split(':');
356
+ display.setScaleType(scaletype);
357
+ } // draw crosshatches on wiggle
358
+ else if (opt.startsWith('crosshatch:')) {
359
+ const [, val] = opt.split(':');
360
+ display.setCrossHatches((0, _util.booleanize)(val));
361
+ } // turn off fill on bigwig with fill:false
362
+ else if (opt.startsWith('fill:')) {
363
+ const [, val] = opt.split(':');
364
+ display.setFill((0, _util.booleanize)(val));
365
+ } // set resolution:superfine to use finer bigwig bin size
366
+ else if (opt.startsWith('resolution:')) {
367
+ let [, val] = opt.split(':');
368
+
369
+ if (val === 'fine') {
370
+ val = 10;
371
+ } else if (val === 'superfine') {
372
+ val = 100;
373
+ }
374
+
375
+ display.setResolution(val);
376
+ }
379
377
  });
380
378
  }
381
379
 
package/dist/util.js CHANGED
@@ -6,6 +6,6 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.booleanize = void 0;
7
7
 
8
8
  // nice helper function from https://stackoverflow.com/questions/263965/
9
- const booleanize = string => string === "false" ? false : !!string;
9
+ const booleanize = string => string === 'false' ? false : !!string;
10
10
 
11
11
  exports.booleanize = booleanize;
package/package.json CHANGED
@@ -1,17 +1,9 @@
1
1
  {
2
2
  "name": "@jbrowse/img",
3
- "version": "1.3.4",
3
+ "version": "1.5.2",
4
4
  "main": "index.js",
5
5
  "author": "JBrowse Team",
6
6
  "license": "Apache-2.0",
7
- "devDependencies": {
8
- "@babel/cli": "^7.12.17",
9
- "@babel/core": "^7.12.17",
10
- "@babel/plugin-transform-runtime": "^7.12.17",
11
- "@babel/preset-env": "^7.12.17",
12
- "@babel/preset-react": "^7.12.13",
13
- "jest": "^26.6.3"
14
- },
15
7
  "bin": {
16
8
  "jb2export": "./dist/bin.js"
17
9
  },
@@ -19,18 +11,23 @@
19
11
  "dist"
20
12
  ],
21
13
  "scripts": {
14
+ "pretest": "cd ../jbrowse-react-linear-genome-view; yarn build; cd ../jb2export",
22
15
  "test": "jest",
23
16
  "prebuild": "rm -rf dist",
24
17
  "build": "babel src -d dist",
25
18
  "preversion": "npm run build",
26
19
  "snap": "npm run build && node dist/index.js --config data/config.json --defaultSession --out out.svg",
27
20
  "snappng": "npm run build && node dist/index.js --config data/config.json --defaultSession --out out.png",
28
- "tiny": "npm run build && node dist/index.js --fasta data/volvox/volvox.fa --bam data/volvox/volvox-sorted.bam --loc ctgA:1-5000",
21
+ "snappdf": "npm run build && node dist/index.js --config data/config.json --defaultSession --out out.pdf",
22
+ "snapjpg": "npm run build && node dist/index.js --config data/config.json --defaultSession --out out.jpg",
23
+ "tiny": "npm run build && node dist/index.js --fasta data/volvox/volvox.fa --bam data/volvox/volvox-sorted.bam --loc ctgA:1-5000 --out tiny.svg",
29
24
  "tinypng": "npm run build && node dist/index.js --fasta data/volvox/volvox.fa --bam data/volvox/volvox-sorted.bam --loc ctgA:1-5000 --out out.png",
30
25
  "postversion": "git push --follow-tags"
31
26
  },
32
27
  "dependencies": {
33
- "@jbrowse/react-linear-genome-view": "^1.3.5",
28
+ "@jbrowse/plugin-linear-genome-view": "^1.5.2",
29
+ "@jbrowse/react-linear-genome-view": "^1.5.2",
30
+ "mobx": "^5.10.1",
34
31
  "react": "^17.0.1",
35
32
  "react-dom": "^17.0.1",
36
33
  "tmp": "^0.2.1",
@@ -38,5 +35,6 @@
38
35
  },
39
36
  "publishConfig": {
40
37
  "access": "public"
41
- }
38
+ },
39
+ "gitHead": "94fdfbc34787ab8f12a87e00038da74b247b42fa"
42
40
  }
@@ -1,91 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- var _renderRegion = require("./renderRegion");
6
-
7
- var _fs = _interopRequireDefault(require("fs"));
8
-
9
- function hashCode(str) {
10
- var hash = 0;
11
- let chr;
12
- if (str.length === 0) return hash;
13
-
14
- for (let i = 0; i < str.length; i++) {
15
- chr = str.charCodeAt(i);
16
- hash = (hash << 5) - hash + chr;
17
- hash |= 0; // Convert to 32bit integer
18
- }
19
-
20
- return hash;
21
- }
22
-
23
- const timeout = 20000;
24
- test("renders a region with --session and --config args", async () => {
25
- const result = await (0, _renderRegion.renderRegion)({
26
- session: "test/clingen_session.json",
27
- config: "data/config.json"
28
- });
29
-
30
- _fs.default.writeFileSync("test/svg_from_config_and_session_param.svg", result);
31
-
32
- expect(hashCode(result)).toMatchSnapshot();
33
- }, timeout);
34
- test("renders a region with --session, --tracks, and --assembly args", async () => {
35
- const result = await (0, _renderRegion.renderRegion)({
36
- session: "test/clingen_session.json",
37
- tracks: "data/tracks.json",
38
- assembly: "data/assembly.json"
39
- });
40
-
41
- _fs.default.writeFileSync("test/svg_from_separate_session_and_tracks.svg", result);
42
-
43
- expect(hashCode(result)).toMatchSnapshot();
44
- }, timeout);
45
- test("renders volvox with variety of args", async () => {
46
- console.error = jest.fn();
47
- const result = await (0, _renderRegion.renderRegion)({
48
- fasta: "data/volvox/volvox.fa",
49
- trackList: [["bam", ["data/volvox/volvox-sorted.bam"]], ["cram", ["data/volvox/volvox-sorted.cram"]], ["bigwig", ["data/volvox/volvox-sorted.bam.coverage.bw"]], ["vcfgz", ["data/volvox/volvox.filtered.vcf.gz"]], ["gffgz", ["data/volvox/volvox.sort.gff3.gz"]], ["bigbed", ["data/volvox/volvox.bb"]], ["bedgz", ["data/volvox/volvox-bed12.bed.gz"]]],
50
- loc: "ctgA:1000-2000"
51
- }); // can't do a snapshot test here, slightly inconsistent results(?)
52
-
53
- _fs.default.writeFileSync("test/svg_from_volvox_fasta_and_bam.svg", result);
54
-
55
- expect(result).toBeTruthy();
56
- }, timeout);
57
- test("configtracks arg with urls", async () => {
58
- const result = await (0, _renderRegion.renderRegion)({
59
- config: "data/config.json",
60
- trackList: [["configtracks", ["ncbi_refseq_109_hg38"]]],
61
- assembly: "GRCh38",
62
- loc: "chr1:50,000-60,000"
63
- }); // can't do a snapshot test here, slightly inconsistent results(?)
64
-
65
- _fs.default.writeFileSync("test/svg_configtracks_simple.svg", result);
66
-
67
- expect(result).toBeTruthy();
68
- }, timeout * 3);
69
- test("configtracks arg with local files", async () => {
70
- const result = await (0, _renderRegion.renderRegion)({
71
- config: "data/volvox/config.json",
72
- trackList: [["configtracks", ["volvox_sv"]]],
73
- assembly: "volvox",
74
- loc: "ctgA:1-50,000"
75
- }); // can't do a snapshot test here, slightly inconsistent results(?)
76
-
77
- _fs.default.writeFileSync("test/svg_configtracks_local.svg", result);
78
-
79
- expect(result).toBeTruthy();
80
- }, timeout * 3);
81
- xtest("renders --hic", async () => {
82
- const result = await (0, _renderRegion.renderRegion)({
83
- fasta: "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz",
84
- trackList: [["hic", ["https://s3.amazonaws.com/igv.broadinstitute.org/data/hic/intra_nofrag_30.hic"]]],
85
- loc: "1:2,000,000-10,000,000"
86
- });
87
-
88
- _fs.default.writeFileSync("test/svg_from_human_hic.svg", result);
89
-
90
- expect(result).toBeTruthy();
91
- }, 20000);
@@ -1,8 +0,0 @@
1
- "use strict";
2
-
3
- var _parseArgv = require("./parseArgv");
4
-
5
- test("parse", () => {
6
- const args = "--bam dad.bam color:red --vcf variants.vcf --bam mom.bam --defaultSession --out out.svg --noRasterize";
7
- expect((0, _parseArgv.parseArgv)(args.split(" "))).toEqual([["bam", ["dad.bam", "color:red"]], ["vcf", ["variants.vcf"]], ["bam", ["mom.bam"]], ["defaultSession", []], ["out", ["out.svg"]], ["noRasterize", []]]);
8
- });