diff --git a/package-lock.json b/package-lock.json index 62d7e58..188323d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,11 +19,13 @@ "lock": "^1.1.0", "normalize.css": "^8.0.1", "react": "^18.2.0", + "react-color": "^2.19.3", "react-dom": "^18.2.0", "three": "^0.158.0", "zustand": "^4.4.6" }, "devDependencies": { + "@types/react-color": "^3.0.10", "@types/react-dom": "^18.2.15", "@types/three": "^0.155.0", "@typescript-eslint/eslint-plugin": "^6.10.0", @@ -928,6 +930,14 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "node_modules/@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1658,6 +1668,16 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-color": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.10.tgz", + "integrity": "sha512-6K5BAn3zyd8lW8UbckIAVeXGxR82Za9jyGD2DBEynsa7fKaguLDVtjfypzs7fgEV7bULgs7uhds8A8v1wABTvQ==", + "dev": true, + "dependencies": { + "@types/react": "*", + "@types/reactcss": "*" + } + }, "node_modules/@types/react-dom": { "version": "18.2.15", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.15.tgz", @@ -1682,6 +1702,15 @@ "@types/react": "*" } }, + "node_modules/@types/reactcss": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.9.tgz", + "integrity": "sha512-dN2TtynLIZaZZ4gQNK6WM0Nff8GWYCXKl1Kvsp59WgROtx03ixCwuC1UWdesgt2O1P5Qk+0+SIfsy3eiwblMEA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.5", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz", @@ -4450,6 +4479,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -4500,6 +4534,11 @@ "node": ">=12" } }, + "node_modules/material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==" + }, "node_modules/math-expression-evaluator": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz", @@ -5018,6 +5057,23 @@ "react": "^16.3.0 || ^17.0.0" } }, + "node_modules/react-color": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", + "integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==", + "dependencies": { + "@icons/material": "^0.2.4", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -5146,6 +5202,14 @@ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "dependencies": { + "lodash": "^4.0.1" + } + }, "node_modules/reduce-css-calc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", @@ -5631,6 +5695,11 @@ "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==", "dev": true }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + }, "node_modules/tinypool": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", @@ -5788,7 +5857,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "devOptional": true, + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index af9b278..d7a391f 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,13 @@ "lock": "^1.1.0", "normalize.css": "^8.0.1", "react": "^18.2.0", + "react-color": "^2.19.3", "react-dom": "^18.2.0", "three": "^0.158.0", "zustand": "^4.4.6" }, "devDependencies": { + "@types/react-color": "^3.0.10", "@types/react-dom": "^18.2.15", "@types/three": "^0.155.0", "@typescript-eslint/eslint-plugin": "^6.10.0", diff --git a/src/plot/centrePlot.tsx b/src/plot/centrePlot.tsx index 7527107..ae86343 100644 --- a/src/plot/centrePlot.tsx +++ b/src/plot/centrePlot.tsx @@ -36,6 +36,8 @@ import { nanometres2Angstroms, } from "../utils/units"; import { convertBetweenQAndD, convertBetweenQAndS } from "../results/scatteringQuantities"; +import { color2String } from "./plotUtils"; + export default function CentrePlot(): JSX.Element { const plotConfig = usePlotStore(); @@ -214,8 +216,8 @@ export default function CentrePlot(): JSX.Element { } return ( - - + +
)} @@ -333,7 +335,7 @@ export default function CentrePlot(): JSX.Element { {plotConfig.detector && ( { + plotConfig.update({ detectorColour: color.rgb }) + } + + const handleCameraTubeColourChange = (color: ColorResult) => { + plotConfig.update({ cameraTubeColor: color.rgb }) + } + return ( Legend - Add something to do with colors here } - label="Detector" + label={ + + + Detector: + } /> { - plotConfig.update({ beamstop: checked }); - plotConfig.update({ qrange: checked }); - }} + checked={plotConfig.cameraTube} + onChange={(_, checked) => + plotConfig.update({ cameraTube: checked }) + } /> } - label="Beamstop" + label={ + + + Camera Tube: + } /> - plotConfig.update({ cameraTube: checked }) - } + checked={plotConfig.beamstop} + onChange={(_, checked) => { + plotConfig.update({ beamstop: checked }); + plotConfig.update({ qrange: checked }); + }} /> } - label="Camera tube" + label="Beamstop" + /> - - Current calibrant: {5} - Axes: ((set) => ({ detector: true, + detectorColour: { r: 1, g: 2, b: 1, a: 0.2 }, beamstop: true, cameraTube: true, + cameraTubeColor: { r: 1, g: 2, b: 1, a: 0.2 }, clearnace: true, qrange: true, mask: false, diff --git a/src/plot/plotUtils.ts b/src/plot/plotUtils.ts index 50fa698..9e14892 100644 --- a/src/plot/plotUtils.ts +++ b/src/plot/plotUtils.ts @@ -1,5 +1,6 @@ import { CircularDevice, Detector } from "../utils/types"; import NumericRange from "../calculations/numericRange"; +import { RGBColor } from "react-color"; const offset = 100; @@ -18,3 +19,7 @@ export const getDomains = ( yAxis: new NumericRange(-offset, Math.round(maxLength + offset)), }; }; + +export const color2String = (color: RGBColor) => { + return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})` +}; \ No newline at end of file diff --git a/src/presets/presetManager.ts b/src/presets/presetManager.ts index 923714f..a700d3a 100644 --- a/src/presets/presetManager.ts +++ b/src/presets/presetManager.ts @@ -16,4 +16,3 @@ export interface AppDataFormat extends BeamlineConfig { export const detectorList = detectorData as Record; export const presetList = presetData as Record; export const defaultConfig = presetList[Object.keys(presetList)[0]]; - diff --git a/src/utils/colourPicker.tsx b/src/utils/colourPicker.tsx new file mode 100644 index 0000000..41c0db3 --- /dev/null +++ b/src/utils/colourPicker.tsx @@ -0,0 +1,34 @@ +import Popover from '@mui/material/Popover'; +import React from 'react'; +import { ColorResult, RGBColor, SketchPicker } from 'react-color'; +import { IconButton } from '@mui/material'; +import { color2String } from '../plot/plotUtils'; +import SquareIcon from '@mui/icons-material/Square'; + +export default function ColourPickerPopover(props: { color: RGBColor, onChangeComplete: (color: ColorResult) => void }) { + const [anchorEl, setAnchorEl] = React.useState(null); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + const open = Boolean(anchorEl); + + return ( +
+ + + + +
+ ); +} \ No newline at end of file