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

WIP React-less HiGlass-less Gosling #1086

Open
wants to merge 169 commits into
base: main
Choose a base branch
from
Open
Changes from 6 commits
Commits
Show all changes
169 commits
Select commit Hold shift + click to select a range
52b12e0
feat: new demo page
etowahadams Jun 12, 2024
f1255fc
Merge pull request #1 from etowahadams/new-dev-server
etowahadams Jun 12, 2024
cafc659
feat: upgrade pixi
etowahadams Jun 12, 2024
3acfc54
feat: pixi-manager
etowahadams Jun 12, 2024
c0dd708
feat: alias
etowahadams Jun 12, 2024
9f00ad8
feat: add to demo
etowahadams Jun 12, 2024
2b7f4f5
Merge pull request #2 from etowahadams/pixi-manager
etowahadams Jun 12, 2024
a3fc509
Merge branch 'gosling-lang:main' into main
etowahadams Jun 12, 2024
1107a7e
refactor: add react import
etowahadams Jun 12, 2024
6e48246
feat: remove higlass dependencies, add vendored dependencies
etowahadams Jun 12, 2024
c070488
feat: vendored higlass imports
etowahadams Jun 12, 2024
ff118a9
Merge pull request #3 from etowahadams/higlass-imports
etowahadams Jun 12, 2024
887a5f2
Merge branch 'gosling-lang:main' into main
etowahadams Jun 12, 2024
3c1d8d2
feat: higlass alias, fix pixi manager
etowahadams Jun 12, 2024
a0e8fb6
feat: dummy track
etowahadams Jun 12, 2024
186ebd1
feat: dummy track example
etowahadams Jun 12, 2024
a6c1a74
feat: higlass types
etowahadams Jun 12, 2024
1470400
Merge pull request #4 from etowahadams/dummy-track
etowahadams Jun 12, 2024
f257186
feat: export PixiTrack
etowahadams Jun 12, 2024
e43796e
feat: text track
etowahadams Jun 12, 2024
12a1363
feat: text track alias
etowahadams Jun 12, 2024
099c357
feat: text track
etowahadams Jun 12, 2024
e7a4980
feat: higlass utils
etowahadams Jun 12, 2024
06edb1f
feat: text track example
etowahadams Jun 12, 2024
604d78f
Merge pull request #5 from etowahadams/text-track
etowahadams Jun 12, 2024
b435c83
feat: add signals
etowahadams Jun 12, 2024
52f6648
feat: circular brush
etowahadams Jun 12, 2024
91398aa
fix: alias name
etowahadams Jun 12, 2024
8a39ab2
feat: circular brush example
etowahadams Jun 12, 2024
bca07c4
Merge pull request #6 from etowahadams/circular-brush
etowahadams Jun 12, 2024
b043339
Merge branch 'gosling-lang:main' into main
etowahadams Jun 12, 2024
6d6ab8c
Merge branch 'gosling-lang:main' into main
etowahadams Jun 12, 2024
29bc2aa
feat: tile proxy
etowahadams Jun 12, 2024
f120886
feat: basic gosling track
etowahadams Jun 12, 2024
deaa172
feat: make GoslingTrackClass standalone
etowahadams Jun 12, 2024
901686a
feat: remove HGC from mark drawing
etowahadams Jun 12, 2024
3835cb0
feat: export TiledPixiTrack
etowahadams Jun 12, 2024
952828a
feat: add interactors
etowahadams Jun 13, 2024
0f7f84b
feat: export hg datafetcher
etowahadams Jun 13, 2024
63ac37a
fix: linear brush model
etowahadams Jun 13, 2024
41c5bfd
feat: GoslingTrack plot
etowahadams Jun 13, 2024
32285f7
feat: gosling track example
etowahadams Jun 13, 2024
2ee784e
Merge pull request #7 from etowahadams/gosling-track
etowahadams Jun 13, 2024
e16d445
feat: axis track
etowahadams Jun 13, 2024
e41130a
feat: axis track example
etowahadams Jun 13, 2024
1778bae
feat: brush linear
etowahadams Jun 13, 2024
1048754
fix: add missing type package
etowahadams Jun 13, 2024
c56d5b0
refactor: remove types
etowahadams Jun 13, 2024
d15977a
feat: add example
etowahadams Jun 13, 2024
c70fa6a
Merge pull request #8 from etowahadams/linear-brush
etowahadams Jun 13, 2024
9bd22f4
feat: rename to brush-circular
etowahadams Jun 13, 2024
c5b95dd
feat: rename genomic axis
etowahadams Jun 13, 2024
829142b
feat: bigwig datafetcher
etowahadams Jun 13, 2024
ce31563
fix: update datafetchers
etowahadams Jun 13, 2024
2c2fc8e
feat: compile
etowahadams Jun 13, 2024
5ba3607
feat: add basic layout
etowahadams Jun 14, 2024
e030b4a
feat: new examples
etowahadams Jun 17, 2024
19cfcb9
feat: new render function
etowahadams Jun 17, 2024
67928cb
refactor: split into files
etowahadams Jun 17, 2024
124a9e4
feat: beddb data
etowahadams Jun 18, 2024
88a8b9f
feat: don't show labels on overlay tracks
etowahadams Jun 18, 2024
7b68785
refactor: rendering
etowahadams Jun 18, 2024
90455f2
feat: corces example
etowahadams Jun 18, 2024
a2ff1fe
feat: brush linear
etowahadams Jun 18, 2024
4298cd3
feat: simple linked views
etowahadams Jun 18, 2024
58b095f
feat: linked brush
etowahadams Jun 19, 2024
d0e4591
feat: refactored linking
etowahadams Jun 20, 2024
9fa84fe
fix: linkedEncoding
etowahadams Jun 20, 2024
ba16d2a
refactor: clean up circular brush
etowahadams Jun 20, 2024
11775fd
feat: dual circular brush plot
etowahadams Jun 21, 2024
b68abc8
feat: linked circle
etowahadams Jun 21, 2024
65f0a31
fix: brushing
etowahadams Jun 21, 2024
cb71018
Merge pull request #9 from etowahadams/spec-to-pos
etowahadams Jun 21, 2024
8d66d03
feat: identify broken track
etowahadams Jun 21, 2024
01ed2f6
fix: give correct bounding box for circular
etowahadams Jun 24, 2024
7e7bb52
fix: cancer spec
etowahadams Jun 24, 2024
65cfba6
Merge pull request #10 from etowahadams/fix-cancer-vis
etowahadams Jun 24, 2024
a6e54d4
feat: mocked worker
etowahadams Jun 24, 2024
e50c0e0
make vitest run on demo
etowahadams Jun 24, 2024
41f5488
test: linkedEncoding
etowahadams Jun 24, 2024
80ba261
Merge pull request #11 from etowahadams/fix-tests
etowahadams Jun 24, 2024
ae2e062
feat: heatmap plot
etowahadams Jun 24, 2024
20720e3
feat: alias for heatmap
etowahadams Jun 24, 2024
cd34ca8
feat: heatmap example
etowahadams Jun 24, 2024
db1fd6b
refactor: heatmap plot inputs
etowahadams Jun 24, 2024
b662ed0
refactor heatmap internals
etowahadams Jun 24, 2024
e4dafe3
feat: introduce signals
etowahadams Jun 24, 2024
8bde195
copy over zoomPan interactor
etowahadams Jun 24, 2024
95e2891
feat: zoomPanXY interactor
etowahadams Jun 25, 2024
4f35c1a
feat: full working zoomXY
etowahadams Jun 25, 2024
8fa24b0
refactor: rename to panZoomHeatmap
etowahadams Jun 25, 2024
08824a8
feat: heatmap options
etowahadams Jun 25, 2024
28aa1ba
Merge pull request #12 from etowahadams/heatmap
etowahadams Jun 25, 2024
0f4f79c
feat: refactor connectivity
etowahadams Jun 25, 2024
997dc35
Merge pull request #13 from etowahadams/refactor-linking
etowahadams Jun 25, 2024
ccac22c
feat: working heatmap
etowahadams Jun 25, 2024
12c29e5
feat: working heatmap
etowahadams Jun 25, 2024
9e1bc6c
feat: add basic heatmap axis
etowahadams Jun 26, 2024
00a0c2f
feat: basic reverse orientation
etowahadams Jun 26, 2024
2c0fb9f
feat: reverse example
etowahadams Jun 26, 2024
7353692
feat: panZoom for axis track
etowahadams Jun 26, 2024
9ac8874
feat: vertical Gosling track
etowahadams Jun 26, 2024
358002f
feat: make brushes use new interactor
etowahadams Jun 26, 2024
ff2cccb
feat: working example
etowahadams Jun 26, 2024
8618c1c
feat: basic fix to heatmap scaling
etowahadams Jun 26, 2024
2f79d6d
feat: working heatmap x and y
etowahadams Jun 27, 2024
6e11667
feat: refine heatmap axis
etowahadams Jun 27, 2024
ca64862
feat: static brushes
etowahadams Jun 27, 2024
3d5ee57
Merge pull request #14 from etowahadams/heatmap-rendering
etowahadams Jun 27, 2024
6847ced
fix: unused imports
etowahadams Jun 28, 2024
390e5f7
refine matrix linking
etowahadams Jun 28, 2024
d75df4d
feat: basic gosling component
etowahadams Jun 28, 2024
608a0dc
feat: basic editor
etowahadams Jun 28, 2024
16ee5b7
fix: x domain
etowahadams Jun 28, 2024
426f8cc
feat: fix linking bugs
etowahadams Jun 28, 2024
79a885f
remove old test
etowahadams Jun 28, 2024
398b120
Merge pull request #15 from etowahadams/basic-gos-component
etowahadams Jun 28, 2024
7ffb851
fix: csv datafetcher options
etowahadams Jul 1, 2024
314f4be
feat: add csv example
etowahadams Jul 2, 2024
9c7f6b8
fix: give spec
etowahadams Jul 2, 2024
5d4e2f2
Merge pull request #16 from etowahadams/fix-give
etowahadams Jul 2, 2024
50f11bb
fix: json data fetcher
etowahadams Jul 2, 2024
f49a917
Merge pull request #17 from etowahadams/fix-json-data
etowahadams Jul 2, 2024
0d13bfa
fix: single overlay
etowahadams Jul 2, 2024
bb86b7d
fix: no show heatmap label
etowahadams Jul 2, 2024
5875e2b
fix: move effect to tracks
etowahadams Jul 2, 2024
f7f9747
only put interactor if not overlaid on previous
etowahadams Jul 2, 2024
6bdc6f9
fix: bounding box calculation
etowahadams Jul 2, 2024
2874b20
feat: add basic y domain
etowahadams Jul 3, 2024
25f17b2
feat: add test
etowahadams Jul 3, 2024
d39eaf6
fix panZoom yDomain
etowahadams Jul 3, 2024
7d9828a
feat: yDomain for gosling plot
etowahadams Jul 3, 2024
dd14c20
update matrix example
etowahadams Jul 3, 2024
0a98c43
fix: multiple same linkingId
etowahadams Jul 3, 2024
e6a8166
update matrix
etowahadams Jul 3, 2024
f6f6d41
Merge pull request #18 from etowahadams/matrix-annotations
etowahadams Jul 3, 2024
cd62c05
reorganize files
etowahadams Jul 3, 2024
65a2ab8
feat: basic resizing
etowahadams Jul 6, 2024
db148fe
refactor no more callback
etowahadams Jul 6, 2024
328988a
resize pixi canvas after rendering
etowahadams Jul 6, 2024
fc8117f
feat: rescale height
etowahadams Jul 6, 2024
c6bd779
fixes for responsive height
etowahadams Jul 6, 2024
c56f704
Merge pull request #19 from etowahadams/responsive-width
etowahadams Jul 6, 2024
d591b16
pixi manager property comment
etowahadams Jul 6, 2024
664bd44
feat: basic pixi manager persistance
etowahadams Jul 6, 2024
cde2d99
remove console warns
etowahadams Jul 6, 2024
4ae90d5
Merge pull request #20 from etowahadams/better-component
etowahadams Jul 6, 2024
7b07dc8
fix: brushes and types
etowahadams Jul 6, 2024
789f7cf
comment about types
etowahadams Jul 6, 2024
246ddda
add documentation
etowahadams Jul 6, 2024
6b7c2fa
Merge pull request #21 from etowahadams/color-brushes
etowahadams Jul 6, 2024
280b8d1
feat: use color
etowahadams Jul 6, 2024
31995fb
Merge pull request #22 from etowahadams/fix-heatmap-color
etowahadams Jul 6, 2024
03e79f1
feat: dummy track
etowahadams Jul 6, 2024
4cb915a
Merge pull request #23 from etowahadams/add-dummy-track
etowahadams Jul 6, 2024
36b3c86
make csv data fetcher take assembly
etowahadams Jul 6, 2024
dc372b8
Merge pull request #24 from etowahadams/fix-csv
etowahadams Jul 6, 2024
943b5be
feat: gff data fetcher
etowahadams Jul 6, 2024
7f217a5
feat: bam
etowahadams Jul 6, 2024
f217432
feat: bed data fetcher
etowahadams Jul 6, 2024
fd2b1ee
feat: vcf data fetcher
etowahadams Jul 6, 2024
75eb0b5
Merge pull request #25 from etowahadams/other-data-types
etowahadams Jul 6, 2024
c2d0548
feat: basic tooltip
etowahadams Jul 7, 2024
beebbbf
feat: working tooltip on static
etowahadams Jul 7, 2024
6be04c1
no zoom pan with alt key
etowahadams Jul 7, 2024
0e34e75
clear brush when click
etowahadams Jul 7, 2024
69ff028
clarify linked encoding
etowahadams Jul 8, 2024
05f0417
Merge pull request #26 from etowahadams/tooltip
etowahadams Jul 8, 2024
6b62a32
add explanation
etowahadams Jul 8, 2024
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
2 changes: 1 addition & 1 deletion demo/linking/linkedEncoding.ts
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ export interface LinkedEncoding {
signal: Signal;
tracks: {
id: string;
encoding: 'x' | 'brush';
encoding: 'x' | 'y' | 'brush';
}[];
}

