• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eweitz / ideogram / 2118

pending completion
2118

push

travis-ci-com

eweitz
Consolidate Gene Hints into Gene Leads

1766 of 2271 branches covered (77.76%)

Branch coverage included in aggregate %.

6 of 6 new or added lines in 2 files covered. (100.0%)

4626 of 5173 relevant lines covered (89.43%)

34820.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.56
/src/js/ideogram.js
1
/**
2
 * @fileoverview Core module of Ideogram.js, links all other modules
3
 * This file defines the Ideogram class, its constructor method, and its
4
 * static methods.  All instance methods are defined in other modules.
5
 *
6
 */
7

8
import version from './version';
9

10
import {
11
  configure, initDrawChromosomes, handleRotateOnClick, onLoad,
12
  init, finishInit, writeContainer
13
} from './init/init';
14

15
import {
16
  onLoadAnnots, onDrawAnnots, processAnnotData, restoreDefaultTracks,
17
  updateDisplayedTracks, initAnnotSettings, fetchAnnots, drawAnnots,
18
  getHistogramBars, drawHeatmaps, deserializeAnnotsForHeatmap, fillAnnots,
19
  drawProcessedAnnots, drawSynteny, startHideAnnotTooltipTimeout,
20
  showAnnotTooltip, onWillShowAnnotTooltip, onDidShowAnnotTooltip,
21
  setOriginalTrackIndexes,
22
  afterRawAnnots, onClickAnnot, downloadAnnotations, addAnnotLabel,
23
  removeAnnotLabel, fillAnnotLabels, clearAnnotLabels, flattenAnnots
24
  // fadeOutAnnotLabels
25
} from './annotations/annotations';
26

27
import {highlight, unhighlight} from './annotations/highlight';
28

29
import {
30
  esearch, esummary, elink,
31
  getOrganismFromEutils, getTaxids,
32
  getAssemblyAndChromosomesFromEutils
33
} from './services/services';
34

35
import {
36
  drawBandLabels, getBandColorGradients, processBandData,
37
  setBandsToShow, hideUnshownBandLabels, drawBandLabelText, drawBandLabelStalk
38
} from './bands/bands';
39

40
import {onBrushMove, onBrushEnd, createBrush} from './brush';
41
import {onCursorMove, createClickCursor} from './cursor';
42
import {drawSexChromosomes, setSexChromosomes} from './sex-chromosomes';
43
import {convertBpToPx, convertPxToBp} from './coordinate-converters';
44
import {
45
  unpackAnnots, packAnnots, initCrossFilter, filterAnnots
46
} from './filter';
47

48
import {
49
  assemblyIsAccession, getDataDir, round, onDidRotate, getSvg, d3,
50
  getTaxid, getCommonName, getScientificName, fetch as _fetch,
51
  isRoman, parseRoman
52
} from './lib';
53

54
import {
55
  getChromosomeModel, getChromosomePixels
56
} from './views/chromosome-model';
57

58
import {
59
  appendHomolog, drawChromosome, rotateAndToggleDisplay, setOverflowScroll
60
} from './views/draw-chromosomes';
61

62
import {
63
  drawChromosomeLabels, rotateChromosomeLabels
64
} from './views/chromosome-labels.js';
65

66
import {
67
  _initGeneLeads, _initRelatedGenes,
68
  plotRelatedGenes, getRelatedGenesByType
69
} from './kit/related-genes';
70

