Skip to content

Commit a50ed93

Browse files
committed
feat(events): 1-D / PlotXY double_click reports ydata (data coords)
The 1-D dblclick handler already computed xdata; add ydata by inverting the linear y transform. draw1d caches the rendered y bounds (p._1dDMin/_1dDMax) so the inverse uses exactly what was drawn — for a PlotXY coordinate axis the y range is y_range, not the hidden zero-curve's data_min/max. Matches the 2-D image path so a coordinate axis can be picked in data space. Test: test_double_click_reports_data_coords (centre click → centre of x/y range).
1 parent 6cc6b4b commit a50ed93

3 files changed

Lines changed: 40 additions & 3 deletions

File tree

anyplotlib/figure_esm.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,6 +3261,10 @@ fn fs(in : VsOut) -> @location(0) vec4<f32> {
32613261
const x0=st.view_x0||0, x1=st.view_x1||1;
32623262
let dMin=st.data_min, dMax=st.data_max;
32633263
if (st.y_range && st.y_range.length === 2) { dMin = st.y_range[0]; dMax = st.y_range[1]; }
3264+
// Cache the linear y bounds so the dblclick handler inverts event y → data y
3265+
// using exactly what was drawn (for a PlotXY coordinate axis the y range is
3266+
// y_range, not the hidden zero-curve's data_min/max).
3267+
p._1dDMin=dMin; p._1dDMax=dMax;
32643268
const units=st.units||'', yUnits=st.y_units||'';
32653269

32663270
const isLog = st.yscale === 'log';
@@ -4588,14 +4592,20 @@ fn fs(in : VsOut) -> @location(0) vec4<f32> {
45884592
overlayCanvas.addEventListener('dblclick',(e)=>{
45894593
const {mx,my}=_clientPos(e,overlayCanvas,p.pw,p.ph);
45904594
const st=p.state;
4591-
let xdata=null;
4595+
let xdata=null, ydata=null;
45924596
if(st){
45934597
const r=_plotRect1d(p);
45944598
const xArr=p._1dXArr||(st.x_axis_b64?_decodeF64(st.x_axis_b64):(st.x_axis||[]));
45954599
const frac=_canvasXToFrac1d(mx,st.view_x0,st.view_x1,r);
45964600
xdata=xArr.length>=2?_axisFracToVal(xArr,frac):frac;
4597-
}
4598-
_emitEvent(p.id,'double_click',null,{..._pointerFields(e),button:e.button,x:mx,y:my,xdata});
4601+
// ydata: invert the linear y transform. Prefer the bounds draw1d cached
4602+
// (exactly what was rendered) — for a coordinate axis (PlotXY) data_min
4603+
// may be the zero-curve's range, so y_range / the cache is authoritative.
4604+
let dMin=(p._1dDMin!=null?p._1dDMin:st.data_min), dMax=(p._1dDMax!=null?p._1dDMax:st.data_max);
4605+
if(dMin==null && st.y_range && st.y_range.length===2){ dMin=st.y_range[0]; dMax=st.y_range[1]; }
4606+
if(dMin!=null && dMax!=null) ydata=dMin+((r.y+r.h-my)/(r.h||1))*(dMax-dMin);
4607+
}
4608+
_emitEvent(p.id,'double_click',null,{..._pointerFields(e),button:e.button,x:mx,y:my,xdata,ydata});
45994609
});
46004610
overlayCanvas.addEventListener('wheel',(e)=>{
46014611
_emitEvent(p.id,'wheel',null,{

anyplotlib/tests/test_plotxy/test_plotxy.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ def test_scatter_returns_collection_with_offsets():
5858
assert pts["n"] == 3
5959

6060

61+
def test_double_click_reports_data_coords(interact_page):
62+
"""A ``double_click`` on a coordinate (PlotXY) panel reports ``xdata``/``ydata``
63+
in DATA coords (like the 2-D image path) — needed for a data-coord pick such
64+
as the IPF-refine mask. Clicking panel-centre ⇒ centre of the x/y range."""
65+
from anyplotlib.tests.test_interactive._event_test_utils import (
66+
_collect_events, _get_events, _plot_center_page,
67+
)
68+
fig, ax = apl.subplots(1, 1, figsize=(400, 300))
69+
ax.axes2d(xlim=(0, 10), ylim=(0, 20), aspect="equal")
70+
page = interact_page(fig)
71+
_collect_events(page)
72+
73+
px, py = _plot_center_page(400, 300)
74+
page.mouse.dblclick(px, py)
75+
page.wait_for_timeout(100)
76+
77+
evs = _get_events(page, "double_click")
78+
assert evs, "expected a double_click event"
79+
e = evs[-1]
80+
assert e.get("xdata") is not None and e.get("ydata") is not None
81+
assert abs(e["xdata"] - 5.0) < 1.5 # centre of x range (0, 10)
82+
assert abs(e["ydata"] - 10.0) < 3.0 # centre of y range (0, 20)
83+
84+
6185
def test_render_is_chromatic(take_screenshot):
6286
"""End-to-end: a filled triangle + coloured scatter + labels in data coords
6387
must actually draw (canvas is chromatic, not blank)."""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The ``double_click`` event on a 1-D / :class:`PlotXY` panel now reports
2+
``ydata`` alongside ``xdata`` (data coordinates), matching the 2-D image path —
3+
so a coordinate axis can be picked in data space (e.g. an IPF / pole-figure mask).

0 commit comments

Comments
 (0)