Skip to content

spatial layout #1138

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

Draft
wants to merge 14 commits into
base: v2
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
13 changes: 10 additions & 3 deletions demo/GoslingComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function GoslingComponent({ spec, width, height, urlToFetchOptions }: Gos
if (!pixiManager) {
const canvasWidth = 1000,
canvasHeight = 1000; // These initial sizes don't matter because the size will be updated
const pixiManager = new PixiManager(canvasWidth, canvasHeight, plotElement, () => {});
const pixiManager = new PixiManager(canvasWidth, canvasHeight, plotElement, () => { });
renderGosling(spec, plotElement, pixiManager, urlToFetchOptions);
setPixiManager(pixiManager);
} else {
Expand All @@ -37,6 +37,8 @@ export function GoslingComponent({ spec, width, height, urlToFetchOptions }: Gos

return <div id="plot" style={{ height: '100%' }}></div>;
}

const baseTheme = getTheme('light');
/**
* This is the main function. It takes a Gosling spec and renders it using the PixiManager
*/
Expand All @@ -47,7 +49,12 @@ function renderGosling(
urlToFetchOptions?: UrlToFetchOptions
) {
// 1. Compile the spec
const compileResult = compile(gs, [], getTheme('light'), { containerSize: { width: 0, height: 0 } });
const compileResult = compile(
gs,
[],
{ ...baseTheme, axis: { ...baseTheme.axis, labelExcludeChrPrefix: true, labelMargin: 1 } },
{ containerSize: { width: 0, height: 0 } }
);
const { trackInfos, gs: processedSpec, theme } = compileResult;
console.warn('Spec', processedSpec);
// 2. Extract all of the linking information from the spec
Expand Down Expand Up @@ -93,7 +100,7 @@ function renderGosling(
/** Debounces the resize observer */
function debounce(f: (arg0: unknown) => unknown, delay: number) {
let timer = 0;
return function (...args: [arg0: unknown]) {
return function(...args: [arg0: unknown]) {
clearTimeout(timer);
timer = setTimeout(() => f.apply(this, args), delay);
};
Expand Down
3 changes: 3 additions & 0 deletions demo/renderer/dataFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import type { UrlToFetchOptions } from 'src/compiler/compile';
export function getDataFetcher(spec: ProcessedTrack, urlToFetchOptions?: UrlToFetchOptions) {
if (!('data' in spec)) {
console.warn('No data in the track spec', spec);
// A data object can be missing in 3D tracks. In this case, just pass an empty data.
// The 3d track can still use the 3D genome model for visual encoding.
return new JsonDataFetcher({ type: 'json', values: [], assembly: spec.assembly });
}

const urlFetchOptions = ('url' in spec.data && urlToFetchOptions?.[spec.data.url]) || {};
Expand Down
17 changes: 17 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 type { UrlToFetchOptions } from 'src/compiler/compile';
import { createSpatialTrack } from '../../src/tracks/spatial-track/spatial-track';
import type { CsvDataFetcherClass } from 'src/data-fetchers/csv/csv-data-fetcher';

/**
* Takes a list of track definitions and linkedEncodings and renders them
Expand Down Expand Up @@ -109,6 +111,21 @@ export function renderTrackDefs(
if (type === TrackType.Dummy) {
new DummyTrack(options, pixiManager.makeContainer(boundingBox).overlayDiv);
}
// Add a new track type for Chromospace
if (type === TrackType.Spatial) {
// 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;
console.log('!@$!#%@#');
console.log(options.spec);
if (options.spec.data) {
// Ensure to pull all data needed
options.spec.data.sampleLength = 30000;
}
const datafetcher = getDataFetcher(options.spec, urlToFetchOptions);
createSpatialTrack(options, datafetcher as CsvDataFetcherClass, container);
}
});
}

Expand Down
4 changes: 2 additions & 2 deletions demo/track-def/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function getAxisTrackLinearOptions(
startAngle: 0,
endAngle: 0,
layout: 'linear',
assembly: 'hg38',
assembly: track.assembly ?? 'hg38',
stroke: 'transparent', // text outline
color: theme.axis.labelColor,
labelMargin: theme.axis.labelMargin,
Expand Down Expand Up @@ -165,7 +165,7 @@ function getAxisTrackCircularOptions(
height: boundingBox.height,
startAngle,
endAngle,
assembly: 'hg38',
assembly: track.assembly,
stroke: 'transparent', // text outline
color: theme.axis.labelColor,
labelMargin: theme.axis.labelMargin,
Expand Down
21 changes: 20 additions & 1 deletion demo/track-def/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { type BrushLinearTrackOptions } from '@gosling-lang/brush-linear';
import type { TrackInfo } from '../../src/compiler/bounding-box';
import type { CompleteThemeDeep } from '../../src/core/utils/theme';
import type { GoslingTrackOptions } from '../../src/tracks/gosling-track/gosling-track';
import type { SpatialTrackOptions } from 'src/tracks/spatial-track/spatial-track';

import { proccessTextHeader } from './text';
import { processHeatmapTrack, isHeatmapTrack } from './heatmap';
Expand All @@ -25,9 +26,11 @@ export enum TrackType {
Axis,
BrushLinear,
BrushCircular,
Heatmap
Heatmap,
Spatial
}


/**
* Associate options to each track type
*/
Expand All @@ -39,6 +42,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 +87,21 @@ export function createTrackDefs(trackInfos: TrackInfo[], theme: Required<Complet
// We have a dummy track
const dummyTrackDefs = processDummyTrack(track, boundingBox);
trackDefs.push(...dummyTrackDefs);
} else if ('layout' in track && track.layout === 'spatial') {
// We have a 3D track
console.warn('got 3D track', track);
const trackDef: TrackDef<SpatialTrackOptions> = {
type: TrackType.Spatial,
trackId: track.id,
boundingBox,
options: {
spec: track,
color: track.color ? track.color.value : undefined,
test: track.test,
data3D: track.data3D,
}
};
trackDefs.push(trackDef);
} else {
// We have a gosling track
const goslingAxisDefs = processGoslingTrack(track, boundingBox, theme);
Expand Down
8 changes: 7 additions & 1 deletion demo/track-def/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { DataDeep, Assembly, DummyTrackStyle, Mark, X, Y } from '@gosling-l
*/

/** A Track after it has been compiled */
export type ProcessedTrack = ProcessedLinearTrack | ProcessedCircularTrack | ProcessedDummyTrack;
export type ProcessedTrack = ProcessedLinearTrack | ProcessedCircularTrack | ProcessedDummyTrack | ProcessedSpatialTrack;
/** All tracks potentially have these properties */
export interface ProcessedTrackBase {
id: string;
Expand Down Expand Up @@ -49,6 +49,12 @@ export type ProcessedCircularTrack = ProcessedTrackBase & {
innerRadius: number;
};

export type ProcessedSpatialTrack = ProcessedTrackBase & {
layout: 'spatial';
test: string;
data3D: string;
};

export type ProcessedDummyTrack = ProcessedTrackBase & {
type?: string;
style?: DummyTrackStyle;
Expand Down
Loading
Loading