Note: For production, use the blank-map-content.js
file instead of map-content.js (this file is for demo purpose). To
find the map ID, search by the state name in blank-map-content.js.
Drill-Down enables multi-level regional exploration. It highlights states and allows drilling into
counties/regions within each state. Each state can show a text label, tooltip, and custom
styling. Regions support tooltips, stroke, hover color, and optional click
actions. Configurations are handled via drill_down_map_config, and enhanced interactions
like zooming and fullscreen are defined in general_config
The Drill-Down Map Plugin enables hierarchical navigation in your SVG-based map, allowing users to zoom into subregions (e.g., states β counties) while keeping interactivity like tooltips, strokes, and text labels.
Navigate from a country to individual states, and from states to regions or counties.
Display additional info (tooltips, links, labels) per region level.
Highlight regions using color/stroke changes on hover.
Useful for dashboards, analytics, regional statistics, education platforms.
Ensure your project follows this structure:
your-project/ βββ gmh-plugin/ β βββ assets/ β β βββ css/ β β β βββ style.css β β βββ js/ β β β βββ script/ β β β β βββ geomaphub.js β β β β βββ lib/ β β β β β βββ drill-down-gmh.js β Required β β β β β βββ advanced-zoom-gmh.js β Required β β β β β βββ interactive-tooltip-gmh.js β Required for interactive (tooltips and links.) β βββ data/ β β βββ us/ β β β βββ map-content-drill-down.js β β β βββ us-drill-down.svg β index.html
πΉ drill_down_map_config
export const drill_down_map_config = [
{
/**
* @property {string} targetClass - Unique identifier for the main state.
*/
"targetClass": "US-WA",
/**
* @property {string} tooltip - Text displayed when hovering over this state.
*/
"tooltip": "Washington",
/**
* @property {Object} color - Fill color settings for the state.
* @property {string} color.default - Default fill color.
* @property {string} color.on_hover - Fill color on hover.
*/
"color": {
"default": "#f3faff",
"on_hover": "#005999"
},
/**
* @property {Object} stroke - Border (stroke) settings for the state.
* @property {string} stroke.color - Border color.
* @property {string} stroke.width - Border width.
*/
"stroke": {
"color": "#6B8B9E",
"width": "0.8px"
},
/**
* @property {Object} text_label - Configuration for the state's text label.
* @property {string} text_label.tooltip - Tooltip on label hover.
* @property {string} text_label.text - Label text (e.g., state abbreviation).
* @property {Object} text_label.position - X and Y coordinates for positioning.
* @property {string} text_label.position.x - X coordinate.
* @property {string} text_label.position.y - Y coordinate.
* @property {Object} text_label.font - Styling for label font.
* @property {string} text_label.font.size - Font size.
* @property {string} text_label.font.color - Font color.
* @property {string} text_label.font.hover_color - Color on hover.
*/
"text_label": {
"tooltip": "Washington",
"text": "WA",
"position": {
"x": "137",
"y": "62"
},
"font": {
"size": "8px",
"color": "black",
"hover_color": "white",
}
},
/**
* @property {Array<Object>} region - Nested counties or regions inside the state.
*/
"region": [
{
/**
* @property {string} targetClass - Unique identifier for the region.
*/
"targetClass": "WA-Adams",
/**
* @property {string} tooltip - Tooltip text for the region.
*/
"tooltip": "Adams",
/**
* @property {Object} color - Color settings for the region.
*/
"color": {
"default": "#f3faff",
"on_hover": "#005999"
},
/**
* @property {Object} stroke - Stroke settings for the region.
*/
"stroke": {
"color": "#6B8B9E",
"width": "0.8px"
},
/**
* @property {Object} on_click - Click behavior settings (Optional).
* @property {string} on_click.url - Redirect URL.
* @property {string} on_click.target - Target tab or window.
* @property {string} on_click.cursor - Cursor style on hover.
*/
"on_click": {
"url": "https://en.wikipedia.org/wiki/Washington",
"target": "_blank",
"cursor": "pointer"
},
},
{
/**
* @property {string} targetClass - Unique identifier for the region.
*/
"targetClass": "WA-Asotin",
/**
* @property {string} tooltip - Tooltip text for the region.
*/
"tooltip": "Asotin",
/**
* @property {Object} color - Color settings for the region.
*/
"color": {
"default": "#f3faff",
"on_hover": "#005999"
},
/**
* @property {Object} stroke - Stroke settings for the region.
*/
"stroke": {
"color": "#6B8B9E",
"width": "0.8px"
}
},
]
}
]
π§ drill_down_map_config Object
| Key | Description |
|---|---|
targetClass |
Unique identifier for the top-level region (e.g., "US-WA") |
tooltip |
Tooltip text shown on hover |
color.default |
Default fill color for the region |
color.on_hover |
Fill color when hovering over the region |
stroke.color |
Stroke/border color for the region |
stroke.width |
Stroke/border width |
text_label.tooltip |
Tooltip text shown on the region label |
text_label.text |
Abbreviation or label text (e.g., "WA") |
text_label.position.x |
X-coordinate for label placement |
text_label.position.y |
Y-coordinate for label placement |
text_label.font.size |
Font size of the label (e.g., "8px") |
text_label.font.color |
Default color of the label text |
text_label.font.hover_color |
Color on hover |
region[] |
Array of nested counties/regions under the top-level state |
π§© region[] Object (Nested Inside Each State)
| Key | Description |
|---|---|
targetClass |
Unique identifier for the sub-region (e.g., "WA-Adams") |
tooltip |
Tooltip text shown on hover |
color.default |
Default fill color for the region |
color.on_hover |
Fill color on hover |
stroke.color |
Border color for the region |
stroke.width |
Border width for the region |
on_click.url |
URL to open when region is clicked (optional) |
on_click.target |
HTML target behavior (_blank, _self, etc.) (optional) |
on_click.cursor |
Cursor style on hover (pointer, default, etc.) (optional) |
πΉ general_config
/**
* @constant {Object} general_config - Global configuration settings used throughout the map.
*/
export const general_config = {
/**
* @property {Object} id - DOM element IDs used for various parts of the map.
*/
"id": {
"map_abbr": "USA",
"svg_id": "US-DRILL-DOWN-MAP-GMH",
"marker_id": "US-MARKER-GMH",
"tooltip_id": "tooltip-gmh",
"custom_tooltip_id": "custom-tooltip-gmh",
},
/**
* @property {Object} advanced_zoom - Advanced zoom functionality buttons and container.
*/
"advanced_zoom": {
"control_id": {
"reset_zoom": "ADVANCED-ZOOM-RESET-GMH", /** Button ID for resetting zoom. */
"zoom_in": "ADVANCED-ZOOM-IN-GMH", /** Button ID for zooming in. */
"zoom_out": "ADVANCED-ZOOM-OUT-GMH", /** Button ID for zooming out. */
"toggle_fullscreen": "ADVANCED-ZOOM-TOGGLE-FULLSCREEN-GMH", /** Button ID for toggling fullscreen. */
"fullscreen_container_class": "svg-container-gmh" /** Class for the fullscreen container. */
},
},
/**
* @property {Object} text_label - Global text label settings.
*/
"text_label": {
"id": "US-DRILL-DOWN-TEXT-LABEL-GMH",
"prefix": "TEXT",
"font": {
"size": "12px",
"color": "black",
}
},
/**
* @property {Object} outer_stroke - Outer stroke styling.
*/
"outer_stroke": {
"id": "OUTER-STROKE",
"stroke": {
"color": "#6B8B9E",
"width": "0.8px"
},
},
/**
* @property {Object} state - Default style for US states.
*/
"state": {
"color": {
"default": "#f3faff",
"on_hover": "#005999",
},
"stroke": {
"color": "#6B8B9E",
"width": "0.8px"
},
},
/**
* @property {Object} region - Default style for inner regions (counties).
*/
"region": {
"color": {
"default": "#f3faff",
"on_hover": "#005999",
},
"stroke": {
"color": "#6B8B9E",
"width": "0.8px"
},
}
}
βοΈ general_config β advanced_zoom
| Key | Description |
|---|---|
control_id.reset_zoom |
ID of the zoom reset button |
control_id.zoom_in |
ID of the zoom-in button |
control_id.zoom_out |
ID of the zoom-out button |
control_id.toggle_fullscreen |
ID of the fullscreen toggle button |
control_id.fullscreen_container_class |
Class name of the container for fullscreen toggle |
π€ general_config β text_label
| Key | Description |
|---|---|
id |
ID for the text label container |
prefix |
Prefix string used for dynamically generated IDs |
font.size |
Default font size for all labels |
font.color |
Default font color for all labels |
π¨ general_config β state and region
| Key | Description |
|---|---|
color.default |
Default fill color |
color.on_hover |
Fill color on hover |
stroke.color |
Border color |
stroke.width |
Border width |
<!-- Drill-Down Map -->
<script type="module">
const currentCountry = "us";
async function initMap() {
try {
// Dynamically import map-specific data
const {drill_down_map_config, general_config} = await import(`/gmh-plugin/data/${currentCountry}/map-content-drill-down.js`);
const {GEOMapHub} = await import('/gmh-plugin/assets/js/script/geomaphub.js');
const {geoMapHubDrillDown} = await import('/gmh-plugin/assets/js/script/lib/drill-down-gmh.js');
const {geoMapHubAdvancedZoom} = await import('/gmh-plugin/assets/js/script/lib/advanced-zoom-gmh.js');
const {geoMapHubInteractiveTooltip} = await import('/gmh-plugin/assets/js/script/lib/interactive-tooltip-gmh.js');
const map = new GEOMapHub("#svg-wrapper-gmh", {
svgUrl: `/gmh-plugin/data/${currentCountry}/${currentCountry}-drill-down.svg`,
drillDownMapConfig: drill_down_map_config,
zoomOptions: {
zoomControls: true,
zoomToLocation: {
onClick: true,
animation: false,
},
handleDrag: true,
wheelZoom: true,
fingerPinch: true,
toggleFullScreen: true
},
generalConfig: general_config,
});
map.registerPlugin(geoMapHubDrillDown);
map.registerPlugin(geoMapHubAdvancedZoom);
map.registerPlugin(geoMapHubInteractiveTooltip);
map.init();
} catch (error) {
console.error("Error initializing map:", error);
}
}
initMap();
</script>
<!-- Drill-Down Map -->
Here's a working example to display the map
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GEO Map Hub – Drill-Down Map</title>
<link rel="stylesheet" href="/gmh-plugin/assets/css/style.css" />
</head>
<body>
<div id="tooltip-gmh"></div>
<div id="custom-tooltip-gmh"></div>
<div class="svg-container-gmh">
<div id="html-content-gmh" class="zoom-element">
<button class="home-gmh" id="ADVANCED-ZOOM-RESET-GMH">Reset</button>
<button class="plus-gmh" id="ADVANCED-ZOOM-IN-GMH">+</button>
<button class="minus-gmh" id="ADVANCED-ZOOM-OUT-GMH">-</button>
<button class="fullscreen-gmh" id="ADVANCED-ZOOM-TOGGLE-FULLSCREEN-GMH">Fullscreen</button>
</div>
<div id="svg-wrapper-gmh"></div>
</div>
<!-- Drill-Down Map -->
<script type="module">
const currentCountry = "us";
async function initMap() {
try {
// Dynamically import map-specific data
const {drill_down_map_config, general_config} = await import(`/gmh-plugin/data/${currentCountry}/map-content-drill-down.js`);
const {GEOMapHub} = await import('/gmh-plugin/assets/js/script/geomaphub.js');
const {geoMapHubDrillDown} = await import('/gmh-plugin/assets/js/script/lib/drill-down-gmh.js');
const {geoMapHubAdvancedZoom} = await import('/gmh-plugin/assets/js/script/lib/advanced-zoom-gmh.js');
const {geoMapHubInteractiveTooltip} = await import('/gmh-plugin/assets/js/script/lib/interactive-tooltip-gmh.js');
const map = new GEOMapHub("#svg-wrapper-gmh", {
svgUrl: `/gmh-plugin/data/${currentCountry}/${currentCountry}-drill-down.svg`,
drillDownMapConfig: drill_down_map_config,
zoomOptions: {
zoomControls: true,
zoomToLocation: {
onClick: true,
animation: false,
},
handleDrag: true,
wheelZoom: true,
fingerPinch: true,
toggleFullScreen: true
},
generalConfig: general_config,
});
map.registerPlugin(geoMapHubDrillDown);
map.registerPlugin(geoMapHubAdvancedZoom);
map.registerPlugin(geoMapHubInteractiveTooltip);
map.init();
} catch (error) {
console.error("Error initializing map:", error);
}
}
initMap();
</script>
<!-- Drill-Down Map -->
</body>
</html>
If you're testing with a .html file locally and see this error:
Access to script at 'file:///...' from origin 'null' has been blocked by CORS policy...
It means you're loading the file using the file:// protocol.
Option 1: Use a Local Server (Recommended for HTML)
Live Server (VS Code Extension)
Install Live Server, right-click your HTML, and choose βOpen with Live Serverβ.
Or use any other local server:
# Python 3 python -m http.server # Node.js npx http-server # PHP php -S localhost:8080
Or use a local web server (e.g., XAMPP or Laragon)
Option 2: Deploy to a Real Server
You can upload your files to:
Your cPanel or shared hosting
A staging VPS or domain
Once the files are accessible via http:// or https://, the plugin works without issues.
| Feature | Behavior |
|---|---|
| π§ State Click | Zooms into a selected state to show detailed regions. |
| π§± Regions | Each region supports custom color, tooltip, and optional click actions. |
| π― Advanced Zoom | Includes zoom in/out, reset, and fullscreen toggle. |
| π·οΈ Text Labels | Short text labels are positioned with defined styles and hover colors. |
| π§© Tooltip | Interactive tooltip appears on hover for states and regions. |
| π Clickable Regions | Regions can be linked with a URL that opens in a new tab. |
Some features may not work in the preview.
Click here to explore the complete website.GEO Map Hub uses cookies to ensure proper functionality and provide an enhanced user experience. By continuing, you consent to the use of all cookies. To learn more, read our Cookie Statement.