code: def migrate_chart(config: dict[str, Any]) -> dict[str, Any]:
      """
      Used to migrate old viz types to new ones.
      """
      migrators = {
          class_.source_viz_type: class_
          for class_ in processors.__dict__.values()
          if isclass(class_)
          and issubclass(class_, MigrateViz)
          and hasattr(class_, "source_viz_type")
      }
  
      output = copy.deepcopy(config)
      if config["viz_type"] not in migrators:
          return output
  
      migrator = migrators[config["viz_type"]](output["params"])
      # pylint: disable=protected-access
      migrator._pre_action()
      migrator._migrate()
      migrator._post_action()
      params = migrator.data
  
      params["viz_type"] = migrator.target_viz_type
      output.update(
          {
              "params": json.dumps(params),
              "viz_type": migrator.target_viz_type,
          }
      )
  
      # also update `query_context`
      try:
          query_context = json.loads(
              output.get("query_context") or "{}"
          )
      except (json.decoder.JSONDecodeError, TypeError):
          query_context = {}
      if "form_data" in query_context:
          query_context["form_data"] = output["params"]
          output["query_context"] = json.dumps(query_context)
  
      return output
  
file_path: superset/superset/commands/chart/importers/v1/utils.py
imports: import copy
  import json
  from inspect import isclass
  from typing import Any
  from flask import g
  from sqlalchemy.orm import Session
  from superset import security_manager
  from superset.commands.exceptions import ImportFailedError
  from superset.migrations.shared.migrate_viz import processors
  from superset.migrations.shared.migrate_viz.base import MigrateViz
  from superset.models.slice import Slice
label_desc: Use image node_id 2 for calling a global function with example usage: migrate_chart(config) and returns: output, output