mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-23 13:13:33 +00:00
fix(canvas): round coordinates to nearest grid cell (#1507)
Previously the canvas coordinates were rounded towards zero, which causes the rendering to be off by one pixel in some cases. It also meant that pixels at the extreme edges of the canvas can only be drawn if the point was exactly on the edge of the canvas. This commit rounds the coordinates to the nearest integer instead. This may change the output for some apps using Canvas / Charts.
This commit is contained in:
parent
56d5e05762
commit
ec30390446
6 changed files with 124 additions and 374 deletions
|
@ -362,6 +362,9 @@ impl<'a, 'b> Painter<'a, 'b> {
|
|||
/// and `[0, height - 1]` respectively. The resolution of the grid is used to convert the
|
||||
/// `(x, y)` coordinates to the location of a point on the grid.
|
||||
///
|
||||
/// Points are rounded to the nearest grid cell (with points exactly in the center of a cell
|
||||
/// rounding up).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -377,7 +380,7 @@ impl<'a, 'b> Painter<'a, 'b> {
|
|||
/// assert_eq!(point, Some((0, 7)));
|
||||
///
|
||||
/// let point = painter.get_point(1.5, 1.0);
|
||||
/// assert_eq!(point, Some((1, 3)));
|
||||
/// assert_eq!(point, Some((2, 4)));
|
||||
///
|
||||
/// let point = painter.get_point(0.0, 0.0);
|
||||
/// assert_eq!(point, None);
|
||||
|
@ -389,20 +392,18 @@ impl<'a, 'b> Painter<'a, 'b> {
|
|||
/// assert_eq!(point, Some((0, 0)));
|
||||
/// ```
|
||||
pub fn get_point(&self, x: f64, y: f64) -> Option<(usize, usize)> {
|
||||
let left = self.context.x_bounds[0];
|
||||
let right = self.context.x_bounds[1];
|
||||
let top = self.context.y_bounds[1];
|
||||
let bottom = self.context.y_bounds[0];
|
||||
let [left, right] = self.context.x_bounds;
|
||||
let [bottom, top] = self.context.y_bounds;
|
||||
if x < left || x > right || y < bottom || y > top {
|
||||
return None;
|
||||
}
|
||||
let width = (self.context.x_bounds[1] - self.context.x_bounds[0]).abs();
|
||||
let height = (self.context.y_bounds[1] - self.context.y_bounds[0]).abs();
|
||||
if width == 0.0 || height == 0.0 {
|
||||
let width = right - left;
|
||||
let height = top - bottom;
|
||||
if width <= 0.0 || height <= 0.0 {
|
||||
return None;
|
||||
}
|
||||
let x = ((x - left) * (self.resolution.0 - 1.0) / width) as usize;
|
||||
let y = ((top - y) * (self.resolution.1 - 1.0) / height) as usize;
|
||||
let x = ((x - left) * (self.resolution.0 - 1.0) / width).round() as usize;
|
||||
let y = ((top - y) * (self.resolution.1 - 1.0) / height).round() as usize;
|
||||
Some((x, y))
|
||||
}
|
||||
|
||||
|
|
|
@ -53,10 +53,10 @@ mod tests {
|
|||
.y_bounds([-10.0, 10.0]);
|
||||
canvas.render(buffer.area, &mut buffer);
|
||||
let expected = Buffer::with_lines([
|
||||
" ⢀⣠⢤⣀ ",
|
||||
" ⢰⠋ ⠈⣇",
|
||||
" ⠘⣆⡀ ⣠⠇",
|
||||
" ⠉⠉⠁ ",
|
||||
" ⣀⣀⣀ ",
|
||||
" ⡞⠁ ⠈⢣",
|
||||
" ⢇⡀ ⢀⡼",
|
||||
" ⠉⠉⠉ ",
|
||||
" ",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
|
|
|
@ -168,7 +168,7 @@ mod tests {
|
|||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"••••• ",
|
||||
"•••••• ",
|
||||
])]
|
||||
#[case::off_grid6(&Line::new(-1.0, -1.0, 10.0, 10.0, Color::Red), [
|
||||
" •",
|
||||
|
@ -238,12 +238,12 @@ mod tests {
|
|||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" •",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
"• ",
|
||||
" ",
|
||||
" ••",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
"•• ",
|
||||
])]
|
||||
// dy < dx, x1 > x2
|
||||
#[case::diagonal2(&Line::new(10.0, 0.0, 0.0, 5.0, Color::Red), [
|
||||
|
@ -251,15 +251,16 @@ mod tests {
|
|||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" •",
|
||||
" ",
|
||||
"•• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" •• ",
|
||||
" ••",
|
||||
])]
|
||||
// dy > dx, y1 < y2
|
||||
#[case::diagonal3(&Line::new(0.0, 0.0, 5.0, 10.0, Color::Red), [
|
||||
" • ",
|
||||
" • ",
|
||||
" • ",
|
||||
" • ",
|
||||
|
@ -269,11 +270,9 @@ mod tests {
|
|||
" • ",
|
||||
" • ",
|
||||
"• ",
|
||||
"• ",
|
||||
])]
|
||||
// dy > dx, y1 > y2
|
||||
#[case::diagonal4(&Line::new(0.0, 10.0, 5.0, 0.0, Color::Red), [
|
||||
"• ",
|
||||
"• ",
|
||||
" • ",
|
||||
" • ",
|
||||
|
@ -283,6 +282,7 @@ mod tests {
|
|||
" • ",
|
||||
" • ",
|
||||
" • ",
|
||||
" • ",
|
||||
])]
|
||||
fn tests<'expected_line, ExpectedLines>(#[case] line: &Line, #[case] expected: ExpectedLines)
|
||||
where
|
||||
|
|
|
@ -102,44 +102,44 @@ mod tests {
|
|||
canvas.render(buffer.area, &mut buffer);
|
||||
let expected = Buffer::with_lines([
|
||||
" ",
|
||||
" ••••••• •• •• •• • ",
|
||||
" •••••••••••••• ••• •••• ••• •• •••• ",
|
||||
" •••••••••••••••• •• ••• ••••••• •• •• ••• ",
|
||||
"• • •• •••••• •••••••••••• •• ••• • ••••• ••••••••• •• • • • • ",
|
||||
"••••• •••• •••••••• •• •• ••• •••• •••• •• • • ",
|
||||
" •••••••• ••••••• ••••• ••• •••••••• • ••••• ",
|
||||
" •• •• •• ••••••• •• ••• •••• •• • ",
|
||||
"••• ••• •••••• •••• •••• •• • •• ",
|
||||
" • ••••••••• •• • ••• • •• •• •• ",
|
||||
" • • •••• •• ••••••••• ••• • • • •• ",
|
||||
" • • ••••• •••• •• •••••• ",
|
||||
" • •• • • •• • ••••• ",
|
||||
" •• •• • • •• •• • ",
|
||||
" •• ••• ••• • • ••••• • ••• ",
|
||||
" • •••• ••• • • • • • •• ",
|
||||
" •••• • • •• • • •• •• ",
|
||||
" ••• •• • • • •• ••• ••• ",
|
||||
" • • • •• • • • • • ",
|
||||
" • • • • • • ••• • • ",
|
||||
" • • • • •• • • • ",
|
||||
" • • •• ••• • ",
|
||||
" • • • • • • • • ",
|
||||
" • • • •• • • • • • ",
|
||||
" • • • • ",
|
||||
" • • • • • • ",
|
||||
" • •• • • • • •• • ",
|
||||
" • • • •••• •• ",
|
||||
" • • •• ••• ",
|
||||
" •• • ",
|
||||
" •• • ",
|
||||
" •• ",
|
||||
" • ",
|
||||
" • •• •••••••• •• •••• ••••• ••• •• ••• ",
|
||||
" ••••••••••••••• • •••• • • ••••••• ••• ",
|
||||
" • •••• ••••••••••••••• •• •• • ••• •• •••• •• ••••••• ••• ",
|
||||
"••••• •••••••••••• •••• • •••••• •••• • ••• ••••• •",
|
||||
" •• • • •••• •••••••• •••• •• • •• • ••• •• •••",
|
||||
" •••• ••• •••••• ••••• • •• •••••• • ••••• ",
|
||||
"••••• ••• • •• •• ••••••• •• •• •• ",
|
||||
" •• •••• ••••• •• • • • •• ",
|
||||
" • • ••••••• •• •••• ••• •• • •• • •• ",
|
||||
" • •• ••••••••• • •• •••• • ",
|
||||
" •• •• • • • •• • ••••• ",
|
||||
" •• ••• • •••• • • • ",
|
||||
" • • •• • •• •• • • ",
|
||||
" •• • ••••••• • • • • • •• • ",
|
||||
" ••••••••• • •• • • • •• • •• ",
|
||||
" •• •• • ••• • ••• •• ",
|
||||
" ••• • • • • • •• ••• ••• ",
|
||||
" • • •• • •• ",
|
||||
" • • ••• • • ••• ••• ",
|
||||
" • • • • • ••• ",
|
||||
" • • • • • • • ",
|
||||
" • • • • ••• •• •",
|
||||
" • • • • •• • • • ",
|
||||
" • • • • • ",
|
||||
" • • • • • ",
|
||||
" •• •• •• •• • • ",
|
||||
" • • ••• •• ",
|
||||
" • • •• •• ",
|
||||
" • • ",
|
||||
" ••••• ",
|
||||
" ",
|
||||
" ••• • •••• • • •• • ",
|
||||
" •••• •••••• •••••• •••••• • ••• ",
|
||||
" •• •••••• ••••• •• • ••• • •• ",
|
||||
"• ••••• •• •• •••••• • •• ",
|
||||
"• • • • • • • ",
|
||||
" • ",
|
||||
" •• ",
|
||||
" ••• • • ••••• • •••• • • •• •• •• ",
|
||||
" • • • •••••• ••••••••• • •• •• ••• ",
|
||||
"• ••• •••• •••• • • • ••• • • ••• •",
|
||||
" •• • • •• • •• •• ",
|
||||
"• • • ",
|
||||
" ",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
|
@ -161,44 +161,44 @@ mod tests {
|
|||
canvas.render(buffer.area, &mut buffer);
|
||||
let expected = Buffer::with_lines([
|
||||
" ",
|
||||
" ⢀⣠⠤⠤⠤⠔⢤⣤⡄⠤⡠⣄⠢⠂⢢⠰⣠⡄⣀⡀ ⣀ ",
|
||||
" ⢀⣀⡤⣦⠲⢶⣿⣮⣿⡉⣰⢶⢏⡂ ⢀⣟⠁ ⢺⣻⢿⠏ ⠈⠉⠁ ⢀⣀ ⠈⠓⢳⣢⣂⡀ ",
|
||||
" ⡞⣳⣿⣻⡧⣷⣿⣿⢿⢿⣧⡀⠉⠉⠙⢆ ⣰⠇ ⣠⠞⠃⢉⣄⣀⣠⠴⠊⠉⠁ ⠐⠾⠤⢤⠤⡄⠐⣻⠜⢓⠂ ",
|
||||
"⢍ ⢀⡴⠊⠙⠓⠒⠒⠤⠖⠺⠿⠽⣷⣬⢬⣾⣷⢻⣷⢲⢲⣍⠱⡀ ⠹⡗ ⢀⢐⠟ ⡔⠒⠉⠲⠤⢀⢄⡀⢩⣣⠦⢷⢼⡏⠈ ⠉⠉⠉ ⠈⠈⠉⠖⠤⠆⠒⠭",
|
||||
"⠶⢽⡲⣽⡆ ⠈⣠⣽⣯⡼⢯⣘⡯⠃⠘⡆ ⢰⠒⠁ ⢾⣚⠟ ⢀⠆ ⣔⠆ ⢷⠾⠋⠁ ⠙⠁ ⠠⡤",
|
||||
" ⠠⢧⣄⣀⡶⠦⠤⡀ ⢰⡁ ⠉⡻⠙⣎⡥ ⠘⠲⠇ ⢀⡀⠨⣁⡄⣸⢫⡤⠄ ⣀⢠⣤⠊⣼⠅⠖⠋⠁",
|
||||
" ⣠⠾⠛⠁ ⠈⣱ ⠋⠦⢤⡼ ⠈⠈⠦⡀ ⢀⣿⣇ ⢹⣷⣂⡞⠃ ⢀⣂⡀ ⠏⣜ ",
|
||||
" ⠙⣷⡄ ⠘⠆ ⢀⣀⡠⣗ ⠘⣻⣽⡟⠉⠈ ⢹⡇ ⠟⠁ ",
|
||||
" ⠈⡟ ⢎⣻⡿⠾⠇ ⠘⠇ ⣀⡀ ⣤⣤⡆ ⡠⡦ ⢀⠎⡏ ",
|
||||
" ⡇ ⣀⠏⠋ ⢸⠒⢃⡖⢻⢟⣷⣄⣰⣡⠥⣱ ⢏⣧ ⣀ ⡴⠚⢰⠟ ",
|
||||
" ⢳ ⢸⠃ ⠸⣄⣼⣠⢼⡴⡟⢿⢿⣀⣄ ⠸⡹ ⠘⡯⢿⡇⡠⢼⠁ ",
|
||||
" ⢳⣀ ⢀⠞⠁ ⢠⠋⠁ ⠐⠧⡄⣬⣉⣈⡽ ⢧⠘⢽⠟⠉ ",
|
||||
" ⣿⣄ ⡴⠚⠛⣿⣀ ⢠⠖ ⠈⠁ ⠹⣧ ⢾⣄⡀ ⡼ ⠈ ",
|
||||
" ⣀ ⠘⣿⡄ ⡇ ⣘⣻ ⡏ ⢻⡄ ⠘⠿⢿⠒⠲⡀ ⢀⡀ ⢀⡰⣗ ",
|
||||
" ⠉⠷ ⢫⡀⢧⡼⡟⠉⣛⣳⣦⡀ ⠈⡇ ⠸⣱ ⢀⡼ ⢺ ⡸⠉⢇ ⣾⡏ ⣁ ",
|
||||
" ⠉⠒⢆⡓⡆ ⠠⡃ ⢳⣇⡠⠏ ⠐⡄⡞ ⠘⣇⡀⢱ ⣾⡀ ",
|
||||
" ⢹⣇⣀⣾⡷⠤⡆ ⢣ ⠯⢺⠇ ⢣⣅ ⣽⢱⡔ ⢠⢿⣗ ",
|
||||
" ⠙⢱ ⠘⠦⡄ ⠈⢦⡠⣠⢶⣀ ⡜ ⠈⠿ ⢠⣽⢆ ⢀⣼⡜⠿ ",
|
||||
" ⢀⡞ ⢱⡀ ⢸ ⡔⠁ ⢻⢿⢰⠏⢸⣤⣴⣆ ",
|
||||
" ⢘⠆ ⠙⠢⢄ ⠸⡀ ⡸⠁ ⠈⣞⡎⠥⡟⣿⠠⠿⣷⠒⢤⢀⣆ ",
|
||||
" ⠘⠆ ⢈⠂ ⢳ ⡇ ⠈⠳⠶⣤⣭⣠ ⠋⢧⡬⣟⠉⠷⡄ ",
|
||||
" ⢨ ⡜ ⢸ ⠸ ⣠ ⠁⢁⣰⢶ ⡇⠉⠁ ⠛ ",
|
||||
"⠆ ⠈⢱⡀ ⡆ ⡇ ⢀⡜⡴⢹ ⢰⠏⠁⠘⢶⠹⡀ ⠸ ⢠⡶",
|
||||
" ⠅ ⣸ ⢸ ⢫ ⡞⡊ ⢠⠔⠋ ⢳⡀ ⠐⣦ ",
|
||||
" ⡅ ⡏ ⠈⡆ ⢠⠎ ⠳⠃ ⢸ ⢳ ",
|
||||
" ⠨ ⡸⠁ ⢱ ⡸ ⠈⡇ ⢀⣀⡀ ⢸ ",
|
||||
" ⠸ ⠐⡶⠁ ⠘⠖⠚ ⠣⠒⠋ ⠱⣇ ⢀⠇ ⠰⡄ ",
|
||||
" ⠽ ⣰⡖⠁ ⠘⢚⡊ ⢀⣿⠇",
|
||||
" ⡯⢀⡟ ⠘⠏ ⢠⢾⠃ ",
|
||||
" ⠇⢨⠆ ⢠⡄ ⠈⠁ ",
|
||||
" ⢧⣷⡀⠚ ",
|
||||
" ⠉⠁ ",
|
||||
" ⢀⡀ ",
|
||||
" ⢠⡾⠋ ⣀⡠⠖⢦⣀⣀ ⣀⠤⠦⢤⠤⠶⠤⠖⠦⠤⠤⠤⠴⠤⢤⣄ ",
|
||||
" ⢀⣤⣀ ⡀ ⣼⣻⠙⡆ ⢀⡤⠤⠤⠴⠒⠖⠒⠒⠒⠚⠉⠋⠁ ⢰⡳⠊⠁ ⠈⠉⠉⠒⠤⣤ ",
|
||||
" ⢀⣀⣀⡴⠖⠒⠒⠚⠛⠛⠛⠒⠚⠳⠉⠉⠉⠉⢉⣉⡥⠔⠃ ⢀⣠⠤⠴⠃ ⢠⠞⠁ ",
|
||||
" ⠘⠛⣓⣒⠆ ⠸⠥⣀⣤⡦⠠⣞⣭⣇⣘⠿⠆ ⣖⠛ ",
|
||||
"⠶⠔⠲⠤⠠⠜⢗⠤⠄ ⠘⠉ ⠁ ⠈⠉⠒⠔⠤",
|
||||
" ⢀⣀⣤⠄⠤⠤⣤⣀⡀⣀⣀⡄⠄⢄⣀⣄⡄⢀⡀ ",
|
||||
" ⢀⣀⣤⠰⢤⣼⡯⢽⡟⣀⢶⣺⡛⠁ ⠈⢰⠃⠁ ⢖⣒⣾⡟⠂ ⠈⠛⠁ ⠺⢩⢖⡄ ",
|
||||
" ⡬⢍⣿⣟⣿⣻⣿⣿⣿⡾⣯⡀⠈⠁⠁⢦ ⢀⡿ ⠈ ⢠⢶⠘⠋⡁⣀⢠⠤⠖⠘⠉⠁⠈⠼⡧⡄⣄⡀ ⢫⣗⠒⠆ ",
|
||||
"⣓ ⣠⠖⠓⠒⠢⠤⢄⠤⠶⠽⠽⣶⣃⣽⡮⣿⡷⣗⣤⡭⣍⢓⡄ ⠸⣷ ⢀⣀⠿⠇ ⢀⠔⠒⠲⠄⢄⢀⡀⢙⣑⡄⠴⡍⣟⠉ ⠑⠉⠉ ⠑⠐⠦⠤⣤⠤⢞",
|
||||
"⠶⢧⣗⢾⡆ ⠈⠈⠁⠈⠉⢀⣹⣶⣩⣽⣐⢮⠃ ⣇ ⢀⡔⠊ ⢰⣖⣲ ⢀⡐⠁⣰⠦ ⢲⣶⠛⠋ ⠐⠋ ⡤",
|
||||
" ⠉⣮⣀⣀⣴⡤⣠⡀ ⡎ ⠛⢫⠙⢫⢫ ⠈⠦⠼ ⡃⡀⢸⠼⣤⡄ ⡀⣀⣀⡐⡶⣣⢤⠖⠉",
|
||||
" ⢀⡽⠟⠃ ⠈⠱⡀ ⠙⠢⣀⣨⠆⠈⠁⢧⡀ ⣸⣷ ⢹⣷⣼⣸⠃ ⢀⡐⢀ ⠁⡚⣨⠆ ",
|
||||
" ⠘⢳⡀ ⠈⠾ ⣀⣀⣽ ⠸⢼⣇⡧⠋⠉⠁ ⠉⣿ ⠢⠂ ",
|
||||
" ⠈⢻ ⠜⢹⣵⠻⠇ ⠈⢻ ⢀⡀ ⢠⣠⡤ ⢀⢤ ⢰⣯ ",
|
||||
" ⢼ ⢀⣾⠛⠉ ⠐⡖⠒⡰⢺⣞⣵⡄⢀⣏⡭⣙⡄⢕⢫⡀ ⢀ ⢠⠖⢱⡿⠃ ",
|
||||
" ⠸ ⠠⡎ ⠰⣅⣰⣃⣘⡣⡿⢻⡿⣁⣀ ⠸⣽ ⠐⣿⣽⣫ ⡸⡇ ",
|
||||
" ⠳⣄ ⡰⠃ ⢀⠎⠉ ⢧⡀⣠⣛⠈⢻ ⢻⠘⢺⡿⠚⠁ ",
|
||||
" ⢻⣇ ⣠⠲⠖⢲⡇ ⡸ ⠉⠃⠈⠉⣿ ⢰⣆ ⢸ ⠈⠁ ",
|
||||
" ⠈⢿⣆ ⡟ ⣘⣻ ⡸ ⢸⢇ ⠈⠯⢿⡒⠲⡀ ⢀⡀ ⣀⢾ ",
|
||||
" ⠈⢳ ⠸⡀⢳⣠⢾⠉⢹⣦⣤⣀ ⡇ ⡿⡄ ⢰⠃ ⠑⡂ ⢠⠏⢣ ⣼⡮⠁⢈⡀ ",
|
||||
" ⠙⠲⢆⡿⢦⠈⠉⠁⠁ ⡇ ⠱⣇⣀⠼⠃ ⡃⢰⠃ ⠸⢶ ⠘⠄ ⢾⡁ ",
|
||||
" ⠙⣾⣀⡴⡶⢤⣤ ⢳ ⠻⠵⡆ ⠸⣸ ⢸⡳⡤⠃⢀⡾⣿ ",
|
||||
" ⠘⢻⠁ ⠈⠦⣄ ⢧⣀⣀⠤⣀ ⢐⠁ ⠈⠩⠆ ⣘⣧⠁ ⡸⡔⢿ ",
|
||||
" ⡸ ⢨ ⠁ ⠉⡇ ⢀⠎ ⢻⢿⠄⡴⢑⣧⡠⡄ ",
|
||||
" ⡇ ⠈⠋⠦⡄ ⠈⡆ ⢠⠃ ⢏⡇⢧⣼⣾⣧⣽⣿⠶⢤⡀⣤ ",
|
||||
" ⣇ ⠈⡇ ⢸ ⢸ ⠈⠶⣦⣄⣋⣁⡀⠸⣵⢠⣻⠋⠷⣄ ",
|
||||
" ⠰⡀ ⣰⠁ ⢘⠆ ⢸ ⢠⡀ ⠙⠋⢠⠦⡄⣷⠙⠃ ⠙ ",
|
||||
"⠄ ⠣⡀ ⡃ ⢸ ⣸⢡⢾⠆ ⡞⠛⠘⢧⡏⡆ ⠸⠄ ⡤",
|
||||
" ⠱ ⢠⠃ ⠸⡀ ⢸⠁⢸⢨ ⡤⠚ ⠱⡀ ⢦ ⠁",
|
||||
" ⠅ ⡖⠉ ⡇ ⡜ ⠸⠔ ⡇ ⢳ ",
|
||||
" ⡇ ⢀⠃ ⢱⡀ ⢰⠃ ⣇ ⢀⡀ ⢸ ",
|
||||
" ⢀⠃ ⡦⠏ ⠈⠷⠖⠃ ⠾⠴⠊⠁⠹⣦ ⡞ ⣄ ",
|
||||
" ⢸ ⡤⠃ ⠘⢲⠖⠃ ⣽⡆",
|
||||
" ⢸ ⣸⠁ ⠈⠿ ⢀⢼⠏ ",
|
||||
" ⠞ ⡗ ⣄ ⠈⠋ ",
|
||||
" ⢧⡼⡁⠲⠂ ",
|
||||
" ⠙⠉ ",
|
||||
" ⡀ ",
|
||||
" ⣴⠏⠁ ⣀⡤⢤⣀⣀ ⢀⣀⣤⣀⣀⡴⣄⡤⢤⣀⠤⠤⠴⣄⣀⡀ ",
|
||||
" ⣀⣀ ⣠⣿⡍⣆ ⣠⣤⣤⠤⠴⠶⠖⠲⠤⠔⠛⠒⠉ ⠈⠨⣇⠖⠋ ⠈⠉⠓⠢⠤⢄ ",
|
||||
" ⡀ ⣠⠤⠴⠒⠚⠛⠛⠒⠢⠤⠿⠙⠉⠉⠑⢋⣚⣉⠥⠚ ⢀⣀⡠⠟⠁ ⡴⠋ ",
|
||||
" ⠐⠶⣛⣫⡤ ⠐⢏⣀⣤⣤ ⣴⣋⢇⢀⣮⡥ ⣴⠓ ",
|
||||
"⠤⠤⠤⠤⡀⣈⢣⣠⡄ ⠉⠊⠉⠉⠉ ⠈⠓⠆⠤⠤",
|
||||
" ",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
|
|
|
@ -149,42 +149,43 @@ mod tests {
|
|||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10));
|
||||
let canvas = Canvas::default()
|
||||
.marker(Marker::Braille)
|
||||
.x_bounds([0.0, 10.0])
|
||||
.y_bounds([0.0, 10.0])
|
||||
.x_bounds([0.0, 20.0])
|
||||
.y_bounds([0.0, 20.0])
|
||||
.paint(|context| {
|
||||
// a rectangle that will draw the outside part of the braille
|
||||
context.draw(&Rectangle {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
width: 10.0,
|
||||
height: 10.0,
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
color: Color::Red,
|
||||
});
|
||||
// a rectangle that will draw the inside part of the braille
|
||||
context.draw(&Rectangle {
|
||||
x: 2.0,
|
||||
y: 1.75,
|
||||
width: 6.5,
|
||||
height: 6.5,
|
||||
x: 4.0,
|
||||
y: 4.0,
|
||||
width: 12.0,
|
||||
height: 12.0,
|
||||
color: Color::Green,
|
||||
});
|
||||
});
|
||||
canvas.render(buffer.area, &mut buffer);
|
||||
let mut expected = Buffer::with_lines([
|
||||
"⡏⠉⠉⠉⠉⠉⠉⠉⠉⢹",
|
||||
"⡇⢠⠤⠤⠤⠤⠤⠤⡄⢸",
|
||||
"⡇⢸ ⡇⢸",
|
||||
"⡇⢸ ⡇⢸",
|
||||
"⡇⢸ ⡇⢸",
|
||||
"⡇⢸ ⡇⢸",
|
||||
"⡇⢸ ⡇⢸",
|
||||
"⡇⢸ ⡇⢸",
|
||||
"⡇⠈⠉⠉⠉⠉⠉⠉⠁⢸",
|
||||
"⡇ ⢸",
|
||||
"⡇ ⡏⠉⠉⠉⠉⢹ ⢸",
|
||||
"⡇ ⡇ ⢸ ⢸",
|
||||
"⡇ ⡇ ⢸ ⢸",
|
||||
"⡇ ⡇ ⢸ ⢸",
|
||||
"⡇ ⡇ ⢸ ⢸",
|
||||
"⡇ ⣇⣀⣀⣀⣀⣸ ⢸",
|
||||
"⡇ ⢸",
|
||||
"⣇⣀⣀⣀⣀⣀⣀⣀⣀⣸",
|
||||
]);
|
||||
expected.set_style(buffer.area, Style::new().red());
|
||||
expected.set_style(buffer.area.inner(Margin::new(1, 1)), Style::new().green());
|
||||
expected.set_style(buffer.area.inner(Margin::new(2, 2)), Style::reset());
|
||||
expected.set_style(buffer.area.inner(Margin::new(1, 1)), Style::reset());
|
||||
expected.set_style(buffer.area.inner(Margin::new(2, 2)), Style::new().green());
|
||||
expected.set_style(buffer.area.inner(Margin::new(3, 3)), Style::reset());
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -365,258 +365,6 @@ fn widgets_chart_can_have_empty_datasets() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
#[test]
|
||||
fn widgets_chart_can_have_a_legend() {
|
||||
let backend = TestBackend::new(60, 30);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
terminal
|
||||
.draw(|f| {
|
||||
let datasets = vec![
|
||||
Dataset::default()
|
||||
.name("Dataset 1")
|
||||
.style(Style::default().fg(Color::Blue))
|
||||
.data(&[
|
||||
(0.0, 0.0),
|
||||
(10.0, 1.0),
|
||||
(20.0, 2.0),
|
||||
(30.0, 3.0),
|
||||
(40.0, 4.0),
|
||||
(50.0, 5.0),
|
||||
(60.0, 6.0),
|
||||
(70.0, 7.0),
|
||||
(80.0, 8.0),
|
||||
(90.0, 9.0),
|
||||
(100.0, 10.0),
|
||||
])
|
||||
.graph_type(Line),
|
||||
Dataset::default()
|
||||
.name("Dataset 2")
|
||||
.style(Style::default().fg(Color::Green))
|
||||
.data(&[
|
||||
(0.0, 10.0),
|
||||
(10.0, 9.0),
|
||||
(20.0, 8.0),
|
||||
(30.0, 7.0),
|
||||
(40.0, 6.0),
|
||||
(50.0, 5.0),
|
||||
(60.0, 4.0),
|
||||
(70.0, 3.0),
|
||||
(80.0, 2.0),
|
||||
(90.0, 1.0),
|
||||
(100.0, 0.0),
|
||||
])
|
||||
.graph_type(Line),
|
||||
];
|
||||
let chart = Chart::new(datasets)
|
||||
.style(Style::default().bg(Color::White))
|
||||
.block(Block::bordered().title("Chart Test"))
|
||||
.x_axis(
|
||||
Axis::default()
|
||||
.bounds([0.0, 100.0])
|
||||
.title(Span::styled("X Axis", Style::default().fg(Color::Yellow)))
|
||||
.labels(create_labels(&["0.0", "50.0", "100.0"])),
|
||||
)
|
||||
.y_axis(
|
||||
Axis::default()
|
||||
.bounds([0.0, 10.0])
|
||||
.title("Y Axis")
|
||||
.labels(create_labels(&["0.0", "5.0", "10.0"])),
|
||||
);
|
||||
f.render_widget(
|
||||
chart,
|
||||
Rect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 60,
|
||||
height: 30,
|
||||
},
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
let mut expected = Buffer::with_lines([
|
||||
"┌Chart Test────────────────────────────────────────────────┐",
|
||||
"│10.0│Y Axis ┌─────────┐│",
|
||||
"│ │ •• │Dataset 1││",
|
||||
"│ │ •• │Dataset 2││",
|
||||
"│ │ •• └─────────┘│",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ ••• •• │",
|
||||
"│ │ ••• │",
|
||||
"│5.0 │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ ••• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• ••• │",
|
||||
"│ │ •• •• │",
|
||||
"│ │ •• •• │",
|
||||
"│0.0 │• X Axis│",
|
||||
"│ └─────────────────────────────────────────────────────│",
|
||||
"│ 0.0 50.0 100.0│",
|
||||
"└──────────────────────────────────────────────────────────┘",
|
||||
]);
|
||||
|
||||
// Set expected background color
|
||||
for row in 0..30 {
|
||||
for col in 0..60 {
|
||||
expected[(col, row)].set_bg(Color::White);
|
||||
}
|
||||
}
|
||||
|
||||
// Set expected colors of the first dataset
|
||||
let line1 = vec![
|
||||
(48, 5),
|
||||
(49, 5),
|
||||
(46, 6),
|
||||
(47, 6),
|
||||
(44, 7),
|
||||
(45, 7),
|
||||
(42, 8),
|
||||
(43, 8),
|
||||
(40, 9),
|
||||
(41, 9),
|
||||
(38, 10),
|
||||
(39, 10),
|
||||
(36, 11),
|
||||
(37, 11),
|
||||
(34, 12),
|
||||
(35, 12),
|
||||
(33, 13),
|
||||
(30, 14),
|
||||
(31, 14),
|
||||
(28, 15),
|
||||
(29, 15),
|
||||
(25, 16),
|
||||
(26, 16),
|
||||
(27, 16),
|
||||
(23, 17),
|
||||
(24, 17),
|
||||
(21, 18),
|
||||
(22, 18),
|
||||
(19, 19),
|
||||
(20, 19),
|
||||
(17, 20),
|
||||
(18, 20),
|
||||
(15, 21),
|
||||
(16, 21),
|
||||
(13, 22),
|
||||
(14, 22),
|
||||
(11, 23),
|
||||
(12, 23),
|
||||
(9, 24),
|
||||
(10, 24),
|
||||
(7, 25),
|
||||
(8, 25),
|
||||
(6, 26),
|
||||
];
|
||||
let legend1 = vec![
|
||||
(49, 2),
|
||||
(50, 2),
|
||||
(51, 2),
|
||||
(52, 2),
|
||||
(53, 2),
|
||||
(54, 2),
|
||||
(55, 2),
|
||||
(56, 2),
|
||||
(57, 2),
|
||||
];
|
||||
for (col, row) in line1 {
|
||||
expected[(col, row)].set_fg(Color::Blue);
|
||||
}
|
||||
for (col, row) in legend1 {
|
||||
expected[(col, row)].set_fg(Color::Blue);
|
||||
}
|
||||
|
||||
// Set expected colors of the second dataset
|
||||
let line2 = vec![
|
||||
(8, 2),
|
||||
(9, 2),
|
||||
(10, 3),
|
||||
(11, 3),
|
||||
(12, 4),
|
||||
(13, 4),
|
||||
(14, 5),
|
||||
(15, 5),
|
||||
(16, 6),
|
||||
(17, 6),
|
||||
(18, 7),
|
||||
(19, 7),
|
||||
(20, 8),
|
||||
(21, 8),
|
||||
(22, 9),
|
||||
(23, 9),
|
||||
(24, 10),
|
||||
(25, 10),
|
||||
(26, 11),
|
||||
(27, 11),
|
||||
(28, 12),
|
||||
(29, 12),
|
||||
(30, 12),
|
||||
(31, 13),
|
||||
(32, 13),
|
||||
(33, 14),
|
||||
(34, 14),
|
||||
(35, 15),
|
||||
(36, 15),
|
||||
(37, 16),
|
||||
(38, 16),
|
||||
(39, 17),
|
||||
(40, 17),
|
||||
(41, 18),
|
||||
(42, 18),
|
||||
(43, 19),
|
||||
(44, 19),
|
||||
(45, 20),
|
||||
(46, 20),
|
||||
(47, 21),
|
||||
(48, 21),
|
||||
(49, 22),
|
||||
(50, 22),
|
||||
(51, 23),
|
||||
(52, 23),
|
||||
(53, 23),
|
||||
(54, 24),
|
||||
(55, 24),
|
||||
(56, 25),
|
||||
(57, 25),
|
||||
];
|
||||
let legend2 = vec![
|
||||
(49, 3),
|
||||
(50, 3),
|
||||
(51, 3),
|
||||
(52, 3),
|
||||
(53, 3),
|
||||
(54, 3),
|
||||
(55, 3),
|
||||
(56, 3),
|
||||
(57, 3),
|
||||
];
|
||||
for (col, row) in line2 {
|
||||
expected[(col, row)].set_fg(Color::Green);
|
||||
}
|
||||
for (col, row) in legend2 {
|
||||
expected[(col, row)].set_fg(Color::Green);
|
||||
}
|
||||
|
||||
// Set expected colors of the x axis
|
||||
let x_axis_title = vec![(53, 26), (54, 26), (55, 26), (56, 26), (57, 26), (58, 26)];
|
||||
for (col, row) in x_axis_title {
|
||||
expected[(col, row)].set_fg(Color::Yellow);
|
||||
}
|
||||
terminal.backend().assert_buffer(&expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn widgets_chart_top_line_styling_is_correct() {
|
||||
let backend = TestBackend::new(9, 5);
|
||||
|
|
Loading…
Reference in a new issue