Skip to content

REF: io/formats/html.py (and io/formats/format.py) #24637

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions pandas/io/formats/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ def space_format(x, y):
for i, (col, x) in enumerate(zip(columns,
fmt_columns))]

if self.show_index_names and self.has_index_names:
if self.show_row_idx_names:
for x in str_columns:
x.append('')

Expand All @@ -793,30 +793,41 @@ def has_index_names(self):
def has_column_names(self):
return _has_names(self.frame.columns)

@property
def show_row_idx_names(self):
return all((self.has_index_names,
self.index,
self.show_index_names))

@property
def show_col_idx_names(self):
return all((self.has_column_names,
self.show_index_names,
self.header))

def _get_formatted_index(self, frame):
# Note: this is only used by to_string() and to_latex(), not by
# to_html().
index = frame.index
columns = frame.columns

show_index_names = self.show_index_names and self.has_index_names
show_col_names = (self.show_index_names and self.has_column_names)

fmt = self._get_formatter('__index__')

if isinstance(index, ABCMultiIndex):
fmt_index = index.format(sparsify=self.sparsify, adjoin=False,
names=show_index_names, formatter=fmt)
fmt_index = index.format(
sparsify=self.sparsify, adjoin=False,
names=self.show_row_idx_names, formatter=fmt)
else:
fmt_index = [index.format(name=show_index_names, formatter=fmt)]
fmt_index = [index.format(
name=self.show_row_idx_names, formatter=fmt)]

fmt_index = [tuple(_make_fixed_width(list(x), justify='left',
minimum=(self.col_space or 0),
adj=self.adj)) for x in fmt_index]

adjoined = self.adj.adjoin(1, *fmt_index).split('\n')

# empty space for columns
if show_col_names:
if self.show_col_idx_names:
col_header = ['{x}'.format(x=x)
for x in self._get_column_name_list()]
else:
Expand Down
92 changes: 35 additions & 57 deletions pandas/io/formats/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,11 @@ def __init__(self, formatter, classes=None, notebook=False, border=None,

@property
def show_row_idx_names(self):
return all((self.fmt.has_index_names,
self.fmt.index,
self.fmt.show_index_names))
return self.fmt.show_row_idx_names

@property
def show_col_idx_names(self):
# see gh-22579
# Column misalignment also occurs for
# a standard index when the columns index is named.
# Determine if ANY column names need to be displayed
# since if the row index is not displayed a column of
# blank cells need to be included before the DataFrame values.
# TODO: refactor to add show_col_idx_names property to
# DataFrameFormatter
return all((self.fmt.has_column_names,
self.fmt.show_index_names,
self.fmt.header))
return self.fmt.show_col_idx_names

@property
def row_levels(self):
Expand Down Expand Up @@ -184,14 +172,28 @@ def write_style(self):
template = dedent('\n'.join((template_first,
template_mid,
template_last)))
if self.notebook:
self.write(template)
self.write(template)

def write_result(self, buf):
indent = 0
id_section = ""
frame = self.frame
if self.notebook:
self.write('<div>')
self.write_style()

self._write_table()

if self.should_show_dimensions:
by = chr(215) if compat.PY3 else unichr(215) # ×
self.write(u('<p>{rows} rows {by} {cols} columns</p>')
.format(rows=len(self.frame),
by=by,
cols=len(self.frame.columns)))

if self.notebook:
self.write('</div>')

buffer_put_lines(buf, self.elements)

def _write_table(self, indent=0):
_classes = ['dataframe'] # Default class.
use_mathjax = get_option("display.html.use_mathjax")
if not use_mathjax:
Expand All @@ -204,33 +206,21 @@ def write_result(self, buf):
.format(typ=type(self.classes)))
_classes.extend(self.classes)

if self.notebook:
self.write('<div>')

self.write_style()

if self.table_id is not None:
if self.table_id is None:
id_section = ""
else:
id_section = ' id="{table_id}"'.format(table_id=self.table_id)

self.write('<table border="{border}" class="{cls}"{id_section}>'
.format(border=self.border, cls=' '.join(_classes),
id_section=id_section), indent)

indent += self.indent_delta
indent = self._write_header(indent)
indent = self._write_body(indent)
if self.fmt.header or self.show_row_idx_names:
self._write_header(indent + self.indent_delta)

self.write('</table>', indent)
if self.should_show_dimensions:
by = chr(215) if compat.PY3 else unichr(215) # ×
self.write(u('<p>{rows} rows {by} {cols} columns</p>')
.format(rows=len(frame),
by=by,
cols=len(frame.columns)))
self._write_body(indent + self.indent_delta)

if self.notebook:
self.write('</div>')

buffer_put_lines(buf, self.elements)
self.write('</table>', indent)

def _write_col_header(self, indent):
truncate_h = self.fmt.truncate_h
Expand Down Expand Up @@ -359,41 +349,29 @@ def _write_row_header(self, indent):
self.write_tr(row, indent, self.indent_delta, header=True)

def _write_header(self, indent):
if not (self.fmt.header or self.show_row_idx_names):
# write nothing
return indent

self.write('<thead>', indent)
indent += self.indent_delta

if self.fmt.header:
self._write_col_header(indent)
self._write_col_header(indent + self.indent_delta)

if self.show_row_idx_names:
self._write_row_header(indent)
self._write_row_header(indent + self.indent_delta)

indent -= self.indent_delta
self.write('</thead>', indent)

return indent

def _write_body(self, indent):
self.write('<tbody>', indent)
indent += self.indent_delta

fmt_values = {i: self.fmt._format_col(i) for i in range(self.ncols)}

# write values
if self.fmt.index and isinstance(self.frame.index, ABCMultiIndex):
self._write_hierarchical_rows(fmt_values, indent)
self._write_hierarchical_rows(
fmt_values, indent + self.indent_delta)
else:
self._write_regular_rows(fmt_values, indent)
self._write_regular_rows(
fmt_values, indent + self.indent_delta)

indent -= self.indent_delta
self.write('</tbody>', indent)
indent -= self.indent_delta

return indent

def _write_regular_rows(self, fmt_values, indent):
truncate_h = self.fmt.truncate_h
Expand Down