Make size column configurable graph
This commit makes the size column configurable to graphs by configuration file. And this commit adds color styles by thresholds which are configurable. Change-Id: Ifdc6961efbb178cc314c0fbd4d948a1ba19dcdd6
This commit is contained in:
parent
45e8402f31
commit
a34fdef1ed
|
@ -143,3 +143,12 @@ reviewkeys:
|
||||||
- key: 'meta 4'
|
- key: 'meta 4'
|
||||||
approvals: []
|
approvals: []
|
||||||
message: "recheck"
|
message: "recheck"
|
||||||
|
|
||||||
|
# 'size-column' is a set of customize parameters for the 'Size' column
|
||||||
|
# on your dashboard.
|
||||||
|
# 'type' must be 'graph' or 'number'. Default is 'graph'.
|
||||||
|
# 'thresholds' is for bar graphs width (when graph) or color styles
|
||||||
|
# (when number).
|
||||||
|
size-column:
|
||||||
|
type: 'graph'
|
||||||
|
thresholds: [1, 10, 100, 1000]
|
||||||
|
|
|
@ -111,6 +111,11 @@ class ConfigSchema(object):
|
||||||
|
|
||||||
keymaps = [keymap]
|
keymaps = [keymap]
|
||||||
|
|
||||||
|
thresholds = [int, int, int, int, int, int, int, int]
|
||||||
|
size_column = {v.Required('type'): v.Any('graph', 'splitGraph', 'number',
|
||||||
|
'disabled', None),
|
||||||
|
v.Optional('thresholds'): thresholds}
|
||||||
|
|
||||||
def getSchema(self, data):
|
def getSchema(self, data):
|
||||||
schema = v.Schema({v.Required('servers'): self.servers,
|
schema = v.Schema({v.Required('servers'): self.servers,
|
||||||
'palettes': self.palettes,
|
'palettes': self.palettes,
|
||||||
|
@ -129,6 +134,7 @@ class ConfigSchema(object):
|
||||||
'breadcrumbs': bool,
|
'breadcrumbs': bool,
|
||||||
'change-list-options': self.change_list_options,
|
'change-list-options': self.change_list_options,
|
||||||
'expire-age': str,
|
'expire-age': str,
|
||||||
|
'size-column': self.size_column,
|
||||||
})
|
})
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
@ -250,6 +256,15 @@ class Config(object):
|
||||||
|
|
||||||
self.expire_age = self.config.get('expire-age', '2 months')
|
self.expire_age = self.config.get('expire-age', '2 months')
|
||||||
|
|
||||||
|
self.size_column = self.config.get('size-column', {})
|
||||||
|
self.size_column['type'] = self.size_column.get('type', 'graph')
|
||||||
|
if self.size_column['type'] == 'graph':
|
||||||
|
self.size_column['thresholds'] = self.size_column.get('thresholds',
|
||||||
|
[1, 10, 100, 1000])
|
||||||
|
else:
|
||||||
|
self.size_column['thresholds'] = self.size_column.get('thresholds',
|
||||||
|
[1, 10, 100, 200, 400, 600, 800, 1000])
|
||||||
|
|
||||||
def getServer(self, name=None):
|
def getServer(self, name=None):
|
||||||
for server in self.config['servers']:
|
for server in self.config['servers']:
|
||||||
if name is None or name == server['name']:
|
if name is None or name == server['name']:
|
||||||
|
|
|
@ -98,6 +98,22 @@ DEFAULT_PALETTE={
|
||||||
'added-removed-graph': ['dark green', 'dark red'],
|
'added-removed-graph': ['dark green', 'dark red'],
|
||||||
'focused-added-graph': ['default,standout', 'dark green'],
|
'focused-added-graph': ['default,standout', 'dark green'],
|
||||||
'focused-removed-graph': ['default,standout', 'dark red'],
|
'focused-removed-graph': ['default,standout', 'dark red'],
|
||||||
|
'line-count-threshold-1': ['light green', ''],
|
||||||
|
'focused-line-count-threshold-1': ['light green,standout', ''],
|
||||||
|
'line-count-threshold-2': ['light cyan', ''],
|
||||||
|
'focused-line-count-threshold-2': ['light cyan,standout', ''],
|
||||||
|
'line-count-threshold-3': ['light blue', ''],
|
||||||
|
'focused-line-count-threshold-3': ['light blue,standout', ''],
|
||||||
|
'line-count-threshold-4': ['yellow', ''],
|
||||||
|
'focused-line-count-threshold-4': ['yellow,standout', ''],
|
||||||
|
'line-count-threshold-5': ['dark magenta', ''],
|
||||||
|
'focused-line-count-threshold-5': ['dark magenta,standout', ''],
|
||||||
|
'line-count-threshold-6': ['light magenta', ''],
|
||||||
|
'focused-line-count-threshold-6': ['light magenta,standout', ''],
|
||||||
|
'line-count-threshold-7': ['dark red', ''],
|
||||||
|
'focused-line-count-threshold-7': ['dark red,standout', ''],
|
||||||
|
'line-count-threshold-8': ['light red', ''],
|
||||||
|
'focused-line-count-threshold-8': ['light red,standout', ''],
|
||||||
}
|
}
|
||||||
|
|
||||||
# A delta from the default palette
|
# A delta from the default palette
|
||||||
|
|
|
@ -104,6 +104,15 @@ class ChangeRow(urwid.Button, ChangeListColumns):
|
||||||
|
|
||||||
'added-graph': 'focused-added-graph',
|
'added-graph': 'focused-added-graph',
|
||||||
'removed-graph': 'focused-removed-graph',
|
'removed-graph': 'focused-removed-graph',
|
||||||
|
|
||||||
|
'line-count-threshold-1': 'focused-line-count-threshold-1',
|
||||||
|
'line-count-threshold-2': 'focused-line-count-threshold-2',
|
||||||
|
'line-count-threshold-3': 'focused-line-count-threshold-3',
|
||||||
|
'line-count-threshold-4': 'focused-line-count-threshold-4',
|
||||||
|
'line-count-threshold-5': 'focused-line-count-threshold-5',
|
||||||
|
'line-count-threshold-6': 'focused-line-count-threshold-6',
|
||||||
|
'line-count-threshold-7': 'focused-line-count-threshold-7',
|
||||||
|
'line-count-threshold-8': 'focused-line-count-threshold-8',
|
||||||
}
|
}
|
||||||
|
|
||||||
def selectable(self):
|
def selectable(self):
|
||||||
|
@ -148,7 +157,7 @@ class ChangeRow(urwid.Button, ChangeListColumns):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _makeSize(self, added, removed):
|
def _makeSizeGraph(self, added, removed):
|
||||||
# Removed is a red graph on top, added is a green graph on bottom.
|
# Removed is a red graph on top, added is a green graph on bottom.
|
||||||
#
|
#
|
||||||
# The graph is 4 cells wide. If both the red and green graphs
|
# The graph is 4 cells wide. If both the red and green graphs
|
||||||
|
@ -165,7 +174,9 @@ class ChangeRow(urwid.Button, ChangeListColumns):
|
||||||
ret = []
|
ret = []
|
||||||
# The graph is logarithmic -- one cell for each order of
|
# The graph is logarithmic -- one cell for each order of
|
||||||
# magnitude.
|
# magnitude.
|
||||||
for threshold in [1, 10, 100, 1000]:
|
conf_thresholds = self.app.config.size_column['thresholds']
|
||||||
|
# for threshold in [1, 10, 100, 1000]:
|
||||||
|
for threshold in conf_thresholds:
|
||||||
color = []
|
color = []
|
||||||
if (added > threshold and removed > threshold):
|
if (added > threshold and removed > threshold):
|
||||||
ret.append(('added-removed-graph', lower_box))
|
ret.append(('added-removed-graph', lower_box))
|
||||||
|
@ -177,6 +188,36 @@ class ChangeRow(urwid.Button, ChangeListColumns):
|
||||||
ret.append(' ')
|
ret.append(' ')
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def _makeSizeSplitGraph(self, added, removed):
|
||||||
|
# Removed is a red graph on right, added is a green graph on left.
|
||||||
|
# conf_thresholds[7]: Full block,
|
||||||
|
# conf_thresholds[6]: Left seven eighths block,
|
||||||
|
# ...., conf_thresholds[0]: Left one eighth block.
|
||||||
|
# You can see the character table at the wikipedia[1] or somewhere.
|
||||||
|
# [1] https://en.wikipedia.org/wiki/Block_Elements#Character_table
|
||||||
|
conf_thresholds = self.app.config.size_column['thresholds']
|
||||||
|
thresholds = [(conf_thresholds[7], u'\u2588'),
|
||||||
|
(conf_thresholds[6], u'\u2589'),
|
||||||
|
(conf_thresholds[5], u'\u258a'),
|
||||||
|
(conf_thresholds[4], u'\u258b'),
|
||||||
|
(conf_thresholds[3], u'\u258c'),
|
||||||
|
(conf_thresholds[2], u'\u258d'),
|
||||||
|
(conf_thresholds[1], u'\u258e'),
|
||||||
|
(conf_thresholds[0], u'\u258f')]
|
||||||
|
ret = []
|
||||||
|
# The graph is logarithmic -- one cell for each order of
|
||||||
|
# magnitude.
|
||||||
|
for diff in [[added, 'added-graph'], [removed, 'removed-graph']]:
|
||||||
|
for threshold in thresholds:
|
||||||
|
if (diff[0] == 0):
|
||||||
|
ret.append(' ')
|
||||||
|
break
|
||||||
|
if (diff[0] >= threshold[0]):
|
||||||
|
ret.append((diff[1], threshold[1]))
|
||||||
|
break
|
||||||
|
ret.append(' ')
|
||||||
|
return ret
|
||||||
|
|
||||||
def update(self, change, categories):
|
def update(self, change, categories):
|
||||||
if change.reviewed or change.hidden:
|
if change.reviewed or change.hidden:
|
||||||
style = 'reviewed-change'
|
style = 'reviewed-change'
|
||||||
|
@ -217,7 +258,32 @@ class ChangeRow(urwid.Button, ChangeListColumns):
|
||||||
continue
|
continue
|
||||||
total_added += rfile.inserted or 0
|
total_added += rfile.inserted or 0
|
||||||
total_removed += rfile.deleted or 0
|
total_removed += rfile.deleted or 0
|
||||||
self.size.set_text(self._makeSize(total_added, total_removed))
|
if self.app.config.size_column['type'] == 'number':
|
||||||
|
total_added_removed = total_added + total_removed
|
||||||
|
thresholds = self.app.config.size_column['thresholds']
|
||||||
|
size_style = 'line-count-threshold-1'
|
||||||
|
if (total_added_removed >= thresholds[7]):
|
||||||
|
size_style = 'line-count-threshold-8'
|
||||||
|
elif (total_added_removed >= thresholds[6]):
|
||||||
|
size_style = 'line-count-threshold-7'
|
||||||
|
elif (total_added_removed >= thresholds[5]):
|
||||||
|
size_style = 'line-count-threshold-6'
|
||||||
|
elif (total_added_removed >= thresholds[4]):
|
||||||
|
size_style = 'line-count-threshold-5'
|
||||||
|
elif (total_added_removed >= thresholds[3]):
|
||||||
|
size_style = 'line-count-threshold-4'
|
||||||
|
elif (total_added_removed >= thresholds[2]):
|
||||||
|
size_style = 'line-count-threshold-3'
|
||||||
|
elif (total_added_removed >= thresholds[1]):
|
||||||
|
size_style = 'line-count-threshold-2'
|
||||||
|
elif (total_added_removed >= thresholds[0]):
|
||||||
|
size_style = 'line-count-threshold-1'
|
||||||
|
self.size.set_text((size_style, str(total_added_removed)))
|
||||||
|
elif self.app.config.size_column['type'] == 'splitGraph':
|
||||||
|
self.size.set_text(self._makeSizeSplitGraph(total_added,
|
||||||
|
total_removed))
|
||||||
|
else:
|
||||||
|
self.size.set_text(self._makeSizeGraph(total_added, total_removed))
|
||||||
|
|
||||||
self.category_columns = []
|
self.category_columns = []
|
||||||
for category in categories:
|
for category in categories:
|
||||||
|
@ -267,6 +333,7 @@ class ChangeListHeader(urwid.WidgetWrap, ChangeListColumns):
|
||||||
@mouse_scroll_decorator.ScrollByWheel
|
@mouse_scroll_decorator.ScrollByWheel
|
||||||
class ChangeListView(urwid.WidgetWrap, mywid.Searchable):
|
class ChangeListView(urwid.WidgetWrap, mywid.Searchable):
|
||||||
required_columns = set(['Number', 'Subject', 'Updated'])
|
required_columns = set(['Number', 'Subject', 'Updated'])
|
||||||
|
# FIXME(masayukig): Disable 'Size' column when configured
|
||||||
optional_columns = set(['Topic', 'Branch', 'Size'])
|
optional_columns = set(['Topic', 'Branch', 'Size'])
|
||||||
|
|
||||||
def getCommands(self):
|
def getCommands(self):
|
||||||
|
@ -344,6 +411,9 @@ class ChangeListView(urwid.WidgetWrap, mywid.Searchable):
|
||||||
# not.
|
# not.
|
||||||
self.enabled_columns.discard('Owner')
|
self.enabled_columns.discard('Owner')
|
||||||
self.disabled_columns.add('Owner')
|
self.disabled_columns.add('Owner')
|
||||||
|
if app.config.size_column['type'] == 'disabled':
|
||||||
|
self.enabled_columns.discard('Size')
|
||||||
|
self.disabled_columns.add('Size')
|
||||||
self.sort_by = sort_by or app.config.change_list_options['sort-by']
|
self.sort_by = sort_by or app.config.change_list_options['sort-by']
|
||||||
if reverse is not None:
|
if reverse is not None:
|
||||||
self.reverse = reverse
|
self.reverse = reverse
|
||||||
|
|
Loading…
Reference in New Issue