Git Product home page Git Product logo

scatter-gl's Introduction

ScatterGL

Interactive 3D / 2D webgl-accelerated scatter plot point renderer. Core functionality from the embedding projector, capable of rendering and interacting with tens of thousands of points.

Examples

Basic use

// where `points` is an array of 2 or 3-dimensional points as number arrays.
const dataset = new ScatterGL.Dataset(points);
const scatterGL = new ScatterGL(containerElement);
scatterGL.render(dataset);

Installation

with yarn / npm
yarn add scatter-gl
via cdn
<!-- Load three.js -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<!-- Load scatter-gl.js -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/scatter-gl.min.js"></script>

Parameters

The ScatterGL constructor can accept a number of parameters via a ScatterGLParams object:

Parameter Type Description default
camera Camera An object containing default parameters for the camera Camera params object (zoom: number, target: Point3D, and position: Point3D)
onClick (point: Point | null) => void A callback invoked when clicking on a point or elsewhere
onHover (point: Point | null) => void A callback invoked when hovering over a point
onSelect (points: Point[]) => void A callback invoked when a point or points are selected
onCameraMove (cameraPosition: THREE.Vector3, cameraTarget: THREE.Vector3) => void A callback invoked the camera moves due to user interaction.
pointColorer `(index: number, selectedIndices: Set, hoverIndex: number null) => string` A function to determine the color of points
renderMode RenderMode The render mode to display points, one of RenderMode.POINT, RenderMode.SPRITE, or RenderMode.TEXT RenderMode.POINT
showLabelsOnHover boolean Whether or not to render label text on hover true
selectEnabled boolean true Whether or not a user can select points by clicking
styles Styles An object containing style parameters to override the default options
rotateOnStart boolean Whether or not the renderer automatically rotates until interaction true
orbitControls OrbitControlParams An object containing default parameters for the orbit controls Orbit Controls params object (zoomSpeed: number, autoRotateSpeed: number, and mouseRotateSpeed: number)

ScatterGL methods

Method Description
isOrbiting() Returns whether the orbit animation is currently on
render(dataset: Dataset) Initializes and renders a dataset to the container element
resize() Updates the render size based on the container element
resetZoom() Resets the camera zoom to default
select(pointIndices: number[]) Selects points by index
setPanMode() Sets interaction mode to 'pan'
setPointColorer(pointColorer: PointColorer) Sets a function to determine colors
setHoverPointIndex() Sets the hovered point
setPointRenderMode() Sets point render mode
setRenderMode(renderMode: RenderMode) Sets a specific render mode
setSelectMode() Sets interaction mode to 'select'
setSequences(sequences: Sequence[]) Sets sequences with which to render polylines
setSpriteRenderMode() Sets sprite render mode
setTextRenderMode() Sets text render mode
updateDataset(dataset: Dataset) Updates the dataset
startOrbitAnimation() Begin rotating until an interaction
stopOrbitAnimation() Stops automatic rotation

ScatterGL Styles

See styles.ts for interfaces and descriptions of a user-configurable styles object that can be provided to ScatterGL to configure colors, sizes, fog, etc.

Advanced usage

See the demo app for examples of interaction handling, spritesheet rendering, and point coloring.

Styling

You can provide an object in the form of Styles via the styles parameter of the ScatterGLParams object.

Development

yarn
yarn demo

This is not an officially supported Google product

scatter-gl's People

Contributors

1wheel avatar annxingyuan avatar biharygergo avatar cannoneyed avatar cjqian avatar dependabot[bot] avatar jameswex avatar radames avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

scatter-gl's Issues

[Feature Request] - Ability to scroll horizontally and vertically

Hi,

I have this requirement to horizontally and vertically scroll the scatter-plot. When we are zoomed in, it becomes difficult to see the hidden data points.

I understand that we can perform the horizontal scroll by two fingers mouse down + mouse move event but the operation is not very user friendly. I was hoping for something like what google map does to move around the map.

Thank you.

[Feature Request] Flags to enable/disable and set draw distance shader

