pipeworks_mud_mapper.callbacks.map_callbacks ============================================ .. py:module:: pipeworks_mud_mapper.callbacks.map_callbacks .. autoapi-nested-parse:: Map visualization and interaction callbacks. This module handles: - Rendering the flattened map when zone data or visibility filter changes - Selecting rooms when clicked on the map The map displays all Z-levels on a single 2D plane with visual differentiation: - **z=-1 (Down)**: Black filled circles (smallest) - **z=0 (Ground)**: Blue filled circles (largest) - **z=+1 (Up)**: White circles with black border (medium) Component Dependencies ---------------------- **Inputs:** - ``current-zone-data``: Zone data for rendering - ``z-level-filter``: List of visible Z-levels (checklist) - ``selected-room``: Currently selected room - ``map-graph``: Click events on the map **Outputs:** - ``map-graph``: Updated Plotly figure - ``selected-room``: Room ID from click Click Selection with Stacked Rooms ---------------------------------- When rooms overlap (same X,Y, different Z), ground level (z=0) receives clicks first due to render order. To select a lower-level room: 1. Uncheck higher levels in the z-level-filter 2. Click the now-visible lower-level room 3. Re-check levels when done .. seealso:: :py:obj:`-`, :py:obj:`-` Functions --------- .. autoapisummary:: pipeworks_mud_mapper.callbacks.map_callbacks.update_map_with_rooms pipeworks_mud_mapper.callbacks.map_callbacks.handle_map_click pipeworks_mud_mapper.callbacks.map_callbacks.adjust_z_level_offset_x pipeworks_mud_mapper.callbacks.map_callbacks.adjust_z_level_offset_y Module Contents --------------- .. py:function:: update_map_with_rooms(zone_data, visible_z_levels, selected_room, visual_offset_x, visual_offset_y) Update the map figure when zone data, visibility, or selection changes. Re-renders the Plotly figure with rooms from all visible Z-levels, displayed on a single 2D plane with visual differentiation by level. :param zone_data: Current zone data containing rooms, or None if no zone loaded. :type zone_data: :py:class:`dict | None` :param visible_z_levels: List of Z-levels to display, from the filter checklist. Default is all levels: [-1, 0, 1]. Empty list shows base map only. :type visible_z_levels: :py:class:`list[int]` :param selected_room: Currently selected room ID, or None. Selected room is highlighted in red regardless of its Z-level. :type selected_room: :py:class:`str | None` :param visual_offset_x: X-axis scale factor for Z-level visual offset. Controls horizontal separation of stacked rooms. :type visual_offset_x: :py:class:`float | None` :param visual_offset_y: Y-axis scale factor for Z-level visual offset. Controls vertical separation of stacked rooms. :type visual_offset_y: :py:class:`float | None` :returns: * :py:class:`dict` -- Plotly figure dictionary for the map graph. * :py:class:`Rendering Behavior` * :py:class:`------------------` * **- Rooms are rendered in Z-order** (:py:class:`z=-1 first`, :py:class:`z=+1 second`, :py:class:`z=0 last`) * :py:class:`- Ground level (z=0) appears on top` and :py:class:`receives clicks first` * :py:class:`- Exit lines only connect rooms on the same Z-level` * - Vertical exits (up/down) are shown as ``"U/D"`` labels near stacked rooms * :py:class:`- Cross-zone exits are shown as triangle markers near the source room` * :py:class:`- Hover text includes Z-level information for each room` .. admonition:: Examples Show all levels (default):: >>> figure = update_map_with_rooms(zone_data, [-1, 0, 1], None, 1.0) Show only ground level:: >>> figure = update_map_with_rooms(zone_data, [0], None, 1.0) Hide ground to select a basement room:: >>> figure = update_map_with_rooms(zone_data, [-1, 1], "cellar", 1.0) .. py:function:: handle_map_click(click_data, zone_data, current_selection) Select a room when clicked, or unselect if clicking the same room again. Extracts the room ID from the clicked point's text field and validates that it exists in the current zone. Clicking on an already-selected room toggles the selection off. :param click_data: Plotly click event data containing information about the clicked point, or None if no click occurred. :type click_data: :py:class:`dict | None` :param zone_data: Current zone data containing rooms dictionary. :type zone_data: :py:class:`dict | None` :param current_selection: Currently selected room ID, used for toggle behavior. :type current_selection: :py:class:`str | None` :returns: * :py:class:`str | None | no_update` -- Room ID if a new room was clicked, None if the same room was clicked again (toggle off), or no_update if the click was on a non-room element like an exit line. * :py:class:`Click Handling Details` * :py:class:`----------------------` * :py:class:`- Room ID is stored in the ``text`` field` of :py:class:`Scatter points` * :py:class:`- Clicking an already-selected room clears the selection (toggle)` * :py:class:`- Clicks on exit lines return no_update (hoverinfo=```"skip"``:py:class:`)` * :py:class:`- Invalid room IDs (not in zone_data) return no_update` * :py:class:`Stacked Room Selection` * :py:class:`----------------------` * :py:class:`When rooms are stacked (same X,Y`, :py:class:`different Z)`, :py:class:`the topmost visible` * :py:class:`room receives the click. Due` to :py:class:`render order` * :py:class:`- If z=0 is visible`, :py:class:`ground-level room gets the click` * :py:class:`- If z=0 is hidden but z=+1 visible`, :py:class:`upper-level room gets the click` * :py:class:`- If only z=-1 is visible`, :py:class:`lower-level room gets the click` * :py:class:`To select a specific stacked room`, :py:class:`use the z-level-filter` to :py:class:`hide` * :py:class:`the levels above it.` .. admonition:: Examples Click data structure from Plotly:: >>> click_data = { ... "points": [{ ... "x": 0, ... "y": 0, ... "text": "spawn", # Room ID ... "curveNumber": 2, ... }] ... } >>> handle_map_click(click_data, zone_data, None) 'spawn' Click same room again to unselect:: >>> handle_map_click(click_data, zone_data, "spawn") None .. py:function:: adjust_z_level_offset_x(decrease_clicks, increase_clicks, current_value) Adjust the X-axis visual offset via +/- buttons. .. py:function:: adjust_z_level_offset_y(decrease_clicks, increase_clicks, current_value) Adjust the Y-axis visual offset via +/- buttons.