class_docstr: Class that takes care of converting unspecified data blob
  (Dict or List[Dict]) into datapoints (List[Dict]).
  If some properties that are required by Template class are missing
  ('x', 'y') it will attempt to fill in the blanks.
class_docstr_tok: ["Class","that","takes","care","of","converting","unspecified","data","blob","(","Dict","or","List","[","Dict","]",")","into","datapoints","(","List","[","Dict","]",")",".","If","some","properties","that","are","required","by","Template","class","are","missing","(","'","x","'",",","'","y","'",")","it","will","attempt","to","fill","in","the","blanks","."]
code: def flat_datapoints(self, revision):  # noqa: C901, PLR0912
      file2datapoints, properties = self.convert()
  
      props_update: Dict[str, Union[str, List[Dict[str, str]]]] = {}
  
      xs = list(_get_xs(properties, file2datapoints))
  
      # assign "step" if no x provided
      if not xs:
          x_file, x_field = (
              None,
              INDEX,
          )
      else:
          x_file, x_field = xs[0]
  
      num_xs = len(xs)
      multiple_x_fields = num_xs > 1 and len({x[1] for x in xs}) > 1
      props_update["x"] = (
          "dvc_inferred_x_value" if multiple_x_fields else x_field
      )
  
      ys = list(_get_ys(properties, file2datapoints))
  
      num_ys = len(ys)
      if num_xs > 1 and num_xs != num_ys:
          raise DvcException(
              "Cannot have different number of x and y data sources. Found "
              f"{num_xs} x and {num_ys} y data sources."
          )
  
      all_datapoints = []
      if ys:
          _all_y_files, _all_y_fields = list(zip(*ys))
          all_y_fields = set(_all_y_fields)
          all_y_files = set(_all_y_files)
      else:
          all_y_files = set()
          all_y_fields = set()
  
      # override to unified y field name if there are different y fields
      if len(all_y_fields) > 1:
          props_update["y"] = "dvc_inferred_y_value"
      else:
          props_update["y"] = first(all_y_fields)
  
      # get common prefix to drop from file names
      if len(all_y_files) > 1:
          common_prefix_len = len(os.path.commonpath(list(all_y_files)))
      else:
          common_prefix_len = 0
  
      props_update["anchors_y_definitions"] = [
          {
              FILENAME: _get_short_y_file(y_file, common_prefix_len),
              FIELD: y_field,
          }
          for y_file, y_field in ys
      ]
  
      for i, (y_file, y_field) in enumerate(ys):
          if num_xs > 1:
              x_file, x_field = xs[i]
          datapoints = [{**d} for d in file2datapoints.get(y_file, [])]
  
          if props_update.get("y", None) == "dvc_inferred_y_value":
              _update_from_field(
                  datapoints,
                  field="dvc_inferred_y_value",
                  source_field=y_field,
              )
  
          if x_field == INDEX and x_file is None:
              _update_from_index(datapoints, INDEX)
          else:
              x_datapoints = file2datapoints.get(x_file, [])
              try:
                  _update_from_field(
                      datapoints,
                      field="dvc_inferred_x_value"
                      if multiple_x_fields
                      else x_field,
                      source_datapoints=x_datapoints,
                      source_field=x_field,
                  )
              except IndexError:
                  raise DvcException(  # noqa: B904
                      f"Cannot join '{x_field}' from '{x_file}' and "
                      f"'{y_field}' from '{y_file}'. "
                      "They have to have same length."
                  )
  
          _update_all(
              datapoints,
              update_dict={
                  REVISION: revision,
                  FILENAME: _get_short_y_file(
                      y_file, common_prefix_len
                  ),
                  FIELD: y_field,
              },
          )
  
          all_datapoints.extend(datapoints)
  
      if not all_datapoints:
          return [], {}
  
      properties = {**properties, **props_update}
  
      return all_datapoints, properties
  
imports: import os
  from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
  from funcy import first, last
  from dvc.exceptions import DvcException
  from dvc.render import FIELD, FILENAME, INDEX, REVISION
  from .None import Converter
label_desc: Use image node_id 7 for calling the VegaConverter obj's underlying member method code with example usage: obj.flat_datapoints(revision) and returns: all_datapoints,  properties, list,  dict