svgmap 2.20.1 → 2.21.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 +22 -0
- package/dist/index.cjs +186 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +186 -4
- package/dist/index.js.map +1 -1
- package/dist/svg-map.css +9 -0
- package/dist/svg-map.min.css +1 -1
- package/dist/svg-map.umd.js +186 -4
- package/dist/svg-map.umd.js.map +1 -1
- package/dist/svg-map.umd.min.js +1 -1
- package/dist/svgMap.css +9 -0
- package/dist/svgMap.js +186 -4
- package/dist/svgMap.js.map +1 -1
- package/dist/svgMap.min.css +1 -1
- package/dist/svgMap.min.js +1 -1
- package/package.json +1 -1
- package/src/js/core/svg-map.js +186 -4
- package/src/scss/map.scss +11 -0
package/dist/index.js
CHANGED
|
@@ -2373,7 +2373,34 @@ class svgMap {
|
|
|
2373
2373
|
showContinentSelector: false,
|
|
2374
2374
|
|
|
2375
2375
|
// Reset zoom on resize
|
|
2376
|
-
resetZoomOnResize: false
|
|
2376
|
+
resetZoomOnResize: false,
|
|
2377
|
+
|
|
2378
|
+
// Static pins: false | string[] | function(countryID, countryValues) => boolean
|
|
2379
|
+
staticPins: false,
|
|
2380
|
+
|
|
2381
|
+
// Default pin fill color
|
|
2382
|
+
pinColor: '#000000',
|
|
2383
|
+
|
|
2384
|
+
// Default pin stroke color and width (circle pins; width is in screen pixels with non-scaling stroke)
|
|
2385
|
+
pinStrokeColor: '#ffffff',
|
|
2386
|
+
pinStrokeWidth: 1.5,
|
|
2387
|
+
|
|
2388
|
+
// Default pin radius in SVG units (viewBox is 2000 × 1001)
|
|
2389
|
+
pinSize: 8,
|
|
2390
|
+
|
|
2391
|
+
// Custom pin element: function(countryID, countryValues) => SVGElement | null
|
|
2392
|
+
onGetPin: null,
|
|
2393
|
+
|
|
2394
|
+
// Image URL to use as a pin instead of the default circle (can also be set per-country via values[id].pinImage)
|
|
2395
|
+
pinImage: null,
|
|
2396
|
+
|
|
2397
|
+
// Width and height of the pin image in SVG units (viewBox is 2000 × 1001)
|
|
2398
|
+
pinImageWidth: 20,
|
|
2399
|
+
pinImageHeight: 20,
|
|
2400
|
+
|
|
2401
|
+
// Offset from computed pin position, in SVG units (added after auto center or pinX/pinY)
|
|
2402
|
+
pinOffsetX: 0,
|
|
2403
|
+
pinOffsetY: 0
|
|
2377
2404
|
};
|
|
2378
2405
|
|
|
2379
2406
|
this.options = Object.assign({}, defaultOptions, options);
|
|
@@ -3247,7 +3274,7 @@ class svgMap {
|
|
|
3247
3274
|
}
|
|
3248
3275
|
countryElement.parentNode.insertBefore(
|
|
3249
3276
|
countryElement,
|
|
3250
|
-
this.persistentTooltipGroup || null
|
|
3277
|
+
this.persistentTooltipGroup || this.pinGroup || null
|
|
3251
3278
|
);
|
|
3252
3279
|
if (setActive) {
|
|
3253
3280
|
countryElement.classList.add('svgMap-active');
|
|
@@ -3367,6 +3394,10 @@ class svgMap {
|
|
|
3367
3394
|
this.createPersistentTooltips(countryElements);
|
|
3368
3395
|
}
|
|
3369
3396
|
|
|
3397
|
+
if (this.options.staticPins) {
|
|
3398
|
+
this.createStaticPins(countryElements);
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3370
3401
|
let pointerStart = null;
|
|
3371
3402
|
let activeCountry = null;
|
|
3372
3403
|
|
|
@@ -3429,7 +3460,7 @@ class svgMap {
|
|
|
3429
3460
|
clearActive();
|
|
3430
3461
|
countryElement.parentNode.insertBefore(
|
|
3431
3462
|
countryElement,
|
|
3432
|
-
this.persistentTooltipGroup || null
|
|
3463
|
+
this.persistentTooltipGroup || this.pinGroup || null
|
|
3433
3464
|
);
|
|
3434
3465
|
countryElement.classList.add('svgMap-active');
|
|
3435
3466
|
this.setTooltipContent(this.getTooltipContent(countryID));
|
|
@@ -3443,7 +3474,7 @@ class svgMap {
|
|
|
3443
3474
|
clearActive();
|
|
3444
3475
|
countryElement.parentNode.insertBefore(
|
|
3445
3476
|
countryElement,
|
|
3446
|
-
this.persistentTooltipGroup || null
|
|
3477
|
+
this.persistentTooltipGroup || this.pinGroup || null
|
|
3447
3478
|
);
|
|
3448
3479
|
countryElement.classList.add('svgMap-active');
|
|
3449
3480
|
this.setTooltipContent(this.getTooltipContent(countryID));
|
|
@@ -3631,6 +3662,157 @@ class svgMap {
|
|
|
3631
3662
|
);
|
|
3632
3663
|
}
|
|
3633
3664
|
|
|
3665
|
+
// Create static pins on the map
|
|
3666
|
+
|
|
3667
|
+
createStaticPins(countryElements) {
|
|
3668
|
+
if (this.pinGroup) {
|
|
3669
|
+
this.pinGroup.remove();
|
|
3670
|
+
}
|
|
3671
|
+
|
|
3672
|
+
this.pinGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
|
3673
|
+
this.pinGroup.classList.add('svgMap-pin-group');
|
|
3674
|
+
this.mapImage.appendChild(this.pinGroup);
|
|
3675
|
+
|
|
3676
|
+
countryElements.forEach(
|
|
3677
|
+
function (countryElement) {
|
|
3678
|
+
var countryID = countryElement.getAttribute('data-id');
|
|
3679
|
+
if (!this.shouldShowPin(countryID)) {
|
|
3680
|
+
return;
|
|
3681
|
+
}
|
|
3682
|
+
|
|
3683
|
+
var countryValues = this.options.data.values[countryID];
|
|
3684
|
+
var cx, cy;
|
|
3685
|
+
|
|
3686
|
+
if (
|
|
3687
|
+
countryValues &&
|
|
3688
|
+
countryValues.pinX != null &&
|
|
3689
|
+
countryValues.pinY != null
|
|
3690
|
+
) {
|
|
3691
|
+
cx = countryValues.pinX;
|
|
3692
|
+
cy = countryValues.pinY;
|
|
3693
|
+
} else {
|
|
3694
|
+
// Split the path at absolute M commands and use the largest sub-path
|
|
3695
|
+
// to avoid overseas territories (islands, colonies) skewing the center.
|
|
3696
|
+
var d = countryElement.getAttribute('d');
|
|
3697
|
+
var subPaths = d.split(/(?=M)/).filter((s) => s.trim().length > 0);
|
|
3698
|
+
var largestBB = null;
|
|
3699
|
+
var largestArea = -1;
|
|
3700
|
+
|
|
3701
|
+
subPaths.forEach(
|
|
3702
|
+
function (subPath) {
|
|
3703
|
+
var tmp = document.createElementNS(
|
|
3704
|
+
'http://www.w3.org/2000/svg',
|
|
3705
|
+
'path'
|
|
3706
|
+
);
|
|
3707
|
+
tmp.setAttribute('d', subPath);
|
|
3708
|
+
this.mapImage.appendChild(tmp);
|
|
3709
|
+
var bb = tmp.getBBox();
|
|
3710
|
+
var area = bb.width * bb.height;
|
|
3711
|
+
if (area > largestArea) {
|
|
3712
|
+
largestArea = area;
|
|
3713
|
+
largestBB = bb;
|
|
3714
|
+
}
|
|
3715
|
+
this.mapImage.removeChild(tmp);
|
|
3716
|
+
}.bind(this)
|
|
3717
|
+
);
|
|
3718
|
+
|
|
3719
|
+
cx = largestBB.x + largestBB.width / 2;
|
|
3720
|
+
cy = largestBB.y + largestBB.height / 2;
|
|
3721
|
+
}
|
|
3722
|
+
|
|
3723
|
+
var offsetX =
|
|
3724
|
+
countryValues && countryValues.pinOffsetX != null
|
|
3725
|
+
? countryValues.pinOffsetX
|
|
3726
|
+
: this.options.pinOffsetX;
|
|
3727
|
+
var offsetY =
|
|
3728
|
+
countryValues && countryValues.pinOffsetY != null
|
|
3729
|
+
? countryValues.pinOffsetY
|
|
3730
|
+
: this.options.pinOffsetY;
|
|
3731
|
+
cx += offsetX;
|
|
3732
|
+
cy += offsetY;
|
|
3733
|
+
|
|
3734
|
+
var color =
|
|
3735
|
+
(countryValues && countryValues.pinColor) || this.options.pinColor;
|
|
3736
|
+
var size =
|
|
3737
|
+
(countryValues && countryValues.pinSize) || this.options.pinSize;
|
|
3738
|
+
var strokeColor =
|
|
3739
|
+
(countryValues && countryValues.pinStrokeColor) ||
|
|
3740
|
+
this.options.pinStrokeColor;
|
|
3741
|
+
var strokeWidth =
|
|
3742
|
+
(countryValues && countryValues.pinStrokeWidth) ||
|
|
3743
|
+
this.options.pinStrokeWidth;
|
|
3744
|
+
|
|
3745
|
+
if (typeof this.options.onGetPin === 'function') {
|
|
3746
|
+
var custom = this.options.onGetPin(countryID, countryValues);
|
|
3747
|
+
if (custom) {
|
|
3748
|
+
custom.setAttribute(
|
|
3749
|
+
'transform',
|
|
3750
|
+
'translate(' + cx + ',' + cy + ')'
|
|
3751
|
+
);
|
|
3752
|
+
this.pinGroup.appendChild(custom);
|
|
3753
|
+
return;
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
|
|
3757
|
+
var pinImage =
|
|
3758
|
+
(countryValues && countryValues.pinImage) || this.options.pinImage;
|
|
3759
|
+
|
|
3760
|
+
if (pinImage) {
|
|
3761
|
+
var pinW =
|
|
3762
|
+
(countryValues && countryValues.pinImageWidth) ||
|
|
3763
|
+
this.options.pinImageWidth;
|
|
3764
|
+
var pinH =
|
|
3765
|
+
(countryValues && countryValues.pinImageHeight) ||
|
|
3766
|
+
this.options.pinImageHeight;
|
|
3767
|
+
var img = document.createElementNS(
|
|
3768
|
+
'http://www.w3.org/2000/svg',
|
|
3769
|
+
'image'
|
|
3770
|
+
);
|
|
3771
|
+
img.setAttribute('href', pinImage);
|
|
3772
|
+
img.setAttribute('x', cx - pinW / 2);
|
|
3773
|
+
img.setAttribute('y', cy - pinH / 2);
|
|
3774
|
+
img.setAttribute('width', pinW);
|
|
3775
|
+
img.setAttribute('height', pinH);
|
|
3776
|
+
img.setAttribute('data-id', countryID);
|
|
3777
|
+
img.classList.add('svgMap-pin');
|
|
3778
|
+
this.pinGroup.appendChild(img);
|
|
3779
|
+
return;
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3782
|
+
var circle = document.createElementNS(
|
|
3783
|
+
'http://www.w3.org/2000/svg',
|
|
3784
|
+
'circle'
|
|
3785
|
+
);
|
|
3786
|
+
circle.setAttribute('cx', cx);
|
|
3787
|
+
circle.setAttribute('cy', cy);
|
|
3788
|
+
circle.setAttribute('r', size);
|
|
3789
|
+
circle.setAttribute('fill', color);
|
|
3790
|
+
if (strokeWidth > 0) {
|
|
3791
|
+
circle.setAttribute('stroke', strokeColor);
|
|
3792
|
+
circle.setAttribute('stroke-width', strokeWidth);
|
|
3793
|
+
circle.setAttribute('vector-effect', 'non-scaling-stroke');
|
|
3794
|
+
}
|
|
3795
|
+
circle.setAttribute('data-id', countryID);
|
|
3796
|
+
circle.classList.add('svgMap-pin');
|
|
3797
|
+
this.pinGroup.appendChild(circle);
|
|
3798
|
+
}.bind(this)
|
|
3799
|
+
);
|
|
3800
|
+
}
|
|
3801
|
+
|
|
3802
|
+
// Check if a static pin should be shown for a country
|
|
3803
|
+
|
|
3804
|
+
shouldShowPin(countryID) {
|
|
3805
|
+
var pins = this.options.staticPins;
|
|
3806
|
+
var countryValues = this.options.data.values[countryID];
|
|
3807
|
+
if (Array.isArray(pins)) {
|
|
3808
|
+
return pins.indexOf(countryID) !== -1;
|
|
3809
|
+
}
|
|
3810
|
+
if (typeof pins === 'function') {
|
|
3811
|
+
return pins(countryID, countryValues);
|
|
3812
|
+
}
|
|
3813
|
+
return false;
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3634
3816
|
// Check if a persistent tooltip should be shown on load
|
|
3635
3817
|
|
|
3636
3818
|
shouldShowTooltipOnLoad(countryID) {
|