diff --git a/src/tracks/gosling-track/gosling-track-model.ts b/src/tracks/gosling-track/gosling-track-model.ts index 051aa06af..c89532f8a 100644 --- a/src/tracks/gosling-track/gosling-track-model.ts +++ b/src/tracks/gosling-track/gosling-track-model.ts @@ -61,7 +61,6 @@ export class GoslingTrackModel { private specComplete: SingleTrack; // processed spec, being used in visualizations /* data */ - private dataOriginal: { [k: string]: number | string }[]; private dataAggregated: { [k: string]: number | string }[]; /* channel scales */ @@ -77,11 +76,10 @@ export class GoslingTrackModel { this.theme = theme ?? getTheme(); - this.dataOriginal = JSON.parse(JSON.stringify(data)); - this.dataAggregated = JSON.parse(JSON.stringify(data)); + this.dataAggregated = data; // this will be updated after validity of the spec is checked - this.specOriginal = JSON.parse(JSON.stringify(spec)); - this.specComplete = JSON.parse(JSON.stringify(spec)); + this.specOriginal = spec; + this.specComplete = structuredClone(spec); this.channelScales = {}; @@ -101,7 +99,6 @@ export class GoslingTrackModel { // generate scales based on domains and ranges this.generateScales(); - // EXPERIMENTAL: aggregate data when `aggregate` option is used this.dataAggregated = aggregateData(this.spec(), this.dataAggregated); // Add default specs. diff --git a/src/tracks/gosling-track/gosling-track.ts b/src/tracks/gosling-track/gosling-track.ts index 91c68f32e..16b4a4420 100644 --- a/src/tracks/gosling-track/gosling-track.ts +++ b/src/tracks/gosling-track/gosling-track.ts @@ -173,6 +173,7 @@ const factory: PluginTrackFactory = (HGC, context, op #loadingTextBg = new HGC.libraries.PIXI.Graphics(); #loadingText = new HGC.libraries.PIXI.Text('', loadingTextStyle); prevVisibleAndFetchedTiles?: Tile[]; + resolvedTracks: SingleTrack[] | undefined; /* * * @@ -238,7 +239,7 @@ const factory: PluginTrackFactory = (HGC, context, op if (this.options?.showMousePosition && !this.hideMousePosition) { this.hideMousePosition = HGC.utils.showMousePosition( this, - Is2DTrack(resolveSuperposedTracks(this.options.spec)[0]), + Is2DTrack(this.getResolvedTracks()[0]), this.isShowGlobalMousePosition() ); } @@ -579,7 +580,7 @@ const factory: PluginTrackFactory = (HGC, context, op ); let yTiles: number[] | undefined; - if (Is2DTrack(resolveSuperposedTracks(this.options.spec)[0])) { + if (Is2DTrack(this.getResolvedTracks()[0])) { // it makes sense only when the y-axis is being used for a genomic field yTiles = tileProxy.calculateTilesFromResolution( sortedResolutions[zoomLevel], @@ -603,7 +604,7 @@ const factory: PluginTrackFactory = (HGC, context, op ); let yTiles: number[] | undefined; - if (Is2DTrack(resolveSuperposedTracks(this.options.spec)[0])) { + if (Is2DTrack(this.getResolvedTracks()[0])) { // it makes sense only when the y-axis is being used for a genomic field yTiles = tileProxy.calculateTiles( zoomLevel, @@ -801,12 +802,24 @@ const factory: PluginTrackFactory = (HGC, context, op } /** - * Creates an array of SingleTracks if there are overlaid tracks + * Creates an array of SingleTracks if there are overlaid tracks. + * This method cannot be private because it is called by functions which are called by super.draw(); */ - #getResolvedTracks() { - const copy = structuredClone(this.options.spec); + getResolvedTracks() { + if (!this.resolvedTracks) { + const copy = structuredClone(this.options.spec); + const tracks = resolveSuperposedTracks(copy).filter(t => t.mark !== 'brush'); + // We will never need to access the values field in the data spec. It can be quite large which can degrade performance so we remove it. + tracks.forEach(track => { + if ('values' in track.data) { + track.data.values = []; + } + }); + this.resolvedTracks = tracks; + } // Brushes are drawn by another plugin track. - return resolveSuperposedTracks(copy).filter(t => t.mark !== 'brush'); + + return this.resolvedTracks; } /** @@ -824,7 +837,7 @@ const factory: PluginTrackFactory = (HGC, context, op } const tileInfo = initProcessedTileInfo(); - const resolvedTracks = this.#getResolvedTracks(); + const resolvedTracks = this.getResolvedTracks(); if (resolvedTracks.length === 0) { // we do not have enough track to display @@ -880,7 +893,7 @@ const factory: PluginTrackFactory = (HGC, context, op // clear the array first tileInfo.goslingModels = []; - const resolvedTracks = this.#getResolvedTracks(); + const resolvedTracks = this.getResolvedTracks(); resolvedTracks.forEach(resolvedSpec => { let tabularDataTransformed = Array.from(tileInfo.tabularData); resolvedSpec.dataTransform?.forEach(t => { @@ -1404,7 +1417,7 @@ const factory: PluginTrackFactory = (HGC, context, op scaleOffset: [number, number], channelKey: 'color' | 'stroke' ) { - resolveSuperposedTracks(this.options.spec).map(spec => { + this.getResolvedTracks().map(spec => { if (spec._renderingId === _renderingId) { const channel = spec[channelKey]; if (IsChannelDeep(channel)) {