code: def build_agg_data(
      df,
      x,
      y,
      inputs,
      agg,
      z=None,
      group_col=None,
      animate_by=None,
      extended_aggregation=[],
      dropna=True,
  ):
      """
      Builds aggregated data when an aggregation (sum, mean, max, min...) is selected from the front-end.
  
      :param df: dataframe that contains data for chart
      :type df: :class:`pandas:pandas.DataFrame`
      :param x: column to use for the X-Axis
      :type x: str
      :param y: columns to use for the Y-Axes
      :type y: list of str
      :param inputs: additional chart configurations (chart_type, group, rolling_win, rolling_comp...)
      :type inputs: dict
      :param agg: points to a specific function that can be applied to
                  :func: pandas.core.groupby.DataFrameGroupBy.  Possible values are: count, first, last mean,
                  median, min, max, std, var, mad, prod, sum
      :type agg: str
      :param z: column to use for the Z-Axis
      :type z: str, optional
      :param group_col: column to use for grouping
      :type group_col: str, optional
      :param animate_by: column to use for break up data into frames for animation
      :type animate_by: str, optional
      :param extended_aggregation: list of configurations that point to a specific function that can be applied to
                  :func: pandas.core.groupby.DataFrameGroupBy.  Possible values are: count, first, last mean,
                  median, min, max, std, var, mad, prod, sum
      :type extended_aggregation: list, optional
      :return: dataframe of aggregated data
      :rtype: :class:`pandas:pandas.DataFrame`
      """
      z_exists = len(make_list(z))
      idx_cols = make_list(animate_by) + make_list(group_col) + [x]
      agg_cols = make_list(y)
      if z_exists:
          idx_cols += make_list(y)
          agg_cols = make_list(z)
  
      is_agg = not len(extended_aggregation or [])
      if is_agg and agg == "raw":
          return df, [], agg_cols
  
      if is_agg and agg == "corr":
          if not z_exists:
              raise NotImplementedError(
                  "Correlation aggregation is only available for 3-dimensional charts!"
              )
      if is_agg and agg == "rolling":
          if z_exists:
              raise NotImplementedError(
                  "Rolling computations have not been implemented for 3-dimensional charts!"
              )
          window, comp = map(
              inputs.get, ["rolling_win", "rolling_comp"]
          )
          agg_df = df.set_index(x).rolling(window=window)
          agg_df = pd.DataFrame(
              {c: getattr(agg_df[c], comp)() for c in y}
          )
          agg_df = agg_df.reset_index()
          code = [
              "chart_data = chart_data.set_index('{x}').rolling(window={window})".format(
                  x=x, window=window
              ),
              "chart_data = pd.DataFrame({'"
              + ", ".join(
                  [
                      "'{c}': chart_data['{c}'].{comp}()".format(
                          c=c, comp=comp
                      )
                      for c in y
                  ]
              )
              + "})",
              "chart_data = chart_data.reset_index()",
          ]
          return agg_df, code, y
  
      aggs = build_aggs(y, z, agg, extended_aggregation)
  
      if "drop_duplicates" in aggs:
          groups = [
              df[idx_cols + [col]].drop_duplicates()
              for col in aggs["drop_duplicates"]
          ]
          if len(groups) == 1:
              groups = groups[0]
              code = "chart_data = chart_data[['{}']].drop_duplicates()".format(
                  "','".join(idx_cols + aggs["drop_duplicates"])
              )
          else:
              groups = pd.merge(*groups, on=idx_cols, how="outer")
              code = (
                  "idx_cols = ['{}']\n"
                  "agg_cols = ['{}']\n"
                  "chart_data = pd.merge(\n"
                  "\t*[chart_data[idx_cols + [col]].drop_duplicates() for col in agg_cols],\n"
                  "\ton=idx_cols,\n"
                  "\thow='outer'\n"
                  ")"
              ).format(
                  "','".join(idx_cols),
                  "','".join(aggs["drop_duplicates"]),
              )
          group_cols = [
              "{}{}drop_duplicates".format(col, CHART_JOINER_CHAR)
              for col in aggs["drop_duplicates"]
          ]
          groups.columns = idx_cols + group_cols
      else:
          groups = pandas_util.groupby(df, idx_cols, dropna=dropna)
          groups, code, group_cols = compute_aggs(
              df, groups, aggs, idx_cols, group_col, dropna=dropna
          )
  
      if animate_by is not None:
          full_idx = pd.MultiIndex.from_product(
              [df[c].unique() for c in idx_cols], names=idx_cols
          )
          groups = groups.reindex(full_idx).fillna(0)
          code += [
              "idx_cols = ['{cols}']".format(
                  cols="', '".join(idx_cols)
              ),
              "full_idx = pd.MultiIndex.from_product([df[c].unique() for c in idx_cols], names=idx_cols)"
              "chart_data = chart_data.reindex(full_idx).fillna(0)",
          ]
      if groups.index.name != "index":
          return groups.reset_index(), code, group_cols
      return groups, code, group_cols
  
imports: import copy
  import numpy
  import pandas
  import dtale.global_state
  import dtale.pandas_util
  from dtale.column_analysis import handle_cleaners
  from dtale.constants import CHART_JOINER_CHAR
  from dtale.query import build_col_key, run_query
  from dtale.utils import ChartBuildingError, build_formatters, classify_type, find_dtype, find_dtype_formatter, flatten_lists, get_dtypes, json_int, make_list, triple_quote
label_desc: Use image node_id 12 for calling a global function with example usage: build_agg_data(df, x, y, inputs, agg, z, group_col, animate_by, extended_aggregation, dropna) and returns: groups,  code,  group_cols, df,  list,  agg_cols, agg_df,  code,  y, groups,  code,  group_cols