def convert()

in superset/migrations/versions/2018-07-22_11-59_bebcf3fed1fe_convert_dashboard_v1_positions.py [0:0]


def convert(positions, level, parent, root):  # noqa: C901
    if len(positions) == 0:
        return

    if len(positions) == 1 or level >= MAX_RECURSIVE_LEVEL:
        # special treatment for single chart dash:
        # always wrap chart inside a row
        if parent["type"] == DASHBOARD_GRID_TYPE:
            row_container = get_row_container()
            root[row_container["id"]] = row_container
            parent["children"].append(row_container["id"])
            parent = row_container

        chart_holder = get_chart_holder(positions[0])
        root[chart_holder["id"]] = chart_holder
        parent["children"].append(chart_holder["id"])
        return

    current_positions = positions[:]
    boundary = get_boundary(current_positions)
    top = boundary["top"]
    bottom = boundary["bottom"]
    left = boundary["left"]
    right = boundary["right"]

    # find row dividers
    layers = []
    current_row = top + 1
    while len(current_positions) and current_row <= bottom:
        upper = []
        lower = []

        is_row_divider = True
        for position in current_positions:
            row = position["row"]
            size_y = position["size_y"]
            if row + size_y <= current_row:
                lower.append(position)
                continue
            elif row >= current_row:
                upper.append(position)
                continue
            is_row_divider = False
            break

        if is_row_divider:
            current_positions = upper[:]
            layers.append(lower)
        current_row += 1

    # Each layer is a list of positions belong to same row section
    # they can be a list of charts, or arranged in columns, or mixed
    for layer in layers:
        if len(layer) == 0:
            continue

        if len(layer) == 1 and parent["type"] == COLUMN_TYPE:
            chart_holder = get_chart_holder(layer[0])
            root[chart_holder["id"]] = chart_holder
            parent["children"].append(chart_holder["id"])
            continue

        # create a new row
        row_container = get_row_container()
        root[row_container["id"]] = row_container
        parent["children"].append(row_container["id"])

        current_positions = layer[:]
        if not has_overlap(current_positions):
            # this is a list of charts in the same row
            sorted_by_col = sorted(current_positions, key=lambda pos: pos["col"])
            for position in sorted_by_col:
                chart_holder = get_chart_holder(position)
                root[chart_holder["id"]] = chart_holder
                row_container["children"].append(chart_holder["id"])
        else:
            # this row has columns, find col dividers
            current_col = left + 1
            while len(current_positions) and current_col <= right:
                upper = []
                lower = []

                is_col_divider = True
                for position in current_positions:
                    col = position["col"]
                    size_x = position["size_x"]
                    if col + size_x <= current_col:
                        lower.append(position)
                        continue
                    elif col >= current_col:
                        upper.append(position)
                        continue
                    is_col_divider = False
                    break

                if is_col_divider:
                    # is single chart in the column:
                    # add to parent container without create new column container
                    if len(lower) == 1:
                        chart_holder = get_chart_holder(lower[0])
                        root[chart_holder["id"]] = chart_holder
                        row_container["children"].append(chart_holder["id"])
                    else:
                        # create new col container
                        col_container = get_col_container()
                        root[col_container["id"]] = col_container

                        if not has_overlap(lower, False):
                            sorted_by_row = sorted(lower, key=lambda pos: pos["row"])
                            for position in sorted_by_row:
                                chart_holder = get_chart_holder(position)
                                root[chart_holder["id"]] = chart_holder
                                col_container["children"].append(chart_holder["id"])
                        else:
                            convert(lower, level + 2, col_container, root)

                        # add col meta
                        if len(col_container["children"]):
                            row_container["children"].append(col_container["id"])
                            col_container["meta"]["width"] = get_children_max(
                                col_container["children"], "width", root
                            )

                    current_positions = upper[:]
                current_col += 1

        # add row meta
        row_container["meta"]["width"] = get_children_sum(
            row_container["children"], "width", root
        )