diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 100% rename from .eslintrc.js rename to .eslintrc.cjs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9b6b30df..8e91ed77 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,6 @@ jobs: uses: actions/setup-node@v3 with: node-version: "20.x" - cache: "pnpm" - name: Install deps run: pnpm install - name: Lint @@ -42,7 +41,6 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} - cache: "pnpm" - name: Install deps run: pnpm install diff --git a/README.md b/README.md index e30187b4..5fc98e12 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,46 @@

A point cloud library for visualizing point clouds using 2D and 3D canvases. + +## Installation + +```bash +# or pnpm, yarn, etc +npm install @arizeai/point-cloud @react-three/drei +``` + +## Usage + +Basic usage: + +```tsx +import { ThreeDimensionalCanvas, ThreeDimensionalControls, Points, type PointBaseProps } from '@arizeai/point-cloud'; + +const data: PointBaseProps[] = [ + { position: [0, 0, 0], metaData: {} }, + { position: [1, 1, 1], metaData: {} }, +]; + +export const PointCloud = () => { + return ( + + + + + ); +}; +``` + +See additional usage examples in Storybook. + +```bash +npm run storybook +``` + +## Usage with React 19 + +React 19 is not yet supported by stable versions of `@react-three/drei`. To use this library with React 19, you can try the following: + +```bash +npm install @arizeai/point-cloud @react-three/drei@alpha +``` diff --git a/package.json b/package.json index 9db1358c..e390aeee 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-unused-imports": "^3.1.0", "husky": "^7.0.4", + "prettier": "^3.4.2", "react": "18", "react-dom": "18", "react-is": "^18.1.0", diff --git a/src/Cluster.tsx b/src/Cluster.tsx index 0a58f4bd..7bc5cde5 100644 --- a/src/Cluster.tsx +++ b/src/Cluster.tsx @@ -43,7 +43,7 @@ export function Cluster({ const geometries: THREE.SphereGeometry[] = []; // Keep track of the points added so that we can remove duplicates const pointSet = new Set(); - data.forEach(point => { + data.forEach((point) => { const { position } = point; // Remove duplicates if (!pointSet.has(position.join(","))) { diff --git a/src/LassoSelect.tsx b/src/LassoSelect.tsx index 8e5070c1..f0cff596 100644 --- a/src/LassoSelect.tsx +++ b/src/LassoSelect.tsx @@ -191,10 +191,8 @@ export function LassoSelect({ // Animation frames to draw the selections useFrame(({ camera }) => { - const { - selectionShapeNeedsUpdate, - selectionPoints, - } = selectionState.current; + const { selectionShapeNeedsUpdate, selectionPoints } = + selectionState.current; // Update the selection lasso lines if (selectionShapeNeedsUpdate) { const ogLength = selectionPoints.length; @@ -270,7 +268,7 @@ function updateSelection({ // A vector to re-use in calculating it's intersection with the polygon const pointVector = new THREE.Vector3(); - points.forEach(point => { + points.forEach((point) => { const isThreeD = point.position.length === 3; // Initialize the point vector from the point position const pointPosition = isThreeD diff --git a/src/Points.tsx b/src/Points.tsx index fda49e3b..1978548e 100644 --- a/src/Points.tsx +++ b/src/Points.tsx @@ -208,15 +208,15 @@ export function Points({ { + onPointerUp={(e) => { if (e.intersections) { const instanceIds = e.intersections - .map(e => e?.instanceId) + .map((e) => e?.instanceId) .filter((i): i is NonNullable => i != null); // Multi click onPointsClicked && - onPointsClicked(instanceIds.map(i => data[i])); + onPointsClicked(instanceIds.map((i) => data[i])); // Single click instanceIds.length > 0 && @@ -224,10 +224,10 @@ export function Points({ onPointClicked(data[instanceIds[0]]); } }} - onPointerOver={e => { + onPointerOver={(e) => { if (e.intersections) { const instanceIds = e.intersections - .map(e => e?.instanceId) + .map((e) => e?.instanceId) .filter((i): i is NonNullable => i != null); // Single instance callback diff --git a/src/ThreeDimensionalBounds.tsx b/src/ThreeDimensionalBounds.tsx index 1fbbfda9..ce740471 100644 --- a/src/ThreeDimensionalBounds.tsx +++ b/src/ThreeDimensionalBounds.tsx @@ -74,9 +74,8 @@ export function ThreeDimensionalBounds({ camera.zoom = Math.min(width / boundsWidth, height / boundsHeight) * boundsZoomPaddingFactor; - const furthestPointDim = getMaxDimensionFromThreeDimensionalBounds( - bounds, - ); + const furthestPointDim = + getMaxDimensionFromThreeDimensionalBounds(bounds); // Set the camera position to be a bit further away than the furthest coordinate value, to allow for rotation of the cloud without clipping through the near plane // The default near value is .1, so if we move the camera back this far, we are guaranteed to be not clip the near plane diff --git a/src/utils/threeDimensionalUtils.ts b/src/utils/threeDimensionalUtils.ts index 316ca62f..4b9a65c3 100644 --- a/src/utils/threeDimensionalUtils.ts +++ b/src/utils/threeDimensionalUtils.ts @@ -34,7 +34,7 @@ export function getThreeDimensionalBounds( minZ = Infinity, maxZ = -Infinity; - points.forEach(p => { + points.forEach((p) => { minX = Math.min(minX, p[0]); minY = Math.min(minY, p[1]); minZ = Math.min(minZ, p[2]); diff --git a/src/utils/twoDimensionalUtils.ts b/src/utils/twoDimensionalUtils.ts index 7659691b..7a324b22 100644 --- a/src/utils/twoDimensionalUtils.ts +++ b/src/utils/twoDimensionalUtils.ts @@ -30,7 +30,7 @@ export function getTwoDimensionalBounds( maxX = -Infinity, maxY = -Infinity; - points.forEach(p => { + points.forEach((p) => { minX = Math.min(minX, p[0]); minY = Math.min(minY, p[1]); maxX = Math.max(maxX, p[0]);