简体   繁体   中英

How do I highlight the marker on the map when click on matching carousel corresponding to the marker to the map?

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 class="hoverinfo">' + 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 class="city__locations-slide">
        <div class="city__locations-slide-inner">
          <p class="">${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" class="city__locations-prev-button"/>',
    nextArrow: '<button type="button" class="city__locations-next-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 class="row">
    <div class="columns small-24">
      <div id="map-location" class="push--40 city__locations"></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!

if you can add some data attributes to the

return '<div data-unique-identifier class="hoverinfo">' + 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 class="' + new Date(data.someDate) === new Date('Jul 12 2011') ? highlight : hoverinfo + '">' + data.name + '</div>';

It's hard to help without a minimal reproducible example

I hope this helps

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 class="hoverinfo">' + 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" class="city__locations-prev-button"/>', nextArrow: '<button type="button" class="city__locations-next-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/slick@1.8.1/slick/slick.css" /> <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/kenwheeler/slick@1.8.1/slick/slick-theme.css" /> </head> <body> <div class="container"> <div class="row"> <div class="columns small-24"> <div id="map" class="" style="position: relative; height: 100%; width: 100%; background-color: rgb(255, 255, 255, 1);"></div> <div id="map-location" class="push--40 city__locations"> <div class="city__locations-slide"> <div class="city__locations__locations-slide-inner"> <p>Madison, WI</p> </div> </div> <div class="city__locations-slide"> <div class="city__locations__locations-slide-inner"> <p>Columbus, OH</p> </div> </div> <div class="city__locations-slide"> <div class="city__locations__locations-slide-inner"> <p>Gainesville, FL</p> </div> </div> <div class="city__locations-slide"> <div class="city__locations__locations-slide-inner"> <p>Chestnut Hill, MA</p> </div> </div> </div> </div> </div> </div> <div id="glow" class="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/slick@1.8.1/slick/slick.min.js"></script> </body> </html>

https://jsfiddle.net/PatrickHume/e1m7quj6/90/

I hope this helps ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM