Skip to content

Commit

Permalink
feat: stretch x
Browse files Browse the repository at this point in the history
  • Loading branch information
etowahadams committed Dec 13, 2023
1 parent afb8ae4 commit 2e8c544
Showing 1 changed file with 65 additions and 27 deletions.
92 changes: 65 additions & 27 deletions src/tracks/gosling-track/gosling-track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
hasDataTransform
} from '@gosling-lang/gosling-schema';
import { HIGLASS_AXIS_SIZE } from '../../compiler/higlass-model';
import { type ScaleContinuousNumeric } from 'd3-scale';
import { flatArrayToPairArray } from '../../core/utils/array';
import { createPluginTrack, type PluginTrackFactory, type TrackConfig } from '../../core/utils/define-plugin-track';
import { uuid } from '../../core/utils/uuid';
Expand Down Expand Up @@ -333,41 +334,59 @@ const factory: PluginTrackFactory<Tile, GoslingTrackOptions> = (HGC, context, op
override drawTile(tile: Tile) {
if (PRINT_RENDERING_CYCLE) console.warn('drawTile(tile)');

tile.drawnAtScale = this._xScale.copy(); // being used in `super.draw()`
if (!tile.drawnAtScale) {
// This is the first time this tile is being drawn
tile.drawnAtScale = this._xScale.copy();
}

const tileInfo = this.#processedTileInfo[tile.tileId];
if (!tileInfo) {
// We do not have a track model prepared to visualize
return;
}

tile.graphics?.clear();
tile.graphics?.removeChildren();

// This is only to render embellishments only once.
// TODO: Instead of rendering and removing for every tiles, render pBorder only once
this.pBackground.clear();
this.pBackground.removeChildren();
this.pBorder.clear();
this.pBorder.removeChildren();
this.displayedLegends = [];

// Because a single tile contains one track or multiple tracks overlaid, we draw marks and embellishments
// for each GoslingTrackModel
tileInfo.goslingModels.forEach((model: GoslingTrackModel) => {
// check visibility condition
const trackWidth = this.dimensions[0];
const zoomLevel = this._xScale.invert(trackWidth) - this._xScale.invert(0);

if (!model.trackVisibility({ zoomLevel })) {
return;
}
drawPreEmbellishment(HGC, this, tile, model, this.options.theme);
drawMark(HGC, this, tile, model);
drawPostEmbellishment(HGC, this, tile, model, this.options.theme);
});
const [graphicsXScale, graphicsXPos] = this.getXScaleAndOffset(tile.drawnAtScale);
// const [graphicsYScale, graphicsYPos] = this.#getYScaleAndOffset(tile.drawnAtScale);
// console.warn(graphicsYScale);

this.forceDraw();
if (graphicsXScale != 1 && graphicsXScale < 2 && graphicsXScale > 0.5) {
// if graphicsXScale is 1, nothing has been drawn yet so we don't stretch
// if graphicsXScale is less than 2 or greater than 0.5, we can stretch the graphics
tile.graphics.scale.x = graphicsXScale;
tile.graphics.position.x = graphicsXPos;

// tile.graphics.scale.y = graphicsYScale;
// tile.graphics.position.y = graphicsYPos;
} else {
tile.drawnAtScale = this._xScale.copy();
tile.graphics?.clear();
tile.graphics?.removeChildren();

// This is only to render embellishments only once.
// TODO: Instead of rendering and removing for every tiles, render pBorder only once
this.pBackground.clear();
this.pBackground.removeChildren();
this.pBorder.clear();
this.pBorder.removeChildren();
this.displayedLegends = [];

// Because a single tile contains one track or multiple tracks overlaid, we draw marks and embellishments
// for each GoslingTrackModel
tileInfo.goslingModels.forEach((model: GoslingTrackModel) => {
// check visibility condition
const trackWidth = this.dimensions[0];
const zoomLevel = this._xScale.invert(trackWidth) - this._xScale.invert(0);

if (!model.trackVisibility({ zoomLevel })) {
return;
}
drawPreEmbellishment(HGC, this, tile, model, this.options.theme);
drawMark(HGC, this, tile, model);
drawPostEmbellishment(HGC, this, tile, model, this.options.theme);
});

this.forceDraw();
}
}

/**
Expand All @@ -391,6 +410,25 @@ const factory: PluginTrackFactory<Tile, GoslingTrackOptions> = (HGC, context, op
this.draw();
this.forceDraw();
}

/**
* Calulates how much the tile has been scaled, and how much to offset the tile.
* @param drawnAtScale The scale at which the tile has been drawn
* @returns [scale, offset]
*/
#getYScaleAndOffset(drawnAtScale: ScaleContinuousNumeric<number, number>) {
const dA = drawnAtScale.domain();
const dB = this._yScale.domain();

// scaling between tiles
const tileK = (dA[1] - dA[0]) / (dB[1] - dB[0]);

const newRange = this._yScale.domain().map(drawnAtScale);

const posOffset = newRange[0];

return [tileK, -posOffset * tileK];
}
/**
* Clears MouseEventModel from each GoslingTrackModel. Must be a public method because it is called from draw()
*/
Expand Down

0 comments on commit 2e8c544

Please sign in to comment.