Exemple #1
0
 def __init__(self, name, ctype, data, minwidth=2, color=None):
     self._name = name
     self._type = ctype
     self._color = color
     self._alignleft = ctype in (ltype.str, ltype.time)
     # May be empty if the column has 0 rows.
     self._strdata = list(self._stringify_data(data))
     self._rmargin = "  "
     if ctype == ltype.real:
         self._align_at_dot()
     if self._strdata:
         self._width = max(term.length(name), minwidth,
                           max(len(field) for field in self._strdata))
     else:
         self._width = max(term.length(name), minwidth)
Exemple #2
0
 def __init__(self, name, ctype, data, color=None):
     self._name = name
     self._type = ctype
     self._color = color
     self._alignleft = ctype in {"str", "enum", "time"}
     # May be empty if the column has 0 rows.
     self._strdata = list(self._stringify_data(data))
     self._rmargin = "  "
     if ctype == "real":
         self._align_at_dot()
     if self._strdata:
         self._width = max(term.length(name), 2,
                           max(len(field) for field in self._strdata))
     else:
         self._width = max(term.length(name), 2)
Exemple #3
0
 def _format(self, value):
     diff = self._width - term.length(value)
     if diff >= 0:
         whitespace = " " * diff
         if self._alignleft:
             return value + whitespace
         else:
             return whitespace + value
     else:
         return value[:self._width - 1] + "…"
Exemple #4
0
    def _draw(self):
        self._fetch_data()
        columns = []

        # Process key columns
        keynames = self._conn.key_names
        keydata = self._conn.key_data
        keyltypes = self._conn.key_ltypes
        keystypes = self._conn.key_stypes
        if keydata:
            for i, colname in enumerate(keynames):
                if self._show_types and keystypes[i]:
                    colname = term.color("cyan", keystypes[i].name)
                oldwidth = self._colwidths.get(colname, 2)
                col = _Column(name=colname,
                              ctype=keyltypes[i],
                              data=keydata[i],
                              color="bright_black",
                              minwidth=oldwidth)
                self._colwidths[colname] = col.width
                columns.append(col)
            if keynames[0]:
                columns[-1].margin = ""
                columns.append(_Divider())

        # Process data columns
        viewnames = self._conn.view_names
        viewltypes = self._conn.view_ltypes
        viewstypes = self._conn.view_stypes
        viewdata = self._conn.view_data
        if viewdata:
            for i, colname in enumerate(viewnames):
                if self._show_types:
                    colname = term.color("cyan", viewstypes[i].name)
                oldwidth = self._colwidths.get(i + self._view_col0, 2)
                col = _Column(name=colname,
                              ctype=viewltypes[i],
                              data=viewdata[i],
                              minwidth=oldwidth)
                if self._view_ncols < self._conn.frame_ncols:
                    col.width = min(col.width, _Column.MAX_WIDTH)
                self._colwidths[i + self._view_col0] = col.width
                columns.append(col)
            columns[-1].margin = ""

        # Adjust widths of columns
        total_width = sum(col.width + len(col.margin) for col in columns)
        extra_space = term.width - total_width - DataFrameWidget.RIGHT_MARGIN
        if extra_space > 0:
            if self._view_col0 + self._view_ncols < self._conn.frame_ncols:
                self._view_ncols += max(1, extra_space // 8)
                self._draw()
                return
            elif self._view_col0 > 0:
                w = self._fetch_column_width(self._view_col0 - 1)
                if w + 2 <= extra_space:
                    self._view_col0 -= 1
                    self._view_ncols += 1
                    self._max_col0 = self._view_col0
                    self._draw()
                    return
        else:
            if self._max_col0 == self._view_col0:
                self._max_col0 += 1
            available_width = term.width - DataFrameWidget.RIGHT_MARGIN
            for i, col in enumerate(columns):
                col.width = min(col.width, available_width)
                available_width -= col.width + len(col.margin)
                if available_width <= 0:
                    available_width = 0
                    col.margin = ""
                else:
                    self._view_ncols = i + 1

        # Generate the elements of the display
        at_last_row = (self._view_row0 + self._view_nrows == self._conn.frame_nrows)
        grey = lambda s: term.color("bright_black", s)
        header = ["".join(col.header for col in columns),
                  grey("".join(col.divider for col in columns))]
        rows = ["".join(col.value(j) for col in columns)
                for j in range(self._view_nrows)]
        srows = plural_form(self._conn.frame_nrows, "row")
        scols = plural_form(self._conn.frame_ncols, "column")
        footer = ["" if at_last_row else grey("..."),
                  "[%s x %s]" % (srows, scols), ""]

        # Display hint about navigation keys
        if self._show_navbar:
            remaining_width = term.width
            if self._jump_string is None:
                nav_elements = [grey("Press") + " q " + grey("to quit"),
                                "  ↑←↓→ " + grey("to move"),
                                "  wasd " + grey("to page"),
                                "  t " + grey("to toggle types"),
                                "  g " + grey("to jump")]
                for elem in nav_elements:
                    l = term.length(elem)
                    if l > remaining_width:
                        break
                    remaining_width -= l
                    footer[2] += elem
            else:
                footer[2] = grey("Go to (row:col): ") + self._jump_string

        # Render the table
        lines = header + rows + footer
        term.rewrite_lines(lines, self._n_displayed_lines)
        self._n_displayed_lines = len(lines) - 1
Exemple #5
0
    def draw(self):
        data = self._fetch_data()
        colnames = data["names"]
        coltypes = data["types"]
        stypes = data["stypes"]
        coldata = data["columns"]
        indices = data["indices"]

        # Create column with row indices
        oldwidth = self._colwidths.get("index", 3)
        indexcolumn = _Column(name="", ctype="str", data=indices)
        indexcolumn.color = term.bright_black
        indexcolumn.margin = "  "
        indexcolumn.width = max(oldwidth, indexcolumn.width)
        self._colwidths["index"] = indexcolumn.width

        # Data columns
        columns = [indexcolumn]
        for i in range(self._view_ncols):
            if self._show_types == 1:
                name = term.green(coltypes[i])
            elif self._show_types == 2:
                name = term.cyan(stypes[i])
            else:
                name = colnames[i]
            oldwidth = self._colwidths.get(i + self._view_col0, 0)
            col = _Column(name=name, ctype=coltypes[i], data=coldata[i])
            col.width = max(col.width, oldwidth)
            if self._view_ncols < self._frame_ncols:
                col.width = min(col.width, _Column.MAX_WIDTH)
            self._colwidths[i + self._view_col0] = col.width
            columns.append(col)
        columns[-1].margin = ""

        # Adjust widths of columns
        total_width = sum(col.width + len(col.margin) for col in columns)
        extra_space = term.width - total_width - DataFrameWidget.RIGHT_MARGIN
        if extra_space > 0:
            if self._view_col0 + self._view_ncols < self._frame_ncols:
                self._view_ncols += max(1, extra_space // 8)
                return self.draw()
            elif self._view_col0 > 0:
                w = self._fetch_column_width(self._view_col0 - 1)
                if w + 2 <= extra_space:
                    self._view_col0 -= 1
                    self._view_ncols += 1
                    self._max_col0 = self._view_col0
                    return self.draw()
        else:
            if self._max_col0 == self._view_col0:
                self._max_col0 += 1
            available_width = term.width - DataFrameWidget.RIGHT_MARGIN
            for i, col in enumerate(columns):
                col.width = min(col.width, available_width)
                available_width -= col.width + len(col.margin)
                if available_width <= 0:
                    available_width = 0
                    col.margin = ""
                else:
                    self._view_ncols = i + 1

        # Generate the elements of the display
        grey = term.bright_black
        header = [
            "".join(col.header for col in columns),
            grey("".join(col.divider for col in columns))
        ]
        rows = [
            "".join(col.value(j) for col in columns)
            for j in range(self._view_nrows)
        ]
        srows = plural_form(self._frame_nrows, "row")
        scols = plural_form(self._frame_ncols, "column")
        footer = ["", "[%s x %s]" % (srows, scols), ""]

        # Display hint about navigation keys
        if self._show_navbar:
            remaining_width = term.width
            if self._jump_string is None:
                nav_elements = [
                    grey("Press") + " q " + grey("to quit"),
                    "  ↑←↓→ " + grey("to move"), "  wasd " + grey("to page"),
                    "  t " + grey("to toggle types"), "  g " + grey("to jump")
                ]
                for elem in nav_elements:
                    l = term.length(elem)
                    if l > remaining_width:
                        break
                    remaining_width -= l
                    footer[2] += elem
            else:
                footer[2] = grey("Go to (row:col): ") + self._jump_string

        # Render the table
        lines = header + rows + footer
        out = (term.move_x(0) + term.move_up * self._n_displayed_lines +
               (term.clear_eol + "\n").join(lines) + term.clear_eol)
        print(out, end="")
        self._n_displayed_lines = len(lines) - 1