svgmap 2.19.2 → 2.20.0
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/README.md +6 -3
- package/dist/index.cjs +283 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +283 -38
- package/dist/index.js.map +1 -1
- package/dist/svg-map.css +61 -21
- package/dist/svg-map.min.css +1 -1
- package/dist/svg-map.umd.js +283 -38
- package/dist/svg-map.umd.js.map +1 -1
- package/dist/svg-map.umd.min.js +1 -1
- package/dist/svgMap.css +61 -21
- package/dist/svgMap.js +283 -38
- package/dist/svgMap.js.map +1 -1
- package/dist/svgMap.min.css +1 -1
- package/dist/svgMap.min.js +1 -1
- package/package.json +5 -5
- package/src/js/core/svg-map.js +283 -38
- package/src/scss/map.scss +4 -0
- package/src/scss/tooltip.scss +26 -6
package/README.md
CHANGED
|
@@ -22,9 +22,8 @@ import 'svgmap/dist/svg-map.css';
|
|
|
22
22
|
### CDN
|
|
23
23
|
|
|
24
24
|
```html
|
|
25
|
-
<script src="https://cdn.jsdelivr.net/npm/
|
|
26
|
-
<
|
|
27
|
-
<link href="https://cdn.jsdelivr.net/npm/svgmap@v2.18.0/dist/svg-map.min.css" rel="stylesheet">
|
|
25
|
+
<script src="https://cdn.jsdelivr.net/npm/svgmap@v2.19.2/dist/svg-map.umd.min.js"></script>
|
|
26
|
+
<link href="https://cdn.jsdelivr.net/npm/svgmap@v2.19.2/dist/svg-map.min.css" rel="stylesheet">
|
|
28
27
|
```
|
|
29
28
|
|
|
30
29
|
---
|
|
@@ -100,7 +99,11 @@ You can pass the following options into svgMap:
|
|
|
100
99
|
| `hideFlag` | `boolean` | `false` | Hide the flag in tooltips |
|
|
101
100
|
| `noDataText` | `string` | `'No data available'` | The text to be shown when no data is present |
|
|
102
101
|
| `touchLink` | `boolean` | `false` | Set to `true` to open the link (see `data.values.link`) on mobile devices, by default the tooltip will be shown |
|
|
102
|
+
| `showTooltips` | `boolean` | `true` | When `false`, disables hover and touch-following tooltips only. Persistent on-map labels from `persistentTooltips` are unaffected. On touch devices, countries with a `link` open it on the first tap instead of using the two-tap pattern (first tap preview, second tap navigate). |
|
|
103
|
+
| `tooltipTrigger` | `'hover'`, `'click'` | `'hover'` | How the floating tooltip opens with the **mouse**: `'hover'` opens on mouseenter/mouseleave.`'click'` opens on primary click and closes when clicking outside the map countries or tooltip. Only applies when `showTooltips` is `true`. |
|
|
104
|
+
| `persistentTooltips` | `false`, `array`, `function` | `false` | Persistent tooltips fixed on the map when it loads: an array of country IDs, or a function (`function (countryID, countryValues) { … }`) to decide per country. Independent of `showTooltips`. Best used with `showTooltips: false` or `tooltipTrigger: 'click'`. |
|
|
103
105
|
| `onGetTooltip` | `function` | | Called when a tooltip is created to custimize the tooltip content (`function (tooltipDiv, countryID, countryValues) { return 'Custom HTML'; }`) |
|
|
106
|
+
| `onCountryClick` | `function` | | Called when the user clicks a country (primary button, pointer released without dragging). Signature: `function (countryID, event) { … }`. Use this for custom actions instead of or in addition to `data.values.link`. Return `false` to skip opening the URL when the country has a `link`. On touch devices with a link, the callback runs when the tap would navigate (not on the first tap that only shows the tooltip). Countries show a pointer cursor while this option is set. |
|
|
104
107
|
| `countries` | `object` | | Additional options specific to countries: |
|
|
105
108
|
| `↳ EH` | `boolean` | `true` | When set to `false`, Western Sahara (EH) will be combined with Morocco (MA) |
|
|
106
109
|
| `data` | `object` | | The chart data to use for coloring and to show in the tooltip. Use a unique data-id as key and provide following options as value: |
|
package/dist/index.cjs
CHANGED
|
@@ -2344,6 +2344,15 @@ class svgMap {
|
|
|
2344
2344
|
// Set to true to open the link on mobile devices, set to false (default) to show the tooltip
|
|
2345
2345
|
touchLink: false,
|
|
2346
2346
|
|
|
2347
|
+
// When false, disables hover/touch-following tooltips (not the on-map persistent labels; see persistentTooltips)
|
|
2348
|
+
showTooltips: true,
|
|
2349
|
+
|
|
2350
|
+
// 'hover' (default): mouse shows tooltip on enter. 'click': mouse opens tooltip on click; touch/pen unchanged.
|
|
2351
|
+
tooltipTrigger: 'hover',
|
|
2352
|
+
|
|
2353
|
+
// Persistent on-map tooltips: an array of country IDs, or a function (countryID, countryValues) => boolean
|
|
2354
|
+
persistentTooltips: false,
|
|
2355
|
+
|
|
2347
2356
|
// Set to true to show the to show a zoom reset button
|
|
2348
2357
|
showZoomReset: false,
|
|
2349
2358
|
|
|
@@ -2352,6 +2361,10 @@ class svgMap {
|
|
|
2352
2361
|
return null;
|
|
2353
2362
|
},
|
|
2354
2363
|
|
|
2364
|
+
// Called on country click (pointer released without dragging). Receives
|
|
2365
|
+
// (countryID, event). Return false to skip opening data.values[*].link.
|
|
2366
|
+
onCountryClick: null,
|
|
2367
|
+
|
|
2355
2368
|
// Country specific options
|
|
2356
2369
|
countries: {
|
|
2357
2370
|
// Western Sahara: Set to false to combine Morocco (MA) and Western Sahara (EH)
|
|
@@ -2391,6 +2404,9 @@ class svgMap {
|
|
|
2391
2404
|
// Wrapper element
|
|
2392
2405
|
this.wrapper = document.getElementById(this.options.targetElementID);
|
|
2393
2406
|
this.wrapper.classList.add('svgMap-wrapper');
|
|
2407
|
+
if (typeof this.options.onCountryClick === 'function') {
|
|
2408
|
+
this.wrapper.classList.add('svgMap-country-click-callback');
|
|
2409
|
+
}
|
|
2394
2410
|
|
|
2395
2411
|
// Container element
|
|
2396
2412
|
this.container = document.createElement('div');
|
|
@@ -3082,7 +3098,9 @@ class svgMap {
|
|
|
3082
3098
|
|
|
3083
3099
|
createMap() {
|
|
3084
3100
|
// Create the tooltip
|
|
3085
|
-
this.
|
|
3101
|
+
if (this.options.showTooltips) {
|
|
3102
|
+
this.createTooltip();
|
|
3103
|
+
}
|
|
3086
3104
|
|
|
3087
3105
|
// Create map wrappers
|
|
3088
3106
|
this.mapWrapper = this.createElement(
|
|
@@ -3090,6 +3108,10 @@ class svgMap {
|
|
|
3090
3108
|
'svgMap-map-wrapper',
|
|
3091
3109
|
this.mapContainer
|
|
3092
3110
|
);
|
|
3111
|
+
this.mapWrapper.style.setProperty(
|
|
3112
|
+
'--svg-map-country-fill',
|
|
3113
|
+
this.toHex(this.options.colorNoData)
|
|
3114
|
+
);
|
|
3093
3115
|
this.mapImage = document.createElementNS(
|
|
3094
3116
|
'http://www.w3.org/2000/svg',
|
|
3095
3117
|
'svg'
|
|
@@ -3204,6 +3226,7 @@ class svgMap {
|
|
|
3204
3226
|
}.bind(this);
|
|
3205
3227
|
|
|
3206
3228
|
// Add map elements
|
|
3229
|
+
var countryElements = [];
|
|
3207
3230
|
Object.keys(mapPaths).forEach(
|
|
3208
3231
|
function (countryID) {
|
|
3209
3232
|
var countryData = this.mapPaths[countryID];
|
|
@@ -3225,6 +3248,7 @@ class svgMap {
|
|
|
3225
3248
|
countryElement.classList.add('svgMap-country');
|
|
3226
3249
|
|
|
3227
3250
|
this.mapImage.appendChild(countryElement);
|
|
3251
|
+
countryElements.push(countryElement);
|
|
3228
3252
|
|
|
3229
3253
|
// Add tooltip when touch is used
|
|
3230
3254
|
function handlePointerMove(e) {
|
|
@@ -3240,7 +3264,7 @@ class svgMap {
|
|
|
3240
3264
|
this.hideTooltip();
|
|
3241
3265
|
document
|
|
3242
3266
|
.querySelectorAll('.svgMap-active')
|
|
3243
|
-
.forEach(el => el.classList.remove('svgMap-active'));
|
|
3267
|
+
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3244
3268
|
}
|
|
3245
3269
|
}
|
|
3246
3270
|
|
|
@@ -3249,29 +3273,40 @@ class svgMap {
|
|
|
3249
3273
|
countryElement.addEventListener(
|
|
3250
3274
|
'pointerenter',
|
|
3251
3275
|
function (e) {
|
|
3276
|
+
if (
|
|
3277
|
+
e.pointerType === 'mouse' &&
|
|
3278
|
+
this.options.showTooltips &&
|
|
3279
|
+
this.options.tooltipTrigger === 'click'
|
|
3280
|
+
) {
|
|
3281
|
+
return;
|
|
3282
|
+
}
|
|
3283
|
+
|
|
3252
3284
|
// Only add pointermove listener for non-touch pointers
|
|
3253
3285
|
if (e.pointerType !== 'touch') {
|
|
3254
|
-
document.addEventListener(
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
{ passive: true }
|
|
3258
|
-
);
|
|
3286
|
+
document.addEventListener('pointermove', handlePointerMoveBound, {
|
|
3287
|
+
passive: true
|
|
3288
|
+
});
|
|
3259
3289
|
}
|
|
3260
3290
|
|
|
3261
3291
|
document
|
|
3262
3292
|
.querySelectorAll('.svgMap-active')
|
|
3263
|
-
.forEach(el => el.classList.remove('svgMap-active'));
|
|
3293
|
+
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3264
3294
|
|
|
3265
|
-
countryElement.parentNode.
|
|
3295
|
+
countryElement.parentNode.insertBefore(
|
|
3296
|
+
countryElement,
|
|
3297
|
+
this.persistentTooltipGroup || null
|
|
3298
|
+
);
|
|
3266
3299
|
countryElement.classList.add('svgMap-active');
|
|
3267
3300
|
|
|
3268
3301
|
const countryID = countryElement.getAttribute('data-id');
|
|
3269
|
-
|
|
3270
|
-
|
|
3302
|
+
if (this.options.showTooltips) {
|
|
3303
|
+
this.setTooltipContent(this.getTooltipContent(countryID));
|
|
3304
|
+
this.showTooltip(e);
|
|
3271
3305
|
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3306
|
+
// For touch, move tooltip to the touch position and keep it there
|
|
3307
|
+
if (e.pointerType === 'touch') {
|
|
3308
|
+
this.moveTooltip(e);
|
|
3309
|
+
}
|
|
3275
3310
|
}
|
|
3276
3311
|
}.bind(this)
|
|
3277
3312
|
);
|
|
@@ -3290,7 +3325,10 @@ class svgMap {
|
|
|
3290
3325
|
'touchend',
|
|
3291
3326
|
function (e) {
|
|
3292
3327
|
const touch = e.changedTouches[0];
|
|
3293
|
-
const elementAtEnd = document.elementFromPoint(
|
|
3328
|
+
const elementAtEnd = document.elementFromPoint(
|
|
3329
|
+
touch.clientX,
|
|
3330
|
+
touch.clientY
|
|
3331
|
+
);
|
|
3294
3332
|
|
|
3295
3333
|
// Only hide if touch ended outside the country or tooltip
|
|
3296
3334
|
if (
|
|
@@ -3301,7 +3339,7 @@ class svgMap {
|
|
|
3301
3339
|
this.hideTooltip();
|
|
3302
3340
|
document
|
|
3303
3341
|
.querySelectorAll('.svgMap-active')
|
|
3304
|
-
.forEach(el => el.classList.remove('svgMap-active'));
|
|
3342
|
+
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3305
3343
|
}
|
|
3306
3344
|
}.bind(this),
|
|
3307
3345
|
{ passive: true }
|
|
@@ -3312,11 +3350,22 @@ class svgMap {
|
|
|
3312
3350
|
'pointerleave',
|
|
3313
3351
|
function (e) {
|
|
3314
3352
|
if (e.pointerType !== 'touch') {
|
|
3315
|
-
document.removeEventListener(
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
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
|
+
}
|
|
3320
3369
|
}
|
|
3321
3370
|
}.bind(this)
|
|
3322
3371
|
);
|
|
@@ -3336,7 +3385,7 @@ class svgMap {
|
|
|
3336
3385
|
this.hideTooltip();
|
|
3337
3386
|
document
|
|
3338
3387
|
.querySelectorAll('.svgMap-active')
|
|
3339
|
-
.forEach(el => el.classList.remove('svgMap-active'));
|
|
3388
|
+
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3340
3389
|
}.bind(this),
|
|
3341
3390
|
{ passive: true }
|
|
3342
3391
|
);
|
|
@@ -3360,17 +3409,29 @@ class svgMap {
|
|
|
3360
3409
|
}.bind(this)
|
|
3361
3410
|
);
|
|
3362
3411
|
|
|
3412
|
+
var persistent = this.options.persistentTooltips;
|
|
3413
|
+
if (
|
|
3414
|
+
persistent &&
|
|
3415
|
+
(Array.isArray(persistent) || typeof persistent === 'function')
|
|
3416
|
+
) {
|
|
3417
|
+
this.createPersistentTooltips(countryElements);
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3363
3420
|
let pointerStart = null;
|
|
3364
3421
|
let activeCountry = null;
|
|
3365
3422
|
|
|
3366
|
-
this.mapImage.addEventListener(
|
|
3367
|
-
|
|
3368
|
-
|
|
3423
|
+
this.mapImage.addEventListener(
|
|
3424
|
+
'pointerdown',
|
|
3425
|
+
(e) => {
|
|
3426
|
+
// Ignore right click (on desktop it allows inspecting the chart elements without opening the URL)
|
|
3427
|
+
if (e.button !== 0) return;
|
|
3369
3428
|
|
|
3370
|
-
|
|
3371
|
-
|
|
3429
|
+
pointerStart = { x: e.clientX, y: e.clientY };
|
|
3430
|
+
},
|
|
3431
|
+
{ passive: true }
|
|
3432
|
+
);
|
|
3372
3433
|
|
|
3373
|
-
this.mapImage.addEventListener('pointerup', e => {
|
|
3434
|
+
this.mapImage.addEventListener('pointerup', (e) => {
|
|
3374
3435
|
// Ignore right click (on desktop it allows inspecting the chart elements without opening the URL)
|
|
3375
3436
|
if (e.button !== 0) return;
|
|
3376
3437
|
|
|
@@ -3390,31 +3451,137 @@ class svgMap {
|
|
|
3390
3451
|
|
|
3391
3452
|
const countryID = countryElement.getAttribute('data-id');
|
|
3392
3453
|
const link = countryElement.getAttribute('data-link');
|
|
3393
|
-
const
|
|
3394
|
-
|
|
3395
|
-
|
|
3454
|
+
const linkTarget = countryElement.getAttribute('data-link-target');
|
|
3455
|
+
const hasCallback = typeof this.options.onCountryClick === 'function';
|
|
3456
|
+
const hasLink = !!link;
|
|
3396
3457
|
const isTouch = e.pointerType === 'touch' || e.pointerType === 'pen';
|
|
3397
3458
|
|
|
3459
|
+
const isClickTooltipMouse =
|
|
3460
|
+
e.pointerType === 'mouse' &&
|
|
3461
|
+
this.options.showTooltips &&
|
|
3462
|
+
this.options.tooltipTrigger === 'click';
|
|
3463
|
+
|
|
3464
|
+
if (!hasLink && !hasCallback && !isClickTooltipMouse) return;
|
|
3465
|
+
|
|
3466
|
+
if (isClickTooltipMouse && this.options.showTooltips) {
|
|
3467
|
+
const willNavigate =
|
|
3468
|
+
hasLink && countryElement.classList.contains('svgMap-active');
|
|
3469
|
+
const shouldFireCallback = hasCallback && (!hasLink || willNavigate);
|
|
3470
|
+
|
|
3471
|
+
var callbackResultClick;
|
|
3472
|
+
if (shouldFireCallback) {
|
|
3473
|
+
callbackResultClick = this.options.onCountryClick(countryID, e);
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
if (hasLink) {
|
|
3477
|
+
if (callbackResultClick === false) return;
|
|
3478
|
+
if (countryElement.classList.contains('svgMap-active')) {
|
|
3479
|
+
if (linkTarget) window.open(link, linkTarget);
|
|
3480
|
+
else window.location.href = link;
|
|
3481
|
+
} else {
|
|
3482
|
+
this.mapImage
|
|
3483
|
+
.querySelectorAll('.svgMap-country.svgMap-active')
|
|
3484
|
+
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3485
|
+
countryElement.parentNode.insertBefore(
|
|
3486
|
+
countryElement,
|
|
3487
|
+
this.persistentTooltipGroup || null
|
|
3488
|
+
);
|
|
3489
|
+
countryElement.classList.add('svgMap-active');
|
|
3490
|
+
this.setTooltipContent(this.getTooltipContent(countryID));
|
|
3491
|
+
this.showTooltip(e);
|
|
3492
|
+
}
|
|
3493
|
+
return;
|
|
3494
|
+
}
|
|
3495
|
+
|
|
3496
|
+
if (callbackResultClick === false) return;
|
|
3497
|
+
|
|
3498
|
+
this.mapImage
|
|
3499
|
+
.querySelectorAll('.svgMap-country.svgMap-active')
|
|
3500
|
+
.forEach((el) => el.classList.remove('svgMap-active'));
|
|
3501
|
+
countryElement.parentNode.insertBefore(
|
|
3502
|
+
countryElement,
|
|
3503
|
+
this.persistentTooltipGroup || null
|
|
3504
|
+
);
|
|
3505
|
+
countryElement.classList.add('svgMap-active');
|
|
3506
|
+
this.setTooltipContent(this.getTooltipContent(countryID));
|
|
3507
|
+
this.showTooltip(e);
|
|
3508
|
+
return;
|
|
3509
|
+
}
|
|
3510
|
+
|
|
3511
|
+
const willNavigate =
|
|
3512
|
+
hasLink &&
|
|
3513
|
+
(!isTouch || countryElement.classList.contains('svgMap-active'));
|
|
3514
|
+
|
|
3515
|
+
const shouldFireCallback =
|
|
3516
|
+
hasCallback && (!hasLink || !isTouch || willNavigate);
|
|
3517
|
+
|
|
3518
|
+
var callbackResult;
|
|
3519
|
+
if (shouldFireCallback) {
|
|
3520
|
+
callbackResult = this.options.onCountryClick(countryID, e);
|
|
3521
|
+
}
|
|
3522
|
+
|
|
3523
|
+
if (!hasLink) return;
|
|
3524
|
+
|
|
3525
|
+
if (callbackResult === false) return;
|
|
3526
|
+
|
|
3398
3527
|
if (isTouch) {
|
|
3399
3528
|
// Touch: only open if already active
|
|
3400
3529
|
if (countryElement.classList.contains('svgMap-active')) {
|
|
3401
|
-
if (
|
|
3530
|
+
if (linkTarget) window.open(link, linkTarget);
|
|
3402
3531
|
else window.location.href = link;
|
|
3403
3532
|
} else {
|
|
3404
|
-
// first tap shows tooltip
|
|
3533
|
+
// first tap shows tooltip (or opens link immediately if tooltips are off)
|
|
3405
3534
|
if (activeCountry) activeCountry.classList.remove('svgMap-active');
|
|
3406
3535
|
activeCountry = countryElement;
|
|
3407
3536
|
countryElement.classList.add('svgMap-active');
|
|
3408
|
-
|
|
3409
|
-
|
|
3537
|
+
if (this.options.showTooltips) {
|
|
3538
|
+
this.setTooltipContent(this.getTooltipContent(countryID));
|
|
3539
|
+
this.showTooltip(e);
|
|
3540
|
+
} else {
|
|
3541
|
+
if (linkTarget) window.open(link, linkTarget);
|
|
3542
|
+
else window.location.href = link;
|
|
3543
|
+
}
|
|
3410
3544
|
}
|
|
3411
3545
|
} else {
|
|
3412
3546
|
// Desktop: open immediately
|
|
3413
|
-
if (
|
|
3547
|
+
if (linkTarget) window.open(link, linkTarget);
|
|
3414
3548
|
else window.location.href = link;
|
|
3415
3549
|
}
|
|
3416
3550
|
});
|
|
3417
3551
|
|
|
3552
|
+
this._clickTooltipOutsideHandler = function (ev) {
|
|
3553
|
+
if (ev.pointerType !== 'mouse') return;
|
|
3554
|
+
if (
|
|
3555
|
+
!this.options.showTooltips ||
|
|
3556
|
+
this.options.tooltipTrigger !== 'click' ||
|
|
3557
|
+
!this.tooltip
|
|
3558
|
+
) {
|
|
3559
|
+
return;
|
|
3560
|
+
}
|
|
3561
|
+
if (!this.tooltip.classList.contains('svgMap-active')) return;
|
|
3562
|
+
var node = ev.target;
|
|
3563
|
+
if (
|
|
3564
|
+
node &&
|
|
3565
|
+
node.closest &&
|
|
3566
|
+
(node.closest('.svgMap-country') || node.closest('.svgMap-tooltip'))
|
|
3567
|
+
) {
|
|
3568
|
+
return;
|
|
3569
|
+
}
|
|
3570
|
+
this.hideTooltip();
|
|
3571
|
+
if (this.mapImage) {
|
|
3572
|
+
this.mapImage
|
|
3573
|
+
.querySelectorAll('.svgMap-country.svgMap-active')
|
|
3574
|
+
.forEach(function (el) {
|
|
3575
|
+
el.classList.remove('svgMap-active');
|
|
3576
|
+
});
|
|
3577
|
+
}
|
|
3578
|
+
}.bind(this);
|
|
3579
|
+
document.addEventListener(
|
|
3580
|
+
'pointerdown',
|
|
3581
|
+
this._clickTooltipOutsideHandler,
|
|
3582
|
+
true
|
|
3583
|
+
);
|
|
3584
|
+
|
|
3418
3585
|
// Expose instance
|
|
3419
3586
|
var me = this;
|
|
3420
3587
|
|
|
@@ -3480,13 +3647,82 @@ class svgMap {
|
|
|
3480
3647
|
}
|
|
3481
3648
|
}
|
|
3482
3649
|
|
|
3650
|
+
// Create the persistent tooltips
|
|
3651
|
+
|
|
3652
|
+
createPersistentTooltips(countryElements) {
|
|
3653
|
+
if (this.persistentTooltipGroup) {
|
|
3654
|
+
this.persistentTooltipGroup.remove();
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
this.persistentTooltipGroup = document.createElementNS(
|
|
3658
|
+
'http://www.w3.org/2000/svg',
|
|
3659
|
+
'g'
|
|
3660
|
+
);
|
|
3661
|
+
this.persistentTooltipGroup.classList.add('svgMap-persistent-tooltips');
|
|
3662
|
+
this.mapImage.appendChild(this.persistentTooltipGroup);
|
|
3663
|
+
|
|
3664
|
+
countryElements.forEach(
|
|
3665
|
+
function (countryElement) {
|
|
3666
|
+
var countryID = countryElement.getAttribute('data-id');
|
|
3667
|
+
if (!this.shouldShowTooltipOnLoad(countryID)) {
|
|
3668
|
+
return;
|
|
3669
|
+
}
|
|
3670
|
+
|
|
3671
|
+
var boundingBox = countryElement.getBBox();
|
|
3672
|
+
var tooltipPosition = {
|
|
3673
|
+
x: boundingBox.x + boundingBox.width / 2,
|
|
3674
|
+
y: boundingBox.y + boundingBox.height / 2
|
|
3675
|
+
};
|
|
3676
|
+
|
|
3677
|
+
var tooltipObject = document.createElementNS(
|
|
3678
|
+
'http://www.w3.org/2000/svg',
|
|
3679
|
+
'foreignObject'
|
|
3680
|
+
);
|
|
3681
|
+
tooltipObject.setAttribute('x', tooltipPosition.x);
|
|
3682
|
+
tooltipObject.setAttribute('y', tooltipPosition.y);
|
|
3683
|
+
tooltipObject.setAttribute('width', 1);
|
|
3684
|
+
tooltipObject.setAttribute('height', 1);
|
|
3685
|
+
tooltipObject.classList.add('svgMap-persistent-tooltip-wrapper');
|
|
3686
|
+
|
|
3687
|
+
var tooltipElement = this.createElement(
|
|
3688
|
+
'div',
|
|
3689
|
+
'svgMap-persistent-tooltip',
|
|
3690
|
+
tooltipObject
|
|
3691
|
+
);
|
|
3692
|
+
tooltipElement.append(
|
|
3693
|
+
this.getTooltipContent(countryID, tooltipElement)
|
|
3694
|
+
);
|
|
3695
|
+
this.createElement('div', 'svgMap-tooltip-pointer', tooltipElement);
|
|
3696
|
+
|
|
3697
|
+
this.persistentTooltipGroup.appendChild(tooltipObject);
|
|
3698
|
+
}.bind(this)
|
|
3699
|
+
);
|
|
3700
|
+
}
|
|
3701
|
+
|
|
3702
|
+
// Check if a persistent tooltip should be shown on load
|
|
3703
|
+
|
|
3704
|
+
shouldShowTooltipOnLoad(countryID) {
|
|
3705
|
+
var persistent = this.options.persistentTooltips;
|
|
3706
|
+
var countryValues = this.options.data.values[countryID];
|
|
3707
|
+
|
|
3708
|
+
if (Array.isArray(persistent)) {
|
|
3709
|
+
return persistent.indexOf(countryID) !== -1;
|
|
3710
|
+
}
|
|
3711
|
+
|
|
3712
|
+
if (typeof persistent === 'function') {
|
|
3713
|
+
return persistent(countryID, countryValues);
|
|
3714
|
+
}
|
|
3715
|
+
|
|
3716
|
+
return false;
|
|
3717
|
+
}
|
|
3718
|
+
|
|
3483
3719
|
// Create the tooltip content
|
|
3484
3720
|
|
|
3485
|
-
getTooltipContent(countryID) {
|
|
3721
|
+
getTooltipContent(countryID, tooltipDiv = this.tooltip) {
|
|
3486
3722
|
// Custom tooltip
|
|
3487
3723
|
if (this.options.onGetTooltip) {
|
|
3488
3724
|
var customDiv = this.options.onGetTooltip(
|
|
3489
|
-
|
|
3725
|
+
tooltipDiv,
|
|
3490
3726
|
countryID,
|
|
3491
3727
|
this.options.data.values[countryID]
|
|
3492
3728
|
);
|
|
@@ -4468,6 +4704,9 @@ class svgMap {
|
|
|
4468
4704
|
// Show the tooltip
|
|
4469
4705
|
|
|
4470
4706
|
showTooltip(e) {
|
|
4707
|
+
if (!this.tooltip) {
|
|
4708
|
+
return;
|
|
4709
|
+
}
|
|
4471
4710
|
this.tooltip.classList.add('svgMap-active');
|
|
4472
4711
|
this.moveTooltip(e);
|
|
4473
4712
|
}
|
|
@@ -4475,12 +4714,18 @@ class svgMap {
|
|
|
4475
4714
|
// Hide the tooltip
|
|
4476
4715
|
|
|
4477
4716
|
hideTooltip() {
|
|
4717
|
+
if (!this.tooltip) {
|
|
4718
|
+
return;
|
|
4719
|
+
}
|
|
4478
4720
|
this.tooltip.classList.remove('svgMap-active');
|
|
4479
4721
|
}
|
|
4480
4722
|
|
|
4481
4723
|
// Move the tooltip
|
|
4482
4724
|
|
|
4483
4725
|
moveTooltip(e) {
|
|
4726
|
+
if (!this.tooltip) {
|
|
4727
|
+
return;
|
|
4728
|
+
}
|
|
4484
4729
|
var x = e.pageX || (e.touches && e.touches[0] ? e.touches[0].pageX : null);
|
|
4485
4730
|
var y = e.pageY || (e.touches && e.touches[0] ? e.touches[0].pageY : null);
|
|
4486
4731
|
|