3 changes: 2 additions & 1 deletion src/interactors/panZoom.ts
Original file line number Diff line number Diff line change
@@ -42,10 +42,11 @@ export function panZoom(plot: Plot, xDomain: Signal<[number, number]>, yDomain?:
const isRect = event.target.tagName === 'rect';
const isMousedown = event.type === 'mousedown';
const isDraggingBrush = isRect && isMousedown;
const isAltPressed = event.altKey;
// Here are the default filters
const defaultFilter = (!event.ctrlKey || event.type === 'wheel') && !event.button;
// Use the default filter and our custom filter
return defaultFilter && !isDraggingBrush;
return defaultFilter && !isDraggingBrush && !isAltPressed;
})
// @ts-expect-error We need to reset the transform when the user stops zooming
.on('end', () => (plot.domOverlay.__zoom = new ZoomTransform(1, 0, 0)))
4 changes: 2 additions & 2 deletions src/pixi-manager/pixi-manager.ts
Original file line number Diff line number Diff line change
@@ -34,9 +34,9 @@ export class PixiManager {
backgroundColor: 0xffffff,
eventMode: 'static',
eventFeatures: {
move: false,
move: true,
globalMove: false,
click: false,
click: true,
wheel: false
}
});
65 changes: 63 additions & 2 deletions src/tracks/gosling-track/gosling-track-plot.ts
Original file line number Diff line number Diff line change
@@ -98,10 +98,71 @@ export class GoslingTrack extends GoslingTrackClass implements Plot {

// Every time the domain gets changed we want to update the zoom
effect(() => {
const newScaleX = this._refXScale.domain(this.xDomain.value);
const newScaleY = this._refYScale.domain(this.yDomain.value);
const newScaleX = scaleLinear().range(this._refXScale.range()).domain(this.xDomain.value);
const newScaleY = scaleLinear().range(this._refYScale.range()).domain(this.yDomain.value);
this.zoomed(newScaleX, newScaleY);
});
this.addTooltip();
}

