Skip to content

Horizontal legend #342

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

Closed

Conversation

theGreatWhiteShark
Copy link

Hey,

It would be really awesome to have a better control over the legend of the leaflet widget to enable people to make better customizations.

I hacked a little bit around and I got a version working fine for the shiny app I'm currently writing. But I'm fairly new to JavaScript programming so it probably won't be perfect.

In the R/legend.R::addLegend function I added a argument "orientation" passed to the widget as a option.

With this additional option I trigger if-statements in the inst/htmlwidgets/leaflet.js to render the legend in different ways.

Since the linear-gradient and svg element arn't nicely to tweak using CSS at all I'm also thinking of adding some additional arguments for changing the width and height of the legend.

…rolled by the option parameter 'orientation'. The switching between the two views is done by if statements
The was some very weird indentation going on and since it doesn't look like my pull request has any success why not indenting it uniformly
beforehand I was trying to center the ticks on the legend. But this was yielding wrong results since it is actually the pretty() function in R creating those asymmetric labels. Therefore I corrected the offset for the labels to correspond to the supplied values and made the labels center below the ticks
if the left-most or right-most tick is to near the end of the color bar some parts of the label will be cut. Since a decrease/increase in the 'values' values would not be enough (because of the range of the predefined palette) just a warning is raised to change the values in the calling code
singleBinHeight is renamed in singleBinLength and imported via options. Also tickOffset, totalHeight and the new totalWidth are imported this way. Therefore we now have the option of customizing the width and height of the legend
the user now has the options to specify the height and the width of the legend. Therefore totalHeight, the width of the color (in case of orientation horizontal totalWidth and height) are determined along the tickOffset in the R script and not the JS wrapper anymore. This will clear the path for a more power full control of the tick number according to the precision of the labels (quite important for the horizontal direction since overlaps occured)
I want to easily play with the number of ticks in the legend's label to have full control over the width of the labels. This is essential for the horizonal orientation since overlaps must be prevented
I introduced a heuristic trying to estimate the width of the labels generated for the horizontal direction. Using this and the totalWidth of the color-bar I incremental decrease the number of bins as soon as overlaps occure.
@theGreatWhiteShark
Copy link
Author

I tweaked the code a bit. Now the ticks and labels are in place regardless of the display size (at least the 4 ones I checked).

Also the height and the width of the legend can now be controlled via the shiny app. (Which is really handy for customizing the view)

In addition there is no overlap of the labels in the horizontal orientation anymore. The (R) code will take the desired number of bins, calculates the width of all labels (via a heuristic) and incrementally decreases the bin number until the labels fit below the color-bar without overlap.

I'm not quite sure if I can add some additional commits to an existing pull request but since no one viewed this one in a month I also don't want to start a second one.

@bhaskarvk
Copy link
Collaborator

bhaskarvk commented Jan 25, 2017

@theGreatWhiteShark I really like this PR, but you've directly changed inst/htmlwidgets/leaflet.js which is not the way to go about it.
inst/htmlwidgets/leaflet.js is now auto generated and should not be directly edited. You need to change src/javascript/methods.js and then run grunt build from the project root.

If you've never set up the grunt part before take a look at this slide
https://bhaskarvk.github.io/leaflet-talk-rstudioconf-2017/RstudioConf2017.html#35. You will need node.js and npm.

@theGreatWhiteShark
Copy link
Author

Ah, and all of it even is described in the README. Sorry about that. I was just following this guide http://www.htmlwidgets.org/develop_intro.html :)

I will set up the same stuff using grunt.

Using the orientation parameter users can decide insight R whether to plot leaflet's legend in horizontal or vertical direction. In addition the user is now able control the legend width and height. Since the ticks are stored in a svg object this make customization now much more easy/possible.
it was my first time using eslint and browerify and it was quite a struggle
@theGreatWhiteShark
Copy link
Author

Alright, I applied all changes to javascript/src/method.js

@bhaskarvk
Copy link
Collaborator

May be you forgot to push your changes, I don't see them on this PR.

@theGreatWhiteShark
Copy link
Author

Sorry. I was pushing to master the whole time. But now everything is in place.

I added some heuristics for the width and height of the legend in case the palette is not supplied. Also fix two bug since tick.offset.beginning was not definied in type =='bins', 'factor' and 'quantile'
@tiernanmartin
Copy link

What's the ETA on merging this PR? I'd love to play around with the legend orientation.

@bhaskarvk
Copy link
Collaborator

@jcheng5 one more PR to consider before new CRAN release.

@schloerke schloerke mentioned this pull request Feb 12, 2018
29 tasks
@schloerke
Copy link
Contributor

Hi @theGreatWhiteShark

Could you ...

"
2. Ensure that you have signed the individual or corporate contributor agreement as appropriate. You can send the signed copy to jj@rstudio.com.
"
Excerpt from rstudio/httpuv package, which you had no reason to know existed.

Please let me know when you've sent the email. Thank you for your help!

Best,
Barret

@theGreatWhiteShark
Copy link
Author

Alright. I just sent the mail

@schloerke
Copy link
Contributor

I've merged your commits and the next release branch into branch... https://github.com/schloerke/leaflet/tree/horizontal_legend

Changes:

  • lints
  • changed to larger character width (my computer displayed 7.78 px vs 4 px)
  • attempted to detect the maximum label size.
  • altered how the legend label text was positions as it was not directly underneath the tick mark

Still broken:

  • reasonably large text labels (like "10,000") are only producing a single bin when there should be at least two
  • bins are not being respected when calculated within generate_legend(bins)

Cases that need testing (even if it is testthat::expect_silent({....}) )

  • With pal or with colors and labels
  • With data of each type of pal (numeric, quantile, ...)
  • With numeric data that spans many magnitudes (so labels are of very different size)

@theGreatWhiteShark
Copy link
Author

Thanks. It's been a while since I looked into leaflet- and shiny-based stuff. But as soon as I am done with some other projects I'm currently working on, I'll try to help making my first lines of JavaScript code failsafe and usable.

@CLAassistant
Copy link

CLAassistant commented Oct 2, 2019

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@laurenmarietta
Copy link

Just found this PR as I was looking for a way to make my legend horizontal. Curious to get an update on what prevented @theGreatWhiteShark's code from being merged in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants