Installation
NPM
To install the @aranarium/maps library using npm, run the following command in your project directory:
npm install @arenarium/maps
Import the necessary module and CSS file into your project to begin using the map:
import { mountMap } from '@arenarium/maps';
import '@arenarium/maps/dist/style.css';

// Initialize and mount the map (further configuration details follow)
const map = mountMap(...);
CDN
To include @aranarium/maps directly in your HTML via a Content Delivery Network (CDN), add these script and stylesheet tags to the <head> or <body> of your HTML document:
<script src="https://unpkg.com/@arenarium/maps@latest/dist/index.js"></script>
<link href="https://unpkg.com/@arenarium/maps@latest/dist/style.css" rel="stylesheet" />
Once included, you can access the library's functions through the global arenarium object to mount the map:
// Initialize and mount the map (further configuration details follow)
const map = arenarium.mountMap(...);
Usage
Initialization
To initialize the map, first add a container element to your HTML where the map will be rendered:
<div id="map"></div>
Next, use the mountMap function with a MapOptions object.
const map = mountMap({
    // The ID of the HTML element that will contain the map
    container: 'map',
    // Initial map view settings
    position: {
        center: { lat: 51.505, lng: -0.09 },
        zoom: 13
    },
    // Map styling options
    style: {
        // Name of a predefined theme
        name: 'light',
        // Custom colors for popups and other UI elements
        colors: { primary: 'darkgreen', background: 'white', text: 'black' }
    },
    // Optional: Define restrictions for map panning and zooming
    restriction: {
        minZoom: 10,
        maxZoom: 15,
        maxBounds: {
            sw: { lat: 48.505, lng: -3.09 },
            ne: { lat: 54.505, lng: 3.09 }
        }
    },
});
Styles
You can dynamically change the map's visual appearance by setting a predefined theme:
map.setStyle({ name: 'dark', colors: { primary: 'purple', background: 'darkgray', text: 'black' } });
Alternatively, you can apply a custom map style by providing a URL to a JSON file that adheres to the MapLibre Style Specification. You can also override specific color properties within a custom style.
map.setStyle({
    name: 'custom',
    url: 'https://tiles.openfreemap.org/styles/liberty.json',
    colors: { primary: 'purple', background: 'white', text: 'black' }
});
Popups
To display interactive popups on the map, you first need to define an array of MapPopupData objects:
import { type MapPopupData } from '@arenarium/maps';

const popupData: MapPopupData[] = [];

for (let i = 0; i < count; i++) {
    popupData.push({
        // A unique identifier for the popup
        id: ...,
        // The ranking of the popup, used for visual prioritization
        rank: ..,
        // The latitude of the popup's location
        lat: ...,
        // The longitude of the popup's location
        lng: ...,
        // The desired height of the popup's content area
        height: ...,
        // The desired width of the popup's content area
        width: ...
    });
}
Next, retrieve the dynamic state information for these popups using the API. You will need your API key, which can be found on your API Keys page after signing in.
import { type MapPopupState, type MapPopupStatesRequest } from '@arenarium/maps';

const body: MapPopupStatesRequest = {
    // Your Arenarium API key
    key: 'YOUR_API_KEY',
    // The array of popup data
    data: popupData,
};

const response = await fetch('https://arenarium.dev/api/public/v1/popup/states', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body)
});

const popupStates: MapPopupState[] = await response.json();
Finally, combine the MapPopupData and MapPopupState arrays to create an array of MapPopup objects. For each popup, provide content rendering callbacks for the body and optionally for a custom pin. These callbacks should return a HTMLElement. Use the updatePopups method on the map instance to display or update the popups. This method efficiently adds new popups and updates existing ones based on their IDs. Popups not present in the provided array will remain on the map. This approach is designed for continuous updates of map popups.
import { type MapPopup } from '@arenarium/maps';

const popups: MapPopup[] = [];

for (let i = 0; i < count; i++) {
    popups.push({
        data: popupData[i],
        state: popupStates[i],
        callbacks: {
            // Callback function that returns the HTMLElement object for the popup body (required)
            body: async (id) => { ... }
            // Optional: Callback function that returns the HTMLElement object for a custom pin
            pin: async (id) => { ... }
        }
    });
}

await map.updatePopups(popups);
To remove all popups from the map, use the removePopups method:
await map.removePopups();
Events
You can subscribe to various map events to respond to user interactions and map state changes:
map.on('idle', (position) => { /* Called when the map has finished moving and zooming */ });
map.on('move', (position) => { /* Called while the map is moving */ });
map.on('click', (coordinate) => { /* Called when the map is clicked */ });
To unsubscribe from a specific event listener, use the off method, providing the event key and the handler function:
map.off('idle', handlerFunction);
Position
You can programmatically retrieve the current map position, boundaries, and zoom level:
const position = map.getPosition(); // Returns an object containing center coordinates and zoom
const bounds = map.getBounds();     // Returns the map's current bounding box
const zoom = map.getZoom();         // Returns the current zoom level
To programmatically set the map's center and zoom level:
map.setPosition({ center: { lat: 51.505, lng: -0.09 }, zoom: 13 });
You can also dynamically set restrictions on the map's zoom levels and visible bounds:
map.setMinZoom(10);
map.setMaxZoom(18);
map.setMaxBounds({
    sw: { lat: 51.505, lng: -0.09 },
    ne: { lat: 54.505, lng: 3.09 }
});
About
@arenarium/maps is a library designed for the efficient visualization of a large number of ranked points of interest on your maps. It excels in scenarios where you need to present numerous location-based markers with a clear visual hierarchy based on their importance or ranking. By leveraging optimized rendering techniques and a dedicated API for managing dynamic popup states, this library ensures a smooth and informative user experience.