svgmap 2.20.0 → 2.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +132 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +132 -176
- package/dist/index.js.map +1 -1
- package/dist/svg-map.umd.js +132 -176
- package/dist/svg-map.umd.js.map +1 -1
- package/dist/svg-map.umd.min.js +1 -1
- package/dist/svgMap.js +132 -176
- package/dist/svgMap.js.map +1 -1
- package/dist/svgMap.min.js +1 -1
- package/package.json +4 -4
- package/src/js/core/svg-map.js +132 -176
package/dist/index.cjs
CHANGED
|
@@ -3227,6 +3227,102 @@ class svgMap {
|
|
|
3227
3227
|
|
|
3228
3228
|
// Add map elements
|
|
3229
3229
|
var countryElements = [];
|
|
3230
|
+
|
|
3231
|
+
const clearActive = function clearActive() {
|
|
3232
|
+
this.mapImage
|
|
3233
|
+
.querySelectorAll('.svgMap-active')
|
|
3234
|
+
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3235
|
+
}.bind(this);
|
|
3236
|
+
|
|
3237
|
+
const isClickTooltip =
|
|
3238
|
+
this.options.showTooltips && this.options.tooltipTrigger === 'click';
|
|
3239
|
+
|
|
3240
|
+
const getCountryFromEvent = function (e) {
|
|
3241
|
+
return e.target && e.target.closest
|
|
3242
|
+
? e.target.closest('.svgMap-country')
|
|
3243
|
+
: null;
|
|
3244
|
+
};
|
|
3245
|
+
|
|
3246
|
+
const raiseCountry = function (countryElement, setActive) {
|
|
3247
|
+
if (setActive) {
|
|
3248
|
+
clearActive();
|
|
3249
|
+
}
|
|
3250
|
+
countryElement.parentNode.insertBefore(
|
|
3251
|
+
countryElement,
|
|
3252
|
+
this.persistentTooltipGroup || null
|
|
3253
|
+
);
|
|
3254
|
+
if (setActive) {
|
|
3255
|
+
countryElement.classList.add('svgMap-active');
|
|
3256
|
+
}
|
|
3257
|
+
}.bind(this);
|
|
3258
|
+
|
|
3259
|
+
const showCountryTooltip = function (countryElement, e, setActive) {
|
|
3260
|
+
raiseCountry(countryElement, setActive);
|
|
3261
|
+
this.setTooltipContent(this.getTooltipContent(countryElement.dataset.id));
|
|
3262
|
+
this.showTooltip(e);
|
|
3263
|
+
}.bind(this);
|
|
3264
|
+
|
|
3265
|
+
// Touch only: preview tooltip on finger down without marking country active
|
|
3266
|
+
// (active is set on pointerup so link countries keep two-tap navigation)
|
|
3267
|
+
this.mapImage.addEventListener(
|
|
3268
|
+
'pointerdown',
|
|
3269
|
+
(e) => {
|
|
3270
|
+
if (!this.options.showTooltips || e.pointerType !== 'touch') {
|
|
3271
|
+
return;
|
|
3272
|
+
}
|
|
3273
|
+
|
|
3274
|
+
const countryElement = getCountryFromEvent(e);
|
|
3275
|
+
if (!countryElement) {
|
|
3276
|
+
this.hideTooltip();
|
|
3277
|
+
return;
|
|
3278
|
+
}
|
|
3279
|
+
|
|
3280
|
+
showCountryTooltip(countryElement, e, false);
|
|
3281
|
+
this.moveTooltip(e);
|
|
3282
|
+
},
|
|
3283
|
+
{ passive: true }
|
|
3284
|
+
);
|
|
3285
|
+
|
|
3286
|
+
this.mapImage.addEventListener(
|
|
3287
|
+
'pointercancel',
|
|
3288
|
+
(e) => {
|
|
3289
|
+
if (e.pointerType === 'touch') {
|
|
3290
|
+
this.hideTooltip();
|
|
3291
|
+
}
|
|
3292
|
+
},
|
|
3293
|
+
{ passive: true }
|
|
3294
|
+
);
|
|
3295
|
+
|
|
3296
|
+
// Hover (mouse/pen) and touch drag: raise country + optional floating tooltip
|
|
3297
|
+
this.mapImage.addEventListener(
|
|
3298
|
+
'pointermove',
|
|
3299
|
+
(e) => {
|
|
3300
|
+
const countryElement = getCountryFromEvent(e);
|
|
3301
|
+
if (!countryElement) {
|
|
3302
|
+
clearActive();
|
|
3303
|
+
if (this.options.showTooltips) {
|
|
3304
|
+
this.hideTooltip();
|
|
3305
|
+
}
|
|
3306
|
+
return;
|
|
3307
|
+
}
|
|
3308
|
+
|
|
3309
|
+
const mouseClickMode = e.pointerType === 'mouse' && isClickTooltip;
|
|
3310
|
+
|
|
3311
|
+
// Always raise hovered country (SVG paint order + .svgMap-active stroke)
|
|
3312
|
+
if (!this.options.showTooltips || mouseClickMode) {
|
|
3313
|
+
raiseCountry(countryElement, true);
|
|
3314
|
+
return;
|
|
3315
|
+
}
|
|
3316
|
+
|
|
3317
|
+
showCountryTooltip(countryElement, e, true);
|
|
3318
|
+
|
|
3319
|
+
if (e.pointerType === 'touch') {
|
|
3320
|
+
this.moveTooltip(e);
|
|
3321
|
+
}
|
|
3322
|
+
},
|
|
3323
|
+
{ passive: true }
|
|
3324
|
+
);
|
|
3325
|
+
|
|
3230
3326
|
Object.keys(mapPaths).forEach(
|
|
3231
3327
|
function (countryID) {
|
|
3232
3328
|
var countryData = this.mapPaths[countryID];
|
|
@@ -3244,166 +3340,22 @@ class svgMap {
|
|
|
3244
3340
|
'id',
|
|
3245
3341
|
this.id + '-map-country-' + countryID
|
|
3246
3342
|
);
|
|
3247
|
-
countryElement.
|
|
3343
|
+
countryElement.dataset.id = countryID;
|
|
3248
3344
|
countryElement.classList.add('svgMap-country');
|
|
3249
3345
|
|
|
3250
3346
|
this.mapImage.appendChild(countryElement);
|
|
3251
3347
|
countryElements.push(countryElement);
|
|
3252
3348
|
|
|
3253
|
-
// Add tooltip when touch is used
|
|
3254
|
-
function handlePointerMove(e) {
|
|
3255
|
-
if (e.pointerType === 'touch') return;
|
|
3256
|
-
|
|
3257
|
-
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
3258
|
-
|
|
3259
|
-
if (
|
|
3260
|
-
!target ||
|
|
3261
|
-
(!target.closest('.svgMap-country') &&
|
|
3262
|
-
!target.closest('.svgMap-tooltip'))
|
|
3263
|
-
) {
|
|
3264
|
-
this.hideTooltip();
|
|
3265
|
-
document
|
|
3266
|
-
.querySelectorAll('.svgMap-active')
|
|
3267
|
-
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3268
|
-
}
|
|
3269
|
-
}
|
|
3270
|
-
|
|
3271
|
-
const handlePointerMoveBound = handlePointerMove.bind(this);
|
|
3272
|
-
|
|
3273
|
-
countryElement.addEventListener(
|
|
3274
|
-
'pointerenter',
|
|
3275
|
-
function (e) {
|
|
3276
|
-
if (
|
|
3277
|
-
e.pointerType === 'mouse' &&
|
|
3278
|
-
this.options.showTooltips &&
|
|
3279
|
-
this.options.tooltipTrigger === 'click'
|
|
3280
|
-
) {
|
|
3281
|
-
return;
|
|
3282
|
-
}
|
|
3283
|
-
|
|
3284
|
-
// Only add pointermove listener for non-touch pointers
|
|
3285
|
-
if (e.pointerType !== 'touch') {
|
|
3286
|
-
document.addEventListener('pointermove', handlePointerMoveBound, {
|
|
3287
|
-
passive: true
|
|
3288
|
-
});
|
|
3289
|
-
}
|
|
3290
|
-
|
|
3291
|
-
document
|
|
3292
|
-
.querySelectorAll('.svgMap-active')
|
|
3293
|
-
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3294
|
-
|
|
3295
|
-
countryElement.parentNode.insertBefore(
|
|
3296
|
-
countryElement,
|
|
3297
|
-
this.persistentTooltipGroup || null
|
|
3298
|
-
);
|
|
3299
|
-
countryElement.classList.add('svgMap-active');
|
|
3300
|
-
|
|
3301
|
-
const countryID = countryElement.getAttribute('data-id');
|
|
3302
|
-
if (this.options.showTooltips) {
|
|
3303
|
-
this.setTooltipContent(this.getTooltipContent(countryID));
|
|
3304
|
-
this.showTooltip(e);
|
|
3305
|
-
|
|
3306
|
-
// For touch, move tooltip to the touch position and keep it there
|
|
3307
|
-
if (e.pointerType === 'touch') {
|
|
3308
|
-
this.moveTooltip(e);
|
|
3309
|
-
}
|
|
3310
|
-
}
|
|
3311
|
-
}.bind(this)
|
|
3312
|
-
);
|
|
3313
|
-
|
|
3314
|
-
// Handle touch move - update tooltip position while panning
|
|
3315
|
-
countryElement.addEventListener(
|
|
3316
|
-
'touchmove',
|
|
3317
|
-
function (e) {
|
|
3318
|
-
this.moveTooltip(e);
|
|
3319
|
-
}.bind(this),
|
|
3320
|
-
{ passive: true }
|
|
3321
|
-
);
|
|
3322
|
-
|
|
3323
|
-
// Handle touch end - remove active state and hide tooltip
|
|
3324
|
-
countryElement.addEventListener(
|
|
3325
|
-
'touchend',
|
|
3326
|
-
function (e) {
|
|
3327
|
-
const touch = e.changedTouches[0];
|
|
3328
|
-
const elementAtEnd = document.elementFromPoint(
|
|
3329
|
-
touch.clientX,
|
|
3330
|
-
touch.clientY
|
|
3331
|
-
);
|
|
3332
|
-
|
|
3333
|
-
// Only hide if touch ended outside the country or tooltip
|
|
3334
|
-
if (
|
|
3335
|
-
!elementAtEnd ||
|
|
3336
|
-
(!elementAtEnd.closest('.svgMap-country') &&
|
|
3337
|
-
!elementAtEnd.closest('.svgMap-tooltip'))
|
|
3338
|
-
) {
|
|
3339
|
-
this.hideTooltip();
|
|
3340
|
-
document
|
|
3341
|
-
.querySelectorAll('.svgMap-active')
|
|
3342
|
-
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3343
|
-
}
|
|
3344
|
-
}.bind(this),
|
|
3345
|
-
{ passive: true }
|
|
3346
|
-
);
|
|
3347
|
-
|
|
3348
|
-
// Remove pointermove listener when leaving non-touch pointer
|
|
3349
|
-
countryElement.addEventListener(
|
|
3350
|
-
'pointerleave',
|
|
3351
|
-
function (e) {
|
|
3352
|
-
if (e.pointerType !== 'touch') {
|
|
3353
|
-
document.removeEventListener(
|
|
3354
|
-
'pointermove',
|
|
3355
|
-
handlePointerMoveBound
|
|
3356
|
-
);
|
|
3357
|
-
if (
|
|
3358
|
-
!(
|
|
3359
|
-
e.pointerType === 'mouse' &&
|
|
3360
|
-
this.options.showTooltips &&
|
|
3361
|
-
this.options.tooltipTrigger === 'click'
|
|
3362
|
-
)
|
|
3363
|
-
) {
|
|
3364
|
-
this.hideTooltip();
|
|
3365
|
-
document
|
|
3366
|
-
.querySelectorAll('.svgMap-active')
|
|
3367
|
-
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3368
|
-
}
|
|
3369
|
-
}
|
|
3370
|
-
}.bind(this)
|
|
3371
|
-
);
|
|
3372
|
-
|
|
3373
|
-
document.addEventListener(
|
|
3374
|
-
'pointerover',
|
|
3375
|
-
function (e) {
|
|
3376
|
-
if (e.pointerType !== 'touch') return;
|
|
3377
|
-
|
|
3378
|
-
if (
|
|
3379
|
-
e.target.closest('.svgMap-country') ||
|
|
3380
|
-
e.target.closest('.svgMap-tooltip')
|
|
3381
|
-
) {
|
|
3382
|
-
return;
|
|
3383
|
-
}
|
|
3384
|
-
|
|
3385
|
-
this.hideTooltip();
|
|
3386
|
-
document
|
|
3387
|
-
.querySelectorAll('.svgMap-active')
|
|
3388
|
-
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3389
|
-
}.bind(this),
|
|
3390
|
-
{ passive: true }
|
|
3391
|
-
);
|
|
3392
|
-
|
|
3393
3349
|
if (
|
|
3394
3350
|
this.options.data.values &&
|
|
3395
3351
|
this.options.data.values[countryID] &&
|
|
3396
3352
|
this.options.data.values[countryID]['link']
|
|
3397
3353
|
) {
|
|
3398
|
-
countryElement.
|
|
3399
|
-
'
|
|
3400
|
-
this.options.data.values[countryID]['link']
|
|
3401
|
-
);
|
|
3354
|
+
countryElement.dataset.link =
|
|
3355
|
+
this.options.data.values[countryID]['link'];
|
|
3402
3356
|
if (this.options.data.values[countryID]['linkTarget']) {
|
|
3403
|
-
countryElement.
|
|
3404
|
-
|
|
3405
|
-
this.options.data.values[countryID]['linkTarget']
|
|
3406
|
-
);
|
|
3357
|
+
countryElement.dataset.linkTarget =
|
|
3358
|
+
this.options.data.values[countryID]['linkTarget'];
|
|
3407
3359
|
}
|
|
3408
3360
|
}
|
|
3409
3361
|
}.bind(this)
|
|
@@ -3449,21 +3401,18 @@ class svgMap {
|
|
|
3449
3401
|
const countryElement = e.target.closest('.svgMap-country');
|
|
3450
3402
|
if (!countryElement) return;
|
|
3451
3403
|
|
|
3452
|
-
const countryID = countryElement.
|
|
3453
|
-
const link = countryElement.
|
|
3454
|
-
const linkTarget = countryElement.
|
|
3404
|
+
const countryID = countryElement.dataset.id;
|
|
3405
|
+
const link = countryElement.dataset.link;
|
|
3406
|
+
const linkTarget = countryElement.dataset.linkTarget;
|
|
3455
3407
|
const hasCallback = typeof this.options.onCountryClick === 'function';
|
|
3456
3408
|
const hasLink = !!link;
|
|
3457
3409
|
const isTouch = e.pointerType === 'touch' || e.pointerType === 'pen';
|
|
3458
3410
|
|
|
3459
|
-
const isClickTooltipMouse =
|
|
3460
|
-
e.pointerType === 'mouse' &&
|
|
3461
|
-
this.options.showTooltips &&
|
|
3462
|
-
this.options.tooltipTrigger === 'click';
|
|
3411
|
+
const isClickTooltipMouse = e.pointerType === 'mouse' && isClickTooltip;
|
|
3463
3412
|
|
|
3464
3413
|
if (!hasLink && !hasCallback && !isClickTooltipMouse) return;
|
|
3465
3414
|
|
|
3466
|
-
if (isClickTooltipMouse
|
|
3415
|
+
if (isClickTooltipMouse) {
|
|
3467
3416
|
const willNavigate =
|
|
3468
3417
|
hasLink && countryElement.classList.contains('svgMap-active');
|
|
3469
3418
|
const shouldFireCallback = hasCallback && (!hasLink || willNavigate);
|
|
@@ -3479,9 +3428,7 @@ class svgMap {
|
|
|
3479
3428
|
if (linkTarget) window.open(link, linkTarget);
|
|
3480
3429
|
else window.location.href = link;
|
|
3481
3430
|
} else {
|
|
3482
|
-
|
|
3483
|
-
.querySelectorAll('.svgMap-country.svgMap-active')
|
|
3484
|
-
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3431
|
+
clearActive();
|
|
3485
3432
|
countryElement.parentNode.insertBefore(
|
|
3486
3433
|
countryElement,
|
|
3487
3434
|
this.persistentTooltipGroup || null
|
|
@@ -3495,9 +3442,7 @@ class svgMap {
|
|
|
3495
3442
|
|
|
3496
3443
|
if (callbackResultClick === false) return;
|
|
3497
3444
|
|
|
3498
|
-
|
|
3499
|
-
.querySelectorAll('.svgMap-country.svgMap-active')
|
|
3500
|
-
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3445
|
+
clearActive();
|
|
3501
3446
|
countryElement.parentNode.insertBefore(
|
|
3502
3447
|
countryElement,
|
|
3503
3448
|
this.persistentTooltipGroup || null
|
|
@@ -3550,15 +3495,9 @@ class svgMap {
|
|
|
3550
3495
|
});
|
|
3551
3496
|
|
|
3552
3497
|
this._clickTooltipOutsideHandler = function (ev) {
|
|
3553
|
-
if (
|
|
3554
|
-
if (
|
|
3555
|
-
!this.options.showTooltips ||
|
|
3556
|
-
this.options.tooltipTrigger !== 'click' ||
|
|
3557
|
-
!this.tooltip
|
|
3558
|
-
) {
|
|
3498
|
+
if (!this.tooltip || !this.tooltip.classList.contains('svgMap-active')) {
|
|
3559
3499
|
return;
|
|
3560
3500
|
}
|
|
3561
|
-
if (!this.tooltip.classList.contains('svgMap-active')) return;
|
|
3562
3501
|
var node = ev.target;
|
|
3563
3502
|
if (
|
|
3564
3503
|
node &&
|
|
@@ -3576,11 +3515,6 @@ class svgMap {
|
|
|
3576
3515
|
});
|
|
3577
3516
|
}
|
|
3578
3517
|
}.bind(this);
|
|
3579
|
-
document.addEventListener(
|
|
3580
|
-
'pointerdown',
|
|
3581
|
-
this._clickTooltipOutsideHandler,
|
|
3582
|
-
true
|
|
3583
|
-
);
|
|
3584
3518
|
|
|
3585
3519
|
// Expose instance
|
|
3586
3520
|
var me = this;
|
|
@@ -3663,7 +3597,7 @@ class svgMap {
|
|
|
3663
3597
|
|
|
3664
3598
|
countryElements.forEach(
|
|
3665
3599
|
function (countryElement) {
|
|
3666
|
-
var countryID = countryElement.
|
|
3600
|
+
var countryID = countryElement.dataset.id;
|
|
3667
3601
|
if (!this.shouldShowTooltipOnLoad(countryID)) {
|
|
3668
3602
|
return;
|
|
3669
3603
|
}
|
|
@@ -4708,6 +4642,23 @@ class svgMap {
|
|
|
4708
4642
|
return;
|
|
4709
4643
|
}
|
|
4710
4644
|
this.tooltip.classList.add('svgMap-active');
|
|
4645
|
+
|
|
4646
|
+
if (
|
|
4647
|
+
this.options.showTooltips &&
|
|
4648
|
+
this.options.tooltipTrigger === 'click' &&
|
|
4649
|
+
e.pointerType === 'mouse'
|
|
4650
|
+
) {
|
|
4651
|
+
// don't register event listener in the same frame
|
|
4652
|
+
// to prevent it from being triggered immediately
|
|
4653
|
+
requestAnimationFrame(() => {
|
|
4654
|
+
document.addEventListener(
|
|
4655
|
+
'pointerdown',
|
|
4656
|
+
this._clickTooltipOutsideHandler,
|
|
4657
|
+
{ once: true, passive: true }
|
|
4658
|
+
);
|
|
4659
|
+
});
|
|
4660
|
+
}
|
|
4661
|
+
|
|
4711
4662
|
this.moveTooltip(e);
|
|
4712
4663
|
}
|
|
4713
4664
|
|
|
@@ -4717,7 +4668,12 @@ class svgMap {
|
|
|
4717
4668
|
if (!this.tooltip) {
|
|
4718
4669
|
return;
|
|
4719
4670
|
}
|
|
4671
|
+
|
|
4720
4672
|
this.tooltip.classList.remove('svgMap-active');
|
|
4673
|
+
document.removeEventListener(
|
|
4674
|
+
'pointerdown',
|
|
4675
|
+
this._clickTooltipOutsideHandler
|
|
4676
|
+
);
|
|
4721
4677
|
}
|
|
4722
4678
|
|
|
4723
4679
|
// Move the tooltip
|