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

Added Support For Zoom Direction #78

Merged
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ setViewOptions({
});
```

### Zoom Control Direction

You can now specify to use natural scrolling or inverted scrolling for zooming in and out using the `setViewOptions` function. Default value is `true`.

```javascript
setViewOptions({
useNaturalScrolling: false,
});
```

# Specifications

Documentation for specifications can be found in [docs/specification_doc.md](https://github.com/epiviz/epiviz.gl/blob/main/docs/specification_doc.md). Documentation for the specifications can be generated with [json-schema-for-humans](https://pypi.org/project/json-schema-for-humans/):
Expand Down
189 changes: 102 additions & 87 deletions app/index.html
Original file line number Diff line number Diff line change
@@ -1,93 +1,108 @@
<html>
<head>
<title>epiviz.gl demo</title>
<meta name="title" content="Epiviz.gl demo" />
<meta
name="description"
content="A demo of an interactive point visualization using WebGL"
/>
<link rel="stylesheet" href="./styles/index.css" />
<link rel="icon" href="./assets/favicon.ico" type="image/x-icon" />
<script type="module" src="./scripts/index.js"></script>
</head>

<head>
<title>epiviz.gl demo</title>
<meta name="title" content="Epiviz.gl demo" />
<meta name="description" content="A demo of an interactive point visualization using WebGL" />
<link rel="stylesheet" href="./styles/index.css" />
<link rel="icon" href="./assets/favicon.ico" type="image/x-icon" />
<script type="module" src="./scripts/index.js"></script>
</head>

<body>
<main>
<div class="toolbar">
<div class="specification-select">
<label for="specification-select">Load Spec:</label>
<select name="specification-select" id="specification-select">
<option value="line-plot">Line Plot</option>
<option value="double-line-plot">Double Line Plot</option>
<option value="area-chart">Area Chart</option>
<option value="stacked-area-chart">Stacked Area Chart</option>
<option value="tick-chart">Tick Chart</option>
<option value="inline-data">Inline Data</option>
<option value="data-defined-channels">Data Defined Channels</option>
<option value="double-inline-data">Double Inline Data</option>
<option value="scatter-grid">Grid Scatter Plot</option>
<option value="scatter-grid-margins">
Grid Scatter Plot With Margins
</option>
<option value="tiny-scatter">Tiny Scatter Plot</option>
<option value="heatmap">Heatmap</option>
<option value="signed-bar-chart">Signed Bar Chart</option>
<option value="vertical-signed-bar-chart">
Vertical Signed Bar Chart
</option>
<option value="all-tracks">All Tracks</option>
<option value="arc-track">Arc Track</option>
<option value="box-track">Box Track</option>
<option value="line-track">Line Track</option>
<option value="tsne-100th">t-SNE Dataset (1/100)</option>
<option value="tsne-10th">t-SNE Dataset (1/10)</option>
<option value="tsne">t-SNE Dataset</option>
<option value="matrix">Large Matrix</option>
</select>
</div>
<div class="controls">
Control modes:
<span>
<img src="./assets/pan_tool_black_24dp.svg" alt="pan tool" />
Pan Tool </span>
<span>
<img src="./assets/highlight_alt_black_24dp.svg" alt="box select" />
Selection (Box)
</span>
<span>
<img src="./assets/gesture_black_24dp.svg" alt="lasso select" />
Selection (Lasso)
</span>
<!-- <img src="./assets/zoom_in_black_24dp.svg" alt="zoom in" /> -->
<!-- <img src="./assets/touch_app_black_24dp.svg" alt="tooltip examine" /> -->
</div>
<body>
<main>
<div class="toolbar">
<div class="specification-select">
<label for="specification-select">Load Spec:</label>
<select name="specification-select" id="specification-select">
<option value="line-plot">Line Plot</option>
<option value="double-line-plot">Double Line Plot</option>
<option value="area-chart">Area Chart</option>
<option value="stacked-area-chart">Stacked Area Chart</option>
<option value="tick-chart">Tick Chart</option>
<option value="inline-data">Inline Data</option>
<option value="data-defined-channels">Data Defined Channels</option>
<option value="double-inline-data">Double Inline Data</option>
<option value="scatter-grid">Grid Scatter Plot</option>
<option value="scatter-grid-margins">
Grid Scatter Plot With Margins
</option>
<option value="tiny-scatter">Tiny Scatter Plot</option>
<option value="heatmap">Heatmap</option>
<option value="signed-bar-chart">Signed Bar Chart</option>
<option value="vertical-signed-bar-chart">
Vertical Signed Bar Chart
</option>
<option value="all-tracks">All Tracks</option>
<option value="arc-track">Arc Track</option>
<option value="box-track">Box Track</option>
<option value="line-track">Line Track</option>
<option value="tsne-100th">t-SNE Dataset (1/100)</option>
<option value="tsne-10th">t-SNE Dataset (1/10)</option>
<option value="tsne">t-SNE Dataset</option>
<option value="matrix">Large Matrix</option>
</select>
</div>
<div class="controls">
Control modes:
<span>
<img src="./assets/pan_tool_black_24dp.svg" alt="pan tool" />
Pan Tool
</span>
<span>
<img src="./assets/highlight_alt_black_24dp.svg" alt="box select" />
Selection (Box)
</span>
<span>
<img src="./assets/gesture_black_24dp.svg" alt="lasso select" />
Selection (Lasso)
</span>
<!-- <img src="./assets/zoom_in_black_24dp.svg" alt="zoom in" /> -->
<!-- <img src="./assets/touch_app_black_24dp.svg" alt="tooltip examine" /> -->
</div>

<div class="scroll-state">
Lock pan/zoom along an axis ?
<span>
<label for="lock-x">Lock X</label>
<input type="checkbox" id="lock-x" name="lock-x" />
</span>
<span>
<label for="lock-x">Lock Y</label>
<input type="checkbox" id="lock-y" name="lock-y" />
</span>
<div class="scroll-state">
Lock pan/zoom along an axis ?
<span>
<label for="lock-x">Lock X</label>
<input type="checkbox" id="lock-x" name="lock-x" />
</span>
<span>
<label for="lock-x">Lock Y</label>
<input type="checkbox" id="lock-y" name="lock-y" />
</span>
<span>
<label for="use-natural-scroll">Use Natural Scroll</label>
<input
type="checkbox"
id="use-natural-scroll"
name="use-natural-scroll"
/>
</span>
</div>
</div>
</div>
<div class="panes">
<div class="json-editor">
<div>
<label for="specification-editor">Visualization Specification</label>
<button id="refresh-specification">RUN</button>
<div class="panes">
<div class="json-editor">
<div>
<label for="specification-editor"
>Visualization Specification</label
>
<button id="refresh-specification">RUN</button>
</div>
<textarea
id="specification-editor"
name="specification-editor"
></textarea>
</div>
<textarea id="specification-editor" name="specification-editor"></textarea>
<div class="content"></div>
</div>
<div class="content"></div>
</div>
</main>
<footer>
<a class="github" href="https://github.com/epiviz/epiviz.gl">
See on GitHub
</a>
</footer>
</body>

</html>
</main>
<footer>
<a class="github" href="https://github.com/epiviz/epiviz.gl">
See on GitHub
</a>
</footer>
</body>
</html>
2 changes: 1 addition & 1 deletion app/scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class App {

let selem = document.getElementById("specification-select");
selem.value = "tsne-10th";
selem.dispatchEvent(new Event('change'));
selem.dispatchEvent(new Event("change"));

document.getElementById("refresh-specification").click();
}
Expand Down
15 changes: 11 additions & 4 deletions app/scripts/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const controlsSlice = createSlice({
specification: csv10,
lockedX: false,
lockedY: false,
useNaturalScrolling: false,
},
reducers: {
setSpecification(state, action) {
Expand All @@ -19,10 +20,16 @@ const controlsSlice = createSlice({
},

setScroll(state, action) {
if (action.payload.axis === "x") {
state.lockedX = action.payload.checked;
} else if (action.payload.axis === "y") {
state.lockedY = action.payload.checked;
if (action.payload.axis) {
if (action.payload.axis === "x") {
state.lockedX = action.payload.checked;
} else if (action.payload.axis === "y") {
state.lockedY = action.payload.checked;
}
} else {
for (const key in action.payload) {
state[key] = action.payload[key];
}
}
},
},
Expand Down
5 changes: 5 additions & 0 deletions app/scripts/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ class Toolbar {
document.getElementById("lock-y").addEventListener("change", (event) => {
this.dispatch(setScroll({ axis: "y", checked: event.target.checked }));
});
document
.getElementById("use-natural-scroll")
.addEventListener("change", (event) => {
this.dispatch(setScroll({ useNaturalScrolling: event.target.checked }));
});

document.getElementById("specification-select").value = this.specification;
this.dispatch(setSpecification(exampleMap.get(this.specification)));
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "epiviz.gl",
"version": "1.0.17",
"version": "1.0.18",
"repository": "https://github.com/epiviz/epiviz.gl",
"homepage": "https://github.com/epiviz/epiviz.gl",
"author": {
Expand All @@ -12,6 +12,10 @@
{
"name": "Sam Rosen",
"email": "samrosen90@gmail.com"
},
{
"name": "Ossama Rafique",
"email": "ossamarafique@gmail.com"
}
],
"bugs": "https://github.com/epiviz/epiviz.gl/issues",
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import commonjs from "@rollup/plugin-commonjs";
import pkg from "./package.json";
import json from "@rollup/plugin-json";
import OMT from "@surma/rollup-plugin-off-main-thread";
import nodePolyfills from "rollup-plugin-node-polyfills"; // <-- import here
import nodePolyfills from "rollup-plugin-node-polyfills";

export default {
input: "src/index.js",
Expand Down
26 changes: 18 additions & 8 deletions src/epiviz.gl/mouse-reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class MouseReader {
);
this.throttledUpdateSVG = throttleWithRAF(this._updateSVG.bind(this));
this.uniDirectionalSelectionEnabled = true;
this.useNaturalScrolling = false;
}

/**
Expand Down Expand Up @@ -299,7 +300,9 @@ class MouseReader {
let previousY = null;
if (!this.lockedX) {
previousX = [...this.currentXRange]; // ... to avoid aliasing
const t = -event.wheelDelta / 1000;
const t = this.useNaturalScrolling
? event.wheelDelta / 1000
: -event.wheelDelta / 1000; // Invert based on scrolling preference
const inDataSpace = this._calculateViewportSpot(
...getLayerXandYFromEvent(event)
);
Expand All @@ -315,7 +318,9 @@ class MouseReader {

if (!this.lockedY) {
previousY = [...this.currentYRange];
const t = -event.wheelDelta / 1000;
const t = this.useNaturalScrolling
? event.wheelDelta / 1000
: -event.wheelDelta / 1000; // Invert based on scrolling preference
const inDataSpace = this._calculateViewportSpot(
...getLayerXandYFromEvent(event)
);
Expand Down Expand Up @@ -349,12 +354,17 @@ class MouseReader {
}
}

this.handler.dispatchEvent(event.wheelDelta < 0 ? "zoomIn" : "zoomOut", {
viewport: this.getViewport(),
zoomLevel: calculateZoomLevel(this.getViewport()),
type: this.tool,
event: cloneMouseEvent(event),
});
this.handler.dispatchEvent(
(this.useNaturalScrolling ? event.wheelDelta < 0 : event.wheelDelta > 0)
? "zoomIn"
: "zoomOut",
{
viewport: this.getViewport(),
zoomLevel: calculateZoomLevel(this.getViewport()),
type: this.tool,
event: cloneMouseEvent(event),
}
);

this.handler.sendDrawerState(this.getViewport());
this.throttledUpdateSVG();
Expand Down
1 change: 1 addition & 0 deletions src/epiviz.gl/webgl-vis.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class WebGLVis {
"currentYRange",
"uniDirectionalSelectionEnabled",
"maxZoomLevel",
"useNaturalScrolling",
]);
}

Expand Down
10 changes: 0 additions & 10 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4238,11 +4238,6 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==

process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==

proxy-from-env@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
Expand All @@ -4266,11 +4261,6 @@ punycode@1.3.2:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=

punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==

punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
Expand Down
Loading