ATFutures / geoplumber

Serve geographic data from R and consume with scalable front end.
https://atfutures.github.io/geoplumber/
59 stars 7 forks source link

gp_add_geojson argument: color or colorscheme #44

Closed Robinlovelace closed 5 years ago

Robinlovelace commented 5 years ago

E.g. to change the color of uni_poly in the @examples

layik commented 5 years ago

For now just simple color value to the GeoJSON component on LeafletJS side.

layik commented 5 years ago

One more gp_remove_lines function and we will be able to this with recent pushes.

Robinlovelace commented 5 years ago

Nice!

Robinlovelace commented 5 years ago

I'm just about to work on the additional data layers.

layik commented 5 years ago
gp_create(tolower(tempdir()))
cw <- setwd(tolower(tempdir()))
gp_is_wd_geoplumber()
gp_build()
gp_plumb()

image

To change the color:

# Welcome.js (main component) contains this line: <GeoJSONComponent fetchURL="http://localhost:8000/api/uol" /> is default
# remove it
gp_remove_lines("src/Welcome.js",
                pattern = '<GeoJSONComponent fetchURL="http://localhost:8000/api/uol" />')
# add new geojsoncomponent with different color
gp_add_geojson(endpoint = '/api/uol',
               color = "red")
gp_build()
gp_plumb()

image

From fresh or reproducible example:

gp_create(tolower(tempdir()))
cw <- setwd(tolower(tempdir()))
gp_is_wd_geoplumber()
# <GeoJSONComponent fetchURL="http://localhost:8000/api/uol" /> is default
gp_remove_lines("src/Welcome.js",
                pattern = '<GeoJSONComponent fetchURL="http://localhost:8000/api/uol" />')
# add bew json with different color
gp_add_geojson(endpoint = '/api/uol',
               color = "red")
gp_build()
gp_plumb()
Robinlovelace commented 5 years ago

Looking good. Any thoughts on colorschemes, e.g. based on https://github.com/d3/d3-scale-chromatic which seems to be in-line with the viridis package in R.

layik commented 5 years ago

In the pipeline.

layik commented 5 years ago

@Robinlovelace I have a feeling the later I include d3 the worse it might be.

Shall we, if @cmcaine or @mpadge or anyone else would like to contribute choose a "js vis package" at this stage so we can do things like coloschemes? Do we need a separate ticket? Any thoughts, thanks everyone.

layik commented 5 years ago

My view: I see quite a few npm packages out there wrapping around d3, but I feel lie we should just go for the source, d3. As you mentioned, start with that module.

cmcaine commented 5 years ago

Vega or Vega Lite are the only others I would consider.

On Fri, 12 Oct 2018, 10:04 Layik Hama, notifications@github.com wrote:

My view: I see quite a few npm packages out there, but we should just go for the source, d3 https://github.com/d3. As you mentioned, start with that module https://github.com/d3/d3-scale-chromatic.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ATFutures/geoplumber/issues/44#issuecomment-429257707, or mute the thread https://github.com/notifications/unsubscribe-auth/AFuQeaViMfbhu8WKkk4mGzbqq61c9_CKks5ukFsrgaJpZM4W8sJm .

layik commented 5 years ago

Thanks @cmcaine! Will have a good look.

layik commented 5 years ago

Sounds like two ways of achieving "proper" colorschemes:

  1. Do it in R using approaches used by other mapping packages including shiny's leaflet.
  2. Do it in JS (hence above d3 module)

Still not clear which approach I should be taking in geoplumber but working on it.

Robinlovelace commented 5 years ago

Thanks for the update. What are your views with your JS hat on @cmcaine ?

layik commented 5 years ago

Perhaps I should implement one and leave other for "future work".

What leaflet/R side only approach does, is eventually (2 "do it in JS") but always start with (1).

layik commented 5 years ago

Will see if I can take a simple "color*" grDevices function for a starter.

SymbolixAU commented 5 years ago

If it helps, colourvalues may be of use on the R side.

layik commented 5 years ago

Thanks @SymbolixAU, will check it out right away.

layik commented 5 years ago

Will try and finish this issue.

I do like

n <- 100
m <- grDevices::colorRamp(c("red", "green"))( (1:n)/n )
df <- data.frame(a = 10, x = 1:n)
df$col <- colourvalues::colour_values(df$x, palette = m)
# bar_plot( df ) not sure which package has this except 
# [this](https://www.rdocumentation.org/packages/TeachBayes/versions/0.1.0/topics/bar_plot) 
# which I did not try.

# but can see
> head(df)
   a x       col
1 10 1 #FC0300FF
2 10 2 #FA0500FF
3 10 3 #F70800FF
4 10 4 #F50A00FF
5 10 5 #F20D00FF
6 10 6 #F00F00FF

and we can pipe the result into leaflet/mapbox or even a d3 object etc.

layik commented 5 years ago

I bet one can even go "server = TRUE" and do this on the client if user does not like to send this over the network. But "that" is the evil "Knuth" is talking about.

SymbolixAU commented 5 years ago

@layik I define the bar_plot function here

layik commented 5 years ago

Here is how to sync endpoint colour pallet with front-end JS from above two commits I cannot use reprex:: because it would cause infinite loop. But this should be reproducible from a clean install/app

library(geoplumber)
setwd("~/code/geoplumber/my_app/")
if(!gp_is_wd_geoplumber())
  stop("Create a gp app first or change your dir to one.")
clip <- clipr::read_clip()
clipr <- clipr::write_clip("
rivers <- geojsonsf::geojson_sf(paste0('https://d2ad6b4ur7yvpq.cloudfront.net/',
                                       'naturalearth-3.3.0/',
                                       'ne_110m_rivers_lake_centerlines.geojson'))
names(rivers)
length(rivers)
head(rivers$name)
rivers <- rivers[, c('name', 'geometry')]
nrow(rivers)
n <- nrow(rivers)
m <- grDevices::colorRamp(c('red', 'green'))( (1:n)/n )
rivers$col <- colourvalues::colour_values(rivers$name, palette = m, include_alpha = F)
rivers$lwd <- seq(5, 8, 0.5)
names(rivers)
head(rivers[,c('name', 'col', 'lwd')])
#' now serve `rivers` object from /api/rivers
#' @get /api/rivers
get_rivers <- function(res) {
  geojson <- geojsonsf::sf_geojson(rivers, factors_as_string = FALSE)
  res$body <- geojson
  res
}")
# add backend
gp_endpoint_from_clip()
# add the front
gp_add_geojson(endpoint = "/api/rivers",
               color = "col", # matching above rivers$col
               line_weight = "lwd",
               properties = TRUE)

gp_build()
gp_plumb()
# ctrl + c
clipr::write_clip(clip)

Love the rivers!

image

layik commented 5 years ago

Above is the "API" way of doing things rather than mapdeck or mapview static front way of doing it (dumping pallets as JSON for Leaflet/Mapbox).

That might be something that could go into gp_sf along with #60. I think we can close this ticket.

layik commented 5 years ago

ping @Robinlovelace.

Robinlovelace commented 5 years ago

Really interesting stuff. Look forward to trying this and talking with you about this @layik.

layik commented 5 years ago

To be clear this is sending the colorcheme over the network.

One other parameter could say: do it on the client side for me. And we can use one of the d3 functions to do this on the client side. So ineffect, doing the amazing ‘color_values’ equivalent for a nominated value on the client side.

Robinlovelace commented 5 years ago

Yes to automatic colour valuing on the client side.

layik commented 5 years ago

Sure. There was always going to be some "helpers" to go into gp.

layik commented 5 years ago

Client side could be a fresh ticket.