-
-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Legend pt3] Make legend available to area at start #72
Conversation
With regards to the improvements you mentioned, it is good that you didn't make them here. Since all tests pass without modification, I know that this pull request does not introduce any bugs in existing code, so I don't need to worry about that. Once we finish this task, we can add the improvements by themselves and fix the tests. |
@@ -34,6 +34,8 @@ | |||
(define anchor/c (one-of/c 'top-left 'top 'top-right | |||
'left 'center 'right | |||
'bottom-left 'bottom 'bottom-right)) | |||
(define legend-anchor/c (or/c #f anchor/c | |||
(list/c (one-of/c 'inside 'outside) anchor/c))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure I understand your choice for defining the legend-anchor/c
contract and Legend-Anchor
type. I don't understand what the #f
value is for, and the list definition produces values which don't make sense to me. E.g. where would the legend be placed when the anchor is (outside center)
? Also, the inside
entries overlap with the plain one (e.g. (inside top)
is the same as top
?)
My thought was to make the legend anchor values a type completely independent from anchor/c
, some symbols are common, with some additional ones:
(define legend-anchor/c (one-of/c 'top-left 'top 'top-right
'left 'center 'right
'bottom-left 'bottom 'bottom-right
'outer-top-left 'outer-center-left 'outer-bottom-left
'outer-top-right 'outer-center-right 'outer-bottom-right
))
This would allow placing the legend to the left or right of the plot area. I am not sure that it is worth adding legends at the top and bottom of the plot, did you intend to add that feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#f
: This allows to not print the legend at all. Which makes it easy to implement the original question of legend outside the plot area (return legend as pict?) #49. You now can create a render tree. Pass it to a function that will extract the legend, and later pass this render tree to a plot function (with#f
as legend anchor) and only plot it without the legend.'(outside top/bottom)
: if the legend is only one item, the legend will be much wider than high. Being able to print it at the top or bottom will reduce the space lost for the actual plot. And it looks better in the top-center than the top-left. So yes this was an intended addition. Especially thinking about a future parameter that allows a horizontal layout for the legend.'(inside anchor/c)
is indeed equivalent withanchor/c
. When I started I was thinking it might make sense to instead of an anchor, pass coordinates to place it at an exact position. In the end I didn't go further with this.
In general: '(outside ...)
means it's drawn together with the title, before anything else, and (inside ...) means it's drawn after all other plot items, so indeed '(outside center)
makes less sense since it will result in a legend in the middle of the width/height of the plot, but below all other drawn items. Whereas '(inside center)
will result in a legend in the middle of the area-width/area-height of the plot, and above al other items.
Also: according to the documentation anchor/c should allow 'auto
, which it doesn't, and use 'bottom-left
for things that are not a text-label, whereas the legend implementation uses 'top-left
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'auto
is used for renders such as point-label
, to select an anchor which ensures that the entire label fits inside the plot area, the value does not make sense for the legend, and I forgot to add the documentation. There is also a confusion that the anchor/c
contract is not actually used for the point-label
and related functions, since they are exported directly from Typed-Racket with the Anchor type -- by the way I use this parameter a lot in my own programs.
the #f
case is indeed something I did not thing about, but you are correct that we need it if we want to render the legend as a separate pict. Until now, if the user did not want a legend, they could just not provide a #:label
entry for any of their renderers.
also, your explanation for 'inside
and 'outside
makes sense -- I didn't think about all the possible cases. Leave them as they are, and we see if they need changing.
BTW, I think we should add a todo list on #49 for all the small things that we find, to get to them later. I will add a note about the missing 'auto
documentation as well as the note about not beginning the plot when there are no renderers.
(send area end-plot)) | ||
|
||
(: get-legend-list (-> (Listof renderer2d) Rect (Listof legend-entry))) | ||
(define (get-legend-list renderer-list outer-rect) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think get-legend-entries
is a better name for this (and other similar functions in this pull request). get-legend-list
seems to indicate that the plot has more than one legend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will change it to get-legend-entry-list
, to make the distinction with the (Treeof legend-entry)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, the changes look good, my main question is about the choice for the legend anchor type...
(define-values (x-min x-max y-min y-max) | ||
(if (outside-anchor (plot-legend-anchor)) | ||
(values dc-x-min (+ dc-x-min dc-x-size) | ||
dc-y-min (+ dc-y-min dc-y-size)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand correctly that, if the legend is "outside" you anchor it on the corners of the entire drawing area?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR doesn't really finish implementing the 'outside functionality. For now it indeed just uses the outside bounds of the entire drawing area and places it relative to that. the last PR (#74) then made the actual space reservation and used better bounds as to not draw over the title. When I made this PR I was anticipating more work in that PR, and since we later split out #75 and #76, There are even less changes in 74...
This build on #70 and #71 in order to implement #49.
Although all test pass, a little improvement can be made (changing 3 test cases), see plot2d-utils#L73 and plot3d-utils#L83