Say the first carousel slide is Los Angeles California and when click on it, the red dot marker on the map will change its color to like blue on Los Angeles, CA coordinate. When click on the 2nd slide the 1st highlighted marker will back to default red and the new marker will be highlighted to blue.
I am not sure how to go about connecting these two using Vanilla JS. If logic connects, I can easily change the red dot color using CSS.
I am using DataMaps to render the USA map with coordinates of certain cities from a JSON file and slick-carousel for the bottom carousel.
JSON
[
{
"city": "Madison",
"state": "WI",
"latitude": 43.07199845990384,
"longitude": -89.40813691528471
},
{
"city": "Columbus",
"state": "OH",
"latitude": 40.00178899021552,
"longitude": -83.01964928313465
}
]
Here I fetch the json file, initialization of DataMaps and logic for populate json objects into carousel HTMLs.
// Get JSON data
fetch('assets/json/cities.json')
.then(function (response) {
return response.json();
})
.then(function (data) {
appendData(data);
})
.catch(function (err) {
console.log('error: ' err);
});
var map = new Datamap({
element: document.getElementById("map"),
responsive: true,
height: null,
width: null,
scope: 'usa',
geographyConfig: { // USA map color
popupOnHover: false,
highlightOnHover: false,
borderWidth: 1,
borderOpacity: 0.6,
borderColor: '#ffffff'
},
bubblesConfig: { // USA city popup color
borderWidth: 1,
borderOpacity: 1,
borderColor: '#c5002e',
popupOnHover: true,
radius: null,
fillOpacity: 1,
animate: true,
highlightOnHover: true,
highlightFillColor: '#c5002e', // hover dot color
highlightBorderColor: '#c5002e',
highlightBorderWidth: 1,
highlightBorderOpacity: 1,
highlightFillOpacity: 0.75,
exitDelay: 100,
key: JSON.stringify,
popupTemplate: function(geography, data) {
return '<div >' data.name '</div>';
},
},
fills: {
defaultFill: '#3a3a3a', // map color
city: '#c5002e' // dot color
}
});
// Responsive map
window.addEventListener('resize', function() {
map.resize();
});
// Loop to grab all json objects and render them in the page
function appendData(data) {
for (var i = 0; i < data.length; i ) {
var city = (data[i].city),
state = (data[i].state),
const locations = document.createElement("div");
// Add html
locations.innerHTML = `
<div >
<div >
<p >${city} ${state}</p>
</div>
</div>
`;
document.querySelector(".city__locations").append(locations)
}
Slick-carousel code
//initilize city locations slick carousel
$(document).ready(function() {
$(".city__locations").slick({
dots: true,
prevArrow: '<button type="button" />',
nextArrow: '<button type="button" />',
infinite: true,
slidesToShow: 4,
slidesToScroll: 1,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 1
}
},
{
breakpoint: 640,
settings: {
slidesToShow: 2,
slidesToScroll: 1
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
});
});
HTML
<div >
<div >
<div id="map-location" ></div>
</div>
</div>
Here is initial example in jsbin.
If this all work out, there is another date feature I would like to implement it. When the current date is bigger/equal to the date in the json date object, the red dot marker will also be highlighted it.
Any help is appreciated.
Thanks!
CodePudding user response:
if you can add some data attributes to the
return '<div data-unique-identifier >' data.name '</div>';
then with the carousel divs wire up a mouse over event and then you can use the data attributes to match the div to the corresponding icon. With the date you can again add a custom CSS class in the above line to create a highlight a bit like so:
return '<div data-unique-identifier >' data.name '</div>';
It's hard to help without a minimal reproducible example
I hope this helps
CodePudding user response:
Here is a glow effect, the glow is a bit much, CSS isn't my strong suit but should do what you wanted and you can tweak the CSS. I couldn't find a way to override the CSS on the map dots, so I used a div that is positioned in the create the glow effect
// Init USA map
var map = new Datamap({
element: document.getElementById("map"),
responsive: true,
height: null,
width: null,
scope: 'usa',
geographyConfig: { // USA map color
popupOnHover: false,
highlightOnHover: false,
borderWidth: 1,
borderOpacity: 0.6,
borderColor: '#ffffff'
},
bubblesConfig: { // USA city popup color
borderWidth: 1,
borderOpacity: 1,
borderColor: '#c5002e',
popupOnHover: true,
radius: null,
fillOpacity: 1,
animate: true,
highlightOnHover: true,
highlightFillColor: '#c5002e', // hover dot color
highlightBorderColor: '#c5002e',
highlightBorderWidth: 1,
highlightBorderOpacity: 1,
highlightFillOpacity: 0.75,
exitDelay: 100,
key: JSON.stringify,
popupTemplate: function(geography, data) {
return '<div >' data.name '</div>';
},
},
fills: {
defaultFill: '#3a3a3a', // map color
city: '#c5002e' // dot color
}
});
// Responsive map
window.addEventListener('resize', function() {
map.resize();
});
// City popup
map.bubbles([{
radius: 10,
fillKey: 'city',
name: 'Madison, WI',
cityId: "1",
latitude: 43.07199845990384,
longitude: -89.40813691528471
},
{
radius: 10,
fillKey: 'city',
name: 'Columbus, OH',
cityId: "2",
latitude: 40.00178899021552,
longitude: -83.01964928313465
},
{
radius: 10,
fillKey: 'city',
name: 'Gainesville, FL',
cityId: "3",
latitude: 29.645407365499,
longitude: -82.348610942268
},
{
radius: 10,
fillKey: 'city',
name: 'Chestnut Hill, MA',
cityId: "4",
latitude: 42.335294607839636,
longitude: -71.16643600759312
}
]);
//initilize city locations slick carousel
$(document).ready(function() {
$(".city__locations").slick({
dots: true,
prevArrow: '<button type="button" />',
nextArrow: '<button type="button" />',
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
responsive: [{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 1
}
},
{
breakpoint: 640,
settings: {
slidesToShow: 2,
slidesToScroll: 1
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
});
$(".city__locations-slide").each(function() {
$(this).mouseover(function() {
const location = $(this)
.children(".city__locations__locations-slide-inner")
.children("p").html()
const mapMatch = $(".datamaps-bubble").filter(function() {
return $(this).data("info").name === location
})
$(".glow").css({
top: mapMatch.position().top 'px',
left: mapMatch.position().left 'px',
}).show();
}).mouseout(function() {
$(".glow").hide();
})
})
});
.glow {
display: none;
position: absolute;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 0 60px 30px #fff, 0 0 100px 60px #f0f, 0 0 140px 90px #0ff;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<meta name="viewport" content="width=device-width">
<title>USA Map with carousel</title>
<style>
.city__locations-slide {
background-color: lightgrey;
padding: 10px;
margin: 10px;
}
.city__locations-prev-button {
position: absolute;
left: 0;
top: 30%;
width: 20px;
height: 20px;
z-index: 111;
}
.city__locations-next-button {
position: absolute;
right: 0;
top: 30%;
width: 20px;
height: 20px;
z-index: 111;
}
</style>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick.css" />
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick-theme.css" />
</head>
<body>
<div >
<div >
<div >
<div id="map" style="position: relative; height: 100%; width: 100%; background-color: rgb(255, 255, 255, 1);"></div>
<div id="map-location" >
<div >
<div >
<p>Madison, WI</p>
</div>
</div>
<div >
<div >
<p>Columbus, OH</p>
</div>
</div>
<div >
<div >
<p>Gainesville, FL</p>
</div>
</div>
<div >
<div >
<p>Chestnut Hill, MA</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="glow" >
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/datamaps/0.5.8/datamaps.usa.js"></script>
<script src="//code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="//cdn.jsdelivr.net/gh/kenwheeler/[email protected]/slick/slick.min.js"></script>
</body>
</html>
https://jsfiddle.net/PatrickHume/e1m7quj6/90/
I hope this helps ?