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