Skip to content

Commit 3f0447b

Browse files
godlygeekpablogsal
authored andcommitted
tui: Use half-block characters for memory graph
This is easier to read than our previous braille version, and looks nicer when rendered in a browser or VS Code. It's less granular, unfortunately. The braille version added a new dot for each ~6%, and this implementation adds a new half block for each ~11%. This also fixes a longstanding bug: the graph was only showing half of the data points it should have been showing. Each data point would become the right braille column of one cell as well as the left braille column of the next cell, so we only had half the horizontal granularity we intended to have. Signed-off-by: Matt Wozniski <[email protected]>
1 parent 1cce4cb commit 3f0447b

File tree

3 files changed

+591
-593
lines changed

3 files changed

+591
-593
lines changed

src/memray/reporters/tui.py

+19-34
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from math import ceil
1313
from typing import Any
1414
from typing import DefaultDict
15-
from typing import Deque
1615
from typing import Dict
1716
from typing import Iterable
1817
from typing import List
@@ -96,26 +95,22 @@ def __init__(
9695
maxval: float = 1.0
9796
minval: float = 0.0
9897
self._width = max_data_points
99-
self._graph: List[Deque[str]] = [
100-
deque(maxlen=self._width) for _ in range(height)
101-
]
10298
self._height = height
10399
self._minval = minval
104100
self._maxval = maxval
105-
self._previous_blocks = [0] * height
106101
values = [minval] * (2 * self._width + 1)
107-
self._values = deque(values, maxlen=2 * self._width + 1)
102+
self._values = deque(values, maxlen=2 * self._width)
103+
108104
self._lookup = [
109-
[" ", "⢀", "⢠", "⢰", "⢸"],
110-
["⡀", "⣀", "⣠", "⣰", "⣸"],
111-
["⡄", "⣄", "⣤", "⣴", "⣼"],
112-
["⡆", "⣆", "⣦", "⣶", "⣾"],
113-
["⡇", "⣇", "⣧", "⣷", "⣿"],
105+
[" ", "▗", "▐"],
106+
["▖", "▄", "▟"],
107+
["▌", "▙", "█"],
114108
]
109+
115110
self.border_title = "Heap Usage"
116111

117112
def _value_to_blocks(self, value: float) -> List[int]:
118-
dots_per_block = 4
113+
dots_per_block = 2
119114
if value < self._minval:
120115
n_dots = 0
121116
elif value > self._maxval:
@@ -135,8 +130,8 @@ def _value_to_blocks(self, value: float) -> List[int]:
135130

136131
def add_value(self, value: float) -> None:
137132
if value > self._maxval:
138-
self._reset_max(value)
139-
self._add_value_without_redraw(value)
133+
self._maxval = value
134+
self._values.append(value)
140135
if self._maxval > 1:
141136
self.border_subtitle = (
142137
f"{size_fmt(int(value))}"
@@ -145,30 +140,20 @@ def add_value(self, value: float) -> None:
145140
)
146141
self.refresh()
147142

148-
def _reset_max(self, value: float) -> None:
149-
self._graph = [deque(maxlen=self._width) for _ in range(self._height)]
150-
self._maxval = value
151-
for old_val in list(self._values):
152-
self._add_value_without_redraw(old_val)
153-
154-
def _add_value_without_redraw(self, value: float) -> None:
155-
blocks = self._value_to_blocks(value)
156-
157-
chars = reversed(
158-
tuple(self._lookup[i0][i1] for i0, i1 in zip(self._previous_blocks, blocks))
159-
)
143+
def render_line(self, y: int) -> Strip:
144+
graph: list[list[str]] = [[] for _ in range(self._height)]
145+
blocks_by_index = [self._value_to_blocks(value) for value in self._values]
160146

161-
for row, char in enumerate(chars):
162-
self._graph[row].append(char)
147+
for left, right in zip(blocks_by_index[::2], blocks_by_index[1::2]):
148+
for row, char in enumerate(
149+
reversed(tuple(self._lookup[li][ri] for li, ri in zip(left, right)))
150+
):
151+
graph[row].append(char)
163152

164-
self._values.append(value)
165-
self._previous_blocks = blocks
166-
167-
def render_line(self, y: int) -> Strip:
168-
if y > len(self._graph):
153+
if y > len(graph):
169154
return Strip.blank(self.size.width)
170155
data = " " * self.size.width
171-
data += "".join(self._graph[y])
156+
data += "".join(graph[y])
172157
data = data[-self.size.width :]
173158
return Strip([Segment(data, self.rich_style)])
174159

0 commit comments

Comments
 (0)