@@ -1725,16 +1725,26 @@ class bar:
17251725 trailing spaces. This is useful if anything follows the bar on its
17261726 line, such as if you wish to mark the end of the bar.
17271727
1728- clip (bool):
1729- Should the length of the bar be limited to *width* if a value
1730- greater than 1 is specified.
1728+ clip (real):
1729+ Maximum allowed value.
1730+ If value is larger than clip, it is plotted as if it equals clip
1731+ except bar is terminated with the overflow marker.
1732+
1733+ overflow (str):
1734+ The overflow marker. If value is greater than clip the overflow
1735+ marker is appended to the bar. If False, no marker is used.
1736+ Common values are '➔', '∎', '►', '▞', '▋▍▎▏' or '>>>'.
17311737
17321738 When rendered within a string you can specify a format that overrides the
1733- above arguments. The format strings take the form *WFC * where:
1739+ above arguments. The format strings take the form *WFCO * where:
17341740
17351741 - *W* is an integer that overrides *width*.
17361742 - *F* is either 'f' or 'F' overrides *full_width*; is true if capitalized.
1737- - *C* is either 'c' or 'C' overrides *clip*; is true if capitalized.
1743+ - *C* is a simple real number, 1 or greater.
1744+ - *O* is an arbitrary string that becomes the overflow marker.
1745+
1746+ The format fields are optional, but if one is given, the one listed before
1747+ it must also be given.
17381748
17391749 **Examples**::
17401750
@@ -1748,81 +1758,78 @@ class bar:
17481758 cash: ❭████▊ ❬
17491759 equities: ❭████████████████████████████████▊ ❬
17501760
1761+ In this second example a clipping value of 2 and an overflow marker is added
1762+ to the end of the end of the format string. When the life exceeds 2× the
1763+ maximum life the overflow marker is added to the end of the bar, which adds
1764+ a few vertical bars, a newline, and 20 spaced of indent.
1765+
1766+ >>> hours = dict(drill01=6, drill02=34, drill03=89, drill04=57)
1767+ >>> max_life = 40
1768+ >>> for name, life in hours.items():
1769+ ... print(f"{bar(life/max_life):20F2▋▍▎▏\n }", name)
1770+ ███ drill01
1771+ █████████████████ drill02
1772+ ████████████████████████████████████████▋▍▎▏
1773+ drill03
1774+ ████████████████████████████▌ drill04
1775+
17511776 """
1752- def __init__ (self , value , width = 72 , full_width = False , clip = True ):
1777+ def __init__ (self , value , width = 72 , full_width = False , clip = 1 , overflow = False ):
17531778 self .value = value
17541779 self .width = width
17551780 self .full_width = full_width
17561781 self .clip = clip
1782+ self .overflow = overflow or ''
17571783
1758- def render (self , value = None , width = None , full_width = None , clip = None ):
1784+ def render (self , value = None , width = None , full_width = None , clip = None , overflow = None ):
17591785 """Render bar to string
17601786
1761- Any arguments given will override those specified when class was
1762- instantiated.
1763-
1764- Args:
1765- value (real): Should be normalized (fall between 0 and 1)
1766-
1767- width (int): The width of the bar in characters when value is 1.
1768-
1769- full_width (bool):
1770- Whether bar should be rendered to fill the whole width using
1771- trailing spaces. This is useful if you plan to mark the end of
1772- the bar.
1773-
1774- clip (bool):
1775- Should the length of the bar be limited to *width* if a value
1776- greater than 1 is specified.
1787+ Arguments given override those specified when class was instantiated.
17771788 """
1778-
17791789 value = self .value if value is None else value
17801790 width = self .width if width is None else width
17811791 full_width = self .full_width if full_width is None else full_width
17821792 clip = self .clip if clip is None else clip
1783- scaled = value * width
1784- if clip and scaled > width :
1785- scaled = width
1786- if scaled < 0 :
1787- scaled = 0
1793+ overflow = self .overflow if overflow is None else overflow
1794+
1795+ scaled = max (min (value , clip ), 0 )* width
17881796 buckets = int (scaled )
17891797 frac = int ((NUM_BAR_CHARS * scaled ) % NUM_BAR_CHARS )
1790- extra = BAR_CHARS [frac - 1 :frac ]
1791- bar = buckets * BAR_CHARS [- 1 ] + extra
1798+ if value > clip :
1799+ last = overflow
1800+ else :
1801+ last = BAR_CHARS [frac - 1 :frac ]
1802+ bar = buckets * BAR_CHARS [- 1 ] + last
17921803 if full_width :
17931804 bar += (width - len (bar ))* ' '
17941805 return bar
17951806
17961807 def __format__ (self , formatter ):
1797- # format strings take the form WFC where:
1808+ # format strings take the form WFCO where:
17981809 # W is an integer indicating desired width
17991810 # F is either 'f' or 'F' for full_width, cap is true
1800- # C is either 'c' or 'C' for clip, cap is true
1801- value = self .value
1802- width = self .width
1803- full_width = self .full_width
1804- clip = self .clip
1811+ # C is a simple real number, 1 or greater.
1812+ # O is an arbitrary string that will be used as overflow marker
1813+ value = width = full_width = clip = overflow = None
18051814 if formatter :
1806- match = re .match (r'(\d*)([fFcC]{0,2}) ' , formatter )
1815+ match = re .match (r'(\d*)([fF]?)(\d\.?\d*)?(.*)\Z ' , formatter , re . S )
18071816 try :
18081817 if match [1 ]:
18091818 width = int (match [1 ])
18101819 if 'f' in match [2 ]:
18111820 full_width = False
18121821 if 'F' in match [2 ]:
18131822 full_width = True
1814- if 'c' in match [2 ]:
1815- clip = False
1816- if 'C' in match [2 ]:
1817- clip = True
1823+ clip = float (match [3 ]) if match [3 ] else None
1824+ overflow = match [4 ] or None
18181825 except (TypeError , ValueError ):
18191826 warn ('invalid format string' )
1820- return self .render (value , width , full_width , clip )
1827+ return self .render (value , width , full_width , clip , overflow )
18211828
18221829 def __str__ (self ):
18231830 return self .render ()
18241831
1825- def render_bar (value , width = 72 , full_width = False , clip = True ):
1832+ def render_bar (value , width = 72 , full_width = False , clip = 1 ):
18261833 """Render graphic representation of a value in the form of a bar
18271834
18281835 This function is deprecated. You should instead use::
@@ -1839,9 +1846,10 @@ def render_bar(value, width=72, full_width=False, clip=True):
18391846 trailing spaces. This is useful if you plan to mark the end of
18401847 the bar.
18411848
1842- clip (bool):
1843- Should the length of the bar be limited to *width* if a value
1844- greater than 1 is specified.
1849+ clip (real):
1850+ Maximum allowed value.
1851+ If value is larger than clip, it is plotted as if it equals clip
1852+ except bar is terminated with the overflow marker.
18451853 """
18461854 return bar (value , width , full_width , clip ).render ()
18471855
0 commit comments