From 244094843df50669f85e5d09d6d8b519c4fa3011 Mon Sep 17 00:00:00 2001 From: etowahadams Date: Wed, 12 Jun 2024 17:12:58 -0400 Subject: [PATCH] feat(core): remove DataTrack from schema and compiler (#1074) * feat: remove DataTrack from schema * feat: remove data track from compiler * feat: update schema * feat: remove overrideTemplate * feat: remove tests * fix(core): remove `"template"` key from template track after processing (#1079) fix(core): remove 'template' key from a trample track after spec processing --------- Co-authored-by: SEHI L'YI --- src/compiler/compile.ts | 5 +- src/compiler/spec-preprocess.test.ts | 32 +--- src/compiler/spec-preprocess.ts | 106 ----------- src/core/utils/overlay.ts | 12 +- src/core/utils/template.ts | 4 + src/gosling-schema/gosling.schema.guards.ts | 9 - src/gosling-schema/gosling.schema.json | 197 -------------------- src/gosling-schema/gosling.schema.ts | 10 +- src/gosling-schema/template.schema.json | 3 - 9 files changed, 16 insertions(+), 362 deletions(-) diff --git a/src/compiler/compile.ts b/src/compiler/compile.ts index 45b46ab0..f34c92cf 100644 --- a/src/compiler/compile.ts +++ b/src/compiler/compile.ts @@ -1,6 +1,6 @@ import type { GoslingSpec, TemplateTrackDef, VisUnitApiData } from '@gosling-lang/gosling-schema'; import type { HiGlassSpec } from '@gosling-lang/higlass-schema'; -import { traverseToFixSpecDownstream, overrideDataTemplates } from './spec-preprocess'; +import { traverseToFixSpecDownstream } from './spec-preprocess'; import { replaceTrackTemplates } from '../core/utils/template'; import { getRelativeTrackInfo, type Size } from './bounding-box'; import type { CompleteThemeDeep } from '../core/utils/theme'; @@ -32,9 +32,6 @@ export function compile( // Make sure to keep the original spec as-is const specCopy = JSON.parse(JSON.stringify(spec)); - // Override default visual encoding (i.e., `DataTrack` => `BasicSingleTrack`) - overrideDataTemplates(specCopy); - // Replace track templates with raw gosling specs (i.e., `TemplateTrack` => `SingleTrack | OverlaidTrack`) replaceTrackTemplates(specCopy, templates); diff --git a/src/compiler/spec-preprocess.test.ts b/src/compiler/spec-preprocess.test.ts index 874c42c1..7c1b1617 100644 --- a/src/compiler/spec-preprocess.test.ts +++ b/src/compiler/spec-preprocess.test.ts @@ -1,6 +1,6 @@ import type { GoslingSpec, SingleView, Track } from '@gosling-lang/gosling-schema'; import { getBoundingBox, getRelativeTrackInfo } from './bounding-box'; -import { traverseToFixSpecDownstream, overrideDataTemplates, convertToFlatTracks } from './spec-preprocess'; +import { traverseToFixSpecDownstream, convertToFlatTracks } from './spec-preprocess'; import { getTheme } from '../core/utils/theme'; describe('Fix Spec Downstream', () => { @@ -259,36 +259,6 @@ describe('Spec Preprocess', () => { expect(spec.tracks[1].static).toEqual(false); }); - it('override template (higlass-vector)', () => { - const spec: GoslingSpec = { - tracks: [{ data: { type: 'vector', url: '', column: 'c', value: 'v' }, overrideTemplate: true } as Track] - }; - overrideDataTemplates(spec); - expect(spec.tracks[0]).toHaveProperty('mark'); - }); - - it('override template (higlass-multivec)', () => { - { - const spec: GoslingSpec = { - tracks: [ - { - data: { type: 'multivec', url: '', row: 'r', column: 'c', value: 'v' }, - overrideTemplate: true - } as Track - ] - }; - overrideDataTemplates(spec); - expect(spec.tracks[0]).toHaveProperty('mark'); - } - { - const spec: GoslingSpec = { - tracks: [{ data: { type: 'multivec', url: '', row: 'r', column: 'c', value: 'v' } } as Track] - }; - overrideDataTemplates(spec); - expect(spec.tracks[0]).not.toHaveProperty('mark'); // overrideTemplate is not set, so do not override templates - } - }); - it('Convert To FlatTracks', () => { const dummySpec: Track = { data: { type: 'csv', url: '' }, mark: 'bar', width: 10, height: 10 }; { diff --git a/src/compiler/spec-preprocess.ts b/src/compiler/spec-preprocess.ts index ed53573f..67cca496 100644 --- a/src/compiler/spec-preprocess.ts +++ b/src/compiler/spec-preprocess.ts @@ -11,8 +11,6 @@ import type { DisplaceTransform } from '@gosling-lang/gosling-schema'; import { - IsDataTemplate, - IsDataDeepTileset, IsSingleTrack, IsChannelDeep, IsOverlaidTrack, @@ -461,107 +459,3 @@ export function traverseToFixSpecDownstream(spec: GoslingSpec | SingleView, pare }); } } - -/** - * Get an encoding template for the `higlass-vector` data type. - * @param column - * @param value - */ -export function getVectorTemplate(column: string, value: string): SingleTrack { - return { - data: { - type: 'vector', - url: '', - column, - value - }, - mark: 'bar', - x: { field: column, type: 'genomic', axis: 'top' }, - y: { field: value, type: 'quantitative' }, - width: 400, - height: 100 - }; -} - -export function getMultivecTemplate( - row: string, - column: string, - value: string, - categories: string[] | undefined -): SingleTrack { - return categories && categories.length < 10 - ? { - data: { - type: 'multivec', - url: '', - row, - column, - value, - categories - }, - mark: 'bar', - x: { field: column, type: 'genomic', axis: 'top' }, - y: { field: value, type: 'quantitative' }, - row: { field: row, type: 'nominal', legend: true }, - color: { field: row, type: 'nominal' }, - width: 400, - height: 100 - } - : { - data: { - type: 'multivec', - url: '', - row, - column, - value, - categories - }, - mark: 'rect', - x: { field: column, type: 'genomic', axis: 'top' }, - row: { field: row, type: 'nominal', legend: true }, - color: { field: value, type: 'quantitative' }, - width: 400, - height: 100 - }; -} - -/** - * Override default visual encoding in each track for given data type. - * @param spec - */ -export function overrideDataTemplates(spec: GoslingSpec) { - traverseTracks(spec, (t, i, ts) => { - if (!('data' in t) || !t.data || !IsDataDeepTileset(t.data)) { - // if `data` is not specified, we can not provide a correct template. - return; - } - - if ('alignment' in t) { - // This is an OverlaidTracks, so skip this. - return; - } - - if (!IsDataTemplate(t)) { - // This is not partial specification that we need to use templates - return; - } - - switch (t.data.type) { - case 'vector': - case 'bigwig': - ts[i] = Object.assign(getVectorTemplate(t.data.column ?? 'position', t.data.value ?? 'value'), t); - break; - case 'multivec': - ts[i] = Object.assign( - getMultivecTemplate( - t.data.row ?? 'category', - t.data.column ?? 'position', - t.data.value ?? 'value', - t.data.categories - ), - t - ); - break; - } - }); -} diff --git a/src/core/utils/overlay.ts b/src/core/utils/overlay.ts index 58e0c8cf..1db0651b 100644 --- a/src/core/utils/overlay.ts +++ b/src/core/utils/overlay.ts @@ -6,14 +6,20 @@ import type { ChannelDeep, DataDeep } from '@gosling-lang/gosling-schema'; -import { IsChannelDeep, IsDataTrack, IsOverlaidTrack, IsSingleTrack, IsDummyTrack } from '@gosling-lang/gosling-schema'; +import { + IsChannelDeep, + IsOverlaidTrack, + IsSingleTrack, + IsDummyTrack, + IsTemplateTrack +} from '@gosling-lang/gosling-schema'; /** * Resolve superposed tracks into multiple track specifications. * Some options are corrected to ensure the resolved tracks use consistent visual properties, such as the existence of the axis for genomic coordinates. */ export function resolveSuperposedTracks(track: Track): SingleTrack[] { - if (IsDataTrack(track) || IsDummyTrack(track)) { + if (IsTemplateTrack(track) || IsDummyTrack(track)) { // no BasicSingleTrack to return return []; } @@ -69,7 +75,7 @@ export function resolveSuperposedTracks(track: Track): SingleTrack[] { export function spreadTracksByData(tracks: Track[]): Track[] { return ([] as Track[]).concat( ...tracks.map(t => { - if (IsDataTrack(t) || !IsOverlaidTrack(t) || t._overlay.length <= 1) { + if (!IsOverlaidTrack(t) || t._overlay.length <= 1) { // no overlaid tracks to spread return [t]; } diff --git a/src/core/utils/template.ts b/src/core/utils/template.ts index 85adffce..57294f84 100644 --- a/src/core/utils/template.ts +++ b/src/core/utils/template.ts @@ -303,6 +303,10 @@ export function replaceTrackTemplates(spec: GoslingSpec, templates: TemplateTrac if ('encoding' in viewBase) { delete viewBase.encoding; } + // Remove a template property since it is not a template anymore + if('template' in viewBase) { + delete viewBase.template; + } const convertedView: OverlaidTracks = { ...viewBase, alignment: 'overlay', diff --git a/src/gosling-schema/gosling.schema.guards.ts b/src/gosling-schema/gosling.schema.guards.ts index f4c1ee0c..21ace53c 100644 --- a/src/gosling-schema/gosling.schema.guards.ts +++ b/src/gosling-schema/gosling.schema.guards.ts @@ -22,7 +22,6 @@ import type { MultivecData, MatrixData, VectorData, - DataTrack, BigWigData, SingleView, FlatTracks, @@ -92,18 +91,10 @@ export function IsStackedTracks(_: SingleView): _ is StackedTracks { return !IsFlatTracks(_) && !IsOverlaidTracks(_); } -export function IsDataTrack(_: Track): _ is DataTrack { - // !!! Track might not contain `mark` when it is superposed one - return !IsOverlaidTrack(_) && 'data' in _ && !('mark' in _); -} export function IsDummyTrack(_: Track): _ is DummyTrack { return 'type' in _ && _.type == 'dummy-track'; } -export function IsDataTemplate(_: Partial): boolean { - return !!('data' in _ && 'overrideTemplate' in _ && _.overrideTemplate); -} - export function IsDataDeep(data: DataDeep | Datum[]): data is DataDeep { return typeof data === 'object'; } diff --git a/src/gosling-schema/gosling.schema.json b/src/gosling-schema/gosling.schema.json index 25b31b6a..3b6cfae6 100644 --- a/src/gosling-schema/gosling.schema.json +++ b/src/gosling-schema/gosling.schema.json @@ -559,152 +559,6 @@ } ] }, - "DataTrack": { - "additionalProperties": false, - "description": "Partial specification of `BasicSingleTrack` to use default visual encoding predefined by data type.", - "properties": { - "_assignedHeight": { - "type": "number" - }, - "_assignedWidth": { - "description": "Internal: Used for responsive spec", - "type": "number" - }, - "_invalidTrack": { - "description": "internal", - "type": "boolean" - }, - "_renderingId": { - "description": "internal", - "type": "string" - }, - "assembly": { - "$ref": "#/definitions/Assembly", - "description": "A string that specifies the genome builds to use. Currently support `\"hg38\"`, `\"hg19\"`, `\"hg18\"`, `\"hg17\"`, `\"hg16\"`, `\"mm10\"`, `\"mm9\"`, and `\"unknown\"`.\n\n__Note:__: with `\"unknown\"` assembly, genomic axes do not show chrN: in labels." - }, - "centerRadius": { - "description": "Proportion of the radius of the center white space.\n\n__Default:__ `0.3`", - "type": "number" - }, - "data": { - "$ref": "#/definitions/DataDeep" - }, - "endAngle": { - "description": "Specify the end angle (in the range of [0, 360]) of circular tracks (`{\"layout\": \"circular\"}`).", - "type": "number" - }, - "height": { - "description": "Specify the track height in pixels.", - "type": "number" - }, - "id": { - "description": "Assigned to `uid` in a HiGlass view config, used for API and caching.", - "type": "string" - }, - "innerRadius": { - "description": "Specify the inner radius of tracks when (`{\"layout\": \"circular\"}`).", - "type": "number" - }, - "layout": { - "$ref": "#/definitions/Layout", - "description": "Specify the layout type of all tracks." - }, - "linkingId": { - "description": "Specify an ID for [linking multiple views](http://gosling-lang.org/docs/user-interaction#linking-views)", - "type": "string" - }, - "orientation": { - "$ref": "#/definitions/Orientation", - "description": "Specify the orientation." - }, - "outerRadius": { - "description": "Specify the outer radius of tracks when `{\"layout\": \"circular\"}`.", - "type": "number" - }, - "overlayOnPreviousTrack": { - "type": "boolean" - }, - "prerelease": { - "additionalProperties": false, - "description": "internal", - "type": "object" - }, - "spacing": { - "description": "The size of the gap (1) between tracks, (2) between views, and (3) of the origin of circular tracks. The effect of this property depends on where on the spec you specify the `spacing`.\n\nIn a linear layout, this value is used in pixels, while in a circular layout, this value is used relative to the height of the tracks or views.", - "type": "number" - }, - "startAngle": { - "description": "Specify the start angle (in the range of [0, 360]) of circular tracks (`{\"layout\": \"circular\"}`).", - "type": "number" - }, - "static": { - "description": "Whether to disable [Zooming and Panning](http://gosling-lang.org/docs/user-interaction#zooming-and-panning), __Default:__ `false`.", - "type": "boolean" - }, - "style": { - "$ref": "#/definitions/Style", - "description": "Define the [style](http://gosling-lang.org/docs/visual-channel#style-related-properties) of multive views. Will be overwritten by the style of children elements (e.g., view, track)." - }, - "subtitle": { - "type": "string" - }, - "title": { - "description": "If defined, will show the textual label on the left-top corner of a track.", - "type": "string" - }, - "width": { - "description": "Specify the track width in pixels.", - "type": "number" - }, - "xAxis": { - "$ref": "#/definitions/AxisPosition", - "description": "not supported" - }, - "xDomain": { - "anyOf": [ - { - "$ref": "#/definitions/DomainInterval" - }, - { - "$ref": "#/definitions/DomainChrInterval" - }, - { - "$ref": "#/definitions/DomainChr" - } - ], - "description": "Specify the visible region of genomic x-axis" - }, - "xOffset": { - "description": "Specify the x offset of views in the unit of pixels", - "type": "number" - }, - "yDomain": { - "anyOf": [ - { - "$ref": "#/definitions/DomainInterval" - }, - { - "$ref": "#/definitions/DomainChrInterval" - }, - { - "$ref": "#/definitions/DomainChr" - } - ], - "description": "Specify the visible region of genomic y-axis" - }, - "yOffset": { - "description": "Specify the y offset of views in the unit of pixels", - "type": "number" - }, - "zoomLimits": { - "$ref": "#/definitions/ZoomLimits" - } - }, - "required": [ - "data" - ], - "type": "object" - }, "DataTransform": { "anyOf": [ { @@ -1332,9 +1186,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -1493,9 +1344,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -2118,9 +1966,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -2279,9 +2124,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -2961,9 +2803,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -4203,9 +4042,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -4538,9 +4374,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -4903,9 +4736,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -5278,9 +5108,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -5639,9 +5466,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -6183,9 +6007,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -6551,9 +6372,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -6708,9 +6526,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -7330,9 +7145,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -7487,9 +7299,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -8162,9 +7971,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal", @@ -9176,9 +8982,6 @@ { "$ref": "#/definitions/OverlaidTrack" }, - { - "$ref": "#/definitions/DataTrack" - }, { "$ref": "#/definitions/TemplateTrack" }, diff --git a/src/gosling-schema/gosling.schema.ts b/src/gosling-schema/gosling.schema.ts index 7fa6abbd..59d50225 100644 --- a/src/gosling-schema/gosling.schema.ts +++ b/src/gosling-schema/gosling.schema.ts @@ -154,7 +154,7 @@ export interface CommonViewDef { } /* ----------------------------- TRACK ----------------------------- */ -export type Track = SingleTrack | OverlaidTrack | DataTrack | TemplateTrack | DummyTrack; +export type Track = SingleTrack | OverlaidTrack | TemplateTrack | DummyTrack; export interface CommonTrackDef extends CommonViewDef { /** Assigned to `uid` in a HiGlass view config, used for API and caching. */ @@ -203,12 +203,6 @@ export interface CommonTrackDef extends CommonViewDef { }; } -/** - * Partial specification of `BasicSingleTrack` to use default visual encoding predefined by data type. - */ -export interface DataTrack extends CommonTrackDef { - data: DataDeep; -} /** * A placeholder track. In contrast to other tracks, this track does not display any data. Instead it provides * empty space for third party tools to display their data on top of. @@ -456,7 +450,6 @@ interface SingleTrackBase extends CommonTrackDef { flipY?: boolean; // This is only supported for `link` marks. baselineY?: number; // This is only supported for `link` marks. stretch?: boolean; // Stretch the size to the given range? (e.g., [x, xe]) - overrideTemplate?: boolean; // Override a spec template that is defined for a given data type. } export interface Encoding { @@ -1524,7 +1517,6 @@ export type TemplateTrackMappingDef = Omit< // Experimental flipY?: boolean; // This is only supported for `link` marks. stretch?: boolean; // Stretch the size to the given range? (e.g., [x, xe]) - overrideTemplate?: boolean; // Override a spec template that is defined for a given data type. }; // The main difference is that this allows to specify a `base` property diff --git a/src/gosling-schema/template.schema.json b/src/gosling-schema/template.schema.json index b03abce5..e8f29fbe 100644 --- a/src/gosling-schema/template.schema.json +++ b/src/gosling-schema/template.schema.json @@ -1297,9 +1297,6 @@ "overlayOnPreviousTrack": { "type": "boolean" }, - "overrideTemplate": { - "type": "boolean" - }, "prerelease": { "additionalProperties": false, "description": "internal",