Part of the PyQt → Dash/Plotly migration. See cytoflowweb/PLAN.md for full context.
Estimated effort: 2–3 weeks
Depends on: Phase 2 (#2), Phase 3 (#3)
Tasks
Gate mechanism summary
| Gate type |
Plotly/Dash mechanism |
| Threshold |
clickData → go.layout.Shape vertical line |
| Range (1D) |
dcc.RangeSlider or dragmode='select' + selectedData.range.x |
| Rectangle / Quad (2D) |
dragmode='select' → selectedData.range |
| Non-rectangular (replaces PolygonOp) |
dragmode='lasso' → selectedData.lassoPoints.{x,y} |
Notes
- Lasso coordinates arrive in pre-transformed (scale) space. Apply
scale.inverse() before passing vertices to PolygonOp — the op itself is unchanged.
- Gate overlays rendered as
go.layout.Shape objects sit on top of the plot data.
- An optional "refine gate" editable vertex table can be added as a follow-on enhancement.
Milestone
All gate types work end-to-end. Lasso gate commits on mouseup and triggers pipeline re-run downstream.
Part of the PyQt → Dash/Plotly migration. See
cytoflowweb/PLAN.mdfor full context.Estimated effort: 2–3 weeks
Depends on: Phase 2 (#2), Phase 3 (#3)
Tasks
dcc.GraphclickDatacallback → updates numeric input; vertical line rendered asgo.layout.Shapedcc.RangeSliderbelow the plot, or Plotlydragmode='select'+selectedData.range.xdragmode='select'→ box-select →selectedData.rangedragmode='lasso'→selectedData.lassoPoints→ inverse-scale transform →PolygonOpverticesgo.layout.Shapepath overlaid on the plotGate mechanism summary
clickData→go.layout.Shapevertical linedcc.RangeSliderordragmode='select'+selectedData.range.xdragmode='select'→selectedData.rangedragmode='lasso'→selectedData.lassoPoints.{x,y}Notes
scale.inverse()before passing vertices toPolygonOp— the op itself is unchanged.go.layout.Shapeobjects sit on top of the plot data.Milestone
All gate types work end-to-end. Lasso gate commits on mouseup and triggers pipeline re-run downstream.