This is a combination of quite a few numerous generous open-source contributions. Thanks especially to Mike Bostock, Noah Veltman, Bob Rudis, and Andy Teucher.
library(d3r)
library(albersusa)
library(sf)
library(geojsonio)
library(rmapshaper)
library(htmltools)
tl <- tagList(
tags$head(tags$script(src="https://unpkg.com/flubber")),
tag("svg",list(id="map",style="height:400px; width:900px;")),
tags$script(HTML(
sprintf(
"
var us_geo = %s;
var us_hex = %s;
var projection = d3.geoAlbersUsa();
projection.fitSize([450,400], us_geo);
var path = d3.geoPath().projection(projection);
var path_hex = d3.geoPath()
.projection(d3.geoMercator().fitSize([450,400], us_hex));
var svg = d3.select('#map');
var states = svg.append('g')
.attr('class','states')
.selectAll('path')
.data(us_geo.features)
.enter()
.append('path')
.attr('d', path)
.style('stroke', 'black')
.style('fill', 'none')
.style('pointer-events', 'all');
var hexstates = svg.append('g')
.attr('class', 'hex')
.style('transform', 'translate(450px,0)')
.selectAll('path')
.data(us_hex.features)
.enter()
.append('path')
.attr('d', path_hex)
.style('stroke', 'black')
.style('fill', 'none')
.style('pointer-events', 'all');
states.on('click', function(d) {
var path_strings = flubber.splitPathString(path(d));
var hex_path = hexstates.nodes()
.filter(function(hd) {
return d.properties.iso_3166_2 === d3.select(hd).datum().properties.iso3166_2
})[0]
.getAttribute('d');
if(path_strings.length == 1) {
var interpolator = flubber.interpolate(
d3.select(this).attr('d'),
hex_path
);
} else {
var interpolator = flubber.combine(
path_strings,
hex_path,
{single: true}
);
}
var cloned = d3.select(
d3.select('g.states')
.node()
.appendChild(this.cloneNode(true))
);
cloned
.transition()
.duration(2000)
.attr('transform', 'translate(450,0)')
.style('stroke', 'red')
.style('stroke-width', '3px')
.attrTween('d', function(){ return interpolator; })
.transition()
.style('opacity',0.001)
.remove();
})
hexstates.on('click', function(d) {
var state_path = states.nodes()
.filter(function(hd) {
return d.properties.iso3166_2 === d3.select(hd).datum().properties.iso_3166_2;
})[0]
.getAttribute('d');
var path_strings = flubber.splitPathString(state_path);
if(path_strings.length == 1) {
var interpolator = flubber.interpolate(
d3.select(this).attr('d'),
state_path
);
} else {
var interpolator = flubber.separate(
d3.select(this).attr('d'),
path_strings,
{single: true}
);
}
var cloned = d3.select(
d3.select('g.hex')
.node()
.appendChild(this.cloneNode(true))
);
cloned
.transition()
.duration(2000)
.attr('transform', 'translate(-450,0)')
.style('stroke', 'red')
.style('stroke-width', '3px')
.attrTween('d', function(){ return interpolator; })
.transition()
.style('opacity',0.001)
.remove();
})
",
ms_simplify(geojson_json(usa_sf()), keep=0.03),
paste0(readLines("us_states_hexgrid.geojson"), collapse = "\n")
)
)),
d3_dep_v4(offline=FALSE)
)
browsable(tl)
forked from timelyportfolio's block: flubberized US states to/from hex
https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js
https://unpkg.com/flubber