Currently in 3D mode, it is possible to define a set of points in the space such that performing a specific rotation of that space hides the entire dataset behind what appear to be a draw distance shader positioned at the origin.

While there may be good performance reasons to enable a draw distance shader by default, it would be nice if we had:

  • A disable: boolean flag that turns that shader off
  • [Optional] If possible, a drawDistance: number = 0 property that sets the distance from the origin along the view-plane normal (VPN) at which the draw distance shader takes effect. drawDistance === 0 (default) should start the effect at the origin, drawDistance > 0 should move the shader away from the origin and camera along VPN, and drawDistance < 0 should move the shader to a point between the origin and camera along VPN.

Render Mode - Sprites

Hi,

Thank you for this very useful library.

I have a query regarding sprites render mode.

Currently, the number of small sprites present in the image should be equal to or more than the number of data points on the plot. Is there a way to reuse these sprites and avoid repetition?

I have repetitive images and want to reuse the same image for multiple coordinates.

Thanks.

Point Selection

Why not all points get selected when there is overlap between points? Is it possible to fix it?
Example:

Point selection when zoomed out:
Screen Shot 2021-03-16 at 11 51 05 AM

Points actually selected:
Screen Shot 2021-03-16 at 11 51 50 AM

Thanks for the lib. it's very helpful!

Selection not appeared correctly after colors changed using setPointColorer

Hi,

I don't know if it's a bug or I am doing something wrong. Need help here.

I have a requirement to change colors based on certain user actions. Once the colors are changed using setPointColorer and I try to select one or more data points the selection does not appear on UI.

I get the selected data points in onSelect method but the selected points are not highlighted nor do the unselected point's opacity is changed.

extra console.log?

I just noticed a "console.log" left on latest commit of scatter_plot.ts ://github.com/PAIR-code/scatter-gl/commit/a9e8a816754d53ef573a38df9df7c4d58c7c329f#diff-9298a6445b2ddc4745fb5b8a7229a041b60594f3ea841df333e5d7d4fb4d3053R223

console.log(occ);

It's not substantial! thanks

Release npm package with #26

The current version in the npm doesn't include the fix in #26. Is there any chance we can get an update on the npm with fix?

3D Points do not appear if all points of third dimension are same value

Describe the current behavior

Given a dataset of (x, y, z) points, if all values of the z dimension are the same, the points will not appear on the visualizer. This only works for the image and point rendermodes; the text rendermode is unaffected.

Describe the expected behavior

The points are expected to appear.

Standalone code to reproduce the issue

Adding the line vector[2] = 0 after line 26 in index.ts will replicate this issue.

Issue using sprite image for thumbnails

If I pass in a sprite image to the scatter GL dataset as an HTML Image element, it initially renders fine, but when something changes in my data that requires a scatter plot render() call, the datapoints no longer render at all, but they are invisible. They can still be interacted with, such as clicking, but they can't be seen.

If I pass in a sprite image as a string path to a static image, I don't get this same problem.

"undefined" label in demo on 2D canvas select

Hello @cannoneyed!

This is a very nice little library, thanks for extracting this functionality from the main tensorflow projector. I'm finding it very useful in a project i'm working on.

I found a small bug in the label rendering - when using a 2D canvas and points are selected, an "undefined" string label is also rendered at the same time. This occurs in the github pages demo also. I am not quite sure why this is happening, but two additional details:

  1. the undefined label occurs on the very first point that is passed in the dataset
  2. It only occurs for the canvas renderer, so I wonder if it is related to a 3d ScatterPlotVisualizer which is attached to the ScatterPlot, which is subsequently not removed when the renderer infers the dataset dimensionality. Also, disposeAllVisualizers here is never called, I think.

Anyway, thanks for the library - let me know if I can contribute a fix, if it's obvious to you what the problem is. Ta!

Screen Shot 2021-02-02 at 11 25 06 AM

Use of offsetWidth and offsetHeight induces scroll bars

While exploring an unrelated bug, I noticed that ScatterGL uses offsetWidth and offsetHeight properties of its container to set the size of the canvas it renders into.

