JSVectormap Nextjs two maps are loading

42 Views Asked by At

Using JSVectorMap for a project https://jvm-docs.vercel.app/. It seems to be adding two maps in at different sizes.

enter image description here

enter image description here

This is the page where I am calling the data to add to the map.

Page.tsx

"use client";

import dynamic from "next/dynamic";
import { useState, useEffect, useRef } from "react";
import { userData } from "./api/json";

const WorldMap = dynamic(() => import("./components/worldMap"), {
  ssr: false,
});

export default function Page() {
  const [jsonData, setData] = useState<any[]>([]);
  const observedElementRef = useRef(null);

  async function fetchData() {
    const usersData = await userData();
    setData(usersData);
  }

  useEffect(() => {
    fetchData();
  }, []);

  return (
    <div>
      <h1 className="text-center font-bold py-8 text-2xl">JS Vector Map</h1>
      <div className="pt-[10vh]"></div>
      <div className="px-5" ref={observedElementRef}>
        {jsonData && <WorldMap userData={jsonData} />}
      </div>
      <div className="pt-[10vh]"></div>
    </div>
  );
}

I don't know if it's my code or if everyone sees two maps.

This is the WorldMap component Im using to pass the data in. The component will be used on multiple pages.

WorldMap.tsx

import React, { useEffect, useState } from "react";
// @ts-ignore
import jsVectorMap from "jsvectormap";
import "jsvectormap/dist/maps/world.js";
import "../../styles/worldMap.scss";
import { UserDataProps } from "../../../types/types";

export default function WorldMap({ userData }: any) {
  const [map, setMap] = useState<any>(null);

  const initMap = () => {
    const newMap = new jsVectorMap({
      selector: "#map",
      map: "world",
      zoomOnScroll: false,
      regionsSelectable: false,
      // Regions style
      regionStyle: {
        initial: {
          fill: "#808080",
          "fill-opacity": 1,
        },
      },
      // Marker style
      markerStyle: {
        initial: {
          stroke: "#5a6779",
          strokeWidth: 0,
          fillOpacity: 2,
        },
      },
      onMarkerClick: function (event: any, index: number) {
        // Get the URL from the data
        const url = userData[index].url;

        if (url) {
          // Redirect the user to the URL
          window.location.href = url;
        }
      },
    });

    setMap(newMap);
  };

  useEffect(() => {
    initMap();
  }, []);

  useEffect(() => {
    console.log("map", map);
    if (map) {
      console.log("map", map);
      const delayIncrement = 900;
      const transitionDelay = 2200;

      const showAndRemoveMarkers = (arrayIndex: number) => {
        const markerColor = getMarkerColor(arrayIndex);
        const itemArray = userData[arrayIndex];

        itemArray.forEach((item: UserDataProps, index: number) => {
          setTimeout(() => {
            map.addMarkers([
              {
                name: item.funder,
                coords: [item.lat, item.lng],
                style: {
                  fill: markerColor,
                },
              },
            ]);
          }, index * delayIncrement);

          setTimeout(() => {
            map.removeMarkers([index]);
          }, index * delayIncrement + transitionDelay);
        });

        setTimeout(() => {
          showAndRemoveMarkers((arrayIndex + 1) % userData.length); // Repeat with the next array
        }, itemArray.length * delayIncrement + transitionDelay - delayIncrement);
      };

      showAndRemoveMarkers(0); // Start with the first array
    }
  }, [map, userData]);

  // Define marker colors based on array index
  const getMarkerColor = (index: number): string => {
    const colors = ["blue", "green", "red", "pink"];
    return colors[index % colors.length];
  };

  return (
    <div className="map-container">
      <div id="map"></div>
    </div>
  );
}

What I want to see is one map.

0

There are 0 best solutions below