71
export default class Ideogram {
72
  constructor(config) {
73

74
    // Functions from init.js
75
    this.configure = configure;
84✔
76
    this.initDrawChromosomes = initDrawChromosomes;
84✔
77
    this.onLoad = onLoad;
84✔
78
    this.handleRotateOnClick = handleRotateOnClick;
84✔
79
    this.init = init;
84✔
80
    this.finishInit = finishInit;
84✔
81
    this.writeContainer = writeContainer;
84✔
82

83
    // Functions from annotations.js
84
    this.onLoadAnnots = onLoadAnnots;
84✔
85
    this.onDrawAnnots = onDrawAnnots;
84✔
86
    this.processAnnotData = processAnnotData;
84✔
87
    this.restoreDefaultTracks = restoreDefaultTracks;
84✔
88
    this.updateDisplayedTracks = updateDisplayedTracks;
84✔
89
    this.initAnnotSettings = initAnnotSettings;
84✔
90
    this.fetchAnnots = fetchAnnots;
84✔
91
    this.drawAnnots = drawAnnots;
84✔
92
    this.getHistogramBars = getHistogramBars;
84✔
93
    this.drawHeatmaps = drawHeatmaps;
84✔
94
    this.deserializeAnnotsForHeatmap = deserializeAnnotsForHeatmap;
84✔
95
    this.fillAnnots = fillAnnots;
84✔
96
    this.drawProcessedAnnots = drawProcessedAnnots;
84✔
97
    this.drawSynteny = drawSynteny;
84✔
98
    this.startHideAnnotTooltipTimeout = startHideAnnotTooltipTimeout;
84✔
99
    this.showAnnotTooltip = showAnnotTooltip;
84✔
100
    this.onWillShowAnnotTooltip = onWillShowAnnotTooltip;
84✔
101
    this.onDidShowAnnotTooltip = onDidShowAnnotTooltip;
84✔
102
    this.onClickAnnot = onClickAnnot;
84✔
103
    this.setOriginalTrackIndexes = setOriginalTrackIndexes;
84✔
104
    this.afterRawAnnots = afterRawAnnots;
84✔
105
    this.downloadAnnotations = downloadAnnotations;
84✔
106
    this.addAnnotLabel = addAnnotLabel;
84✔
107
    this.removeAnnotLabel = removeAnnotLabel;
84✔
108
    // this.fadeOutAnnotLabels = fadeOutAnnotLabels;
109
    this.fillAnnotLabels = fillAnnotLabels;
84✔
110
    this.clearAnnotLabels = clearAnnotLabels;
84✔
111
    this.flattenAnnots = flattenAnnots;
84✔
112

113
    this.highlight = highlight;
84✔
114
    this.unhighlight = unhighlight;
84✔
115

116
    // Variables and functions from services.js
117
    this.esearch = esearch;
84✔
118
    this.esummary = esummary;
84✔
119
    this.elink = elink;
84✔
120
    this.getOrganismFromEutils = getOrganismFromEutils;
84✔
121
    this.getTaxids = getTaxids;
84✔
122
    this.getAssemblyAndChromosomesFromEutils =
84✔
123
      getAssemblyAndChromosomesFromEutils;
124

125
    // Functions from bands.js
126
    this.drawBandLabels = drawBandLabels;
84✔
127
    this.getBandColorGradients = getBandColorGradients;
84✔
128
    this.processBandData = processBandData;
84✔
129
    this.setBandsToShow = setBandsToShow;
84✔
130
    this.hideUnshownBandLabels = hideUnshownBandLabels;
84✔
131
    this.drawBandLabelText = drawBandLabelText;
84✔
132
    this.drawBandLabelStalk = drawBandLabelStalk;
84✔
133

134
    // Functions from brush.js
135
    this.onBrushMove = onBrushMove;
84✔
136
    this.onBrushEnd = onBrushEnd;
84✔
137
    this.createBrush = createBrush;
84✔
138

139
    // Functions from cursor.js
140
    this.createClickCursor = createClickCursor;
84✔
141
    this.onCursorMove = onCursorMove;
84✔
142

143
    // Functions from sex-chromosomes.js
144
    this.drawSexChromosomes = drawSexChromosomes;
84✔
145
    this.setSexChromosomes = setSexChromosomes;
84✔
146

147
    // Functions from coordinate-converters.js
148
    this.convertBpToPx = convertBpToPx;
84✔
149
    this.convertPxToBp = convertPxToBp;
84✔
150

151
    // Functions from filter.js
152
    this.unpackAnnots = unpackAnnots;
84✔
153
    this.packAnnots = packAnnots;
84✔
154
    this.initCrossFilter = initCrossFilter;
84✔
155
    this.filterAnnots = filterAnnots;
84✔
156

157
    // Functions from lib
158
    this.assemblyIsAccession = assemblyIsAccession;
84✔
159
    this.getDataDir = getDataDir;
84✔
160
    this.round = round;
84✔
161
    this.onDidRotate = onDidRotate;
84✔
162
    this.getSvg = getSvg;
84✔
163
    this.fetch = _fetch;
84✔
164
    this.getTaxid = getTaxid;
84✔
165
    this.getCommonName = getCommonName;
84✔
166
    this.getScientificName = getScientificName;
84✔
167

168
    // Functions from views/chromosome-model.js
169
    this.getChromosomeModel = getChromosomeModel;
84✔
170
    this.getChromosomePixels = getChromosomePixels;
84✔
171

172
    // Functions from views/chromosome-labels.js
173
    this.drawChromosomeLabels = drawChromosomeLabels;
84✔
174
    this.rotateChromosomeLabels = rotateChromosomeLabels;
84✔
175

176
    // Functions from views/draw-chromosomes.js
177
    this.appendHomolog = appendHomolog;
84✔
178
    this.drawChromosome = drawChromosome;
84✔
179
    this.rotateAndToggleDisplay = rotateAndToggleDisplay;
84✔
180
    this.setOverflowScroll = setOverflowScroll;
84✔
181

182
    this.plotRelatedGenes = plotRelatedGenes;
84✔
183
    this.getRelatedGenesByType = getRelatedGenesByType;
84✔
184

185
    this.configure(config);
84✔
186
  }
187

188
  /**
189
   * Get the current version of Ideogram.js
190
   */
191
  static get version() {
192
    return version;
15✔
193
  }
194

195
  /**
196
  * Enable use of D3 in client apps, via "d3 = Ideogram.d3"
197
  */
198
  static get d3() {
199
    return d3;
17✔
200
  }
201

202
  /**
203
   * Request data from Ensembl REST API
204
   * Docs: https://rest.ensembl.org/
205
   *
206
   * @param {String} path URL path
207
   * @param {Object} body POST body
208
   * @param {String} method HTTP method; 'GET' (default) or 'POST'
209
   */
210
  static async fetchEnsembl(path, body = null, method = 'GET') {
×
211
    const init = {
×
212
      method: method
213
    };
214
    if (body !== null) init.body = JSON.stringify(body);
×
215
    if (method === 'GET') {
×
216
      // Use HTTP parameter, not header, to avoid needless OPTIONS request
217
      const delimiter = path.includes('&') ? '&' : '?';
×
218
      path += delimiter + 'content-type=application/json';
×
219
    } else {
220
      // Method is POST, so content-type must be defined in header
221
      init.headers = {'Content-Type': 'application/json'};
×
222
    }
223

224
    // const random = Math.random();
225
    // console.log(random)
226
    // if (random < 0.5) {
227
    const response = await fetch(`https://rest.ensembl.org${path}`, init);
×
228
    const json = await response.json();
×
229
    return json;
×
230
    // } else {
231
    //   // Mock error
232
    //   init.headers = {'Content-Type': 'application/json'};
233
    //   const response = await fetch('https://httpstat.us/500/cors', init);
234
    //   const json = await response.json();
235
    //   return json;
236
    // }
237
  }
238

239
  /**
240
   * Helper for sortChromosomes().
241
   * Gets names and biological types for diverse chromosome variables
242
   */
243
  static getChrSortNamesAndTypes(a, b) {
244
    var chrAName, chrBName,
245
      aIsCP, bIsCP, aIsMT, bIsMT, aIsAP, bIsAP, aIsNuclear, bIsNuclear;
246

247
    if (typeof a === 'string' || 'chr' in a && 'annots' in a) {
4,235✔
248
      // Chromosome data is from either:
249
      //    - Ideogram static file cache (e.g. homo-sapiens.json)
250
      //    - Ideogram raw annotations
251
      chrAName = (typeof a === 'string') ? a : a.chr;
4,066✔
252
      chrBName = (typeof b === 'string') ? b : b.chr;
4,066✔
253

254
      aIsCP = chrAName === 'CP';
4,066✔
255
      bIsCP = chrBName === 'CP';
4,066✔
256
      aIsMT = chrAName === 'MT';
4,066✔
257
      bIsMT = chrBName === 'MT';
4,066✔
258
      aIsAP = chrAName === 'AP';
4,066✔
259
      bIsAP = chrBName === 'AP';
4,066✔
260
      aIsNuclear = (!aIsCP && !aIsMT && !aIsAP);
4,066✔
261
      bIsNuclear = (!bIsCP && !bIsMT && !bIsAP);
4,066✔
262
    } else {
263
      // Chromosome data is from NCBI E-Utils web API
264
      chrAName = a.name;
169✔
265
      chrBName = b.name;
169✔
266

267
      aIsCP = a.type === 'chloroplast';
169✔
268
      bIsCP = b.type === 'chloroplast';
169✔
269
      aIsMT = a.type === 'mitochondrion';
169✔
270
      bIsMT = b.type === 'mitochondrion';
169✔
271
      aIsAP = a.type === 'apicoplast';
169✔
272
      bIsAP = b.type === 'apicoplast';
169✔
273
      aIsNuclear = a.type === 'nuclear';
169✔
274
      bIsNuclear = b.type === 'nuclear';
169✔
275
    }
276

277
    const chrTypes = {
4,235✔
278
      aIsNuclear, bIsNuclear, aIsCP, bIsCP, aIsMT, bIsMT, aIsAP, bIsAP
279
    };
280

281
    return [chrAName, chrBName, chrTypes];
4,235✔
282
  }
283

284
  /**
285
   * Sorts two chromosome objects by type and name
286
   * - Nuclear chromosomes come before non-nuclear chromosomes.
287
   * - Among nuclear chromosomes, use "natural sorting", e.g.
288
   *   numbers come before letters
289
   * - Among non-nuclear chromosomes, i.e. "MT" (mitochondrial DNA) and
290
   *   "CP" (chromoplast DNA), MT comes first
291
   *
292
   * @param a Chromosome string or object "A"
293
   * @param b Chromosome string or object "B"
294
   * @returns {Number} JavaScript sort order indicator
295
   */
296
  static sortChromosomes(a, b) {
297

298
    let [chrAName, chrBName, chrTypes] =
299
      Ideogram.getChrSortNamesAndTypes(a, b);
4,235✔
300

301
    const {
302
      aIsNuclear, bIsNuclear, aIsCP, bIsCP, aIsMT, bIsMT, aIsAP, bIsAP
303
    } = chrTypes;
4,235✔
304

305
    if (aIsNuclear && bIsNuclear) {
4,235✔
306

307
      if (isRoman(chrAName) && isRoman(chrBName)) {
4,178✔
308
        // As in yeast genome
309
        chrAName = parseRoman(chrAName).toString();
92✔
310
        chrBName = parseRoman(chrBName).toString();
92✔
311
      }
312

313
      return chrAName.localeCompare(chrBName, 'en', {numeric: true});
4,178✔
314
    } else if (!aIsNuclear && bIsNuclear) {
57✔
315
      return 1;
7✔
316
    } else if (aIsMT && bIsCP) {
50!
317
      return 1;
×
318
    } else if (aIsCP && bIsMT) {
50!
319
      return -1;
×
320
    } else if (!aIsAP && !aIsMT && !aIsCP && (bIsMT || bIsCP || bIsAP)) {
50✔
321
      return -1;
49✔
322
    }
323
  }
324

325
  /**
326
   * Wrapper for Ideogram constructor, with generic "Related genes" options
327
   *
328
   * @param {Object} config Ideogram configuration object
329
   */
330
  static initRelatedGenes(config, annotsInList='all') {
11✔
331
    return _initRelatedGenes(config, annotsInList);
11✔
332
  }
333

334

335
  /**
336
   * Wrapper for Ideogram constructor, with generic "Gene leads" options
337
   *
338
   * @param {Object} config Ideogram configuration object
339
  */
340
  static initGeneLeads(config, annotsInList='all') {
×
341
    return _initGeneLeads(config, annotsInList);
×
342
  }
343
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc