Skip to content

Commit 30e47b0

Browse files
committed
Fix: negative tick_mark_size now only affects tick direction
1 parent 0f195ea commit 30e47b0

File tree

1 file changed

+111
-70
lines changed

1 file changed

+111
-70
lines changed

plotters/src/chart/context/cartesian2d/draw_impl.rs

Lines changed: 111 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesia
153153

154154
/* Draw the axis and get the axis range so that we can do further label
155155
* and tick mark drawing */
156-
let axis_range = self.draw_axis(area, axis_style, orientation, tick_size < 0)?;
156+
// Always draw axis on the outer edge (pass false for inward_labels)
157+
let axis_range = self.draw_axis(area, axis_style, orientation, false)?;
157158

158159
/* To make the right label area looks nice, it's a little bit tricky, since for a that is
159160
* very long, we actually prefer left alignment instead of right alignment.
@@ -162,14 +163,14 @@ impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesia
162163
let label_width: Vec<_> = labels
163164
.iter()
164165
.map(|(_, text)| {
165-
if orientation.0 > 0 && orientation.1 == 0 && tick_size >= 0 {
166+
if orientation.0 > 0 && orientation.1 == 0 {
166167
self.drawing_area
167168
.estimate_text_size(text, label_style)
168169
.map(|(w, _)| w)
169170
.unwrap_or(0) as i32
170171
} else {
171-
// Don't ever do the layout estimationfor the drawing area that is either not
172-
// the right one or the tick mark is inward.
172+
// Don't ever do the layout estimation for the drawing area that is either not
173+
// the right one.
173174
0
174175
}
175176
})
@@ -194,51 +195,32 @@ impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesia
194195
continue;
195196
}
196197

197-
let (cx, cy, h_pos, v_pos) = if tick_size >= 0 {
198-
match orientation {
199-
// Right
200-
(dx, dy) if dx > 0 && dy == 0 => {
201-
if w >= right_align_width {
202-
(label_dist, *p - y0, HPos::Left, VPos::Center)
203-
} else {
204-
(
205-
label_dist + right_align_width,
206-
*p - y0,
207-
HPos::Right,
208-
VPos::Center,
209-
)
210-
}
211-
}
212-
// Left
213-
(dx, dy) if dx < 0 && dy == 0 => {
214-
(tw as i32 - label_dist, *p - y0, HPos::Right, VPos::Center)
215-
}
216-
// Bottom
217-
(dx, dy) if dx == 0 && dy > 0 => (*p - x0, label_dist, HPos::Center, VPos::Top),
218-
// Top
219-
(dx, dy) if dx == 0 && dy < 0 => {
220-
(*p - x0, th as i32 - label_dist, HPos::Center, VPos::Bottom)
221-
}
222-
_ => panic!("Bug: Invalid orientation specification"),
223-
}
224-
} else {
225-
match orientation {
226-
// Right
227-
(dx, dy) if dx > 0 && dy == 0 => {
228-
(tw as i32 - label_dist, *p - y0, HPos::Right, VPos::Center)
229-
}
230-
// Left
231-
(dx, dy) if dx < 0 && dy == 0 => {
198+
// Always position labels on the outside
199+
let (cx, cy, h_pos, v_pos) = match orientation {
200+
// Right
201+
(dx, dy) if dx > 0 && dy == 0 => {
202+
if w >= right_align_width {
232203
(label_dist, *p - y0, HPos::Left, VPos::Center)
204+
} else {
205+
(
206+
label_dist + right_align_width,
207+
*p - y0,
208+
HPos::Right,
209+
VPos::Center,
210+
)
233211
}
234-
// Bottom
235-
(dx, dy) if dx == 0 && dy > 0 => {
236-
(*p - x0, th as i32 - label_dist, HPos::Center, VPos::Bottom)
237-
}
238-
// Top
239-
(dx, dy) if dx == 0 && dy < 0 => (*p - x0, label_dist, HPos::Center, VPos::Top),
240-
_ => panic!("Bug: Invalid orientation specification"),
241212
}
213+
// Left
214+
(dx, dy) if dx < 0 && dy == 0 => {
215+
(tw as i32 - label_dist, *p - y0, HPos::Right, VPos::Center)
216+
}
217+
// Bottom
218+
(dx, dy) if dx == 0 && dy > 0 => (*p - x0, label_dist, HPos::Center, VPos::Top),
219+
// Top
220+
(dx, dy) if dx == 0 && dy < 0 => {
221+
(*p - x0, th as i32 - label_dist, HPos::Center, VPos::Bottom)
222+
}
223+
_ => panic!("Bug: Invalid orientation specification"),
242224
};
243225

244226
let (text_x, text_y) = if orientation.0 == 0 {
@@ -250,34 +232,22 @@ impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesia
250232
let label_style = &label_style.pos(Pos::new(h_pos, v_pos));
251233
area.draw_text(t, label_style, (text_x, text_y))?;
252234

253-
if tick_size != 0 {
235+
// Only draw outward tick marks here (tick_size > 0)
236+
// Inward tick marks are drawn separately in draw_mesh
237+
if tick_size > 0 {
254238
if let Some(style) = axis_style {
255239
let xmax = tw as i32 - 1;
256240
let ymax = th as i32 - 1;
257-
let (kx0, ky0, kx1, ky1) = if tick_size > 0 {
258-
match orientation {
259-
(dx, dy) if dx > 0 && dy == 0 => (0, *p - y0, tick_size, *p - y0),
260-
(dx, dy) if dx < 0 && dy == 0 => {
261-
(xmax - tick_size, *p - y0, xmax, *p - y0)
262-
}
263-
(dx, dy) if dx == 0 && dy > 0 => (*p - x0, 0, *p - x0, tick_size),
264-
(dx, dy) if dx == 0 && dy < 0 => {
265-
(*p - x0, ymax - tick_size, *p - x0, ymax)
266-
}
267-
_ => panic!("Bug: Invalid orientation specification"),
241+
let (kx0, ky0, kx1, ky1) = match orientation {
242+
(dx, dy) if dx > 0 && dy == 0 => (0, *p - y0, tick_size, *p - y0),
243+
(dx, dy) if dx < 0 && dy == 0 => {
244+
(xmax - tick_size, *p - y0, xmax, *p - y0)
268245
}
269-
} else {
270-
match orientation {
271-
(dx, dy) if dx > 0 && dy == 0 => {
272-
(xmax, *p - y0, xmax + tick_size, *p - y0)
273-
}
274-
(dx, dy) if dx < 0 && dy == 0 => (0, *p - y0, -tick_size, *p - y0),
275-
(dx, dy) if dx == 0 && dy > 0 => {
276-
(*p - x0, ymax, *p - x0, ymax + tick_size)
277-
}
278-
(dx, dy) if dx == 0 && dy < 0 => (*p - x0, 0, *p - x0, -tick_size),
279-
_ => panic!("Bug: Invalid orientation specification"),
246+
(dx, dy) if dx == 0 && dy > 0 => (*p - x0, 0, *p - x0, tick_size),
247+
(dx, dy) if dx == 0 && dy < 0 => {
248+
(*p - x0, ymax - tick_size, *p - x0, ymax)
280249
}
250+
_ => panic!("Bug: Invalid orientation specification"),
281251
};
282252
let line = PathElement::new(vec![(kx0, ky0), (kx1, ky1)], *style);
283253
area.draw(&line)?;
@@ -364,6 +334,77 @@ impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesia
364334
)?;
365335
}
366336

337+
// Draw inward tick marks on the plot area
338+
let plot_area = self.drawing_area.strip_coord_spec();
339+
let (x0, y0) = self.drawing_area.get_base_pixel();
340+
let (dw, dh) = self.drawing_area.dim_in_pixel();
341+
let dw = dw as i32;
342+
let dh = dh as i32;
343+
344+
if x_axis {
345+
// Top inward ticks (x_tick_size[0] is for top label area)
346+
if x_tick_size[0] < 0 {
347+
let abs_tick = x_tick_size[0].abs();
348+
for (px, _) in &x_labels {
349+
let x = *px - x0;
350+
if x >= 0 && x < dw {
351+
let line = PathElement::new(
352+
vec![(x, 0), (x, abs_tick)],
353+
*axis_style,
354+
);
355+
plot_area.draw(&line)?;
356+
}
357+
}
358+
}
359+
360+
// Bottom inward ticks (x_tick_size[1] is for bottom label area)
361+
if x_tick_size[1] < 0 {
362+
let abs_tick = x_tick_size[1].abs();
363+
for (px, _) in &x_labels {
364+
let x = *px - x0;
365+
if x >= 0 && x < dw {
366+
let line = PathElement::new(
367+
vec![(x, dh - 1 - abs_tick), (x, dh - 1)],
368+
*axis_style,
369+
);
370+
plot_area.draw(&line)?;
371+
}
372+
}
373+
}
374+
}
375+
376+
if y_axis {
377+
// Left inward ticks (y_tick_size[0] is for left label area)
378+
if y_tick_size[0] < 0 {
379+
let abs_tick = y_tick_size[0].abs();
380+
for (py, _) in &y_labels {
381+
let y = *py - y0;
382+
if y >= 0 && y < dh {
383+
let line = PathElement::new(
384+
vec![(0, y), (abs_tick, y)],
385+
*axis_style,
386+
);
387+
plot_area.draw(&line)?;
388+
}
389+
}
390+
}
391+
392+
// Right inward ticks (y_tick_size[1] is for right label area)
393+
if y_tick_size[1] < 0 {
394+
let abs_tick = y_tick_size[1].abs();
395+
for (py, _) in &y_labels {
396+
let y = *py - y0;
397+
if y >= 0 && y < dh {
398+
let line = PathElement::new(
399+
vec![(dw - 1 - abs_tick, y), (dw - 1, y)],
400+
*axis_style,
401+
);
402+
plot_area.draw(&line)?;
403+
}
404+
}
405+
}
406+
}
407+
367408
Ok(())
368409
}
369-
}
410+
}

0 commit comments

Comments
 (0)