code: def test_selection1d_dynamic_map(self):
      # Create dynamic map that inputs selection1d, returns overlay of scatter on
      # selected points
      scatter = Scatter([[0, 0], [1, 1], [2, 2]])
      selection1d = Selection1D(source=scatter)
      dmap = DynamicMap(
          lambda index: scatter.iloc[index].opts(size=len(index) + 1),
          streams=[selection1d],
      )
  
      # Convert to Dash
      components = to_dash(self.app, [scatter, dmap], reset_button=True)
  
      # Check returned components
      self.assertIsInstance(components, DashComponents)
      self.assertEqual(len(components.graphs), 2)
      self.assertEqual(len(components.kdims), 0)
      self.assertIsInstance(components.store, Store)
      self.assertEqual(len(components.resets), 1)
  
      # Get arguments passed to @app.callback decorator
      decorator_args = next(iter(self.app.callback.call_args_list[0]))
      outputs, inputs, states = decorator_args
  
      # Check outputs
      expected_outputs = [
          (g.id, "figure") for g in components.graphs
      ] + [(components.store.id, "data")]
      self.assertEqual(
          [
              (output.component_id, output.component_property)
              for output in outputs
          ],
          expected_outputs,
      )
  
      # Check inputs
      expected_inputs = [
          (g.id, prop)
          for g in components.graphs
          for prop in ["selectedData", "relayoutData"]
      ] + [(components.resets[0].id, "n_clicks")]
  
      self.assertEqual(
          [(ip.component_id, ip.component_property) for ip in inputs],
          expected_inputs,
      )
  
      # Check State
      expected_state = [(components.store.id, "data")]
      self.assertEqual(
          [
              (state.component_id, state.component_property)
              for state in states
          ],
          expected_state,
      )
  
      # Check initial figures
      fig1 = components.graphs[0].figure
      fig2 = components.graphs[1].figure
  
      # Figure holds the scatter trace
      self.assertEqual(len(fig2["data"]), 1)
  
      # Check expected marker size
      self.assertEqual(fig2["data"][0]["marker"]["size"], 1)
      self.assertEqual(list(fig2["data"][0]["x"]), [])
      self.assertEqual(list(fig2["data"][0]["y"]), [])
  
      # Get callback function
      callback_fn = self.app.callback.return_value.call_args[0][0]
  
      # mimic initial callback invocation
      store_value = encode_store_data(
          {"streams": {id(selection1d): selection1d.contents}}
      )
  
      # Update store, then mimic a selection on scatter figure
      # store_value = new_store
      with patch.object(
          CallbackContext,
          "triggered",
          [{"prop_id": inputs[0].component_id + ".selectedData"}],
      ):
          [fig1, fig2, new_store] = callback_fn(
              {
                  "points": [
                      {
                          "curveNumber": 0,
                          "pointNumber": 0,
                          "pointIndex": 0,
                      },
                      {
                          "curveNumber": 0,
                          "pointNumber": 2,
                          "pointIndex": 2,
                      },
                  ]
              },
              {},
              0,
              store_value,
          )
  
      # Figure holds the scatter trace
      self.assertEqual(len(fig2["data"]), 1)
  
      # Check expected marker size
      self.assertEqual(fig2["data"][0]["marker"]["size"], 3)
      self.assertEqual(list(fig2["data"][0]["x"]), [0, 2])
      self.assertEqual(list(fig2["data"][0]["y"]), [0, 2])
  
      # Check that store was updated
      self.assertEqual(
          decode_store_data(new_store),
          {
              "streams": {id(selection1d): {"index": [0, 2]}},
              "kdims": {},
          },
      )
  
      # Click reset button
      store = new_store
      with patch.object(
          CallbackContext,
          "triggered",
          [{"prop_id": components.resets[0].id + ".n_clicks"}],
      ):
          [fig1, fig2, new_store] = callback_fn({}, {}, 1, store)
  
      # Figure holds the scatter trace
      self.assertEqual(len(fig2["data"]), 1)
  
      # Check expected marker size
      self.assertEqual(fig2["data"][0]["marker"]["size"], 1)
      self.assertEqual(list(fig2["data"][0]["x"]), [])
      self.assertEqual(list(fig2["data"][0]["y"]), [])
  
      # Check that store was updated
      self.assertEqual(
          decode_store_data(new_store),
          {
              "streams": {id(selection1d): {"index": []}},
              "reset_nclicks": 1,
              "kdims": {},
          },
      )
  
file_path: holoviews/holoviews/tests/plotting/plotly/test_dash.py
imports: import unittest
  from unittest.mock import MagicMock, patch
  from dash._callback_context import CallbackContext
  from holoviews import Bounds, DynamicMap, Scatter
  from holoviews.plotting.plotly.dash import DashComponents, decode_store_data, encode_store_data, to_dash
  from holoviews.streams import BoundsXY, RangeXY, Selection1D
  from .test_plot import TestPlotlyPlot
  import plotly.io
label_desc: Use image node_id 5 for calling the TestHoloViewsDash obj's underlying member method code with example usage: obj.test_selection1d_dynamic_map() without return types