diff --git a/package-lock.json b/package-lock.json
index c90006cd7..aeb472335 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4543,7 +4543,8 @@
"@juggle/resize-observer": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.0.tgz",
- "integrity": "sha512-P1v2nvK7z2gOLVM/bveIRLG9L99uEahTGgTltyF03zixZAjI9YmKLj5Z9MpS9wBIUt5WDoQORT2lXvLOIF89iA=="
+ "integrity": "sha512-P1v2nvK7z2gOLVM/bveIRLG9L99uEahTGgTltyF03zixZAjI9YmKLj5Z9MpS9wBIUt5WDoQORT2lXvLOIF89iA==",
+ "dev": true
},
"@mdx-js/loader": {
"version": "1.6.22",
@@ -4857,6 +4858,53 @@
"react-lifecycles-compat": "^3.0.4"
}
},
+ "@react-three/fiber": {
+ "version": "6.0.14",
+ "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-6.0.14.tgz",
+ "integrity": "sha512-wrHLFBGhruOitGCeT8sNtLO3qG4y0M1d0xAYpUNIXDD1/d/lrNlUvrTF9r7Q4sR0Reo1OGf2EMUg3CvFXpDYcg==",
+ "requires": {
+ "@babel/runtime": "^7.13.10",
+ "react-merge-refs": "^1.1.0",
+ "react-reconciler": "^0.26.2",
+ "react-three-fiber": "0.0.0-deprecated",
+ "react-use-measure": "^2.0.4",
+ "resize-observer-polyfill": "^1.5.1",
+ "scheduler": "^0.20.2",
+ "use-asset": "^1.0.4",
+ "utility-types": "^3.10.0",
+ "zustand": "^3.3.3"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.13.10",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz",
+ "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "react-reconciler": {
+ "version": "0.26.2",
+ "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz",
+ "integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1",
+ "scheduler": "^0.20.2"
+ }
+ },
+ "react-three-fiber": {
+ "version": "0.0.0-deprecated",
+ "resolved": "https://registry.npmjs.org/react-three-fiber/-/react-three-fiber-0.0.0-deprecated.tgz",
+ "integrity": "sha512-EblIqTAsIpkYeM8bZtC4lcpTE0A2zCEGipFB52RgcQq/q+0oryrk7Sxt+sqhIjUu6xMNEVywV8dr74lz5yWO6A=="
+ },
+ "regenerator-runtime": {
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
+ }
+ }
+ },
"@rollup/plugin-node-resolve": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz",
@@ -8415,18 +8463,19 @@
}
},
"@types/react": {
- "version": "16.14.2",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.2.tgz",
- "integrity": "sha512-BzzcAlyDxXl2nANlabtT4thtvbbnhee8hMmH/CcJrISDBVcJS1iOsP1f0OAgSdGE0MsY9tqcrb9YoZcOFv9dbQ==",
+ "version": "17.0.3",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz",
+ "integrity": "sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==",
"requires": {
"@types/prop-types": "*",
+ "@types/scheduler": "*",
"csstype": "^3.0.2"
},
"dependencies": {
"csstype": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz",
- "integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ=="
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz",
+ "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g=="
}
}
},
@@ -8440,11 +8489,11 @@
}
},
"@types/react-dom": {
- "version": "16.9.10",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.10.tgz",
- "integrity": "sha512-ItatOrnXDMAYpv6G8UCk2VhbYVTjZT9aorLtA/OzDN9XJ2GKcfam68jutoAcILdRjsRUO8qb7AmyObF77Q8QFw==",
+ "version": "17.0.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.3.tgz",
+ "integrity": "sha512-4NnJbCeWE+8YBzupn/YrJxZ8VnjcJq5iR1laqQ1vkpQgBiA7bwk0Rp24fxsdNinzJY2U+HHS4dJJDPdoMjdJ7w==",
"requires": {
- "@types/react": "^16"
+ "@types/react": "*"
}
},
"@types/react-measure": {
@@ -8513,6 +8562,11 @@
"@types/node": "*"
}
},
+ "@types/scheduler": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
+ "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
+ },
"@types/sinonjs__fake-timers": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz",
@@ -17359,6 +17413,13 @@
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
}
},
"hoopy": {
@@ -24916,6 +24977,13 @@
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.8.1"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
}
},
"property-information": {
@@ -25217,13 +25285,12 @@
}
},
"react": {
- "version": "16.14.0",
- "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
- "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
+ "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
"requires": {
"loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "prop-types": "^15.6.2"
+ "object-assign": "^4.1.1"
}
},
"react-app-polyfill": {
@@ -25496,14 +25563,13 @@
}
},
"react-dom": {
- "version": "16.14.0",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz",
- "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==",
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
+ "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
- "prop-types": "^15.6.2",
- "scheduler": "^0.19.1"
+ "scheduler": "^0.20.2"
}
},
"react-draggable": {
@@ -25616,9 +25682,10 @@
}
},
"react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
},
"react-lifecycles-compat": {
"version": "3.0.4",
@@ -25680,32 +25747,6 @@
}
}
},
- "react-promise-suspense": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/react-promise-suspense/-/react-promise-suspense-0.3.3.tgz",
- "integrity": "sha512-OdehKsCEWYoV6pMcwxbvJH99UrbXylmXJ1QpEL9OfHaUBzcAihyfSJV8jFq325M/wW9iKc/BoiLROXxMul+MxA==",
- "requires": {
- "fast-deep-equal": "^2.0.1"
- },
- "dependencies": {
- "fast-deep-equal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
- "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
- }
- }
- },
- "react-reconciler": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.25.1.tgz",
- "integrity": "sha512-R5UwsIvRcSs3w8n9k3tBoTtUHdVhu9u84EG7E5M0Jk9F5i6DA1pQzPfUZd6opYWGy56MJOtV3VADzy6DRwYDjw==",
- "requires": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "prop-types": "^15.6.2",
- "scheduler": "^0.19.1"
- }
- },
"react-reflex": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-reflex/-/react-reflex-4.0.0.tgz",
@@ -25752,6 +25793,11 @@
"requires": {
"isarray": "0.0.1"
}
+ },
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}
}
},
@@ -26585,38 +26631,6 @@
}
}
},
- "react-three-fiber": {
- "version": "4.2.21",
- "resolved": "https://registry.npmjs.org/react-three-fiber/-/react-three-fiber-4.2.21.tgz",
- "integrity": "sha512-lbopEkL36cbAaG/y+iEGT1EFbVaVZBrOe2XGt2+HxsCL8AeWWiQQERo1HYiiqFc4p6DuoNq1hhOSxr1TKQjXuQ==",
- "requires": {
- "@babel/runtime": "^7.9.2",
- "@juggle/resize-observer": "^3.1.3",
- "react-merge-refs": "^1.0.0",
- "react-promise-suspense": "^0.3.2",
- "react-reconciler": "0.25.1",
- "react-use-measure": "^2.0.0",
- "resize-observer-polyfill": "^1.5.1",
- "scheduler": "0.19.1",
- "tiny-emitter": "^2.1.0",
- "utility-types": "^3.10.0"
- },
- "dependencies": {
- "@babel/runtime": {
- "version": "7.12.1",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz",
- "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==",
- "requires": {
- "regenerator-runtime": "^0.13.4"
- }
- },
- "regenerator-runtime": {
- "version": "0.13.7",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
- "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
- }
- }
- },
"react-universal-interface": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz",
@@ -26661,9 +26675,9 @@
}
},
"react-use-measure": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.0.1.tgz",
- "integrity": "sha512-lFfHiqcXbJ2/6aUkZwt8g5YYM7EGqNVxJhMqMPqv1BVXRKp8D7jYLlmma0SvhRY4WYxxkZpCdbJvhDylb5gcEA==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.0.4.tgz",
+ "integrity": "sha512-7K2HIGaPMl3Q9ZQiEVjen3tRXl4UDda8LiTPy/QxP8dP2rl5gPBhf7mMH6MVjjRNv3loU7sNzey/ycPNnHVTxQ==",
"requires": {
"debounce": "^1.2.0"
}
@@ -27892,9 +27906,9 @@
}
},
"scheduler": {
- "version": "0.19.1",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
- "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+ "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
@@ -30190,7 +30204,9 @@
"tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
- "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
+ "dev": true,
+ "optional": true
},
"tiny-invariant": {
"version": "1.1.0",
@@ -30859,6 +30875,21 @@
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
"dev": true
},
+ "use-asset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/use-asset/-/use-asset-1.0.4.tgz",
+ "integrity": "sha512-7/hqDrWa0iMnCoET9W1T07EmD4Eg/Wmoj/X8TGBc++ECRK4m5yTsjP4O6s0yagbxfqIOuUkIxe2/sA+VR2GxZA==",
+ "requires": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "dependencies": {
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ }
+ }
+ },
"use-composed-ref": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz",
diff --git a/package.json b/package.json
index 577482415..798435376 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"postversion": "git push && git push --tags"
},
"dependencies": {
+ "@react-three/fiber": "^6.0.14",
"@visx/axis": "^1.7.0",
"@visx/grid": "^1.7.0",
"@visx/scale": "^1.7.0",
@@ -46,9 +47,9 @@
"ndarray-ops": "^1.2.2",
"ndarray-unpack": "^1.0.0",
"normalize.css": "^8.0.1",
- "react": "^16.14.0",
+ "react": "^17.0.2",
"react-aria-menubutton": "^7.0.1",
- "react-dom": "^16.14.0",
+ "react-dom": "^17.0.2",
"react-error-boundary": "^3.1.1",
"react-icons": "^4.2.0",
"react-measure": "^2.5.2",
@@ -56,7 +57,6 @@
"react-router-dom": "^5.2.0",
"react-slider": "^1.1.4",
"react-suspense-fetch": "^0.3.0",
- "react-three-fiber": "^4.2.21",
"react-use": "^17.2.3",
"react-window": "^1.8.6",
"three": "^0.127.0",
@@ -86,9 +86,9 @@
"@types/lodash-es": "^4.17.4",
"@types/ndarray": "^1.0.8",
"@types/node": "^12.19.7",
- "@types/react": "^16.14.2",
+ "@types/react": "^17.0.3",
"@types/react-aria-menubutton": "^6.2.7",
- "@types/react-dom": "^16.9.10",
+ "@types/react-dom": "^17.0.3",
"@types/react-measure": "^2.0.6",
"@types/react-router-dom": "^5.1.7",
"@types/react-slider": "^1.1.1",
@@ -110,7 +110,7 @@
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1",
"react-app-polyfill": "^2.0.0",
- "react-is": "^16.13.1",
+ "react-is": "^17.0.2",
"react-scripts": "^4.0.3",
"typescript": "^4.2.4"
},
diff --git a/src/h5web/vis-packs/core/heatmap/Mesh.tsx b/src/h5web/vis-packs/core/heatmap/Mesh.tsx
index 782d15d44..755451959 100644
--- a/src/h5web/vis-packs/core/heatmap/Mesh.tsx
+++ b/src/h5web/vis-packs/core/heatmap/Mesh.tsx
@@ -1,6 +1,6 @@
import { rgb } from 'd3-color';
import { memo, useMemo } from 'react';
-import { useThree } from 'react-three-fiber';
+import { useThree } from '@react-three/fiber';
import {
RedFormat,
DataTexture,
@@ -124,13 +124,12 @@ function Mesh(props: Props) {
`,
};
- const { size } = useThree();
- const { width, height } = size;
+ const { width, height } = useThree((state) => state.size);
return (
-
-
+
+
);
}
diff --git a/src/h5web/vis-packs/core/hooks.ts b/src/h5web/vis-packs/core/hooks.ts
index 27228a844..9322cca99 100644
--- a/src/h5web/vis-packs/core/hooks.ts
+++ b/src/h5web/vis-packs/core/hooks.ts
@@ -2,7 +2,7 @@ import type ndarray from 'ndarray';
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { isNumber } from 'lodash-es';
import { createMemo } from 'react-use';
-import { useFrame, useThree } from 'react-three-fiber';
+import { useFrame, useThree } from '@react-three/fiber';
import type { DimensionMapping } from '../../dimension-mapper/models';
import {
applyMapping,
@@ -72,8 +72,7 @@ export function useCanvasScales(): {
ordinateScale: AxisScale;
} {
const { abscissaConfig, ordinateConfig } = useContext(AxisSystemContext);
- const { size } = useThree();
- const { width, height } = size;
+ const { width, height } = useThree((state) => state.size);
return {
abscissaScale: getCanvasScale(abscissaConfig, width),
diff --git a/src/h5web/vis-packs/core/line/DataCurve.tsx b/src/h5web/vis-packs/core/line/DataCurve.tsx
index 0182aa7f5..39e392831 100644
--- a/src/h5web/vis-packs/core/line/DataCurve.tsx
+++ b/src/h5web/vis-packs/core/line/DataCurve.tsx
@@ -1,11 +1,23 @@
import { Suspense, useMemo } from 'react';
-import { Line } from 'react-three-fiber/components';
import { CurveType } from './models';
import GlyphMaterial from './GlyphMaterial';
-import { useThree } from 'react-three-fiber';
-import { BufferGeometry } from 'three';
+import { extend, useThree } from '@react-three/fiber';
+import { BufferGeometry, Line } from 'three';
import ErrorBars from './ErrorBars';
import { useCanvasPoints } from './hooks';
+import type { Object3DNode } from '@react-three/fiber';
+
+extend({ Line_: Line });
+
+// https://github.com/pmndrs/react-three-fiber/issues/1152
+declare global {
+ // eslint-disable-next-line @typescript-eslint/no-namespace
+ namespace JSX {
+ interface IntrinsicElements {
+ line_: Object3DNode;
+ }
+ }
+}
interface Props {
abscissas: number[];
@@ -26,9 +38,9 @@ function DataCurve(props: Props) {
curveType = CurveType.LineOnly,
} = props;
- const { gl } = useThree();
+ const { domElement } = useThree((state) => state.gl);
const curveColor = color.startsWith('--')
- ? window.getComputedStyle(gl.domElement).getPropertyValue(color).trim()
+ ? window.getComputedStyle(domElement).getPropertyValue(color).trim()
: color;
const points = useCanvasPoints(abscissas, ordinates, errors);
@@ -44,9 +56,9 @@ function DataCurve(props: Props) {
return (
-
-
-
+
+
+
diff --git a/src/h5web/vis-packs/core/line/ErrorBars.tsx b/src/h5web/vis-packs/core/line/ErrorBars.tsx
index dc77b8fa2..81891b103 100644
--- a/src/h5web/vis-packs/core/line/ErrorBars.tsx
+++ b/src/h5web/vis-packs/core/line/ErrorBars.tsx
@@ -1,4 +1,4 @@
-import { useUpdate } from 'react-three-fiber';
+import { useLayoutEffect, useRef } from 'react';
import type { BufferGeometry, Vector2, Vector3 } from 'three';
import GlyphMaterial from './GlyphMaterial';
import { GLYPH_URLS } from './models';
@@ -13,24 +13,25 @@ interface Props {
function ErrorBars(props: Props) {
const { barsSegments, capsPoints, color, visible } = props;
- const barsGeometry = useUpdate(
- (geometry: BufferGeometry) => geometry.setFromPoints(barsSegments),
- [barsSegments]
- );
- const capsGeometry = useUpdate(
- (geometry) => geometry.setFromPoints(capsPoints),
- [capsPoints]
- );
+ const barsGeometry = useRef(null);
+ useLayoutEffect(() => {
+ barsGeometry.current?.setFromPoints(barsSegments);
+ }, [barsGeometry, barsSegments]);
+
+ const capsGeometry = useRef(null);
+ useLayoutEffect(() => {
+ capsGeometry.current?.setFromPoints(capsPoints);
+ }, [capsGeometry, capsPoints]);
return (
<>
-
-
+
+
-
+
>
);
diff --git a/src/h5web/vis-packs/core/line/GlyphMaterial.tsx b/src/h5web/vis-packs/core/line/GlyphMaterial.tsx
index 2ffec8e58..02e8d41cc 100644
--- a/src/h5web/vis-packs/core/line/GlyphMaterial.tsx
+++ b/src/h5web/vis-packs/core/line/GlyphMaterial.tsx
@@ -1,4 +1,4 @@
-import { useLoader } from 'react-three-fiber';
+import { useLoader } from '@react-three/fiber';
import { NearestFilter, TextureLoader } from 'three';
import { GLYPH_URLS } from './models';
@@ -13,15 +13,7 @@ function GlyphMaterial(props: Props) {
const sprite = useLoader(TextureLoader, glyphURL || GLYPH_URLS.Cross);
sprite.magFilter = NearestFilter;
- return (
-
- );
+ return ;
}
export default GlyphMaterial;
diff --git a/src/h5web/vis-packs/core/line/hooks.ts b/src/h5web/vis-packs/core/line/hooks.ts
index 4e39f6aa5..f4d51160d 100644
--- a/src/h5web/vis-packs/core/line/hooks.ts
+++ b/src/h5web/vis-packs/core/line/hooks.ts
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
-import { useThree } from 'react-three-fiber';
+import { useThree } from '@react-three/fiber';
import { Vector3 } from 'three';
import { useCanvasScales } from '../hooks';
@@ -8,7 +8,7 @@ export function useCanvasPoints(
ordinates: number[],
errors?: number[]
) {
- const { camera } = useThree();
+ const camera = useThree((state) => state.camera);
const { abscissaScale, ordinateScale } = useCanvasScales();
return useMemo(() => {
diff --git a/src/h5web/vis-packs/core/shared/AxisSystem.tsx b/src/h5web/vis-packs/core/shared/AxisSystem.tsx
index 70fc9c724..332c6ef8d 100644
--- a/src/h5web/vis-packs/core/shared/AxisSystem.tsx
+++ b/src/h5web/vis-packs/core/shared/AxisSystem.tsx
@@ -1,5 +1,5 @@
import { useContext } from 'react';
-import { useThree } from 'react-three-fiber';
+import { useThree } from '@react-three/fiber';
import Html from './Html';
import styles from './AxisSystem.module.css';
import type { AxisOffsets, Domain } from '../models';
@@ -17,8 +17,8 @@ function AxisSystem(props: Props) {
const { abscissaConfig, ordinateConfig } = useContext(AxisSystemContext);
- const { camera, size } = useThree();
- const { position, zoom } = camera;
+ const { position, zoom } = useThree((state) => state.camera);
+ const size = useThree((state) => state.size);
const { width, height } = size;
const { abscissaScale, ordinateScale } = useCanvasScales();
diff --git a/src/h5web/vis-packs/core/shared/Html.tsx b/src/h5web/vis-packs/core/shared/Html.tsx
index 469853187..482a73b4b 100644
--- a/src/h5web/vis-packs/core/shared/Html.tsx
+++ b/src/h5web/vis-packs/core/shared/Html.tsx
@@ -6,7 +6,7 @@ import {
useLayoutEffect,
} from 'react';
import ReactDOM from 'react-dom';
-import { useThree } from 'react-three-fiber';
+import { useThree } from '@react-three/fiber';
// Simplified version of `drei`'s `` component
// https://github.com/pmndrs/drei/blob/v2.2.3/src/Html.tsx
@@ -14,15 +14,15 @@ const Html = forwardRef>(
(props, ref) => {
const { className, style, children, ...divProps } = props;
- const { gl, size } = useThree();
- const { width, height } = size;
+ const { width, height } = useThree((state) => state.size);
+ const gl = useThree((state) => state.gl);
const { parentElement } = gl.domElement;
// Container `div` for ReactDOM to render into, appended next to R3F's `canvas`
const [el] = useState(() => document.createElement('div'));
useEffect(() => {
- el.style.cssText = `position: absolute; top: 0; left: 0; z-index: 0;`;
+ el.style.cssText = `position: absolute; top: 0; left: 0;`;
if (parentElement) {
parentElement.append(el);
@@ -48,6 +48,7 @@ const Html = forwardRef>(
left: 0,
width,
height,
+ pointerEvents: 'none', // let pointer events pass through to canvas
...style,
}}
{...divProps}
diff --git a/src/h5web/vis-packs/core/shared/PanZoomMesh.tsx b/src/h5web/vis-packs/core/shared/PanZoomMesh.tsx
index 333e21297..5ce15cbc3 100644
--- a/src/h5web/vis-packs/core/shared/PanZoomMesh.tsx
+++ b/src/h5web/vis-packs/core/shared/PanZoomMesh.tsx
@@ -1,15 +1,17 @@
import { useRef, useCallback, useEffect } from 'react';
import type { Vector3 } from 'three';
-import { PointerEvent, WheelEvent, useThree } from 'react-three-fiber';
+import { useThree } from '@react-three/fiber';
import { clamp } from 'lodash-es';
import Html from './Html';
import { useWheelCapture } from '../hooks';
+import type { ThreeEvent } from '@react-three/fiber/dist/declarations/src/core/events';
const ZOOM_FACTOR = 0.95;
function PanZoomMesh() {
- const { camera, invalidate, size } = useThree();
- const { width, height } = size;
+ const camera = useThree((state) => state.camera);
+ const { width, height } = useThree((state) => state.size);
+ const invalidate = useThree((state) => state.invalidate);
const startOffsetPosition = useRef(); // `useRef` to avoid re-renders
@@ -33,9 +35,9 @@ function PanZoomMesh() {
);
const onPointerDown = useCallback(
- (evt: PointerEvent) => {
- const { currentTarget, pointerId, unprojectedPoint } = evt;
- currentTarget.setPointerCapture(pointerId);
+ (evt: ThreeEvent) => {
+ const { target, pointerId, unprojectedPoint } = evt;
+ (target as Element).setPointerCapture(pointerId); // https://stackoverflow.com/q/28900077/758806
const projectedPoint = camera.worldToLocal(unprojectedPoint.clone());
startOffsetPosition.current = camera.position.clone().add(projectedPoint);
@@ -43,15 +45,15 @@ function PanZoomMesh() {
[camera]
);
- const onPointerUp = useCallback((evt: PointerEvent) => {
- const { currentTarget, pointerId } = evt;
- currentTarget.releasePointerCapture(pointerId);
+ const onPointerUp = useCallback((evt: ThreeEvent) => {
+ const { target, pointerId } = evt;
+ (target as Element).releasePointerCapture(pointerId); // https://stackoverflow.com/q/28900077/758806
startOffsetPosition.current = undefined;
}, []);
const onPointerMove = useCallback(
- (evt: PointerEvent) => {
+ (evt: ThreeEvent) => {
if (!startOffsetPosition.current) {
return;
}
@@ -69,7 +71,7 @@ function PanZoomMesh() {
);
const onWheel = useCallback(
- (evt: WheelEvent) => {
+ (evt: ThreeEvent) => {
const factor = evt.deltaY > 0 ? ZOOM_FACTOR : 1 / ZOOM_FACTOR;
camera.zoom = Math.max(1, camera.zoom * factor);
@@ -97,8 +99,8 @@ function PanZoomMesh() {
return (
<>
-
-
+
+
>
diff --git a/src/h5web/vis-packs/core/shared/TooltipMesh.tsx b/src/h5web/vis-packs/core/shared/TooltipMesh.tsx
index 223435024..c2e11c0cb 100644
--- a/src/h5web/vis-packs/core/shared/TooltipMesh.tsx
+++ b/src/h5web/vis-packs/core/shared/TooltipMesh.tsx
@@ -1,10 +1,11 @@
import { useCallback } from 'react';
-import { PointerEvent, useThree } from 'react-three-fiber';
+import { useThree } from '@react-three/fiber';
import { TooltipWithBounds, useTooltip } from '@visx/tooltip';
import { Line } from '@visx/shape';
import Html from './Html';
import styles from './TooltipMesh.module.css';
import { useCanvasScales } from '../hooks';
+import type { ThreeEvent } from '@react-three/fiber/dist/declarations/src/core/events';
type Coords = [number, number];
type Guides = 'horizontal' | 'vertical' | 'both';
@@ -18,8 +19,8 @@ interface Props {
function TooltipMesh(props: Props) {
const { formatIndex, formatValue, guides } = props;
- const { camera, size } = useThree();
- const { width, height } = size;
+ const camera = useThree((state) => state.camera);
+ const { width, height } = useThree((state) => state.size);
// Scales to compute data coordinates from unprojected mesh coordinates
const { abscissaScale, ordinateScale } = useCanvasScales();
@@ -36,7 +37,7 @@ function TooltipMesh(props: Props) {
// Update tooltip when pointer moves
// When panning, events are handled and stopped by texture mesh and do not reach this mesh (which is behind)
const onPointerMove = useCallback(
- (evt: PointerEvent) => {
+ (evt: ThreeEvent) => {
const { zoom } = camera;
const projectedPoint = camera.worldToLocal(evt.unprojectedPoint.clone());
@@ -58,8 +59,8 @@ function TooltipMesh(props: Props) {
// Show tooltip after dragging unless pointer has left canvas
const onPointerUp = useCallback(
- (evt: PointerEvent) => {
- const { offsetX: x, offsetY: y } = evt.nativeEvent;
+ (evt: ThreeEvent) => {
+ const { offsetX: x, offsetY: y } = evt;
if (x >= 0 && x <= width && y >= 0 && y <= height) {
onPointerMove(evt);
}
@@ -72,8 +73,8 @@ function TooltipMesh(props: Props) {
return (
<>
-
-
+
+
{tooltipOpen && tooltipData && value && (
diff --git a/src/h5web/vis-packs/core/shared/VisCanvas.tsx b/src/h5web/vis-packs/core/shared/VisCanvas.tsx
index 38ff9527a..b4a6586e3 100644
--- a/src/h5web/vis-packs/core/shared/VisCanvas.tsx
+++ b/src/h5web/vis-packs/core/shared/VisCanvas.tsx
@@ -1,5 +1,5 @@
import type { ReactNode } from 'react';
-import { Canvas } from 'react-three-fiber';
+import { Canvas } from '@react-three/fiber';
import { useMeasure } from 'react-use';
import styles from './VisCanvas.module.css';
import type { AxisConfig } from '../models';
@@ -64,10 +64,10 @@ function VisCanvas(props: Props) {