Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spatial layout #1101

Draft
wants to merge 8 commits into
base: higlassless
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions demo/renderer/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { HeatmapTrack } from '@gosling-lang/heatmap';
import type { PixiManager } from '@pixi-manager';
import { DummyTrack } from '@gosling-lang/dummy-track';

import * as chs from 'chromospace';

/**
* Takes a list of track definitions and linkedEncodings and renders them
* @param trackOptions
Expand Down Expand Up @@ -103,6 +105,44 @@ export function renderTrackDefs(trackDefs: TrackDefs[], linkedEncodings: LinkedE
if (type === TrackType.Dummy) {
new DummyTrack(options, pixiManager.makeContainer(boundingBox).overlayDiv);
}
// Add a new track type for Chromospace
if (type === TrackType.Spatial) {
const color = options.color;
const viewConfig = {
scale: 0.01,
color: color,
//color: "purple"
};
let chromatinScene = chs.initScene();
//~ https://chspace.xyz/?source=https://raw.githubusercontent.com/dvdkouril/chromospace-sample-data/refs/heads/main/dros.3.arrow
// https://pub-5c3f8ce35c924114a178c6e929fc3ac7.r2.dev/Tan-2018_GSM3271353_gm12878_07.arrow
const s = chs.loadFromURL("https://pub-5c3f8ce35c924114a178c6e929fc3ac7.r2.dev/Tan-2018_GSM3271353_gm12878_07.arrow", { center: true, normalize: true });
//const s = chs.loadFromURL("https://raw.githubusercontent.com/dvdkouril/chromospace-sample-data/refs/heads/main/dros.3.arrow", { center: true, normalize: true });
s.then(result => {

if (!result) {
console.warn("error loading remote file");
return;
}

const isModel = "parts" in result; //~ ChromatinModel has .parts
if (isModel) {
chromatinScene = chs.addModelToScene(chromatinScene, result, viewConfig);
} else {
chromatinScene = chs.addChunkToScene(chromatinScene, result, viewConfig);
}
const [_, canvas] = chs.display(chromatinScene, { alwaysRedraw: false });

// Even though Chromospace doesn't use PixiJS, we can use the PixiManager to create a div container that the canvas can be placed into.
// In the final version, we would probably want Chromospace to use an existing canvas element (to limit the creation of new elements).
// But for now this gets the job done.
const container = pixiManager.makeContainer(boundingBox).overlayDiv;
container.appendChild(canvas);
}).catch(error => {
console.log(error);
});

}
});
}

Expand Down
22 changes: 21 additions & 1 deletion demo/track-def/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ export enum TrackType {
Axis,
BrushLinear,
BrushCircular,
Heatmap
Heatmap,
Spatial
}


type SpatialTrackOptions = {
color: string | undefined;
};

/**
* Associate options to each track type
*/
Expand All @@ -39,6 +45,7 @@ interface TrackOptionsMap {
[TrackType.BrushLinear]: BrushLinearTrackOptions;
[TrackType.BrushCircular]: BrushCircularTrackOptions;
[TrackType.Heatmap]: HeatmapTrackOptions;
[TrackType.Spatial]: SpatialTrackOptions; //~ TODO: add actual options
}

