All examples By author By category About

timelyportfolio

R mapedit playback with d3 + flubber


mapedit gets record functionality in 0.2.1, so I wanted to show it off by animating playback with d3.js and flubber.

Code in R

library(sf)
library(mapview)
library(mapedit)

#f <- editMap(leaflet() %>% addTiles())
f <- st_sf(
  st_as_sfc(
    "POLYGON((-135 -7.0137, -135 52.4828, -61.875 52.4828, -61.875 -7.0137, -135 -7.0137))"
  ),
  crs = 4326
)

ed <- editFeatures(f, record=TRUE, viewer=shiny::dialogViewer("edit"))
rec <- attr(ed, "recorder")


library(d3r)
library(htmltools)
library(geojsonio)

tl <- tagList(
  tags$head(tags$script(src="https://unpkg.com/flubber")),
  d3r::d3_dep_v4(offline = FALSE),
  tags$script(HTML(
sprintf(
"
var feat = %s;
var proj = d3.geoMercator().fitSize([800,400], feat[0]);
var path = d3.geoPath().projection(proj);

var svg = d3.select('body').append('svg')
  .style('height', 400)
  .style('width', 800)
  .classed('map', true);

var fpath = svg.append('g')
  .selectAll('path')
  .data([feat[0]])
    .enter()
    .append('path')
    .attr('d', path)
    .style('stroke', 'black')
    .style('fill', 'none')
    .style('pointer-events', 'all');

feat.slice(1).reduce(
  function(left,right,i) {
    var interpolator = flubber.interpolate(
      path(feat[i]),
      path(right)
    );
  
    return left
      .transition()
      .duration(2000)
      .attrTween('d', function(d) {return interpolator});
  },
  fpath
);
",
jsonlite::toJSON(
  Map(
    function(x){geojson_list(x$feature)},
    rec
  ),
  auto_unbox=TRUE,
  force=TRUE
)
)
  ))
)

browsable(tl)