Commit dfb8c80e authored by Sanjay Yadav's avatar Sanjay Yadav

WIP: Custom bar wit circle and heatmap(table functionality WIP).

parent 478f74a2
Pipeline #30553 failed with stage
in 12 seconds
......@@ -14,6 +14,7 @@ import matplotlib.cm
from . import fontwidth
import matplotlib.colors
from . import color as _color
from collections import OrderedDict
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from tornado.template import Template
......@@ -198,8 +199,7 @@ def rect_css(shape, **kwargs):
fill = shape.fill if key == 'fill' else shape.line.fill
rectcss = kwargs[key].rsplit('#')[-1].lower()
rectcss = rectcss + ('0' * (6 - len(rectcss)))
fill.solid()
fill.fore_color.rgb = RGBColor.from_string(rectcss)
chart_css(fill, kwargs, rectcss)
def add_text_to_shape(shape, text, font_size, txt_fill):
......@@ -377,7 +377,7 @@ def _extract_tbl_properties(table, tbl_style, row_idx, rowtype):
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(rowtype, row_text.rsplit(':')[-1])
clr_key = '{}'.format(row_text.rsplit(':')[-1])
if len(row_txt_clr) > 0:
text_dict[clr_key] = row_txt_clr[0].val
else:
......@@ -389,11 +389,11 @@ def _extract_tbl_properties(table, tbl_style, row_idx, rowtype):
info_txt.add_run()
if info_txt.runs:
info_txt = info_txt.runs[0].font
text_dict['{}{}'.format(rowtype, '_italic')] = info_txt.italic
text_dict['{}{}'.format(rowtype, '_bold')] = info_txt.bold
text_dict['{}{}'.format(rowtype, '_txt_size')] = info_txt.size
text_dict['{}{}'.format(rowtype, '_font_name')] = info_txt.name
text_dict['{}{}'.format(rowtype, '_underline')] = info_txt.underline
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']
......@@ -493,6 +493,11 @@ def _table_css(shape, rowtype='header'):
def table_cell_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
cell_fill.solid()
......@@ -500,7 +505,6 @@ def table_cell_css(cell, paragraph, run, info):
if info.get('text'):
text_style = info.get('text')
print(text_style.get('fill'))
if text_style.get('fill'):
rows_text = run.font.fill
rows_text.solid()
......@@ -650,11 +654,13 @@ def chart(shape, spec, data):
info['opacity']['function'] = info['opacity']
info['opacity'] = compile_function(info, 'opacity', data, handler)
if chart_name == 'scatter' and not info.get('color'):
series_names = [series.name for series in shape.chart.series]
info['color'] = dict(zip(series_names, _color.distinct(len(series_names))))
if info.get('color'):
for index, series in enumerate(shape.chart.series):
# fill_graph = info['color'][series.name].rsplit('#')[-1].lower()
# fill_graph = fill_graph + ('0' * (6 - len(fill_graph)))
fill_graph = conver_color_code(info['color'][series.name])
fill_graph = conver_color_code(info['color'].get(series.name, '#cccccc'))
if chart_name == 'scatter':
fill = series.marker.format.fill
line_fill = series.marker.format.line.fill
......@@ -1103,6 +1109,7 @@ def custom_table(shape, spec, data):
tbl_style = _table_css(shape)
_height = row.height + height_margin
y = top + (_height * row_num)
row_type = 'header' if row_num == 0 else 'cell'
for col_num, cell in enumerate(row.cells):
colname = data_cols[col_num]
_width = shape.table.columns[col_num].width
......@@ -1140,35 +1147,126 @@ def custom_table(shape, spec, data):
arrow_width + arrow_width * twenty_percent)
rect_css(arrow, **{'fill': '#ffffff', 'stroke': '#ffffff'})
for curr_cell in cell.text_frame.paragraphs:
if not curr_cell.text.strip():
curr_cell.add_run()
for run in curr_cell.runs:
for paragraph in cell.text_frame.paragraphs:
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]
curr_cell.alignment = PP_ALIGN.RIGHT
_table_text_css(run, text_prop, 'header', txt)
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)
def register(funcname):
"""Registry function."""
registery = {
'text': text,
'oval': oval,
'image': image,
'chart': chart,
'table': table,
'sankey': sankey,
'bullet': bullet,
'treemap': treemap,
'replace': replace,
'rectangle': rectangle,
'calendarmap': calendarmap,
'custom_table': custom_table,
}
if funcname not in registery:
registery[funcname] = funcname
return registery
def bar_circle(shape, spec, data):
"""Function to plot bar chart with circles."""
spec = spec['bar_circle']
bary = spec['bar-y']
circley = spec['circle-y']
bar_data = data[spec['bardata']]
circle_data = data[spec['circledata']]
scale = bar_data[bary].fillna(0).tolist() + circle_data[circley].fillna(0).tolist()
ymax = max(scale)
pixel_inch = 10000
top = shape.top
padding = spec('padding', 40) * pixel_inch
left = shape.left + spec('padding-left', 4) * pixel_inch
width = shape.width
# width = width - (width * 0.20)
ticks = width / float(len(bar_data) or 1)
height = scale_data(0, ymax, shape.height, bar_data[bary])
xpos = pd.np.arange(0, width, ticks)
pos = pd.DataFrame(OrderedDict([
('x', xpos),
('y', shape.height - height),
('width', ticks - padding),
('height', height),
('Category', bar_data['Region']),
(bary, bar_data[bary])
]))
# Handle negative values
neg = pos[(pos['height'] < 0)]
pos.loc[neg.index, 'height'] = -neg['height']
pos.loc[neg.index, 'y'] = neg['y'] + neg['height']
parent = shape._parent
for index, row in pos.iterrows():
_rect = rect(
parent, left + row['x'], top + row['y'], row['width'], row['height'])
txt = parent.add_textbox(
left + row['x'] + row['width'] / 4.0,
top + shape.height,
row['width'] - row['width'] / 4.0, row['width'] - row['width'] / 2.0)
font_size = 16
default_txt_color = '#000000'
add_text_to_shape(txt, row['Category'], font_size, default_txt_color)
txt = parent.add_textbox(
left + row['x'] + row['width'] / 4.0,
top + row['y'],
row['width'] - row['width'] / 4.0, row['width'] - row['width'] / 4.0)
font_size = 16
default_txt_color = '#000000'
add_text_to_shape(txt, '{}%'.format(row[bary]), font_size, default_txt_color)
d = circle_data[circle_data['Category'] == row['Category']]
for i, circle in d.iterrows():
y = top + scale_data(0, ymax, row['width'], circle[circley]) - (row['width'] / 2.0)
sz = scale_data(0, d['Size'].max(), row['width'] / 2.0, circle['Size'])
xaxis = left + row['x'] + (row['width'] / 2.0) - (sz / 2.0)
cir = parent.add_shape(
MSO_SHAPE.OVAL, xaxis, y, sz, sz)
rect_css(cir, **{'fill': '#00441B', 'stroke': '#00441B', 'opacity': 0.7})
rect_css(_rect, **{'fill': '#cccccc', 'stroke': '#cccccc'})
rect_css(shape, **{'fill': '#FBFBFB', 'stroke': '#FBFBFB'})
def heatgrid(shape, spec, data):
"""Create a heat grid."""
spec = spec['heatgrid']
top = shape.top
left = shape.left
width = shape.width
height = spec.get('height', 200000)
parent = shape._parent
shape.element.delete()
data = data[spec['data']]
names = data[spec['group']].unique().tolist()
hours = sorted(data[spec['range']].unique().tolist())
twenty_percent = (width * 0.15)
for idx, hour in enumerate(hours):
txt = parent.add_textbox(
left + ((width - twenty_percent) / len(hours)) * idx + twenty_percent,
top - height - 100000, ((width - twenty_percent) / len(hours)), height)
font_size = 14
default_txt_color = '#000000'
add_text_to_shape(txt, '{}'.format(hour).zfill(2), font_size, default_txt_color)
for index, name in enumerate(names):
d = data[data['name'] == name].reset_index()
w = (width - twenty_percent) / float(len(d))
for idx, row in d.iterrows():
_rect = rect(parent, left + (w * idx) + twenty_percent,
top + (height * index) + 100000 * index,
w - 50000, height)
rect_css(_rect, **{'fill': '#f0f000', 'stroke': '#cccccc'})
txt = parent.add_textbox(
left, top + (height * index) + 100000 * index,
w + twenty_percent, height)
font_size = 14
default_txt_color = '#000000'
add_text_to_shape(txt, name, font_size, default_txt_color)
cmdlist = {
......@@ -1179,8 +1277,9 @@ cmdlist = {
'table': table,
'sankey': sankey,
'bullet': bullet,
'treemap': treemap,
'replace': replace,
'treemap': treemap,
'heatgrid': heatgrid,
'rectangle': rectangle,
'calendarmap': calendarmap,
'custom_table': custom_table,
......
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