/** When the tooltip option is used, the tooltip div will be populated sample information */
addTooltip() {
/** Helper function to get the position relative to the overlay div */
function getRelativePosition(element: HTMLElement, e: MouseEvent) {
const rect = element.getBoundingClientRect();
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
}
const tooltipDiv = document.createElement('tooltip');
const tooltipStyles = {
position: 'absolute',
pointerEvents: 'none',
backgroundColor: 'white',
borderRadius: '5px',
border: '1px solid #dddddd',
boxSizing: 'border-box',
fontSize: '10px'
};
Object.assign(tooltipDiv.style, tooltipStyles);
this.domOverlay.appendChild(tooltipDiv);

// When the mouse moves over the overlay div, update the tooltip position
this.domOverlay.addEventListener('mousemove', (e: MouseEvent) => {
const { x, y } = getRelativePosition(this.domOverlay, e);
this.onMouseMove(x);
// Update the tooltip position
tooltipDiv.style.left = `${x}px`;
tooltipDiv.style.top = `${y}px`;
const tooltip = this.getMouseOverHtml(x, y);
if (tooltip === '' || this.isRangeBrushActivated) {
tooltipDiv.innerHTML = '';
tooltipDiv.style.display = 'none';
} else {
tooltipDiv.innerHTML = tooltip;
tooltipDiv.style.display = 'block';
}
});
// When the mouse leaves the overlay div, clear the tooltip
this.domOverlay.addEventListener('mouseleave', () => {
this.onMouseOut();
tooltipDiv.innerHTML = '';
});
// When the mouse is clicked, hide the tooltip. Likely dragging a brush
this.domOverlay.addEventListener('mousedown', e => {
tooltipDiv.style.display = 'none';
const { x, y } = getRelativePosition(this.domOverlay, e);
this.onMouseDown(x, y, e.altKey);
});
this.domOverlay.addEventListener('mouseup', e => {
const { x, y } = getRelativePosition(this.domOverlay, e);
this.onMouseUp(x, y);
});
this.domOverlay.addEventListener('click', e => {
const { x, y } = getRelativePosition(this.domOverlay, e);
this.onMouseClick(x, y);
});
}

addInteractor(interactor: (plot: GoslingTrack) => void) {
55 changes: 28 additions & 27 deletions src/tracks/gosling-track/gosling-track.ts
Original file line number Diff line number Diff line change
@@ -151,7 +151,7 @@ export class GoslingTrackClass extends TiledPixiTrack<Tile, GoslingTrackOptions>
pMouseSelection = new PIXI.Graphics();
#mouseDownX = 0;
#mouseDownY = 0;
#isRangeBrushActivated = false;
isRangeBrushActivated = false;
#gBrush: Selection<SVGGElement, unknown, null, undefined>;
#loadingTextStyleObj = new PIXI.TextStyle(loadingTextStyle);
#loadingTextBg = new PIXI.Graphics();
@@ -203,23 +203,15 @@ export class GoslingTrackClass extends TiledPixiTrack<Tile, GoslingTrackOptions>
this.pMain.addChild(this.pMouseSelection);

// Enable click event
this.pMask.interactive = true;
this.mRangeBrush = new LinearBrushModel(this.#gBrush, this.options.spec.style?.brush);
this.mRangeBrush.on('brush', this.#onRangeBrush.bind(this));

this.pMask.on('mousedown', (e: PIXI.InteractionEvent) => {
const { x, y } = e.data.getLocalPosition(this.pMain);
this.#onMouseDown(x, y, e.data.originalEvent.altKey);
});
this.pMask.on('mouseup', (e: PIXI.InteractionEvent) => {
const { x, y } = e.data.getLocalPosition(this.pMain);
this.#onMouseUp(x, y);
});
this.pMask.on('mousemove', (e: PIXI.InteractionEvent) => {
const { x } = e.data.getLocalPosition(this.pMain);
this.#onMouseMove(x);
});
this.pMask.on('mouseout', this.#onMouseOut.bind(this));
// this.pMain.onmousemove = e => {
// const { x } = e.getLocalPosition(this.pMain);
// this.onMouseMove(x);
// };
// this.pMain.onmouseout = () => {
// this.#onMouseOut();
// };
this.flipText = this.options.spec.orientation === 'vertical';

// We do not use HiGlass' trackNotFoundText
@@ -1092,39 +1084,39 @@ export class GoslingTrackClass extends TiledPixiTrack<Tile, GoslingTrackOptions>
return;
}

#onMouseDown(mouseX: number, mouseY: number, isAltPressed: boolean) {
onMouseDown(mouseX: number, mouseY: number, isAltPressed: boolean) {
// Record these so that we do not triger click event when dragged.
this.#mouseDownX = mouseX;
this.#mouseDownY = mouseY;

// Determine whether to activate a range brush
const mouseEvents = this.options.spec.mouseEvents;
const rangeSelectEnabled = !!mouseEvents || (IsMouseEventsDeep(mouseEvents) && !!mouseEvents.rangeSelect);
this.#isRangeBrushActivated = rangeSelectEnabled && isAltPressed;
this.isRangeBrushActivated = rangeSelectEnabled && isAltPressed;

this.pMouseHover.clear();
}

#onMouseMove(mouseX: number) {
onMouseMove(mouseX: number) {
if (this.options.spec.layout === 'circular') {
// TODO: We do not yet support range selection on circular tracks
return;
}

if (this.#isRangeBrushActivated) {
if (this.isRangeBrushActivated) {
this.mRangeBrush.updateRange([mouseX, this.#mouseDownX]).drawBrush().visible().disable();
}
}

#onMouseUp(mouseX: number, mouseY: number) {
/** Used for range selections */
onMouseUp(mouseX: number, mouseY: number) {
// `trackClick` API
this.#publishTrackEvents('trackClick', mouseX, mouseY);

const mouseEvents = this.options.spec.mouseEvents;
const clickEnabled = !!mouseEvents || (IsMouseEventsDeep(mouseEvents) && !!mouseEvents.click);
const isDrag = Math.sqrt((this.#mouseDownX - mouseX) ** 2 + (this.#mouseDownY - mouseY) ** 2) > 1;

if (!this.#isRangeBrushActivated && !isDrag) {
if (!this.isRangeBrushActivated && !isDrag) {
// Clicking outside the brush should remove the brush and the selection.
this.mRangeBrush.clear();
this.pMouseSelection.clear();
@@ -1133,7 +1125,7 @@ export class GoslingTrackClass extends TiledPixiTrack<Tile, GoslingTrackOptions>
this.mRangeBrush.enable();
}

this.#isRangeBrushActivated = false;
this.isRangeBrushActivated = false;

if (!this.tilesetInfo) {
// Do not have enough information
@@ -1160,11 +1152,20 @@ export class GoslingTrackClass extends TiledPixiTrack<Tile, GoslingTrackOptions>
}
}

#onMouseOut() {
this.#isRangeBrushActivated = false;
onMouseOut() {
this.isRangeBrushActivated = false;
document.body.style.cursor = 'default';
this.pMouseHover.clear();
}

onMouseClick(mouseX: number, mouseY: number) {
const isDrag = Math.sqrt((this.#mouseDownX - mouseX) ** 2 + (this.#mouseDownY - mouseY) ** 2) > 1;
// Clear the brush if we are not dragging
if (!isDrag) {
this.mRangeBrush.clear();
this.pMouseSelection.clear();
}
}
/**
* From all tiles and overlaid tracks, collect element(s) that are withing a mouse position.
*/
@@ -1361,7 +1362,7 @@ export class GoslingTrackClass extends TiledPixiTrack<Tile, GoslingTrackOptions>
// `trackMouseOver` API
this.#publishTrackEvents('trackMouseOver', mouseX, mouseY);

if (this.#isRangeBrushActivated) {
if (this.isRangeBrushActivated) {
// In the middle of drawing range brush.
return '';
}