Skip to content

Commit bd85f44

Browse files
Redesign Markers and wide lines classes (#134)
Fixes #133
1 parent e0f895e commit bd85f44

File tree

14 files changed

+185
-83
lines changed

14 files changed

+185
-83
lines changed

docs/source/user_guide/tutorial.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,8 @@ for each point and what to display at each point. This can be:
468468
- a :py:class:`framebuf.FrameBuffer` containing a 1-bit image
469469
- a :py:class:`array` of 16-bit integers giving a polygon to fill
470470

471-
The |Markers| shape expects a geometry consisting of an x, y point and a
472-
marker size, the colors for each marker and the shape of each marker.
471+
The |Markers| shape expects a geometry consisting of an x, y point, the colors
472+
for each marker, the size of each marker, and the shape of each marker.
473473
The marker shapes can be specified in the same way as |Points| (which are
474474
not scaled by size), but additionally as constants :py:attr:`Marker.CIRCLE`,
475475
:py:attr:`Marker.SQUARE`, etc. which will be scaled according to the sizes.
@@ -1011,10 +1011,10 @@ markers and text giving the corresponding values::
10111011
[
10121012
Repeat(x1 + 30),
10131013
Range(cy + 74, cy + 114, 12),
1014-
humidity_scale.scale_values(sample_humidities),
10151014
]
10161015
),
10171016
colors.blue,
1017+
humidity_scale.scale_values(sample_humidities),
10181018
Marker.CIRCLE,
10191019
)
10201020
surface.markers(
@@ -1023,10 +1023,10 @@ markers and text giving the corresponding values::
10231023
[
10241024
Repeat(x1 + 40),
10251025
Range(cy + 75, cy + 115, 12),
1026-
humidity_scale.scale_values(sample_humidities),
10271026
]
10281027
),
10291028
colors.grey_a,
1029+
humidity_scale.scale_values(sample_humidities),
10301030
[f"{h}%" for h in sample_humidities],
10311031
)
10321032

examples/lines_example.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@
3939
# draw some lines
4040
lines = WideLines(
4141
ColumnGeometry(
42-
[Range(8, 96, 8), Repeat(20), Range(8, 184, 16), Repeat(100), Range(1, 11)]
42+
[Range(8, 96, 8), Repeat(20), Range(8, 184, 16), Repeat(100)]
4343
),
4444
Interpolated(viridis, 10),
45+
Range(1, 11),
4546
clip=(0, 0, 160, 120),
4647
)
4748
surface.add_shape(DRAWING, lines)
@@ -55,10 +56,10 @@
5556
Repeat(100),
5657
Range(8, 184, 16) + 160,
5758
Repeat(20),
58-
Range(1, 11),
5959
]
6060
),
6161
Interpolated(viridis, 10),
62+
Range(1, 11),
6263
clip=(160, 0, 160, 120),
6364
round=False,
6465
)
@@ -82,12 +83,12 @@
8283
10 + 30 * i,
8384
125,
8485
]
85-
+ [i + 1],
8686
)
8787
for i in range(10)
8888
]
8989
),
9090
Interpolated(viridis, 10),
91+
Range(1, 11),
9192
clip=(0, 120, 320, 120),
9293
)
9394
surface.add_shape(DRAWING, polylines)

examples/polar_example.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -131,22 +131,18 @@
131131
)
132132
surface.add_shape(DRAWING, radar)
133133
markers = Markers(
134-
Extend(
135-
[
136-
polar_points(
137-
196,
138-
64,
139-
ColumnGeometry(
140-
[
141-
[30, 15, 45, 5, 45, 60],
142-
Range(0, 360, 60),
143-
]
144-
),
145-
),
146-
ColumnGeometry([Repeat(12)]),
147-
]
134+
polar_points(
135+
196,
136+
64,
137+
ColumnGeometry(
138+
[
139+
[30, 15, 45, 5, 45, 60],
140+
Range(0, 360, 60),
141+
]
142+
),
148143
),
149144
Repeat(grey_3),
145+
Repeat(12),
150146
[f" {x}" for x in [6, 3, 9, 1, 9, 12]],
151147
clip=(0, 0, 320, 240),
152148
)

examples/scatter_plot_example.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,14 @@ def scale_values(self, data):
181181
marker_colors = time_scale.scale_values(timestamps)
182182

183183
# Create point-size geometry for the data points
184-
markers = ColumnGeometry([xs, ys, marker_sizes])
184+
markers = ColumnGeometry([xs, ys])
185185

186186
# draw the plot
187187
surface.markers(
188188
DRAWING,
189189
markers,
190190
marker_colors,
191+
marker_sizes,
191192
Repeat(Marker.CIRCLE),
192193
clip=(x, y, w, h),
193194
)
@@ -272,10 +273,10 @@ def scale_values(self, data):
272273
[
273274
Repeat(x1 + 30),
274275
Range(cy + 74, cy + 114, 12),
275-
humidity_scale.scale_values(sample_humidities),
276276
]
277277
),
278278
Repeat(colors.blue),
279+
humidity_scale.scale_values(sample_humidities),
279280
Repeat(Marker.CIRCLE),
280281
)
281282
surface.markers(
@@ -284,10 +285,10 @@ def scale_values(self, data):
284285
[
285286
Repeat(x1 + 40),
286287
Range(cy + 75, cy + 115, 12),
287-
humidity_scale.scale_values(sample_humidities),
288288
]
289289
),
290290
Repeat(colors.grey_a),
291+
humidity_scale.scale_values(sample_humidities),
291292
[f"{h}%" for h in sample_humidities],
292293
clip=(x1 + 30, cy + 70, 40, 48),
293294
)

