Skip to content

Commit d79605d

Browse files
Andreas SchmitzAndreas Schmitz
Andreas Schmitz
authored and
Andreas Schmitz
committed
[tools.py] Gantt Chart: added an option which allows grouping of tasks
1 parent 96b7f75 commit d79605d

File tree

1 file changed

+91
-29
lines changed

1 file changed

+91
-29
lines changed

plotly/tools.py

Lines changed: 91 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,7 +1724,7 @@ def _validate_gantt(df):
17241724

17251725
@staticmethod
17261726
def _gantt(chart, colors, title, bar_width, showgrid_x, showgrid_y,
1727-
height, width, tasks=None, task_names=None, data=None):
1727+
height, width, tasks=None, task_names=None, data=None, group_tasks=False):
17281728
"""
17291729
Refer to FigureFactory.create_gantt() for docstring
17301730
"""
@@ -1751,15 +1751,30 @@ def _gantt(chart, colors, title, bar_width, showgrid_x, showgrid_y,
17511751
},
17521752
'yref': 'y',
17531753
}
1754+
# create the list of task names
1755+
for index in range(len(tasks)):
1756+
tn = tasks[index]['name']
1757+
# Is added to task_names if group_tasks is set to False,
1758+
# or if the option is used (True) it only adds them if the
1759+
# name is not already in the list
1760+
if not group_tasks or tn not in task_names:
1761+
task_names.append(tn)
1762+
task_names.reverse()
1763+
17541764

17551765
color_index = 0
17561766
for index in range(len(tasks)):
17571767
tn = tasks[index]['name']
1758-
task_names.append(tn)
17591768
del tasks[index]['name']
17601769
tasks[index].update(shape_template)
1761-
tasks[index]['y0'] = index - bar_width
1762-
tasks[index]['y1'] = index + bar_width
1770+
1771+
# If group_tasks is True, all tasks with the same name belong
1772+
# to the same row.
1773+
groupID = index
1774+
if group_tasks:
1775+
groupID = task_names.index(tn)
1776+
tasks[index]['y0'] = groupID - bar_width
1777+
tasks[index]['y1'] = groupID + bar_width
17631778

