Author: croberts
Date: 2012-11-19 20:40:36 +0000 (Mon, 19 Nov 2012)
New Revision: 5550
Modified:
branches/croberts/cumin/python/cumin/stat.py
Log:
Attempt at stabilizing chart colors for dynamic hierarchical accounting groups.
Modified: branches/croberts/cumin/python/cumin/stat.py
===================================================================
--- branches/croberts/cumin/python/cumin/stat.py 2012-11-16 20:29:45 UTC (rev 5549)
+++ branches/croberts/cumin/python/cumin/stat.py 2012-11-19 20:40:36 UTC (rev 5550)
@@ -942,7 +942,7 @@
chart.graph_div = "%s_chart" % chart.id.replace(".",
"_")
chart.stackSeries = self.stackSeries
chart.legendLocation = self.legendLocation
- chart.colors = self.colors
+ chart.colors = self.get_colors(samples)
chart.legendCols = self.legendCols
chart.fillAndStroke = self.fillAndStroke
chart.gridPadding = self.gridPadding
@@ -1164,13 +1164,24 @@
new_samples.append((dt, value, dev))
samples[stat] = new_samples
+ def get_colors(self, samples):
+ return self.colors
+
class ReportAreaChart(AreaChart):
pass
class GeneralUseChart(AreaChart):
- colors =
('#009926','#992600','#0036d6','#ffc414','730099','#ff00cc',
'#ff0000', \
- '#0000ff', '#00ff00', '#00ffff', '#ff00ff',
'#000000', '#666600', \
- '6633cc', '33ccb3', 'cc6633', '4dcc33',
'cc334d')
+# colors =
('#009926','#992600','#0036d6','#ffc414','#730099','#ff00cc',
'#ff0000', \
+# '#0000ff', '#00ff00', '#00ffff',
'#ff00ff', '#000000', '#666600', \
+# '#6633cc', '#33ccb3', '#cc6633',
'#4dcc33', '#cc334d')
+
+ colors =
("#0000FF","#00FF00","#00FFFF","#FF0000","#FF00FF","#FFFF00","#FFFFFF","#0000AA","#00FFAA","#00AA00","#00AAFF","#00AAAA",\
+
"#FF00AA","#FFFFAA","#FFAA00","#FFAAFF","#FFAAAA","#AA0000","#AA00FF","#AA00AA","#AAFF00","#AAFFFF","#AAFFAA","#AAAA00",\
+
"#AAAAFF","#AAAAAA","#000055","#00FF55","#00AA55","#005500","#0055FF","#0055AA","#005555","#FF0055","#FFFF55","#FFAA55",\
+
"#FF5500","#FF55FF","#FF55AA","#FF5555","#AA0055","#AAFF55","#AAAA55","#AA5500","#AA55FF","#AA55AA","#AA5555","#550000",\
+
"#5500FF","#5500AA","#550055","#55FF00","#55FFFF","#55FFAA","#55FF55","#55AA00","#55AAFF","#55AAAA","#55AA55","#555500",\
+ "#5555FF","#5555AA","#555555")
+
def __init__(self, app, name, page):
super(GeneralUseChart, self).__init__(app, name, page)
self.stackSeries = True
@@ -1184,10 +1195,11 @@
def fetch_samples(self, session, adapter, dur, interval, method, mode, delta, stats,
end_seconds_ago=0):
samples = dict()
-
+
groups_expanded = self.page.group_expand.get(session)
#use groups from url, if present, otherwise grab "all" form database
groups = groups_expanded if len(groups_expanded) > 0 else
self.getTopLevelGroups(self.accGroups.execute(self.app.session).fetchall())
+ groups = sorted(groups)
for group in groups:
group_name = group if isinstance(group, unicode) or isinstance(group, str)
else group[0]
result = self.accUse.execute(self.app.session, group_name, dur,
interval).fetchall()
@@ -1199,12 +1211,50 @@
def getTopLevelGroups(self, groups):
topLevelGroups = []
for group in groups:
- group = group if isinstance(group, unicode) else group[0]
+ group = group if isinstance(group, unicode) or isinstance(group, str) else
group[0]
split_name = group.split(".",1)
if split_name[0] not in topLevelGroups:
topLevelGroups.append(split_name[0])
return topLevelGroups
+
+ def get_colors(self, samples):
+ ''' takes the chart's default set of colors and maps them
+ to a stat name (group name) to provide persistent colors
+ in the resultant chart even when switching groups around
+ '''
+ colors = []
+ trees = {}
+ color_map = {}
+ all_groups = []
+
+ # figure out what all of our groups are
+ groups = self.accGroups.execute(self.app.session).fetchall()
+ groups = [g[0] for g in groups]
+ top_groups = self.getTopLevelGroups(groups)
+ for t_group in top_groups:
+ trees[t_group] = self.build_tree(groups, t_group)
+ self.flatten_tree(trees, all_groups)
+ all_groups = sorted(all_groups)
+
+ # create a designated color for each group
+ for i, group in enumerate(all_groups):
+ color_map[group] = self.colors[i]
+
+ # For all displayed stats, pull the mapped color into the array
+ for stat in sorted(samples):
+ colors.append(color_map[stat])
+
+ return colors
+ def flatten_tree(self, dictIn, listOut):
+ for key, value in dictIn.iteritems():
+ if isinstance(value, dict) and len(value) > 0: # If value itself is
dictionary
+ if key not in listOut:
+ listOut.append(key)
+ self.flatten_tree(value, listOut)
+ else:
+ listOut.append(key)
+
def get_line_title(self, stat):
return stat.replace("<", "").replace(">",
"")
@@ -1255,8 +1305,25 @@
break
vals.sort(key=lambda stat: stat["dt"], reverse=False) #here, we sort by
dt to be sure that our graphs are valid
- return vals
+ return vals
+
+ def build_tree(self, nodes, topNode):
+ tree = {}
+ self.build_tree_recursive(tree, topNode, nodes)
+ return tree
+
+ def build_tree_recursive(self, tree, parent, nodes):
+ children = []
+ for n in nodes:
+ (nparent, sep, leaf) = n.rpartition(".")
+ if nparent == parent:
+ children.append(n)
+
+ for child in children:
+ tree[child] = {}
+ self.build_tree_recursive(tree[child], child, nodes)
+
class AccGroupUseSqlOperation(SqlOperation):
def __init__(self, app, chart):
super(GeneralUseChart.AccGroupUseSqlOperation, self).__init__(app)