/**
Expand Down Expand Up @@ -83,6 +90,19 @@ export function createTrackDefs(trackInfos: TrackInfo[], theme: Required<Complet
// We have a dummy track
const dummyTrackDefs = processDummyTrack(track, boundingBox);
trackDefs.push(...dummyTrackDefs);
} else if ('type' in track && track.type === '3D') {
// We have a 3D track
console.warn('got 3D track', track);
//const trackDef: TrackDef<Record<string, never>> = {
const trackDef: TrackDef<SpatialTrackOptions> = {
type: TrackType.Spatial,
trackId: track.id,
boundingBox,
options: {
color: track.color ? track.color.value : undefined,
}
};
trackDefs.push(trackDef);
} else {
// We have a gosling track
const goslingAxisDefs = processGoslingTrack(track, boundingBox, theme);
Expand Down
87 changes: 87 additions & 0 deletions docs/spatial-layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# 3D chromatin structures in Gosling

The purpose of this file is to document the changes in the specification and
gosling.js to support visualizing 3D structures of chromatin. It should be
merged in the main documentation at some point.

Minimal specification using 3D data:

```javascript
const spec = {
views: [{
layout: "spatial",
tracks: [
{
data: {
url: "https://...",
},
},
],
}]
}
```

## Features

### Specifying visual channels
```javascript
{
/* ... */
views: [{
layout: "spatial",
tracks: [
{
data: {
url: "https://...",
},
color: {
value: "#ff00ff"
},
scale: {
value: 0.01
}
},
],
}]
}
```

### Composing multiple tracks within a spatial view

To create more complex visualizations, we can compose several tracks within a
single view. Then each track can have different visual encodings, filtering,
etc., that will be composed (overlaid) within a single view

```javascript
{
/* ... */
views: [{
layout: "spatial",
tracks: [
{ // track 1
data: {
url: "https://...",
},
color: {
value: "#ff00ff"
},
scale: {
value: 0.01
}
filter: "chr1", //~ select only part to show
},
{ // track 2
data: {
url: "https://...",
},
color: {
value: "#333333"
},
scale: {
value: 0.001
}
},
],
}]
}
```
6 changes: 6 additions & 0 deletions editor/example/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,12 @@ export const editorExampleObj: {
spec: JsonExampleSpecs.EX_SPEC_PERF_ALIGNMENT,
image: THUMBNAILS.PERF_ALIGNMENT
},
SPATIAL_LAYOUT: {
group: 'Experimental',
name: 'Spatial Layout: Integrating spatial models of chromatin',
spec: JsonExampleSpecs.EX_SPEC_SPATIAL,
image: THUMBNAILS.SPATIAL_DRAFT
},
CORCES_ET_AL: {
group: 'Coordinated Multiple Views',
name: 'Corces et al. 2020',
Expand Down
4 changes: 3 additions & 1 deletion editor/example/json-spec/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { EX_SPEC_TEMPLATE } from './track-template';
import { EX_SPEC_MOUSE_EVENT } from './mouse-event';
import { EX_SPEC_PERF_ALIGNMENT } from './perf-alignment';
import { EX_SPEC_DEBUG } from './debug';
import { EX_SPEC_SPATIAL } from './spatial-layout';

export const JsonExampleSpecs = {
EX_SPEC_LAYOUT_AND_ARRANGEMENT_1,
Expand Down Expand Up @@ -59,5 +60,6 @@ export const JsonExampleSpecs = {
EX_SPEC_PILEUP,
EX_SPEC_TEMPLATE,
EX_SPEC_MOUSE_EVENT,
EX_SPEC_DEBUG
EX_SPEC_DEBUG,
EX_SPEC_SPATIAL,
};
104 changes: 104 additions & 0 deletions editor/example/json-spec/spatial-layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import type { GoslingSpec } from '@gosling-lang/gosling-schema';
import { GOSLING_PUBLIC_DATA } from './gosling-data';

export const EX_SPEC_SPATIAL: GoslingSpec = {
title: 'Spatial Layout',
subtitle: 'Example of spatial chromatin data integration',
arrangement: 'vertical',
centerRadius: 0.4,
views: [
{
spacing: 40,
arrangement: 'horizontal',
views: [
//{
// spacing: 5,
// static: true,
// layout: 'circular',
// xDomain: { chromosome: 'chr1' },
// alignment: 'overlay',
// tracks: [
// { mark: 'bar' },
// {
// mark: 'brush',
// x: { linkingId: 'detail' }
// }
// ],
// data: {
// url: GOSLING_PUBLIC_DATA.multivec,
// type: 'multivec',
// row: 'sample',
// column: 'position',
// value: 'peak',
// categories: ['sample 1', 'sample 2', 'sample 3', 'sample 4']
// },
// x: { field: 'start', type: 'genomic' },
// xe: { field: 'end', type: 'genomic' },
// y: { field: 'peak', type: 'quantitative' },
// row: { field: 'sample', type: 'nominal' },
// color: { field: 'sample', type: 'nominal' },
// width: 250,
// height: 130
//},
{
tracks: [{ type: "3D", width: 250, height: 250 }],
},
{
layout: 'linear',
xDomain: { chromosome: 'chr1' },
alignment: 'overlay',
tracks: [
{ mark: 'bar' },
{
mark: 'brush',
x: { linkingId: 'detail' }
}
],
data: {
url: GOSLING_PUBLIC_DATA.multivec,
type: 'multivec',
row: 'sample',
column: 'position',
value: 'peak',
categories: ['sample 1', 'sample 2', 'sample 3', 'sample 4']
},
x: { field: 'start', type: 'genomic' },
xe: { field: 'end', type: 'genomic' },
y: { field: 'peak', type: 'quantitative' },
row: { field: 'sample', type: 'nominal' },
color: { field: 'sample', type: 'nominal' },
width: 400,
height: 200
}
]
},
{
layout: 'linear',
xDomain: { chromosome: 'chr1', interval: [160000000, 200000000] },
linkingId: 'detail',
tracks: [
{
data: {
url: GOSLING_PUBLIC_DATA.multivec,
type: 'multivec',
row: 'sample',
column: 'position',
value: 'peak',
categories: ['sample 1', 'sample 2', 'sample 3', 'sample 4']
},
mark: 'bar',
x: {
field: 'position',
type: 'genomic',
axis: 'top'
},
y: { field: 'peak', type: 'quantitative' },
row: { field: 'sample', type: 'nominal' },
color: { field: 'sample', type: 'nominal' },
width: 690,
height: 200
}
]
}
]
};
4 changes: 3 additions & 1 deletion editor/example/thumbnails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import TEMPLATE from './thumbnails/TEMPLATE.png';
import VISUAL_ENCODING from './thumbnails/VISUAL_ENCODING.png';
import VISUAL_ENCODING_CIRCULAR from './thumbnails/VISUAL_ENCODING_CIRCULAR.png';
import ISLANDVIEWER from './thumbnails/ISLANDVIEWER.png';
import SPATIAL_DRAFT from './thumbnails/SPATIAL.png';

export const THUMBNAILS = {
ALIGNMENT,
Expand Down Expand Up @@ -63,5 +64,6 @@ export const THUMBNAILS = {
TEMPLATE,
VISUAL_ENCODING,
VISUAL_ENCODING_CIRCULAR,
ISLANDVIEWER
ISLANDVIEWER,
SPATIAL_DRAFT,
};
Binary file added editor/example/thumbnails/SPATIAL.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"allotment": "^1.19.0",
"bezier-js": "4.0.3",
"buffer": "^6.0.3",
"chromospace": "^0.1.3",
"css-element-queries": "^1.2.3",
"d3-array": "^3.2.4",
"d3-brush": "^3.0.0",
Expand Down
Loading
Loading