examples/shapes_example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
16 + x + int((16 - 8 * (a % 2)) * math.sin(math.pi * a / 5)),
116116
160 - int((16 - 8 * (a % 2)) * math.cos(math.pi * a / 5)),
117117
)
118-
for a in range(10)
118+
for a in range(11)
119119
]
120120
for x in range(0, 128, 32)
121121
]
@@ -194,10 +194,10 @@
194194
[
195195
Range(160, 320, 16),
196196
Repeat(30),
197-
Range(1, 13, 1),
198197
]
199198
),
200199
Interpolated(viridis, 10),
200+
Range(1, 13, 1),
201201
[
202202
Marker.PIXEL,
203203
Marker.CIRCLE,

src/tempe/component.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,16 @@ def map_xy(self):
289289
xs[i] = int(x)
290290
ys[i] = int(y)
291291

292-
return xs, ys, self.sizes
292+
return xs, ys
293293

294294
def draw(self):
295295
super().draw()
296-
xs, ys, sizes = self.map_xy()
296+
xs, ys = self.map_xy()
297297
self.shapes["markers"] = self.surface.points(
298298
DRAWING,
299-
ColumnGeometry([xs, ys, sizes]),
299+
ColumnGeometry([xs, ys]),
300300
self.colors,
301+
self.sizes,
301302
self.markers,
302303
clip=self.bounds,
303304
)

src/tempe/lines.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
from array import array
66
from math import sqrt
77

8-
from .shapes import ColoredGeometry
8+
from .shapes import SizedGeometry
99
from .util import line_points, intersect_poly_rect
1010

1111

12-
class WideLines(ColoredGeometry):
12+
class WideLines(SizedGeometry):
1313
"""Render multiple colored line segments with variable width.
1414
1515
Geometry should produce x0, y0, x1, y1, width arrays.
1616
"""
1717

18-
def __init__(self, geometry, colors, *, round=True, surface=None, clip=None):
19-
super().__init__(geometry, colors, surface=surface, clip=clip)
18+
def __init__(self, geometry, colors, sizes, *, round=True, surface=None, clip=None):
19+
super().__init__(geometry, colors, sizes, surface=surface, clip=clip)
2020
self.round = round
2121

2222
def draw_raster(self, raster):
@@ -27,8 +27,7 @@ def draw_raster(self, raster):
2727
h = raster.h
2828
vertices = array("h", bytearray(16))
2929
should_round = self.round
30-
for geometry, color in self:
31-
lw = geometry[4]
30+
for geometry, color, lw in self:
3231
if intersect_poly_rect(geometry[:4], 4, x - lw, y - lw, w + 2 * lw, h + 2 * lw):
3332
x0 = geometry[0]
3433
y0 = geometry[1]
@@ -50,19 +49,17 @@ def _get_bounds(self):
5049
min_x = 0x7FFF
5150
max_y = -0x7FFF
5251
min_y = 0x7FFF
53-
for geometry in self.geometry:
54-
max_x = max(max_x, geometry[0] + geometry[4], geometry[2] + geometry[4])
55-
min_x = min(min_x, geometry[0] - geometry[4], geometry[2] - geometry[4])
56-
max_y = max(max_y, geometry[1] + geometry[4], geometry[3] + geometry[4])
57-
min_y = min(min_y, geometry[1] - geometry[4], geometry[3] - geometry[4])
52+
for geometry, w in zip(self.geometry, self.sizes):
53+
max_x = max(max_x, geometry[0] + w, geometry[2] + w)
54+
min_x = min(min_x, geometry[0] - w, geometry[2] - w)
55+
max_y = max(max_y, geometry[1] + w, geometry[3] + w)
56+
min_y = min(min_y, geometry[1] - w, geometry[3] - w)
5857

5958
return (min_x, min_y, max_x - min_x, max_y - min_y)
6059

6160

62-
class WidePolyLines(ColoredGeometry):
61+
class WidePolyLines(SizedGeometry):
6362
"""Render multiple colored polylines with variable width.
64-
65-
Geometry should produce array of [x0, y0, x1, y1, ...] and width.
6663
"""
6764

6865
def draw_raster(self, raster):
@@ -72,9 +69,7 @@ def draw_raster(self, raster):
7269
w = raster.w
7370
h = raster.h
7471
vertices = array("h", bytearray(16))
75-
for geometry, color in self:
76-
lw = geometry[-1]
77-
lines = geometry[:-1]
72+
for lines, color, lw in self:
7873
if intersect_poly_rect(lines, len(lines), x - lw, y - lw, w + 2 * lw, h + 2 * lw):
7974
for i in range(0, len(lines) - 2, 2):
8075
x0 = lines[i]
@@ -99,9 +94,7 @@ def _get_bounds(self):
9994
min_x = 0x7FFF
10095
max_y = -0x7FFF
10196
min_y = 0x7FFF
102-
for geometry in self.geometry:
103-
w = geometry[-1]
104-
lines = geometry[:-1]
97+
for lines, w in zip(self.geometry, self.sizes):
10598
for i in range(0, len(lines), 2):
10699
max_x = max(max_x, lines[i] + w)
107100
min_x = min(min_x, lines[i] - w)

src/tempe/lines.pyi

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,16 @@ by rendering circles at the vertices.
2020
from array import array
2121
from collections.abc import Sequence, Iterable
2222
from math import sqrt
23-
from typing import TypeAlias
23+
from typing import Generator, TypeAlias
2424

25-
from .shapes import ColoredGeometry, point_array, rectangle
25+
from .shapes import SizedGeometry, point_array, rectangle, points
2626
from .colors import rgb565
2727

28-
points_widths: TypeAlias = tuple[int, int, int, int, int]
2928

30-
class WideLines(ColoredGeometry[points_widths]):
29+
class WideLines(SizedGeometry[points]):
3130
"""Render multiple colored line segments with variable width.
3231
33-
Geometry should produce x0, y0, x1, y1, width arrays.
32+
Geometry should produce x0, y0, x1, y1 arrays.
3433
3534
For line widths less than 2, this renders using the standard framebuf
3635
line drawing routines. For line widths of 2 or more, this renders each
@@ -40,9 +39,11 @@ class WideLines(ColoredGeometry[points_widths]):
4039
Parameters
4140
----------
4241
geometry : Iterable[geom]
43-
The sequence of geometries to render.
42+
The sequence of line segments to render.
4443
colors : Iterable[rgb565]
45-
The sequence of colors for each geometry.
44+
The sequence of colors for each line segment.
45+
sizes : Iterable[rgb565]
46+
The sequence of line widths for each line segment.
4647
round : bool
4748
Whether to round the ends with circles, or to leave as a flat end.
4849
surface : Surface | None
@@ -54,19 +55,18 @@ class WideLines(ColoredGeometry[points_widths]):
5455

5556
def __init__(
5657
self,
57-
geometry: Iterable[points_widths],
58+
geometry: Iterable[points],
5859
colors: Iterable[rgb565],
5960
*,
6061
round: bool = True,
6162
surface: "tempe.surface.Surface | None" = None,
6263
clip: rectangle | None = None,
6364
): ...
64-
def __iter__(self) -> tuple[points_widths, int]: ...
6565

66-
class WidePolyLines(ColoredGeometry[point_array]):
66+
class WidePolyLines(SizedGeometry[point_array]):
6767
"""Render multiple colored polylines with variable width.
6868
69-
Geometry should produce array of [x0, y0, x1, y1, ..., width].
69+
Geometry should produce array of [x0, y0, x1, y1, ...].
7070
7171
For line widths less than 2, this renders using the standard framebuf
7272
line drawing routines. For line widths of 2 or more, this renders each

0 commit comments

Comments
 (0)