Reputation: 159
I have a Drilldown world map(continent map + country map) where the second map(the country map) is zoomed-in onload by using fitExtent
function. Since it is zoomed-in, I wanted to implement a draggable feature where I can drag the map and see other part of the map.
//My svg tag
<svg id="mapSVG" width="560"; height="350"></svg>
let zoomControl = function (event) {
svg.selectAll("path")
.attr("transform", event.transform);
}
function loadCountryMap(path, mapData) {
d3.json(path).then(function (json) {
var projection = d3.geoMercator();
var features = json.features;
//The reason why we have to do this is because d3.js has winding problem
//We need to rewind for the map to display correctly
var fixed = features.map(function (feature) {
return turf.rewind(feature, { reverse: true });
})
//Projections
var geoPath = d3.geoPath().projection(projection);
//Zoom in
projection.fitExtent([[mapData.XOffSet, mapData.YOffSet], [width*2, height*2]], { "type": "FeatureCollection", "features": fixed })
//Draggable
svg.selectAll("path")
.data(fixed)
.enter()
.append("path")
.attr("d", geoPath)
.attr("id", function (d) { return d.properties.FIPS_10_; })
.style("fill", "steelblue")
.style("stroke", "transparent")
.on("mouseover", mouseOver)
.on("mouseleave", mouseLeave)
.on("click", mouthClick)
.call(d3.zoom()
.on("zoom", zoomControl)
.scaleExtent([1, 1])
)
})
}
//How I select the svg
var svg = d3.select("svg")
.style("background-color", "white")
.style("border", "solid 1px black");
var width = +svg.attr("width");
var height = +svg.attr("height");
There are two problems with this:
1: By selecting the "svg" tag, this will drag the entire SVG HTML element, instead of the map content of SVG. I also changed it to "path" and "d", it didn't work either.
2: When the drag event first occurred, the dragged elements are being placed at the bottom right corner of the mouse cursor and follow the mouse cursor after that.
I want the zoomed-in map to be draggable to so I can see other part of the map.
The example desired behavior bin. This is the code from Andrew Reid's answer to a question. When the map is zoomed in, it became draggable. I don't see the drag behavior been defined anywhere in the code. I am assuming it is achieved by using d3.zoom()
. However, since my map are zoomed-in by default(onload), and I have a separate mouse click event, I don't think I can use the similar approach.
Upvotes: 1
Views: 618
Reputation: 159
var svg = d3.select("#mapDiv")
.append("svg")
.attr("width", width)
.attr("height", height)
.style("background-color", "white")
.style("border", "solid 1px black")
.call(d3.zoom()
.on("zoom", function (event) {
svg.attr("transform", event.transform)
})
.scaleExtent([1, 1])
)
.append("g");
I have achieved the functionality by grouping my path with .append("g")
. Instead of assigning the zoom functionality path by path, I simply assigned it to the entire SVG and now the map is working fine.
Upvotes: 1