17641779
# check if colors need to be looped
17651780
if color_index >= len(colors):
@@ -1769,7 +1784,7 @@ def _gantt(chart, colors, title, bar_width, showgrid_x, showgrid_y,
17691784
data.append(
17701785
dict(
17711786
x=[tasks[index]['x0'], tasks[index]['x1']],
1772-
y=[index, index],
1787+
y=[groupID, groupID],
17731788
name='',
17741789
marker={'color': 'white'}
17751790
)
@@ -1786,8 +1801,8 @@ def _gantt(chart, colors, title, bar_width, showgrid_x, showgrid_y,
17861801
yaxis=dict(
17871802
showgrid=showgrid_y,
17881803
ticktext=task_names,
1789-
tickvals=list(range(len(tasks))),
1790-
range=[-1, len(tasks) + 1],
1804+
tickvals=list(range(len(task_names))),
1805+
range=[-1, len(task_names) + 1],
17911806
autorange=False,
17921807
zeroline=False,
17931808
),
@@ -1830,7 +1845,7 @@ def _gantt(chart, colors, title, bar_width, showgrid_x, showgrid_y,
18301845
@staticmethod
18311846
def _gantt_colorscale(chart, colors, title, index_col, show_colorbar,
18321847
bar_width, showgrid_x, showgrid_y, height,
1833-
width, tasks=None, task_names=None, data=None):
1848+
width, tasks=None, task_names=None, data=None, group_tasks=False):
18341849
"""
18351850
Refer to FigureFactory.create_gantt() for docstring
18361851
"""
@@ -1870,13 +1885,29 @@ def _gantt_colorscale(chart, colors, title, index_col, show_colorbar,
18701885
"colors given will be used for the lower and upper "
18711886
"bounds on the colormap."
18721887
)
1888+
1889+
# create the list of task names
1890+
for index in range(len(tasks)):
1891+
tn = tasks[index]['name']
1892+
# Is added to task_names if group_tasks is set to False,
1893+
# or if the option is used (True) it only adds them if the
1894+
# name is not already in the list
1895+
if not group_tasks or tn not in task_names:
1896+
task_names.append(tn)
1897+
task_names.reverse()
1898+
18731899
for index in range(len(tasks)):
18741900
tn = tasks[index]['name']
1875-
task_names.append(tn)
18761901
del tasks[index]['name']
18771902
tasks[index].update(shape_template)
1878-
tasks[index]['y0'] = index - bar_width
1879-
tasks[index]['y1'] = index + bar_width
1903+
1904+
# If group_tasks is True, all tasks with the same name belong
1905+
# to the same row.
1906+
groupID = index
1907+
if group_tasks:
1908+
groupID = task_names.index(tn)
1909+
tasks[index]['y0'] = groupID - bar_width
1910+
tasks[index]['y1'] = groupID + bar_width
18801911

18811912
# unlabel color
18821913
colors = FigureFactory._color_parser(
@@ -1902,7 +1933,7 @@ def _gantt_colorscale(chart, colors, title, index_col, show_colorbar,
19021933
data.append(
19031934
dict(
19041935
x=[tasks[index]['x0'], tasks[index]['x1']],
1905-
y=[index, index],
1936+
y=[groupID, groupID],
19061937
name='',
19071938
marker={'color': 'white'}
19081939
)
@@ -1948,13 +1979,27 @@ def _gantt_colorscale(chart, colors, title, index_col, show_colorbar,
19481979
index_vals_dict[key] = colors[c_index]
19491980
c_index += 1
19501981

1982+
# create the list of task names
1983+
for index in range(len(tasks)):
1984+
tn = tasks[index]['name']
1985+
# Is added to task_names if group_tasks is set to False,
1986+
# or if the option is used (True) it only adds them if the
1987+
# name is not already in the list
1988+
if not group_tasks or tn not in task_names:
1989+
task_names.append(tn)
1990+
task_names.reverse()
1991+
19511992
for index in range(len(tasks)):
19521993
tn = tasks[index]['name']
1953-
task_names.append(tn)
19541994
del tasks[index]['name']
19551995
tasks[index].update(shape_template)
1956-
tasks[index]['y0'] = index - bar_width
1957-
tasks[index]['y1'] = index + bar_width
1996+
# If group_tasks is True, all tasks with the same name belong
1997+
# to the same row.
1998+
groupID = index
1999+
if group_tasks:
2000+
groupID = task_names.index(tn)
2001+
tasks[index]['y0'] = groupID - bar_width
2002+
tasks[index]['y1'] = groupID + bar_width
19582003

19592004
tasks[index]['fillcolor'] = index_vals_dict[
19602005
chart[index][index_col]
@@ -1964,7 +2009,7 @@ def _gantt_colorscale(chart, colors, title, index_col, show_colorbar,
19642009
data.append(
19652010
dict(
19662011
x=[tasks[index]['x0'], tasks[index]['x1']],
1967-
y=[index, index],
2012+
y=[groupID, groupID],
19682013
name='',
19692014
marker={'color': 'white'}
19702015
)
@@ -1998,8 +2043,8 @@ def _gantt_colorscale(chart, colors, title, index_col, show_colorbar,
19982043
yaxis=dict(
19992044
showgrid=showgrid_y,
20002045
ticktext=task_names,
2001-
tickvals=list(range(len(tasks))),
2002-
range=[-1, len(tasks) + 1],
2046+
tickvals=list(range(len(task_names))),
2047+
range=[-1, len(task_names) + 1],
20032048
autorange=False,
20042049
zeroline=False,
20052050
),
@@ -2042,7 +2087,7 @@ def _gantt_colorscale(chart, colors, title, index_col, show_colorbar,
20422087
@staticmethod
20432088
def _gantt_dict(chart, colors, title, index_col, show_colorbar, bar_width,
20442089
showgrid_x, showgrid_y, height, width, tasks=None,
2045-
task_names=None, data=None):
2090+
task_names=None, data=None, group_tasks=False):
20462091
"""
20472092
Refer to FigureFactory.create_gantt() for docstring
20482093
"""
@@ -2086,21 +2131,36 @@ def _gantt_dict(chart, colors, title, index_col, show_colorbar, bar_width,
20862131
"keys must be all the values in the index column."
20872132
)
20882133

2134+
# create the list of task names
2135+
for index in range(len(tasks)):
2136+
tn = tasks[index]['name']
2137+
# Is added to task_names if group_tasks is set to False,
2138+
# or if the option is used (True) it only adds them if the
2139+
# name is not already in the list
2140+
if not group_tasks or tn not in task_names:
2141+
task_names.append(tn)
2142+
task_names.reverse()
2143+
20892144
for index in range(len(tasks)):
20902145
tn = tasks[index]['name']
2091-
task_names.append(tn)
20922146
del tasks[index]['name']
20932147
tasks[index].update(shape_template)
2094-
tasks[index]['y0'] = index - bar_width
2095-
tasks[index]['y1'] = index + bar_width
2148+
2149+
# If group_tasks is True, all tasks with the same name belong
2150+
# to the same row.
2151+
groupID = index
2152+
if group_tasks:
2153+
groupID = task_names.index(tn)
2154+
tasks[index]['y0'] = groupID - bar_width
2155+
tasks[index]['y1'] = groupID + bar_width
20962156

20972157
tasks[index]['fillcolor'] = colors[chart[index][index_col]]
20982158

20992159
# add a line for hover text and autorange
21002160
data.append(
21012161
dict(
21022162
x=[tasks[index]['x0'], tasks[index]['x1']],
2103-
y=[index, index],
2163+
y=[groupID, groupID],
21042164
name='',
21052165
marker={'color': 'white'}
21062166
)
@@ -2134,8 +2194,8 @@ def _gantt_dict(chart, colors, title, index_col, show_colorbar, bar_width,
21342194
yaxis=dict(
21352195
showgrid=showgrid_y,
21362196
ticktext=task_names,
2137-
tickvals=list(range(len(tasks))),
2138-
range=[-1, len(tasks) + 1],
2197+
tickvals=list(range(len(task_names))),
2198+
range=[-1, len(task_names) + 1],
21392199
autorange=False,
21402200
zeroline=False,
21412201
),
@@ -2180,7 +2240,7 @@ def create_gantt(df, colors=None, index_col=None, show_colorbar=False,
21802240
reverse_colors=False, title='Gantt Chart',
21812241
bar_width=0.2, showgrid_x=False, showgrid_y=False,
21822242
height=600, width=900, tasks=None,
2183-
task_names=None, data=None):
2243+
task_names=None, data=None, group_tasks=False):
21842244
"""
21852245
Returns figure for a gantt chart
21862246
@@ -2359,22 +2419,23 @@ def create_gantt(df, colors=None, index_col=None, show_colorbar=False,
23592419
)
23602420
fig = FigureFactory._gantt(
23612421
chart, colors, title, bar_width, showgrid_x, showgrid_y,
2362-
height, width, tasks=None, task_names=None, data=None
2422+
height, width, tasks=None, task_names=None, data=None,
2423+
group_tasks=group_tasks
23632424
)
23642425
return fig
23652426
else:
23662427
if not isinstance(colors, dict):
23672428
fig = FigureFactory._gantt_colorscale(
23682429
chart, colors, title, index_col, show_colorbar, bar_width,
23692430
showgrid_x, showgrid_y, height, width,
2370-
tasks=None, task_names=None, data=None
2431+
tasks=None, task_names=None, data=None, group_tasks=group_tasks
23712432
)
23722433
return fig
23732434
else:
23742435
fig = FigureFactory._gantt_dict(
23752436
chart, colors, title, index_col, show_colorbar, bar_width,
23762437
showgrid_x, showgrid_y, height, width,
2377-
tasks=None, task_names=None, data=None
2438+
tasks=None, task_names=None, data=None, group_tasks=group_tasks
23782439
)
23792440
return fig
23802441

@@ -2403,6 +2464,7 @@ def _validate_colors(colors, colortype='tuple'):
24032464
else:
24042465
colors = list(colors)
24052466

2467+
24062468
# convert color elements in list to tuple color
24072469
for j, each_color in enumerate(colors):
24082470
if 'rgb' in each_color:

0 commit comments

Comments
 (0)