Commit 29ddfd17 authored by Sanjay Yadav's avatar Sanjay Yadav

ENH: Changed table configuration.

parent 2a20a72d
Pipeline #31035 failed with stage
in 50 seconds
......@@ -290,6 +290,37 @@ def _update_chart(info, data, chart_data, series_columns, chart='line'):
return chart_data
def chart_css(fill, info, color):
"""Function to add opacity to charts."""
fill.solid()
pix_to_inch = 100000
fill.fore_color.rgb = RGBColor.from_string(color)
solid_fill = fill.fore_color._xFill
alpha = OxmlElement('a:alpha')
alpha.set('val', '%d' % (pix_to_inch * info.get('opacity', 1.0)))
solid_fill.srgbClr.append(alpha)
return fill
def compile_function(spec, key, data, handler):
"""A function to compile configuration."""
if not spec.get(key):
return None
_vars = {'_color': None, 'data': None, 'handler': None}
if not isinstance(spec[key], (dict,)):
spec[key] = {'function': '{}'.format(spec[key])}
elif isinstance(spec[key], (dict,)) and 'function' not in spec[key]:
spec[key] = {'function': '{}'.format(spec[key])}
args = {'data': data, 'handler': handler, '_color': _color}
return build_transform(spec[key], vars=_vars)(**args)[0]
def conver_color_code(colorcode):
"""Convert color code to valid PPTX color code."""
colorcode = colorcode.rsplit('#')[-1].lower()
return colorcode + ('0' * (6 - len(colorcode)))
def _extend_table(shape, data, total_rows, total_columns):
"""Function to extend table rows and columns if required."""
avail_rows = len(shape.table.rows)
......@@ -331,172 +362,41 @@ def _table_cell_gradient(info, data_cols, data):
return color_grad
def chart_css(fill, info, color):
"""Function to add opacity to charts."""
fill.solid()
pix_to_inch = 100000
fill.fore_color.rgb = RGBColor.from_string(color)
solid_fill = fill.fore_color._xFill
alpha = OxmlElement('a:alpha')
alpha.set('val', '%d' % (pix_to_inch * info.get('opacity', 1.0)))
solid_fill.srgbClr.append(alpha)
return fill
def compile_function(spec, key, data, handler):
"""A function to compile configuration."""
if not spec.get(key):
return None
_vars = {'_color': None, 'data': None, 'handler': None}
if not isinstance(spec[key], (dict,)):
spec[key] = {'function': '{}'.format(spec[key])}
elif isinstance(spec[key], (dict,)) and 'function' not in spec[key]:
spec[key] = {'function': '{}'.format(spec[key])}
args = {'data': data, 'handler': handler, '_color': _color}
return build_transform(spec[key], vars=_vars)(**args)[0]
def conver_color_code(colorcode):
"""Convert color code to valid PPTX color code."""
colorcode = colorcode.rsplit('#')[-1].lower()
return colorcode + ('0' * (6 - len(colorcode)))
def _extract_tbl_properties(table, tbl_style, row_idx, rowtype):
'''
Exctracting table properties.
'''
# Get Table rows/columns properties.
row_text_tag = ['./a:p/a:endParaRPr/a:solidFill/a:srgbClr',
'./a:p/a:endParaRPr/a:solidFill/a:schemeClr']
txt_clr_map = {
'./a:p/a:endParaRPr/a:solidFill/a:schemeClr': None,
'./a:p/a:endParaRPr/a:solidFill/a:srgbClr': None
}
text_dict = {}
for row_text in row_text_tag:
row_txt_clr = table.rows[row_idx].cells[0]._tc.txBody.xpath(row_text)
clr_key = '{}'.format(row_text.rsplit(':')[-1])
if len(row_txt_clr) > 0:
text_dict[clr_key] = row_txt_clr[0].val
else:
text_dict[clr_key] = txt_clr_map.get(row_text)
# Text inside Cell properties information.
info_txt = table.rows[row_idx].cells[0].text_frame.paragraphs[0]
if not hasattr(info_txt, 'runs'):
info_txt.add_run()
if info_txt.runs:
info_txt = info_txt.runs[0].font
text_dict['bold'] = info_txt.bold
text_dict['italic'] = info_txt.italic
text_dict['font-size'] = info_txt.size
text_dict['font-family'] = info_txt.name
text_dict['underline'] = info_txt.underline
# Cell properties information.
cell_info = ['./a:srgbClr', './a:schemeClr']
cell_info_map = {'./a:schemeClr': None, './a:srgbClr': None}
cell_dict = {}
info_cell = table.rows[row_idx].cells[0]._tc.tcPr.solidFill
if info_cell is not None:
for cell_prop in cell_info:
cell_clr = info_cell.xpath(cell_prop)
cell_key = '{}_{}'.format(rowtype, cell_prop.rsplit(':')[-1])
if len(cell_clr) > 0:
cell_dict[cell_key] = cell_clr[0].val
else:
cell_dict[cell_key] = cell_info_map.get(cell_prop)
tbl_style['text'] = text_dict
tbl_style['cell'] = cell_dict
return tbl_style
def _table_text_css(run, table_style, rowtype, text):
'''
Function to Apply table styles for rows and columns.
'''
run.text = '{}'.format(text)
rows_text = run.font.fill
rows_text.solid()
rgb = None
theme_color = None
if 'srgbClr' in table_style:
rgb = table_style.get('{}_{}'.format(rowtype, 'srgbClr'))
if 'schemeClr' in table_style:
theme_color = table_style.get('{}_{}'.format(rowtype, 'schemeClr'))
if theme_color:
rows_text.fore_color.theme_color = theme_color
else:
if rgb:
run.font.color.rgb = RGBColor.from_string(rgb) if isinstance(rgb, str) else rgb
if '{}{}'.format(rowtype, '_font_name') in table_style:
run.font.name = table_style['{}{}'.format(rowtype, '_font_name')]
if '{}{}'.format(rowtype, '_txt_size') in table_style:
run.font.size = table_style['{}{}'.format(rowtype, '_txt_size')]
if '{}{}'.format(rowtype, '_bold') in table_style:
run.font.bold = table_style['{}{}'.format(rowtype, '_bold')]
if '{}{}'.format(rowtype, '_italic') in table_style:
run.font.italic = table_style['{}{}'.format(rowtype, '_italic')]
if '{}{}'.format(rowtype, '_underline') in table_style:
run.font.underline = table_style['{}{}'.format(rowtype, '_underline')]
def _table_cell_css(shape, cell, cell_prop, row_type, gradient):
'''
Set cells properties.
'''
props = cell.fill
props.solid()
if gradient:
if isinstance(gradient, str):
clr = gradient.replace('#', '') + ('0' * (6 - len(gradient.replace('#', ''))))
props.fore_color.rgb = RGBColor.from_string(clr)
else:
props.fore_color.rgb = gradient
return
theme_color = cell_prop.get('{}_{}'.format(row_type, 'schemeClr'))
if theme_color:
props.fore_color.theme_color = theme_color
# Setting brightness - Not sure when it gets failed
bright = shape.cells[0]._tc.tcPr
if bright.solidFill.schemeClr.lumMod:
props.fore_color.brightness = bright.solidFill.schemeClr.lumMod.val - 1.0
elif bright.solidFill.schemeClr.lumOff:
props.fore_color.brightness = bright.solidFill.schemeClr.lumOff.val
else:
rgb = cell_prop.get('{}_{}'.format(row_type, 'srgbClr')) or 'ffffff'
if rgb:
props.fore_color.rgb = RGBColor.from_string(rgb) if isinstance(rgb, str) else rgb
def _table_css(shape, rowtype='header'):
'''
Function to get Table style for rows and columns.
'''
def get_table_css(shape):
"""Function to get Table style for rows and columns."""
pixel_inch = 10000
tbl_style = {}
table = shape.table
row_idx = 0 if rowtype == 'header' else 1
# row_idx = 1 if len(table.rows) > 1 else 0
tbl_style = _extract_tbl_properties(table, tbl_style, row_idx, rowtype)
# Get Table Header style' from here yet to implement.
# cell_clr = table.rows[0].cells[0]._tc.tcPr.solidFill.schemeClr.val
# tbl_style['margin_bottom'] = cell_txt_clr.margin_bottom
mapping = {0: 'header', 1: 'row'}
for row_num in range(len(list(shape.table.rows)[:2])):
style = {}
txt = shape.table.rows[row_num].cells[0].text_frame.paragraphs[0]
if txt.alignment:
style['text-align'] = '{}'.format(txt.alignment).split()[0]
if not hasattr(txt, 'runs'):
txt.add_run()
if txt.runs:
txt = txt.runs[0].font
style['bold'] = txt.bold
style['italic'] = txt.italic
style['font-size'] = (txt.size / pixel_inch) if txt.size else txt.size
style['font-family'] = txt.name
style['underline'] = txt.underline
tbl_style[mapping[row_num]] = style
if 'row' not in tbl_style or not len(tbl_style['row']):
tbl_style['row'] = copy.deepcopy(tbl_style['header'])
if 'font-size' not in tbl_style['row']:
tbl_style['row']['font-size'] = tbl_style['header']['font-size']
return tbl_style
def table_cell_css(cell, paragraph, run, info):
def apply_table_css(cell, paragraph, run, info):
"""Mak."""
pixcel_to_inch = 10000
# if 'srgbClr' in info:
# rgb = table_style.get('{}_{}'.format(rowtype, 'srgbClr'))
# if 'schemeClr' in table_style:
# theme_color = table_style.get('{}_{}'.format(rowtype, 'schemeClr'))
if info.get('fill'):
cell_fill = cell.fill
......@@ -539,6 +439,8 @@ def table(shape, spec, data):
color_grad = _table_cell_gradient(spec.get('cell', {}), data_cols, data)
_extend_table(shape, data, len(data) + 1, len(data_cols))
# Fetching Table Style for All Cells and texts.
tbl_style = get_table_css(shape)
for row_num, row in enumerate(shape.table.rows):
cols = len(row.cells._tr.tc_lst)
# Extending cells in newly added rows.
......@@ -554,13 +456,17 @@ def table(shape, spec, data):
for run in paragraph.runs:
txt = colname if row_num == 0 else data[row_num - 1][colname]
run.text = '{}'.format(txt)
cell_css = spec.get(row_type, {})
if 'text' not in cell_css:
cell_css['text'] = {}
txt_css = copy.deepcopy(tbl_style.get('header' if row_num == 0 else 'row', {}))
if color_grad and isinstance(txt, (int, float)):
spec.get(row_type, {}).update(
{'fill': _color.gradient(txt, color_grad)})
if spec.get(row_type, {}).get('fill'):
spec.get(row_type, {}).get('text', {}).update(
{'fill': _color.contrast(spec.get(row_type, {}).get('fill'))})
table_cell_css(cell, paragraph, run, spec.get(row_type, {}))
cell_css['fill'] = _color.gradient(txt, color_grad)
if cell_css.get('fill'):
cell_css['fill'] = _color.contrast(cell_css.get('fill'))
txt_css.update(cell_css.get('text', {}))
cell_css.update({'text': txt_css})
apply_table_css(cell, paragraph, run, cell_css)
def oval(shape, spec, data):
......@@ -1080,7 +986,6 @@ def custom_table(shape, spec, data):
spec = spec['custom_table']
handler = data.pop('handler') if 'handler' in data else None
data = compile_function(spec, 'data', data, handler)
# color_grad = _table_cell_gradient(spec, data)
if isinstance(data, (pd.DataFrame,)):
data = data.to_dict(orient='records')
......@@ -1089,6 +994,8 @@ def custom_table(shape, spec, data):
data_cols = list(data[0].keys())
# Extending table if required.
color_grad = _table_cell_gradient(spec.get('cell', {}), data_cols, data)
# Extending table if required.
_extend_table(shape, data, len(data) + 1, len(data_cols))
top = shape.top
left = shape.left
......@@ -1100,13 +1007,13 @@ def custom_table(shape, spec, data):
fourty_five_percent = 0.45
thirty_five_percent = 0.35
fourty_eight_percent = 0.48
tbl_style = get_table_css(shape)
for row_num, row in enumerate(shape.table.rows):
cols = len(row.cells._tr.tc_lst)
# Extending cells in newly added rows.
while cols < len(data_cols):
row.cells._tr.add_tc()
cols += 1
tbl_style = _table_css(shape)
_height = row.height + height_margin
y = top + (_height * row_num)
row_type = 'header' if row_num == 0 else 'cell'
......@@ -1114,7 +1021,8 @@ def custom_table(shape, spec, data):
colname = data_cols[col_num]
_width = shape.table.columns[col_num].width
x = left + (_width * col_num)
if row_num > 0 and isinstance(data[row_num - 1][colname], (int, float,)):
_d = data[row_num - 1][colname]
if row_num > 0 and isinstance(_d, (int, float,)):
_rect = rect(shape._parent, x + _width * twenty_percent, y + _height / 4.0,
_width * sixty_percent, _height / 4.0)
circ_width = _width * fifteen_percent
......@@ -1151,13 +1059,21 @@ def custom_table(shape, spec, data):
if not paragraph.text.strip():
paragraph.add_run()
for run in paragraph.runs:
text_prop = tbl_style.get('text', {})
txt = colname if row_num == 0 else data[row_num - 1][colname]
run.text = '{}'.format(txt)
paragraph.alignment = PP_ALIGN.RIGHT
text_prop.update(spec.get(row_type, {}))
table_cell_css(cell, paragraph, run, text_prop)
# _table_text_css(run, text_prop, 'header', txt)
cell_css = spec.get(row_type, {})
if 'text' not in cell_css:
cell_css['text'] = {}
txt_css = copy.deepcopy(tbl_style.get('header' if row_num == 0 else 'row', {}))
if color_grad and isinstance(txt, (int, float)):
cell_css['fill'] = _color.gradient(txt, color_grad)
if cell_css.get('fill'):
cell_css['fill'] = _color.contrast(cell_css.get('fill'))
txt_css.update(cell_css.get('text', {}))
cell_css.update({'text': txt_css})
apply_table_css(cell, paragraph, run, cell_css)
def bar_circle(shape, spec, data):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment