Skip to content

Commit

Permalink
spike density with raster map
Browse files Browse the repository at this point in the history
  • Loading branch information
magland committed Feb 19, 2025
1 parent 44019cc commit c3b3d8c
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 33 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Changes

## February 19, 2025
- Added horizontal spacing around splitter bar in HorizontalSplitter component
- Add SpikeDensity plugin view for NWB files
- Added job resubmission capability for failed jobs
- Added optional rastermap sorting to SpikeDensity plugin with UI controls for computing and toggling the sorting

## February 18, 2025
- Added distributed job processing system (neurosift-job-manager)
Expand Down
23 changes: 15 additions & 8 deletions src/components/HorizontalSplitter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {
FunctionComponent,
useCallback,
useEffect,
useRef,
useState,
} from "react";

Expand All @@ -12,6 +13,8 @@ export interface HorizontalSplitterProps {
children: [React.ReactNode, React.ReactNode]; // Exactly two children required
}

const SPLITTER_WIDTH = 8; // Width of the splitter handle area in pixels

const HorizontalSplitter: FunctionComponent<HorizontalSplitterProps> = ({
width,
height,
Expand All @@ -22,6 +25,7 @@ const HorizontalSplitter: FunctionComponent<HorizontalSplitterProps> = ({
initialSplitterPosition,
);
const [isDragging, setIsDragging] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);

const handleMouseDown = useCallback(() => {
setIsDragging(true);
Expand All @@ -31,11 +35,13 @@ const HorizontalSplitter: FunctionComponent<HorizontalSplitterProps> = ({
if (!isDragging) return;

const handleMouseMove = (e: MouseEvent) => {
const newPosition = e.clientX;
if (!containerRef.current) return;
const containerRect = containerRef.current.getBoundingClientRect();
const relativeX = e.clientX - containerRect.left;
// Constrain position to reasonable bounds (minimum 100px from either edge)
const constrainedPosition = Math.max(
100,
Math.min(width - 100, newPosition),
Math.min(width - 100, relativeX),
);
setSplitterPosition(constrainedPosition);
};
Expand All @@ -62,11 +68,12 @@ const HorizontalSplitter: FunctionComponent<HorizontalSplitterProps> = ({
setSplitterPosition((prev) => Math.max(100, Math.min(width - 100, prev)));
}, [width]);

const leftPanelWidth = splitterPosition;
const rightPanelWidth = width - splitterPosition;
const leftPanelWidth = splitterPosition - SPLITTER_WIDTH / 2;
const rightPanelWidth = width - splitterPosition - SPLITTER_WIDTH / 2;

return (
<div
ref={containerRef}
style={{
position: "relative",
width,
Expand All @@ -91,9 +98,9 @@ const HorizontalSplitter: FunctionComponent<HorizontalSplitterProps> = ({
<div
style={{
position: "absolute",
left: splitterPosition - 4,
left: splitterPosition - SPLITTER_WIDTH / 2,
top: 0,
width: 8,
width: SPLITTER_WIDTH,
height,
cursor: "col-resize",
backgroundColor: isDragging ? "#666" : "transparent",
Expand All @@ -104,7 +111,7 @@ const HorizontalSplitter: FunctionComponent<HorizontalSplitterProps> = ({
<div
style={{
position: "absolute",
left: 4,
left: SPLITTER_WIDTH / 2,
top: 0,
width: 1,
height: "100%",
Expand All @@ -115,7 +122,7 @@ const HorizontalSplitter: FunctionComponent<HorizontalSplitterProps> = ({
<div
style={{
position: "absolute",
left: splitterPosition,
left: splitterPosition + SPLITTER_WIDTH / 2,
top: 0,
width: rightPanelWidth,
height,
Expand Down
34 changes: 30 additions & 4 deletions src/jobManager/components/JobStatusHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type Props = {
isRefreshing: boolean;
onSubmit: () => void;
onRefresh: () => void;
submitButtonLabel?: string;
jobLabel: string;
};

export const JobStatusHandler: FunctionComponent<Props> = ({
Expand All @@ -16,12 +16,12 @@ export const JobStatusHandler: FunctionComponent<Props> = ({
isRefreshing,
onSubmit,
onRefresh,
submitButtonLabel = "Submit Job",
jobLabel,
}) => {
if (!job) {
return (
<div>
<button onClick={onSubmit}>{submitButtonLabel}</button>
<button onClick={onSubmit}>Submit {jobLabel}</button>
</div>
);
}
Expand All @@ -41,6 +41,7 @@ export const JobStatusHandler: FunctionComponent<Props> = ({
}}
>
<div>
<p>{jobLabel}</p>
<p>To process this job using Docker or Apptainer:</p>
<code
style={{
Expand Down Expand Up @@ -137,7 +138,7 @@ export const JobStatusHandler: FunctionComponent<Props> = ({
color: "#d32f2f",
}}
>
{error ? `Error: ${error}` : "Job failed"}
`${jobLabel} failed: ${error}`
</div>
<div>
<button onClick={onSubmit}>Resubmit Job</button>
Expand All @@ -146,5 +147,30 @@ export const JobStatusHandler: FunctionComponent<Props> = ({
);
}

if (job.status === "completed") {
return (
<div
style={{
padding: "10px",
display: "flex",
flexDirection: "column",
gap: "15px",
}}
>
<div
style={{
backgroundColor: "#f0f9f1",
border: "1px solid #a5d6a7",
borderRadius: "4px",
padding: "10px",
color: "#1b5e20",
}}
>
{jobLabel} completed successfully
</div>
</div>
);
}

return null;
};
Loading

0 comments on commit c3b3d8c

Please sign in to comment.