As the offsetWidth and offsetHeight return the integer values, this can induce horizontal and/or vertical scroll bars in containers if one dimension is not an integer. See the following screenshot from LIT.

One solution is to take the floor of the width and height from getBoundingClientRect() so that it's guaranteed to be at most 1px smaller in each dimension, thereby avoiding scroll bars. Another solution is to support float values for canvas dimesions.

points color default to dark when backgroundColor is dark

I have tried changing the point color to a lighter color when backgroundColor is say black, but it doesn't change.
here is the code:

scatterGL = new ScatterGL(
      document.querySelector('#scatter-gl-container'),
      { 
        'rotateOnStart': false, 
        'selectEnabled': true, 
        'styles': { 
          backgroundColor: '#000', 
          axesVisible: false,
          point: {
            colorUnselected: '#111',
            colorNoSelection: '#fff', // color defaults to black
          }
        }
      } 
    );

Changing dimension from 3D to 2D do not retain the camera parameters passed in the constructor

Hi,

When I change the dimension from 3D to 2D and vice versa using the setDimensions(nDimensions: number) method, the original camera parameters (camera position & camera zoom)which were passed in the constructor are not retained, they are overridden with the default camera parameters.

I think these parameters should be passed when calling the makeCamera() method.

Thank you.

Working demo on observablehq?

Hi,
This is a great light 3d/2d scatter plot, thanks!
I'm trying to make it work on observablehq but got this error. I'm not sure if I've figure it out, seems like some Threejs version problem.

TypeError: Cannot read property 'ROTATE' of undefined
I've also notice you're using a specific orbit three-orbitcontrols-ts package, and I'm not sure how to load it on observablehq to make it compatible with scatter-gl

https://observablehq.com/d/e04e7853659f6530

thanks for the help

[Feature Request] Intelligent label placement

Depending on the camera orientation/position in the space, it is possible and relatively easy to have labels extend beyond the viewable area and get clipped.

Screen Shot 2022-02-02 at 4 13 26 PM

Would it be possible to implement intelligent label placement such that the label anchor is set to the closer of the two. sides of the viewable area (i.e., if the point is closer to the left side, the the text is anchored to the left and extends to the right, but if the point is closer to the right side, the the text is anchored to the right and extends to the left)? I think this would minimize clipping potential without the math getting too fancy.

How to display custom HTML in tooltips?

I am wondering how to display custom HTML when we hover over the points. Right now only label stings are visible when we hover. Any idea or suggestions would be really appreciated.

Custom HTML - think a title, subtitle, some string, maybe some background color, image ...things like that.

Rectangle Selector is Top-Left, not Bottom-Left (Comments)

In scattergl/scatter_plot_rectangle_selector.ts, the comments in the interface state that x and y refer to the bottom left coordinate, when they refer to the top right.

This is solely an issue in the comments; the rectangular selector works fine. This can easily be replicated/ verified by logging the bounding box.

Hover on sequence callback

When the mouse moves over a line in a sequence, onHover is called with null. The mouse is still over the point, but also on the sequence/line too.

Problems:

  • When user clicks, they want to select the point, but scatter-gl does not think mouse is on a point.
  • The point hover color change effect in my app flickers strangely as the mouse crosses over the line embedded in a point.

Issue with overlap and opacity

Viewing https://pair-code.github.io/scatter-gl/ with 3D disabled and label-based color, it seems that some (non-opaque) points do not let the points behind them be shown.

Here is a zoom of an region of the demo, where, e.g., the yellow-ish point in the middle blends with one of the red circle but not with the other.

Same thing with lower opacity

It looks like the transparency gets kind of premultiplied with the background color.

This behavior makes one of my use case very unusable, where some points have very low opacity points that hide more opaque ones.

Any idea, suggestion of where to start to hack for a fix, or a workaround is welcome.

Add the ability to show/hide datapoints

Toggling data points on/off is a very useful feature, but we're not handling this case explicitly (either removing them entirely, or changing their color, which messes up mouse handling)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.