Skip to content

Commit

Permalink
Flekschas/overlay tracks 1d and 2d (#524)
Browse files Browse the repository at this point in the history
* Remove commented out logs and add a warning for SVG export

* Prettify code style

* Allow setting fill opacity

* Enable 1d vertical overlays

* Determin orientation from track position to support overlays of combined tracks

* Added an example

* Add a simple base test for overlay tracks

* Extend base test

* Remove log
  • Loading branch information
flekschas authored and pkerpedjiev committed Jan 19, 2019
1 parent cdf7a38 commit 4cc7d20
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 27 deletions.
50 changes: 24 additions & 26 deletions app/scripts/OverlayTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,44 @@ class OverlayTrack extends PixiTrack {
draw() {
super.draw();
const graphics = this.pMain;
const fill = colorToHex(this.options.fillColor ? this.options.fillColor : 'blue');
const fill = colorToHex(
this.options.fillColor ? this.options.fillColor : 'blue'
);

graphics.clear();
graphics.beginFill(fill, 0.3);

// console.log('_xScale', this._xScale.range());
// console.log('this.dimensions:', this.dimensions);
graphics.beginFill(fill, this.options.fillOpacity || 0.3);

for (let i = 0; i < this.options.orientationsAndPositions.length; i++) {
const orientation = this.options.orientationsAndPositions[i].orientation;
const position = this.options.orientationsAndPositions[i].position;

/*
console.log('this.position:', this.position);
console.log('position.left:', position.left);
*/

if (orientation === '1d-horizontal') {
const xPos = this.position[0] + position.left
if (orientation === '1d-horizontal' || orientation === '2d') {
const xPos = this.position[0]
+ position.left
+ this._xScale(this.options.extent[0][0]);
const yPos = this.position[1] + position.top;
const height = position.height;
const width = this._xScale(this.options.extent[0][1])
- xPos + position.left + this.position[0];

/*
console.log('top:', yPos);
console.log('height:', position.height);
console.log('yPos:', yPos);
console.log('width:', width);
console.log('height:', height);
*/
- xPos
+ position.left
+ this.position[0];

graphics.drawRect(xPos, yPos, width, height);
}

/*
console.log('orientation:', orientation);
console.log('position:', position);
console.log('this.extent', this.extent);
*/
if (orientation === '1d-vertical' || orientation === '2d') {
const xPos = this.position[0] + position.left;
const yPos = this.position[1]
+ position.top
+ this._yScale(this.options.extent[0][0]);
const width = position.width;
const height = this._yScale(this.options.extent[0][1])
- yPos
+ position.top
+ this.position[1];

graphics.drawRect(xPos, yPos, width, height);
}
}
}

Expand All @@ -79,6 +76,7 @@ class OverlayTrack extends PixiTrack {

exportSVG() {
// TODO: implement me
console.warn('Overlay tracks cannot be exported as SVG yet.');
}
}

Expand Down
21 changes: 20 additions & 1 deletion app/scripts/TiledPlot.js
Original file line number Diff line number Diff line change
Expand Up @@ -967,11 +967,29 @@ class TiledPlot extends React.Component {
orientationsAndPositions: overlayTrack.includes.map((trackUuid) => {
// translate a trackUuid into that track's orientation
const includedTrack = getTrackByUid(this.props.tracks, trackUuid);
const trackPos = includedTrack.position;
if (!includedTrack) {
console.warn(`OverlayTrack included uid (${trackUuid}) not found in the track list`);
return null;
}
const orientation = TRACKS_INFO_BY_TYPE[includedTrack.type].orientation;

let orientation;
if (trackPos === 'top' || trackPos === 'bottom') {
orientation = '1d-horizontal';
}

if (trackPos === 'left' || trackPos === 'right') {
orientation = '1d-vertical';
}

if (trackPos === 'center') {
orientation = '2d';
}

if (!orientation) {
console.warn('Only top, bottom, left, right, or center tracks can be overlaid at the moment');
return null;
}

const positionedTrack = positionedTracks.filter(
track => track.track.uid === trackUuid
Expand All @@ -982,6 +1000,7 @@ class TiledPlot extends React.Component {
// an invalid uuid
return null;
}

const position = {
left: positionedTrack[0].left,
top: positionedTrack[0].top,
Expand Down
106 changes: 106 additions & 0 deletions docs/examples/viewconfs/overlay-tracks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
"editable": true,
"zoomFixed": false,
"trackSourceServers": ["http://higlass.io/api/v1"],
"exportViewUrl": "http://localhost:8000/api/v1/viewconfs/",
"views": [{
"uid": "aa",
"initialXDomain": [-128227010, 3227095876],
"initialYDomain": [-679063376, 3737688490],
"autocompleteSource": "http://higlass.io/api/v1/suggest/?d=OHJakQICQD6gTD7skx4EWA&",
"genomePositionSearchBoxVisible": false,
"chromInfoPath": "//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv",
"tracks": {
"top": [{
"server": "http://higlass.io/api/v1",
"tilesetUid": "OHJakQICQD6gTD7skx4EWA",
"uid": "genes-top",
"type": "horizontal-gene-annotations"
}, {
"chromInfoPath": "//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv",
"type": "horizontal-chromosome-labels",
"position": "top",
"uid": "chroms-top"
}],
"left": [{
"server": "http://higlass.io/api/v1",
"tilesetUid": "OHJakQICQD6gTD7skx4EWA",
"uid": "genes-left",
"type": "vertical-gene-annotations"
}, {
"chromInfoPath": "//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv",
"type": "vertical-chromosome-labels",
"position": "left",
"name": "Chromosome Labels (hg19)",
"uid": "chroms-left"
}],
"center": [{
"uid": "center",
"type": "combined",
"contents": [{
"data": {
"type": "divided",
"children": [{
"server": "http://higlass.io/api/v1",
"tilesetUid": "CQMd6V_cRw6iCI_-Unl3PQ"
}, {
"server": "http://higlass.io/api/v1",
"tilesetUid": "ZCvntCKST0KUvQPGcCbJGA"
}]
},
"type": "heatmap",
"position": "center",
"options": {
"colorRange": ["#FFFFFF", "#F8E71C", "#F5A623", "#D0021B"],
"colorbarPosition": "topRight",
"colorbarLabelsPosition": "outside",
"maxZoom": null,
"labelPosition": "bottomLeft",
"name": "Rao et al. (2014) GM12878 MboI (allreps) 1kb",
"trackBorderWidth": 0,
"trackBorderColor": "black",
"heatmapValueScaling": "log",
"scaleStartPercent": "0.00000",
"scaleEndPercent": "1.00000"
},
"uid": "heatmap",
"name": "Rao et al. (2014) GM12878 MboI (allreps) 1kb",
"transforms": [{
"name": "ICE",
"value": "weight"
}]
}, {
"type": "2d-chromosome-grid",
"chromInfoPath": "//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv",
"tilesetUid": "TIlwFtqxTX-ndtM7Y9k1bw",
"uid": "LUVqXXu2QYiO8XURIwyUyA",
"options": {
"lineStrokeWidth": 1,
"lineStrokeColor": "grey"
}
}]
}],
"right": [],
"bottom": []
},
"layout": {
"w": 12,
"h": 12,
"x": 0,
"y": 0,
"i": "aa",
"moved": false,
"static": false
},
"overlays": [{
"uid": "overlay",
"type": "",
"includes": ["chroms-top", "chroms-left", "genes-top", "genes-left", "center"],
"options": {
"extent": [
[1000000000, 1100000000]
]
}
}]
}]
}
66 changes: 66 additions & 0 deletions test/OverlayTrackTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* eslint-env node, jasmine */

// Utils
// import {
// getTrackObjectFromHGC,
// waitForTilesLoaded
// } from '../app/scripts/utils';

import createElementAndApi from './utils/create-element-and-api';
import removeDiv from './utils/remove-div';

import overlayAnnotations1d2dViewConf from './view-configs/overlay-annotations-1d-2d';

describe('Overlay Track:', () => {
let hgc = null;
let api = null;
let div = null;
let viewConf;

describe('Annotation overlays:', () => {
it('Should render', (done) => {
viewConf = overlayAnnotations1d2dViewConf;

[div, api] = createElementAndApi(viewConf, { bound: true });

hgc = api.getComponent();

const numNormalTracks = viewConf.views[0].tracks.top.length
+ viewConf.views[0].tracks.right.length
+ viewConf.views[0].tracks.bottom.length
+ viewConf.views[0].tracks.left.length
+ viewConf.views[0].tracks.center.length;

expect(numNormalTracks).toEqual(4);

const trackRenderer = hgc.tiledPlots[viewConf.views[0].uid]
.trackRenderer;

const posTracks = trackRenderer.props.positionedTracks;

expect(posTracks.length).toEqual(5);

const overlayTrack = posTracks[posTracks.length - 1];

expect(overlayTrack.track.type).toEqual('overlay-track');

const overlayTrackInfo = trackRenderer
.trackDefObjects[overlayTrack.track.uid];

const overlayTrackDef = overlayTrackInfo.trackDef;
const overlayTrackObj = overlayTrackInfo.trackObject;

expect(overlayTrackDef.width).toEqual(overlayTrackObj.dimensions[0]);
expect(overlayTrackDef.height).toEqual(overlayTrackObj.dimensions[1]);

done();
});

afterEach(() => {
if (api && api.destroy) api.destroy();
if (div) removeDiv(div);
api = undefined;
div = undefined;
});
});
});
63 changes: 63 additions & 0 deletions test/view-configs/overlay-annotations-1d-2d.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const viewConf = {
editable: false,
zoomFixed: false,
views: [{
uid: 'aa',
initialXDomain: [-128227010, 3227095876],
tracks: {
top: [
{
server: 'http://higlass.io/api/v1',
tilesetUid: 'OHJakQICQD6gTD7skx4EWA',
uid: 'genes-top',
type: 'horizontal-gene-annotations'
},
{
chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',
type: 'horizontal-chromosome-labels',
position: 'top',
uid: 'chroms-top'
}
],
left: [
{
server: 'http://higlass.io/api/v1',
tilesetUid: 'OHJakQICQD6gTD7skx4EWA',
uid: 'genes-left',
type: 'vertical-gene-annotations'
},
{
chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',
type: 'vertical-chromosome-labels',
position: 'left',
name: 'Chromosome Labels (hg19)',
uid: 'chroms-left'
}
],
center: [],
right: [],
bottom: []
},
layout: {
w: 12,
h: 12,
x: 0,
y: 0,
i: 'aa',
moved: false,
static: false
},
overlays: [{
uid: 'overlay',
type: '',
includes: ['chroms-top', 'chroms-left', 'genes-top', 'genes-left'],
options: {
extent: [
[1000000000, 1100000000]
]
}
}]
}]
};

export default viewConf;

0 comments on commit 4cc7d20

Please sign in to comment.