code: def test_bar_and_popup(unittest):
      import dtale.views as views
  
      df = pd.DataFrame(
          dict(a=[1, 2, 3], b=[4, 5, 6], c=[7, 8, 9], d=[10, 11, 12])
      )
      with app.test_client() as c:
          df, _ = views.format_data(df)
          build_data_inst({c.port: df})
          global_state.set_dtypes(c.port, views.build_dtypes_state(df))
          inputs = {
              "chart_type": "bar",
              "x": "a",
              "y": ["b", "c"],
              "z": None,
              "group": None,
              "agg": None,
              "window": None,
              "rolling_comp": None,
          }
          chart_inputs = {
              "cpg": False,
              "cpy": True,
              "barmode": "group",
              "barsort": None,
          }
          extended_aggregation = [
              dict(col="b", agg="sum"),
              dict(col="c", agg="mean"),
          ]
          params = build_chart_params(
              c.port,
              inputs,
              chart_inputs,
              dict(type="multi", data={}),
              extended_aggregation=extended_aggregation,
          )
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          resp_data = response.get_json()["response"]
          assert (
              len(
                  resp_data["chart-content"]["children"][0]["props"][
                      "children"
                  ]
              )
              == 2
          )
  
          chart_inputs["cpy"] = False
          params = build_chart_params(
              c.port,
              inputs,
              chart_inputs,
              dict(type="multi", data={}),
              extended_aggregation=extended_aggregation,
          )
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          resp_data = response.get_json()["response"]
          links_div = resp_data["chart-content"]["children"]["props"][
              "children"
          ][0]["props"]["children"]
          url = links_div[0]["props"]["children"][0]["props"]["href"]
          assert url.startswith("/dtale/charts/{}?".format(c.port))
          url_params = dict(get_url_parser()(url.split("?")[-1]))
          unittest.assertEqual(
              url_params,
              {
                  "chart_type": "bar",
                  "x": "a",
                  "barmode": "group",
                  "cpg": "false",
                  "cpy": "false",
                  "y": '["b", "c"]',
                  "yaxis": '{"type": "multi"}',
                  "extended_aggregation": '[{"agg": "sum", "col": "b"}, {"agg": "mean", "col": "c"}]',
              },
          )
          expected = {
              "barmode": "group",
              "legend": {"orientation": "h", "y": -0.3},
              "title": {"text": "Sum of b, Mean of c by a"},
              "xaxis": {"tickformat": "0:g", "title": {"text": "a"}},
              "yaxis": {
                  "tickformat": "0:g",
                  "title": {"text": "Sum of b"},
              },
              "yaxis2": {
                  "anchor": "x",
                  "overlaying": "y",
                  "side": "right",
                  "tickformat": "0:g",
                  "title": {"text": "Mean of c"},
              },
          }
          if parse_version(pd.__version__) >= parse_version("1.3.0"):
              del expected["yaxis2"]["tickformat"]
          unittest.assertEqual(
              resp_data["chart-content"]["children"]["props"][
                  "children"
              ][1]["props"]["figure"]["layout"],
              expected,
          )
  
          response = c.get(url)
          assert response.status_code == 200
          [pathname_val, search_val] = url.split("?")
          response = c.post(
              "/dtale/charts/_dash-update-component",
              json={
                  "output": "popup-content.children",
                  "changedPropIds": ["url.modified_timestamp"],
                  "inputs": [
                      {
                          "id": "url",
                          "property": "pathname",
                          "value": pathname_val,
                      },
                      {
                          "id": "url",
                          "property": "search",
                          "value": "?{}".format(search_val),
                      },
                  ],
              },
          )
          assert response.status_code == 200
  
          inputs["y"] = ["b"]
          inputs["agg"] = "sum"
          chart_inputs["animate_by"] = "c"
          params = build_chart_params(
              c.port,
              inputs,
              chart_inputs,
              extended_aggregation=extended_aggregation,
          )
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          resp_data = response.get_json()["response"]
          assert (
              "frames"
              in resp_data["chart-content"]["children"]["props"][
                  "children"
              ][1]["props"]["figure"]
          )
  
          inputs["y"] = ["b"]
          inputs["agg"] = "raw"
          inputs["group"] = ["d"]
          chart_inputs["animate_by"] = "c"
          params = build_chart_params(
              c.port,
              inputs,
              chart_inputs,
              extended_aggregation=extended_aggregation,
          )
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          resp_data = response.get_json()["response"]
          assert (
              "frames"
              in resp_data["chart-content"]["children"]["props"][
                  "children"
              ][1]["props"]["figure"]
          )
  
          inputs["y"] = ["b", "c"]
          inputs["group"] = None
          chart_inputs["animate_by"] = None
          chart_inputs["barmode"] = "group"
          chart_inputs["barsort"] = build_col_def("sum", "b")
          inputs["agg"] = None
          params = build_chart_params(
              c.port,
              inputs,
              chart_inputs,
              extended_aggregation=extended_aggregation,
          )
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          resp_data = response.get_json()["response"]
          unittest.assertEqual(
              resp_data["chart-content"]["children"]["props"][
                  "children"
              ][1]["props"]["figure"]["layout"],
              {
                  "barmode": "group",
                  "legend": {"orientation": "h", "y": -0.3},
                  "title": {"text": "Sum of b, Mean of c by a"},
                  "xaxis": {
                      "tickmode": "array",
                      "ticktext": [1, 2, 3],
                      "tickvals": [0, 1, 2],
                      "tickformat": "0:g",
                      "title": {"text": "a"},
                  },
                  "yaxis": {
                      "tickformat": "0:g",
                      "title": {"text": "Sum of b, Mean of c"},
                  },
              },
          )
  
          inputs["y"] = ["b"]
          inputs["group"] = ["c"]
          chart_inputs["cpg"] = True
          params = build_chart_params(
              c.port,
              inputs,
              chart_inputs,
              extended_aggregation=extended_aggregation,
          )
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          resp_data = response.get_json()["response"]
          assert len(resp_data["chart-content"]["children"]) == 2
  
          chart_inputs["top_bars"] = 5
          params = build_chart_params(
              c.port,
              inputs,
              chart_inputs,
              extended_aggregation=extended_aggregation,
          )
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          resp_data = response.get_json()["response"]
          assert len(resp_data["chart-content"]["children"]) == 2
  
          chart_inputs["top_bars"] = None
          params["inputs"][-1]["value"] = 1
          params["state"][-3]["value"] = False
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          assert (
              response.get_json()["response"]["load-clicks"]["data"]
              == 1
          )
  
          params["state"][-2]["value"] = 1
          response = c.post(
              "/dtale/charts/_dash-update-component", json=params
          )
          assert response.status_code == 204
  
file_path: dtale/tests/dtale/dash/test_extended_aggregation_charts.py
imports: import pandas
  import pytest
  from pkg_resources import parse_version
  import dtale.global_state
  from dtale.app import build_app
  from tests.dtale import build_data_inst
  from tests.dtale.dash.test_dash import build_chart_params, get_url_parser
  from tests.dtale.test_charts import build_col_def
  from tests.dtale.test_views import URL
label_desc: Use image node_id 2 for calling a global function with example usage: test_bar_and_popup(unittest) without return types