-
Notifications
You must be signed in to change notification settings - Fork 8
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
Showing
6 changed files
with
374 additions
and
22 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
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
107 changes: 107 additions & 0 deletions
107
src/pages/NwbPage/plugins/simple-timeseries/TimeseriesPlotTSV2.tsx
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,107 @@ | ||
import { FunctionComponent, useEffect, useState } from "react"; | ||
import TimeScrollView2 from "@shared/component-time-scroll-view-2/TimeScrollView2"; | ||
import { TimeseriesPlotProps as Props } from "./types"; | ||
|
||
const defaultMargins = { | ||
left: 50, | ||
right: 20, | ||
top: 20, | ||
bottom: 40, | ||
}; | ||
|
||
const hideToolbar = true; | ||
const gridlineOpts = { hideX: false, hideY: false }; | ||
|
||
const TimeseriesPlotTSV2: FunctionComponent<Props> = ({ | ||
width, | ||
height, | ||
timestamps, | ||
data, | ||
visibleStartTime, | ||
visibleEndTime, | ||
channelSeparation, | ||
}) => { | ||
const [canvasElement, setCanvasElement] = useState< | ||
HTMLCanvasElement | undefined | ||
>(); | ||
const [worker, setWorker] = useState<Worker | null>(null); | ||
|
||
// Initialize worker | ||
useEffect(() => { | ||
if (!canvasElement) return; | ||
|
||
const worker = new Worker( | ||
new URL("./timeseriesPlotTSV2Worker", import.meta.url), | ||
); | ||
let offscreenCanvas: OffscreenCanvas; | ||
|
||
try { | ||
offscreenCanvas = canvasElement.transferControlToOffscreen(); | ||
} catch (err) { | ||
console.warn(err); | ||
console.warn( | ||
"Unable to transfer control to offscreen canvas (expected during dev)", | ||
); | ||
return; | ||
} | ||
|
||
worker.postMessage( | ||
{ | ||
canvas: offscreenCanvas, | ||
}, | ||
[offscreenCanvas], | ||
); | ||
|
||
setWorker(worker); | ||
|
||
return () => { | ||
worker.terminate(); | ||
}; | ||
}, [canvasElement]); | ||
|
||
// Update plot when data or view changes | ||
useEffect(() => { | ||
if (!worker) return; | ||
|
||
const opts = { | ||
canvasWidth: width, | ||
canvasHeight: height, | ||
margins: defaultMargins, | ||
visibleStartTimeSec: visibleStartTime, | ||
visibleEndTimeSec: visibleEndTime, | ||
channelSeparation, | ||
data, | ||
timestamps, | ||
}; | ||
|
||
worker.postMessage({ opts }); | ||
}, [ | ||
worker, | ||
width, | ||
height, | ||
visibleStartTime, | ||
visibleEndTime, | ||
channelSeparation, | ||
data, | ||
timestamps, | ||
]); | ||
|
||
const yAxisInfo = { | ||
showTicks: true, | ||
yMin: undefined, | ||
yMax: undefined, | ||
}; | ||
|
||
return ( | ||
<TimeScrollView2 | ||
width={width} | ||
height={height} | ||
onCanvasElement={setCanvasElement} | ||
gridlineOpts={gridlineOpts} | ||
yAxisInfo={yAxisInfo} | ||
hideToolbar={hideToolbar} | ||
/> | ||
); | ||
}; | ||
|
||
export default TimeseriesPlotTSV2; |
90 changes: 90 additions & 0 deletions
90
src/pages/NwbPage/plugins/simple-timeseries/implementation-plan.md
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,90 @@ | ||
# TimeseriesPlot TimeScrollView2 Implementation Plan | ||
|
||
## Overview | ||
Replace Plotly-based visualization with TimeScrollView2 in SimpleTimeseriesView while maintaining the same plotting behavior. | ||
|
||
## Components to Create/Modify | ||
|
||
### 1. TimeseriesPlotTSV2.tsx | ||
- Props interface matching TimeseriesPlot: | ||
```typescript | ||
type Props = { | ||
timestamps: number[] | ||
data: number[][] | ||
visibleStartTime: number | ||
visibleEndTime: number | ||
channelNames?: string[] | ||
channelSeparation: number | ||
width: number | ||
height: number | ||
} | ||
``` | ||
- Key Features: | ||
- Uses TimeScrollView2 for visualization | ||
- Sets up worker communication | ||
- Handles canvas setup and data updates | ||
- Manages visible time range | ||
- Supports channel separation | ||
### 2. timeseriesPlotTSV2Worker.ts | ||
- Responsibilities: | ||
- Receives offscreen canvas | ||
- Handles opts updates (dimensions, margins, time range) | ||
- Processes and renders timeseries data | ||
- Implements efficient drawing algorithm | ||
- Supports channel separation visualization | ||
### 3. SimpleTimeseriesView.tsx Changes | ||
- Add usePlotly flag (initially false) | ||
- Conditional rendering: | ||
```typescript | ||
{timeseriesClient.isLabeledEvents() ? ( | ||
<LabeledEventsPlot ... /> | ||
) : usePlotly ? ( | ||
<TimeseriesPlot ... /> | ||
) : ( | ||
<TimeseriesPlotTSV2 ... /> | ||
)} | ||
``` | ||
## Implementation Steps | ||
1. Create TimeseriesPlotTSV2.tsx: | ||
- Use TimeScrollView2 component | ||
- Set up canvas and worker initialization | ||
- Handle prop updates and data changes | ||
- Implement channel separation logic | ||
2. Create timeseriesPlotTSV2Worker.ts: | ||
- Handle canvas setup messages | ||
- Process opts updates | ||
- Implement drawing logic: | ||
- Clear canvas | ||
- Draw time series lines | ||
- Apply channel separation | ||
- Handle visible range updates | ||
3. Update SimpleTimeseriesView.tsx: | ||
- Add usePlotly flag | ||
- Add conditional rendering | ||
- Ensure props are passed correctly | ||
## Testing Plan | ||
1. Visual Verification: | ||
- Compare rendering with Plotly version | ||
- Verify channel separation works | ||
- Check time range navigation | ||
- Validate multi-channel display | ||
2. Performance Testing: | ||
- Compare rendering speed | ||
- Check memory usage | ||
- Verify worker communication | ||
## Notes | ||
- Worker-based rendering should improve performance | ||
- TimeScrollView2 provides built-in time navigation | ||
- Channel separation needs custom implementation in worker | ||
- Maintain same visual style as Plotly version |
Oops, something went wrong.