-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b6f3655
commit 0bd4779
Showing
12 changed files
with
314 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
import { useInsetOptions } from '../../1d/inset/InsetProvider.js'; | ||
import { useChartData } from '../../context/ChartContext.js'; | ||
|
||
export function ClipPathContainer({ children }) { | ||
const { displayerKey } = useChartData(); | ||
const { id: insetKey = 'primary' } = useInsetOptions() || {}; | ||
|
||
return <g clipPath={`url(#${displayerKey}clip-chart)`}>{children}</g>; | ||
return ( | ||
<g clipPath={`url(#${displayerKey}clip-chart-${insetKey})`}>{children}</g> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import styled from '@emotion/styled'; | ||
import { useEffect, useState } from 'react'; | ||
import { BsArrowsMove } from 'react-icons/bs'; | ||
import { FaTimes } from 'react-icons/fa'; | ||
import { Rnd } from 'react-rnd'; | ||
|
||
import { useGlobal } from '../../context/GlobalContext.js'; | ||
import { ActionsButtonsPopover } from '../../elements/ActionsButtonsPopover.js'; | ||
import type { ActionsButtonsPopoverProps } from '../../elements/ActionsButtonsPopover.js'; | ||
import { Viewer1D } from '../Viewer1D.js'; | ||
|
||
import { InsetProvider } from './InsetProvider.js'; | ||
|
||
import type { Inset } from './index.js'; | ||
|
||
const AUTO_CROP_MARGIN = 30; | ||
|
||
interface InsetBounding { | ||
x: number; | ||
y: number; | ||
width: number; | ||
height: number; | ||
} | ||
|
||
const ReactRnd = styled(Rnd)` | ||
border: 1px solid transparent; | ||
&:hover { | ||
border: 1px solid #ebecf1; | ||
background-color: white; | ||
button { | ||
visibility: visible; | ||
} | ||
} | ||
`; | ||
|
||
export function DraggableInset(props: Pick<Inset, 'id' | 'bounding'>) { | ||
const { id, bounding: externalBounding } = props; | ||
const { viewerRef } = useGlobal(); | ||
const [bounding, setBounding] = useState<InsetBounding>(externalBounding); | ||
const [isMoveActive, setIsMoveActive] = useState(false); | ||
|
||
useEffect(() => { | ||
setBounding({ ...externalBounding }); | ||
}, [externalBounding]); | ||
|
||
// eslint-disable-next-line unicorn/consistent-function-scoping, @typescript-eslint/no-empty-function | ||
function handleRemove() {} | ||
|
||
function handleResize( | ||
internalBounding: Pick<InsetBounding, 'height' | 'width'>, | ||
) { | ||
const { width, height } = externalBounding; | ||
internalBounding.width += width; | ||
internalBounding.height += height; | ||
setBounding((prevBounding) => ({ ...prevBounding, ...internalBounding })); | ||
} | ||
|
||
function handleDrag(internalBounding: Pick<InsetBounding, 'x' | 'y'>) { | ||
setBounding((prevBounding) => ({ ...prevBounding, ...internalBounding })); | ||
} | ||
|
||
if (!viewerRef) return null; | ||
|
||
const { width, height, x, y } = bounding; | ||
|
||
const actionsButtons: ActionsButtonsPopoverProps['buttons'] = [ | ||
{ | ||
icon: <BsArrowsMove />, | ||
|
||
intent: 'none', | ||
title: 'Move information block', | ||
style: { cursor: 'move' }, | ||
className: 'handle', | ||
}, | ||
{ | ||
icon: <FaTimes />, | ||
intent: 'danger', | ||
title: 'Hide information block', | ||
}, | ||
]; | ||
|
||
return ( | ||
<ReactRnd | ||
default={bounding} | ||
minWidth={90 + AUTO_CROP_MARGIN * 2} | ||
minHeight={100 + AUTO_CROP_MARGIN * 2} | ||
dragHandleClassName="handle" | ||
enableUserSelectHack={false} | ||
bounds={viewerRef} | ||
style={{ zIndex: 1 }} | ||
onDragStart={() => setIsMoveActive(true)} | ||
onResize={(e, dir, eRef, { width, height }) => | ||
handleResize({ width, height }) | ||
} | ||
// onResizeStop={(e, dir, eRef, { width, height }) => | ||
// } | ||
onDrag={(e, { x, y }) => { | ||
handleDrag({ x, y }); | ||
}} | ||
onDragStop={(e, { x, y }) => { | ||
handleDrag({ x, y }); | ||
setIsMoveActive(false); | ||
}} | ||
resizeHandleWrapperStyle={{ backgroundColor: 'white' }} | ||
> | ||
<ActionsButtonsPopover | ||
buttons={actionsButtons} | ||
fill | ||
positioningStrategy="fixed" | ||
position="top-left" | ||
direction="row" | ||
targetProps={{ style: { width: '100%', height: '100%' } }} | ||
space={2} | ||
{...(isMoveActive && { isOpen: true })} | ||
modifiers={{ | ||
offset: { | ||
data: { x, y }, | ||
}, | ||
}} | ||
> | ||
<InsetProvider id={id} width={width} height={height}> | ||
<Viewer1D /> | ||
</InsetProvider> | ||
</ActionsButtonsPopover> | ||
</ReactRnd> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import type { ReactNode } from 'react'; | ||
import { createContext, useContext, useMemo } from 'react'; | ||
|
||
export interface InsetPagContextProps { | ||
width: number; | ||
height: number; | ||
id: string; | ||
} | ||
|
||
const InsetContext = createContext<InsetPagContextProps | null>(null); | ||
|
||
export function useInsetOptions() { | ||
return useContext(InsetContext); | ||
} | ||
|
||
interface InsetProviderProps extends InsetPagContextProps { | ||
children: ReactNode; | ||
} | ||
|
||
export function InsetProvider(props: InsetProviderProps) { | ||
const { children, width, height, id = 'primary' } = props; | ||
|
||
const state = useMemo(() => { | ||
return { | ||
width, | ||
height, | ||
margin: { | ||
top: 10, | ||
right: 10, | ||
bottom: 30, | ||
left: 10, | ||
}, | ||
id, | ||
}; | ||
}, [height, id, width]); | ||
|
||
return ( | ||
<InsetContext.Provider value={state}>{children}</InsetContext.Provider> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { DraggableInset } from './DraggableInset.js'; | ||
|
||
export interface InsetBounding { | ||
x: number; | ||
y: number; | ||
width: number; | ||
height: number; | ||
} | ||
|
||
export interface Inset { | ||
id: string; | ||
bounding: InsetBounding; | ||
spectraIds: string[]; | ||
xDomain: number[]; | ||
yDomain: number[]; | ||
} | ||
|
||
const insets: Inset[] = [ | ||
{ | ||
id: 'inset1', | ||
bounding: { x: 0, y: 0, width: 400, height: 200 }, | ||
spectraIds: [], | ||
xDomain: [1, 12], | ||
yDomain: [0, 500], | ||
}, | ||
{ | ||
id: 'inset2', | ||
bounding: { x: 150, y: 0, width: 300, height: 150 }, | ||
spectraIds: [], | ||
xDomain: [1, 12], | ||
yDomain: [0, 500], | ||
}, | ||
]; | ||
|
||
export function Insets() { | ||
return ( | ||
<> | ||
{insets.map((inset) => { | ||
return ( | ||
<DraggableInset | ||
key={inset.id} | ||
id={inset.id} | ||
bounding={inset.bounding} | ||
/> | ||
); | ||
})} | ||
</> | ||
); | ||
} |
Oops, something went wrong.