Upload 4 files
Browse files- .gitattributes +1 -0
- provinces.json +280 -0
- script.js +257 -0
- style.css +132 -28
- vietnam_map.jfif +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
vietnam_map.jfif filter=lfs diff=lfs merge=lfs -text
|
provinces.json
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"name": "Hà Nội",
|
| 4 |
+
"mergedName": "Hà Nội",
|
| 5 |
+
"center": "Hà Nội",
|
| 6 |
+
"naturalArea": "3.359,8",
|
| 7 |
+
"population": "8.587,1",
|
| 8 |
+
"coords": "434,327,440,318,445,332,461,336,472,338,479,345,484,333,481,314,491,314,499,318,502,326,500,338,505,348,512,357,497,362,500,371,499,382,512,394,488,400,484,410,472,401,463,386,452,377,454,362,443,354,429,356,423,348,432,342,426,340"
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"name": "Huế",
|
| 12 |
+
"mergedName": "Huế",
|
| 13 |
+
"center": "Huế",
|
| 14 |
+
"naturalArea": "4.947,1",
|
| 15 |
+
"population": "1.166,5",
|
| 16 |
+
"coords": "643,911,637,899,657,895,672,878,696,896,675,889,700,902,718,922,715,928,728,934,735,925,737,929,744,926,750,937,761,943,737,940,725,955,720,955,711,965,702,955,696,961,675,962,661,959,643,949,637,938,631,926"
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"name": "Lai Châu",
|
| 20 |
+
"mergedName": "Lai Châu",
|
| 21 |
+
"center": "Lai Châu",
|
| 22 |
+
"naturalArea": "9.068,7",
|
| 23 |
+
"population": "489,3",
|
| 24 |
+
"coords": "199,213,207,218,214,236,223,245,223,234,231,228,232,209,241,207,253,196,255,184,243,180,229,175,231,162,226,153,219,160,213,153,207,144,196,135,189,151,178,156,177,166,168,168,166,177,149,172,143,159,113,142,107,145,104,138,98,136,86,160,103,162,115,171,122,180,134,187,139,195,142,206,151,209,155,215,165,216,195,228"
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"name": "Điện Biên",
|
| 28 |
+
"mergedName": "Điện Biên",
|
| 29 |
+
"center": "Điện Biên",
|
| 30 |
+
"naturalArea": "9.539,9",
|
| 31 |
+
"population": "646,2",
|
| 32 |
+
"coords": "194,231,197,217,207,220,210,235,225,242,227,283,210,303,201,309,213,327,211,350,194,349,191,354,189,363,186,378,170,371,161,354,154,349,150,334,138,327,145,319,148,307,141,306,159,286,154,270,142,271,138,256,130,276,120,279,117,246,100,240,102,231,93,222,69,205,57,187,63,182,73,184,72,173,84,164,102,163,111,173,121,181,130,185,138,199,138,208,148,208,153,219,165,216"
|
| 33 |
+
},
|
| 34 |
+
{
|
| 35 |
+
"name": "Sơn La",
|
| 36 |
+
"mergedName": "Sơn La",
|
| 37 |
+
"center": "Sơn La",
|
| 38 |
+
"naturalArea": "14109,8",
|
| 39 |
+
"population": "1.313,3",
|
| 40 |
+
"coords": "217,391,231,390,237,400,244,400,240,391,250,388,250,376,277,369,282,361,297,364,302,372,312,370,320,385,329,388,347,400,359,408,372,408,375,393,387,390,398,387,402,379,377,355,383,346,378,334,371,316,362,308,348,304,333,313,323,308,314,299,318,277,311,269,300,274,279,274,255,265,243,247,237,235,223,233,226,280,204,308,214,328,210,349,196,349,187,378,202,385,211,379"
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"name": "Lạng Sơn",
|
| 44 |
+
"mergedName": "Lạng Sơn",
|
| 45 |
+
"center": "Lạng Sơn",
|
| 46 |
+
"naturalArea": "8.310,2",
|
| 47 |
+
"population": "807,3",
|
| 48 |
+
"coords": "529,183,541,177,553,185,568,182,572,191,583,192,586,206,582,211,586,223,582,235,589,241,591,232,606,236,616,244,627,241,622,251,631,259,643,266,652,268,664,280,651,290,654,301,636,316,624,304,616,301,607,283,595,287,575,281,565,292,559,302,548,302,536,296,529,283,541,271,527,259,521,227,533,215,539,200"
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"name": "Quảng Ninh",
|
| 52 |
+
"mergedName": "Quảng Ninh",
|
| 53 |
+
"center": "Quảng Ninh",
|
| 54 |
+
"naturalArea": "6.207,9",
|
| 55 |
+
"population": "1.381,2",
|
| 56 |
+
"coords": "621,329,624,317,652,305,651,289,663,281,673,278,675,284,702,281,708,275,720,278,737,293,738,308,693,353,679,379,630,393,607,382,598,373,595,363,585,356,560,349,571,334,604,340"
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"name": "Thanh Hoá",
|
| 60 |
+
"mergedName": "Thanh Hoá",
|
| 61 |
+
"center": "Thanh Hoá",
|
| 62 |
+
"naturalArea": "11.114,7",
|
| 63 |
+
"population": "3.3739,5",
|
| 64 |
+
"coords": "348,402,362,408,374,405,396,411,405,408,425,424,452,436,514,472,514,481,503,490,500,507,490,525,487,546,482,554,485,570,470,566,454,546,440,545,432,537,422,539,425,530,408,508,414,493,387,483,390,468,383,468,384,457,371,454,354,456,356,438,344,432,321,429,326,417,339,418"
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"name": "Nghệ An",
|
| 68 |
+
"mergedName": "Nghệ An",
|
| 69 |
+
"center": "Nghệ An",
|
| 70 |
+
"naturalArea": "16.486,5",
|
| 71 |
+
"population": "3.442",
|
| 72 |
+
"coords": "372,507,365,496,375,484,389,485,414,494,410,507,426,532,426,541,435,539,441,547,454,547,472,568,488,571,482,578,482,593,469,598,469,611,478,623,487,644,475,650,475,659,454,655,445,655,426,653,416,653,410,643,389,638,362,632,341,613,329,607,311,592,286,578,279,580,262,568,274,557,286,556,289,547,289,536,277,524,292,523,308,519,320,522,332,527,347,528,353,519"
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"name": "Hà Tĩnh",
|
| 76 |
+
"mergedName": "Hà Tĩnh",
|
| 77 |
+
"center": "Hà Tĩnh",
|
| 78 |
+
"naturalArea": "5.994,4",
|
| 79 |
+
"population": "1.323,7",
|
| 80 |
+
"coords": "408,651,402,669,411,680,419,693,426,695,426,704,434,707,445,702,464,732,487,722,509,720,518,734,542,737,547,729,566,731,560,722,559,713,548,716,544,707,529,693,520,696,485,645,469,657"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"name": "Cao Bằng",
|
| 84 |
+
"mergedName": "Cao Bằng",
|
| 85 |
+
"center": "Cao Bằng",
|
| 86 |
+
"naturalArea": "6.700,4",
|
| 87 |
+
"population": "547,9",
|
| 88 |
+
"coords": "428,127,448,138,458,156,475,144,481,147,485,168,497,172,517,168,521,177,530,183,539,175,551,184,568,184,574,165,578,153,585,159,600,133,563,115,547,126,533,112,512,112,493,118,472,100,457,96"
|
| 89 |
+
},
|
| 90 |
+
|
| 91 |
+
{
|
| 92 |
+
"name": { "1": "Tuyên Quang", "2": "Hà Giang" },
|
| 93 |
+
"naturalArea": { "1": "5.867,9", "2": "7.927,5" },
|
| 94 |
+
"population": { "1": "812,2", "2": "899,9" },
|
| 95 |
+
"mergedName": "Tuyên Quang",
|
| 96 |
+
"center": "Tuyên Quang",
|
| 97 |
+
"coords": "321,146,340,131,360,132,373,120,369,99,378,96,376,86,385,90,400,80,417,78,420,71,427,66,447,78,459,102,429,126,449,138,465,177,447,203,458,239,452,271,459,293,449,296,433,298,407,268,384,224,364,209,358,201,348,204,345,191,334,183,327,165,333,162"
|
| 98 |
+
},
|
| 99 |
+
{
|
| 100 |
+
"name": { "1": "Lào Cai", "2": "Yên Bái" },
|
| 101 |
+
"naturalArea": { "1": "6.364,2", "2": "6.892,7" },
|
| 102 |
+
"population": { "1": "779,9", "2": "855,5" },
|
| 103 |
+
"mergedName": "Lào Cai",
|
| 104 |
+
"center": "Yên Bái",
|
| 105 |
+
"coords": "231,231,234,214,248,202,253,190,247,179,232,180,234,166,226,152,239,134,258,156,275,170,282,148,292,134,307,133,318,148,332,159,333,185,346,192,346,205,359,201,369,213,392,236,403,259,405,270,385,283,381,294,384,307,372,315,361,307,349,305,334,315,314,300,318,271,302,274,271,269,248,254"
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"name": { "1": "Bắc Kạn", "2": "Thái Nguyên" },
|
| 109 |
+
"naturalArea": { "1": "4.860", "2": "3.522" },
|
| 110 |
+
"population": { "1": "326,5", "2": "1.350,3" },
|
| 111 |
+
"mergedName": "Thái Nguyên",
|
| 112 |
+
"center": "Thái Nguyên",
|
| 113 |
+
"coords": "459,184,450,199,451,221,459,240,454,263,451,279,459,290,481,311,498,318,504,306,514,302,514,284,525,281,528,293,537,275,528,260,522,242,520,227,534,213,538,201,531,183,523,177,520,168,507,168,490,169,480,157,480,145,466,153,459,159"
|
| 114 |
+
},
|
| 115 |
+
{
|
| 116 |
+
"name": { "1": "Vĩnh Phúc", "2": "Phú Thọ", "3": "Hoà Bình" },
|
| 117 |
+
"naturalArea": { "1": "1.236", "2": "3.534,6", "3":"4.590,3" },
|
| 118 |
+
"population": { "1": "1.211,3", "2": "1.530,8","3":"880,5" },
|
| 119 |
+
"mergedName": "Phú Thọ",
|
| 120 |
+
"center": "Phú Thọ",
|
| 121 |
+
"coords":"408,408,395,409,374,405,376,391,392,390,403,382,379,358,382,348,374,321,382,310,379,295,382,281,408,272,429,293,444,296,459,290,483,311,483,336,481,346,468,336,451,336,444,324,436,316,429,328,427,340,426,354,444,358,451,364,451,376,463,390,469,402,483,411,490,430,483,424,475,429,475,438,462,432,453,435,430,427"
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"name": { "1": "Bắc Ninh", "2": "Bắc Giang" },
|
| 125 |
+
"naturalArea": { "1": "822,7", "2": "3.895,9" },
|
| 126 |
+
"population": { "1": "1517,4", "2": "1922,7" },
|
| 127 |
+
"mergedName": "Bắc Ninh",
|
| 128 |
+
"center": "Bắc Giang",
|
| 129 |
+
"coords":"508,359,523,359,541,361,544,352,544,341,549,332,564,329,571,334,579,334,592,334,602,335,614,335,621,329,626,319,629,310,623,301,608,287,597,292,588,284,577,284,568,292,562,304,552,305,544,301,531,293,525,280,514,283,517,298,504,308,499,317,504,328,501,337,505,349"
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"name": { "1": "Hưng Yên", "2": "Thái Bình" },
|
| 133 |
+
"naturalArea": { "1": "930,2", "2": "1.584,6" },
|
| 134 |
+
"population": { "1": "1.301", "2": "1.882,3" },
|
| 135 |
+
"mergedName": "Hưng Yên",
|
| 136 |
+
"center": "Hưng Yên",
|
| 137 |
+
"coords":"523,405,529,417,535,424,541,432,541,441,549,435,559,444,570,441,576,448,574,433,574,420,576,409,564,403,558,396,540,396,531,388,523,377,528,365,517,358,504,362,501,376,501,385,508,393,514,400"
|
| 138 |
+
},
|
| 139 |
+
{
|
| 140 |
+
"name": { "1": "Hải Dương", "2": "TP Hải Phòng" },
|
| 141 |
+
"naturalArea": { "1": "1.668,3", "2": "1.526,5" },
|
| 142 |
+
"population": { "1": "1.956,9", "2": "2105" },
|
| 143 |
+
"mergedName": "Thành phố Hải Phòng",
|
| 144 |
+
"center": "Thành phố Hải Phòng",
|
| 145 |
+
"coords":"537,395,529,388,522,379,528,370,526,359,538,361,546,355,544,343,550,334,561,331,574,335,558,346,571,353,580,356,594,367,591,383,598,391,583,394,591,401,583,404,570,401,558,392,547,394"
|
| 146 |
+
},
|
| 147 |
+
{
|
| 148 |
+
"name": { "1": "Hà Nam", "2": "Ninh Bình", "3": "Nam Định" },
|
| 149 |
+
"naturalArea": { "1": "861,9", "2": "1.411,8", "3": "1.668,8" },
|
| 150 |
+
"population": { "1": "885,9", "2": "1.017,1", "3":"1.887,1" },
|
| 151 |
+
"mergedName": "Ninh Bình",
|
| 152 |
+
"center": "Ninh Bình",
|
| 153 |
+
"coords":"474,452,495,467,505,472,516,475,519,485,528,484,537,476,546,467,553,454,564,454,574,454,567,445,558,445,550,437,541,440,534,433,531,422,526,413,522,404,510,395,495,399,484,408,490,428,475,431,475,440,459,437"
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"name": { "1": "Quảng Bình", "2": "Quảng Trị" },
|
| 157 |
+
"naturalArea": { "1": "7.998,8", "2": "4.701,2" },
|
| 158 |
+
"population": { "1": "918,7", "2": "654,2" },
|
| 159 |
+
"mergedName": "Quảng Trị",
|
| 160 |
+
"center": "Quảng Bình",
|
| 161 |
+
"coords":"463,731,472,730,483,724,495,721,508,721,519,733,532,736,544,736,553,731,571,733,558,743,562,760,577,785,586,798,602,811,624,828,636,838,647,859,672,880,662,892,635,900,644,910,630,927,623,931,614,924,609,907,595,913,585,915,585,897,576,892,571,883,571,849,558,849,553,838,543,826,543,811,534,814,522,808,504,792,493,776,478,767,465,745"
|
| 162 |
+
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"name": { "1": "Quảng Nam", "2": "TP Đà Nẵng" },
|
| 166 |
+
"naturalArea": { "1": "10.574,9", "2": "1.284,7" },
|
| 167 |
+
"population": { "1": "1.526,1", "2": "1.245,2" },
|
| 168 |
+
"mergedName": "Đà Nẵng",
|
| 169 |
+
"center": "Thành phố Đà Nẵng",
|
| 170 |
+
"coords":"650,985,665,979,674,969,689,961,699,958,710,966,717,958,725,958,729,945,743,943,753,952,767,964,774,975,788,984,795,1003,811,1024,820,1032,827,1041,815,1042,795,1048,780,1051,770,1066,777,1078,765,1078,755,1092,747,1071,738,1062,726,1060,710,1051,699,1039,683,1038,677,1024,666,1029,654,1012,642,996"
|
| 171 |
+
},
|
| 172 |
+
{
|
| 173 |
+
"name": { "1": "Kon Tum", "2": "Quảng Ngãi" },
|
| 174 |
+
"naturalArea": { "1": "9.677,3", "2": "5.155,2" },
|
| 175 |
+
"population": { "1": "591,3", "2": "1.248,1" },
|
| 176 |
+
"mergedName": "Quảng Ngãi",
|
| 177 |
+
"center": "Quảng Ngãi",
|
| 178 |
+
"coords":"675,1219,690,1208,701,1193,716,1181,741,1175,767,1163,782,1149,786,1134,798,1134,811,1131,817,1136,832,1128,862,1127,859,1112,848,1086,844,1071,850,1058,842,1050,836,1038,832,1047,812,1044,788,1050,773,1067,779,1077,764,1080,758,1091,749,1082,749,1073,738,1067,726,1064,716,1055,705,1046,692,1043,702,1062,689,1082,678,1086,689,1100,681,1110,686,1124,678,1157,668,1157,665,1171,660,1193,666,1205"
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
+
"name": { "1": "Gia Lai", "2": "Bình Định" },
|
| 182 |
+
"naturalArea": { "1": "15.510,1", "2": "6.066,4" },
|
| 183 |
+
"population": { "1": "1.613,9", "2": "1.506,3" },
|
| 184 |
+
"mergedName": "Gia Lai",
|
| 185 |
+
"center": "Bình Định",
|
| 186 |
+
"coords": "677,1219,691,1207,698,1192,711,1184,727,1181,745,1172,762,1166,774,1160,781,1151,790,1134,802,1134,813,1133,828,1133,840,1127,852,1128,863,1128,867,1146,872,1164,879,1177,881,1189,887,1210,891,1222,888,1232,884,1243,872,1247,866,1258,851,1261,835,1261,838,1283,841,1302,823,1315,816,1327,804,1323,795,1315,789,1300,774,1286,754,1283,741,1282,721,1285,701,1288,686,1294,697,1270,692,1255,682,1240,676,1231"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"name": { "1": "Ninh Thuận", "2": "Khánh Hoà" },
|
| 190 |
+
"naturalArea": { "1": "3.355,7", "2": "5.199,6" },
|
| 191 |
+
"population": { "1": "601,2", "2": "1.260,6" },
|
| 192 |
+
"mergedName": "Khánh Hoà",
|
| 193 |
+
"center": "Khánh Hoà",
|
| 194 |
+
"coords": "811,1489,820,1481,814,1468,819,1450,820,1433,825,1424,820,1412,816,1399,819,1389,829,1386,837,1391,841,1374,848,1364,860,1358,876,1346,897,1349,885,1362,879,1374,878,1383,888,1388,896,1397,878,1394,881,1411,881,1432,881,1450,869,1466,882,1474,872,1495,861,1489,860,1519,848,1527,841,1517,832,1516,826,1504,817,1496"
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"name": { "1": "Lâm Đồng", "2": "Đắk Nông", "3": "Bình Thuận"},
|
| 198 |
+
"naturalArea": { "1": "9.781,2", "2": "6.509,3", "3":"7.942,6"},
|
| 199 |
+
"population": { "1": "1.345,0", "2": "681,9", "3":"1.258,8"},
|
| 200 |
+
"mergedName": "Lâm Đồng",
|
| 201 |
+
"center": "Lâm Đồng",
|
| 202 |
+
"coords": "650,1411,652,1431,655,1443,667,1455,671,1473,661,1482,659,1497,671,1497,679,1506,677,1515,694,1521,685,1539,676,1561,683,1564,692,1582,685,1595,691,1615,711,1606,729,1598,739,1598,744,1577,765,1571,775,1576,781,1564,795,1558,799,1545,819,1541,828,1530,845,1526,840,1517,829,1517,823,1505,811,1497,810,1485,819,1478,814,1466,819,1446,819,1428,819,1411,808,1413,793,1414,780,1417,766,1428,756,1425,744,1410,732,1398,741,1389,727,1378,720,1359,686,1362,688,1389,682,1407,674,1414,661,1405"
|
| 203 |
+
},
|
| 204 |
+
{
|
| 205 |
+
"name": { "1": "Đắk Lắk", "2": "Phú Yên" },
|
| 206 |
+
"naturalArea": { "1": "13.070,4", "2": "5.026,0"},
|
| 207 |
+
"population": { "1": "1.931,5", "2": "877,7"},
|
| 208 |
+
"mergedName": "Đắk Lắk",
|
| 209 |
+
"center": "Đắk Lắk",
|
| 210 |
+
"coords":"834,1263,834,1276,840,1300,828,1312,817,1329,796,1320,790,1306,777,1290,751,1281,732,1287,711,1287,689,1294,677,1323,683,1344,686,1359,723,1359,726,1376,741,1388,733,1406,747,1412,754,1425,765,1428,774,1418,786,1416,799,1412,817,1412,816,1397,817,1388,835,1391,843,1371,863,1358,878,1346,897,1346,909,1344,906,1332,890,1312,891,1297,881,1281,890,1269,882,1245,870,1252,861,1258,845,1261"
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"name": {
|
| 214 |
+
"1": "Bà Rịa - Vũng Tàu",
|
| 215 |
+
"2": "Bình Dương",
|
| 216 |
+
"3": "TP Hồ Chí Minh"
|
| 217 |
+
},
|
| 218 |
+
"naturalArea": { "1": "1.982,6", "2": "2.694,6", "3":"2.095,4"},
|
| 219 |
+
"population": { "1": "1.187,5", "2": "2.823,4", "3":"9.456,7"},
|
| 220 |
+
"mergedName": "Thành Phố Hồ Chí Minh",
|
| 221 |
+
"center": "Thành Phố Hồ Chí Minh",
|
| 222 |
+
"coords":"551,1566,555,1559,560,1550,551,1538,548,1522,554,1509,562,1500,568,1507,581,1515,580,1527,589,1522,596,1530,620,1531,617,1542,620,1550,610,1560,599,1562,601,1572,611,1590,595,1593,601,1602,613,1607,619,1614,628,1608,638,1605,643,1598,656,1593,659,1602,668,1599,679,1589,685,1595,691,1613,680,1620,665,1625,655,1637,646,1632,635,1641,640,1623,629,1625,617,1625,622,1634,613,1637,601,1629,599,1610,590,1601,577,1602,568,1595,572,1581,563,1571"
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"name": { "1": "Đồng Nai", "2": "Bình Phước" },
|
| 226 |
+
"naturalArea": { "1": "5.863,6", "2": "6.873,6"},
|
| 227 |
+
"population": { "1": "3.310,9", "2": "1.045,5"},
|
| 228 |
+
"mergedName": "Đồng Nai",
|
| 229 |
+
"center": "Đồng Nai",
|
| 230 |
+
"coords":"652,1411,652,1433,655,1448,665,1456,671,1474,659,1481,655,1490,662,1498,670,1501,677,1511,694,1522,674,1563,688,1566,692,1581,685,1593,677,1587,667,1600,658,1593,646,1593,637,1602,619,1614,613,1603,596,1599,611,1591,607,1579,601,1563,610,1561,623,1554,617,1539,620,1528,601,1524,590,1522,581,1527,580,1514,563,1501,565,1490,554,1474,558,1463,554,1448,568,1450,587,1450,598,1439,617,1438,635,1418"
|
| 231 |
+
},
|
| 232 |
+
{
|
| 233 |
+
"name": { "1": "Tây Ninh", "2": "Long An" },
|
| 234 |
+
"naturalArea": { "1": "4.041,7", "2": "4.494,8"},
|
| 235 |
+
"population": { "1": "1.194,9", "2": "1.743,4"},
|
| 236 |
+
"mergedName": "Tây Ninh",
|
| 237 |
+
"center": "Long An",
|
| 238 |
+
"coords":"455,1572,477,1596,492,1610,504,1617,518,1617,528,1611,542,1611,549,1623,558,1625,562,1632,572,1632,581,1626,593,1620,592,1605,575,1604,566,1596,569,1581,563,1571,549,1565,558,1551,548,1534,548,1518,562,1501,562,1486,540,1485,524,1477,510,1473,501,1489,485,1492,492,1512,489,1528,506,1542,518,1559,530,1565,521,1569,530,1592,512,1589,501,1575,495,1584,480,1565,464,1569"
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"name": { "1": "Cần Thơ", "2": "Sóc Trăng", "3": "Hậu Giang" },
|
| 242 |
+
"naturalArea": { "1": "1.440,4","2":"3.298,2", "3": "1.622,2"},
|
| 243 |
+
"population": { "1": "1.258,9", "2":"1.198,8","3": "728,3"},
|
| 244 |
+
"mergedName": "Cần Thơ",
|
| 245 |
+
"center": "Cần Thơ",
|
| 246 |
+
"coords":"440,1711,450,1703,455,1691,444,1678,420,1659,428,1649,434,1655,446,1652,458,1631,471,1635,483,1644,500,1658,489,1666,479,1659,473,1667,491,1682,497,1696,516,1712,530,1736,530,1753,513,1759,491,1769,489,1754,479,1751,462,1751,461,1726,440,1729,434,1718"
|
| 247 |
+
},
|
| 248 |
+
{
|
| 249 |
+
"name": { "1": "Bến Tre", "2": "Vĩnh Long", "3": "Trà Vinh" },
|
| 250 |
+
"naturalArea": { "1": "2.379,7", "2": "1.525,7", "3":"2.390,8"},
|
| 251 |
+
"population": { "1": "1.299,3", "2": "1.029,6", "3":"1.019,9"},
|
| 252 |
+
"mergedName": "Vĩnh Long",
|
| 253 |
+
"center": "Vĩnh Long",
|
| 254 |
+
"coords":"474,1669,489,1683,500,1687,509,1696,522,1711,537,1726,552,1734,568,1732,574,1723,575,1713,565,1704,551,1690,537,1675,522,1656,533,1665,548,1678,562,1690,572,1699,580,1704,589,1695,577,1684,589,1675,601,1669,593,1659,557,1648,548,1644,527,1645,513,1644,501,1648,492,1647,500,1657,489,1663,479,1659"
|
| 255 |
+
},
|
| 256 |
+
{
|
| 257 |
+
"name": { "1": "Tiền Giang", "2": "Đồng Tháp" },
|
| 258 |
+
"naturalArea": { "1": "2.556,4", "2": "3.382,3"},
|
| 259 |
+
"population": { "1": "1.790,7", "2": "1.600,2"},
|
| 260 |
+
"mergedName": "Đồng Tháp",
|
| 261 |
+
"center": "Tiền Giang",
|
| 262 |
+
"coords":"440,1614,437,1601,428,1598,422,1590,417,1576,429,1581,443,1569,455,1572,474,1596,485,1607,503,1617,516,1617,525,1611,539,1613,548,1622,558,1626,558,1635,574,1634,583,1626,595,1629,599,1647,560,1644,548,1641,534,1646,524,1649,512,1643,504,1647,494,1646,482,1644,474,1632,461,1631,453,1620"
|
| 263 |
+
},
|
| 264 |
+
{
|
| 265 |
+
"name": { "1": "Bạc Liêu", "2": "Cà Mau" },
|
| 266 |
+
"naturalArea": { "1": "2.667,9", "2": "5.274,5"},
|
| 267 |
+
"population": { "1": "925,2", "2": "1.207,4"},
|
| 268 |
+
"mergedName": "Cà Mau",
|
| 269 |
+
"center": "Cà Mau",
|
| 270 |
+
"coords":"373,1739,373,1760,372,1784,372,1798,366,1818,382,1821,378,1828,382,1836,364,1843,373,1848,385,1845,397,1843,405,1837,411,1827,422,1827,428,1815,435,1806,444,1797,452,1786,464,1781,479,1774,492,1769,491,1756,477,1754,465,1751,458,1742,458,1730,440,1729,428,1730,429,1738,428,1751,414,1745,405,1741,396,1736,387,1738"
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"name": { "1": "An Giang", "2": "Kiên Giang" },
|
| 274 |
+
"naturalArea": { "1": "3.536,8", "2": "6.352"},
|
| 275 |
+
"population": { "1": "1.906,3", "2": "1.755,3"},
|
| 276 |
+
"mergedName": "An Giang",
|
| 277 |
+
"center": "Kiên Giang",
|
| 278 |
+
"coords":"371,1739,370,1725,374,1707,377,1699,385,1701,400,1690,403,1698,400,1674,383,1669,374,1662,361,1656,352,1662,343,1651,335,1638,335,1626,344,1623,359,1621,370,1621,379,1614,388,1605,398,1600,392,1584,398,1571,413,1579,421,1594,427,1600,435,1600,436,1612,448,1621,459,1630,450,1639,447,1647,438,1651,427,1648,416,1659,427,1665,438,1678,450,1690,447,1703,433,1719,435,1730,426,1743,424,1752,415,1748,397,1736"
|
| 279 |
+
}
|
| 280 |
+
]
|
script.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const canvas = document.getElementById('mapCanvas');
|
| 2 |
+
const ctx = canvas.getContext('2d');
|
| 3 |
+
|
| 4 |
+
const img = document.querySelector('.map-container img');
|
| 5 |
+
canvas.width = img.clientWidth;
|
| 6 |
+
canvas.height = img.clientHeight;
|
| 7 |
+
|
| 8 |
+
const mapElement = document.getElementById('vietnam-map');
|
| 9 |
+
|
| 10 |
+
let areas = [];
|
| 11 |
+
let locationsData = [];
|
| 12 |
+
|
| 13 |
+
fetch('provinces.json')
|
| 14 |
+
.then(response => {
|
| 15 |
+
if (!response.ok) {
|
| 16 |
+
throw new Error('Network response was not ok');
|
| 17 |
+
}
|
| 18 |
+
return response.json();
|
| 19 |
+
})
|
| 20 |
+
.then(data => {
|
| 21 |
+
locationsData = data;
|
| 22 |
+
areas = locationsData.map(location => {
|
| 23 |
+
if (!location.coords) {
|
| 24 |
+
console.error('Missing coords for location:', location);
|
| 25 |
+
return { coords: [], shape: 'poly' };
|
| 26 |
+
}
|
| 27 |
+
const coords = location.coords.split(',').map(Number);
|
| 28 |
+
const shape = 'poly';
|
| 29 |
+
return { coords, shape };
|
| 30 |
+
});
|
| 31 |
+
createMapAreas();
|
| 32 |
+
})
|
| 33 |
+
.catch(error => {
|
| 34 |
+
console.error('Error loading the JSON file:', error);
|
| 35 |
+
});
|
| 36 |
+
|
| 37 |
+
function updateCanvasSize() {
|
| 38 |
+
// Cập nhật kích thước canvas theo kích thước thực của ảnh
|
| 39 |
+
canvas.width = img.offsetWidth;
|
| 40 |
+
canvas.height = img.offsetHeight;
|
| 41 |
+
canvas.style.width = `${img.offsetWidth}px`;
|
| 42 |
+
canvas.style.height = `${img.offsetHeight}px`;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
// Sửa lại event listener resize
|
| 46 |
+
window.addEventListener('resize', () => {
|
| 47 |
+
updateCanvasSize();
|
| 48 |
+
createMapAreas();
|
| 49 |
+
});
|
| 50 |
+
|
| 51 |
+
// Thêm vào sau khi ảnh đã load
|
| 52 |
+
img.addEventListener('load', () => {
|
| 53 |
+
updateCanvasSize();
|
| 54 |
+
createMapAreas();
|
| 55 |
+
});
|
| 56 |
+
|
| 57 |
+
// Sửa lại hàm createMapAreas
|
| 58 |
+
function createMapAreas() {
|
| 59 |
+
mapElement.innerHTML = '';
|
| 60 |
+
const scaleX = img.offsetWidth / img.naturalWidth;
|
| 61 |
+
const scaleY = img.offsetHeight / img.naturalHeight;
|
| 62 |
+
|
| 63 |
+
areas.forEach((area) => {
|
| 64 |
+
const scaledCoords = area.coords.map((val, index) => {
|
| 65 |
+
return index % 2 === 0
|
| 66 |
+
? Math.round(val * scaleX)
|
| 67 |
+
: Math.round(val * scaleY);
|
| 68 |
+
});
|
| 69 |
+
|
| 70 |
+
const areaElement = document.createElement('area');
|
| 71 |
+
areaElement.setAttribute('shape', area.shape);
|
| 72 |
+
areaElement.setAttribute('coords', scaledCoords.join(','));
|
| 73 |
+
areaElement.setAttribute('href', 'javascript:void(0)');
|
| 74 |
+
mapElement.appendChild(areaElement);
|
| 75 |
+
});
|
| 76 |
+
|
| 77 |
+
setupEventListeners();
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
const drawOutline = (coords) => {
|
| 81 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 82 |
+
ctx.beginPath();
|
| 83 |
+
const scaleX = canvas.width / img.naturalWidth;
|
| 84 |
+
const scaleY = canvas.height / img.naturalHeight;
|
| 85 |
+
|
| 86 |
+
ctx.moveTo(coords[0] * scaleX, coords[1] * scaleY);
|
| 87 |
+
for (let i = 2; i < coords.length; i += 2) {
|
| 88 |
+
ctx.lineTo(coords[i] * scaleX, coords[i + 1] * scaleY);
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
ctx.closePath();
|
| 92 |
+
|
| 93 |
+
// Thêm fill màu da cam nhạt
|
| 94 |
+
ctx.fillStyle = 'rgba(255, 165, 0, 0.3)'; // Màu da cam với độ trong suốt 0.3
|
| 95 |
+
ctx.fill();
|
| 96 |
+
|
| 97 |
+
// Vẽ viền đỏ
|
| 98 |
+
ctx.strokeStyle = 'red';
|
| 99 |
+
ctx.lineWidth = 2;
|
| 100 |
+
ctx.stroke();
|
| 101 |
+
};
|
| 102 |
+
|
| 103 |
+
const clearOutline = () => {
|
| 104 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 105 |
+
};
|
| 106 |
+
|
| 107 |
+
// Tooltip functionality
|
| 108 |
+
const tooltip = document.querySelector('.tooltip-box');
|
| 109 |
+
|
| 110 |
+
const showTooltip = (data, event) => {
|
| 111 |
+
tooltip.style.display = 'block';
|
| 112 |
+
|
| 113 |
+
let nameText = '';
|
| 114 |
+
let areaText = '';
|
| 115 |
+
let areaTotal = 0;
|
| 116 |
+
let popText = '';
|
| 117 |
+
let popTotal = 0;
|
| 118 |
+
|
| 119 |
+
if (typeof data.name === 'object' && Object.keys(data.name).length > 1) {
|
| 120 |
+
// Gộp tên
|
| 121 |
+
nameText = Object.values(data.name).join(' + ');
|
| 122 |
+
|
| 123 |
+
// Diện tích
|
| 124 |
+
for (const key in data.naturalArea) {
|
| 125 |
+
const value = parseFloat(data.naturalArea[key].replace('.', '').replace(',', '.'));
|
| 126 |
+
areaText += `<p>${data.name[key]}: ${data.naturalArea[key]}</p>`;
|
| 127 |
+
areaTotal += value;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
// Dân số
|
| 131 |
+
for (const key in data.population) {
|
| 132 |
+
const value = parseFloat(data.population[key].replace('.', '').replace(',', '.'));
|
| 133 |
+
popText += `<p>${data.name[key]}: ${data.population[key]}</p>`;
|
| 134 |
+
popTotal += value;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
tooltip.innerHTML = `
|
| 138 |
+
<h2>${nameText}</h2>
|
| 139 |
+
<hr>
|
| 140 |
+
<h3>DIỆN TÍCH TỰ NHIÊN (KM²)</h3>
|
| 141 |
+
${areaText}
|
| 142 |
+
<p><strong>Tổng diện tích:</strong> ${areaTotal.toLocaleString('vi-VN')}</p>
|
| 143 |
+
<hr>
|
| 144 |
+
<h3>QUY MÔ DÂN SỐ (NGHÌN NGƯỜI)</h3>
|
| 145 |
+
${popText}
|
| 146 |
+
<p><strong>Tổng dân số:</strong> ${popTotal.toLocaleString('vi-VN')}</p>
|
| 147 |
+
<hr>
|
| 148 |
+
<p>Tên tỉnh, thành sau sáp nhập: <span class="highlight">${data.mergedName}</span></p>
|
| 149 |
+
<p>Trung tâm chính trị - hành chính: <span class="highlight">${data.center}</span></p>
|
| 150 |
+
`;
|
| 151 |
+
} else {
|
| 152 |
+
// Trường hợp chỉ có 1 tỉnh
|
| 153 |
+
tooltip.innerHTML = `
|
| 154 |
+
<h2>${data.name}</h2>
|
| 155 |
+
<hr>
|
| 156 |
+
<h3>DIỆN TÍCH TỰ NHIÊN (KM²)</h3>
|
| 157 |
+
<p>${data.name}: ${data.naturalArea}</p>
|
| 158 |
+
<p><strong>Tổng diện tích:</strong> ${data.naturalArea}</p>
|
| 159 |
+
<hr>
|
| 160 |
+
<h3>QUY MÔ DÂN SỐ (NGHÌN NGƯỜI)</h3>
|
| 161 |
+
<p>${data.name}: ${data.population}</p>
|
| 162 |
+
<p><strong>Tổng dân số:</strong> ${data.population}</p>
|
| 163 |
+
<hr>
|
| 164 |
+
<!-- <p>Tên tỉnh, thành sau sáp nhập: <span class="highlight">${data.mergedName}</span></p>
|
| 165 |
+
<p>Trung tâm chính trị - hành chính: <span class="highlight">${data.center}</span></p>
|
| 166 |
+
-->
|
| 167 |
+
`;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
// Hiện tooltip trước để lấy kích thước thực
|
| 171 |
+
tooltip.style.visibility = 'hidden';
|
| 172 |
+
tooltip.style.display = 'block';
|
| 173 |
+
|
| 174 |
+
const tooltipWidth = tooltip.offsetWidth;
|
| 175 |
+
const tooltipHeight = tooltip.offsetHeight;
|
| 176 |
+
|
| 177 |
+
// Lấy kích thước và vị trí của viewport
|
| 178 |
+
const viewportWidth = window.innerWidth;
|
| 179 |
+
const viewportHeight = window.innerHeight;
|
| 180 |
+
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
| 181 |
+
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
|
| 182 |
+
|
| 183 |
+
// Tính toán vị trí tốt nhất cho tooltip
|
| 184 |
+
let left = event.pageX + 10;
|
| 185 |
+
let top = event.pageY + 10;
|
| 186 |
+
|
| 187 |
+
// Kiểm tra và điều chỉnh vị trí ngang
|
| 188 |
+
if (left + tooltipWidth > viewportWidth + scrollLeft) {
|
| 189 |
+
left = event.pageX - tooltipWidth - 10;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
// Kiểm tra và điều chỉnh vị trí dọc
|
| 193 |
+
if (top + tooltipHeight > viewportHeight + scrollTop) {
|
| 194 |
+
top = event.pageY - tooltipHeight - 10;
|
| 195 |
+
|
| 196 |
+
// Nếu vẫn vượt quá phía trên viewport
|
| 197 |
+
if (top < scrollTop) {
|
| 198 |
+
// Đặt tooltip ở giữa màn hình theo chiều dọc
|
| 199 |
+
top = scrollTop + (viewportHeight - tooltipHeight) / 2;
|
| 200 |
+
}
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
// Đảm bảo tooltip không bị cắt ở các cạnh
|
| 204 |
+
left = Math.max(scrollLeft + 10, Math.min(left, viewportWidth + scrollLeft - tooltipWidth - 10));
|
| 205 |
+
top = Math.max(scrollTop + 10, Math.min(top, viewportHeight + scrollTop - tooltipHeight - 10));
|
| 206 |
+
|
| 207 |
+
// Áp dụng vị trí và hiện tooltip
|
| 208 |
+
tooltip.style.left = `${left}px`;
|
| 209 |
+
tooltip.style.top = `${top}px`;
|
| 210 |
+
tooltip.style.visibility = 'visible';
|
| 211 |
+
tooltip.classList.add('active');
|
| 212 |
+
};
|
| 213 |
+
|
| 214 |
+
// Thêm event listener cho viewport resize
|
| 215 |
+
window.addEventListener('resize', () => {
|
| 216 |
+
if (tooltip.classList.contains('active')) {
|
| 217 |
+
tooltip.classList.remove('active');
|
| 218 |
+
}
|
| 219 |
+
});
|
| 220 |
+
|
| 221 |
+
const hideTooltip = () => {
|
| 222 |
+
tooltip.classList.remove('active');
|
| 223 |
+
};
|
| 224 |
+
|
| 225 |
+
function setupEventListeners() {
|
| 226 |
+
document.querySelectorAll('area').forEach((area, index) => {
|
| 227 |
+
area.addEventListener('mouseenter', () => {
|
| 228 |
+
drawOutline(areas[index].coords);
|
| 229 |
+
});
|
| 230 |
+
area.addEventListener('mouseleave', clearOutline);
|
| 231 |
+
|
| 232 |
+
area.addEventListener('mouseenter', (event) => {
|
| 233 |
+
showTooltip(locationsData[index], event);
|
| 234 |
+
});
|
| 235 |
+
area.addEventListener('mousemove', (event) => {
|
| 236 |
+
// Chỉ cập nhật vị trí nếu tooltip không bị overflow
|
| 237 |
+
const tooltipRect = tooltip.getBoundingClientRect();
|
| 238 |
+
const viewportHeight = window.innerHeight;
|
| 239 |
+
const viewportWidth = window.innerWidth;
|
| 240 |
+
|
| 241 |
+
// Chỉ di chuyển tooltip theo chuột khi có đủ không gian
|
| 242 |
+
if (tooltipRect.width + event.clientX < viewportWidth &&
|
| 243 |
+
tooltipRect.height + event.clientY < viewportHeight) {
|
| 244 |
+
tooltip.style.left = `${event.pageX + 10}px`;
|
| 245 |
+
tooltip.style.top = `${event.pageY + 10}px`;
|
| 246 |
+
}
|
| 247 |
+
});
|
| 248 |
+
area.addEventListener('mouseleave', hideTooltip);
|
| 249 |
+
});
|
| 250 |
+
|
| 251 |
+
document.addEventListener('mousemove', (event) => {
|
| 252 |
+
if (!event.target.closest('area') && !tooltip.contains(event.target)) {
|
| 253 |
+
tooltip.style.display = 'none';
|
| 254 |
+
tooltip.innerHTML = '';
|
| 255 |
+
}
|
| 256 |
+
});
|
| 257 |
+
}
|
style.css
CHANGED
|
@@ -1,28 +1,132 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.container {
|
| 2 |
+
width: 100%;
|
| 3 |
+
display: flex;
|
| 4 |
+
justify-content: center;
|
| 5 |
+
align-items: center;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
.map-container {
|
| 9 |
+
position: relative;
|
| 10 |
+
width: 100%;
|
| 11 |
+
max-width: 1000px;
|
| 12 |
+
/* hoặc kích thước tối đa mong muốn */
|
| 13 |
+
margin: 0 auto;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.map-container img,
|
| 17 |
+
#mapCanvas {
|
| 18 |
+
width: 100%;
|
| 19 |
+
height: auto;
|
| 20 |
+
display: block;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
.map-container img {
|
| 24 |
+
width: 100%;
|
| 25 |
+
height: auto;
|
| 26 |
+
display: block;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
#mapCanvas {
|
| 30 |
+
position: absolute;
|
| 31 |
+
top: 0;
|
| 32 |
+
left: 0;
|
| 33 |
+
width: 100%;
|
| 34 |
+
height: 100%;
|
| 35 |
+
pointer-events: none;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
#vietnam-map {
|
| 39 |
+
width: 100%;
|
| 40 |
+
height: 100%;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
.tooltip-box {
|
| 44 |
+
width: 30vw;
|
| 45 |
+
min-width: 200px;
|
| 46 |
+
max-width: 350px;
|
| 47 |
+
background-color: #f0f8ff;
|
| 48 |
+
opacity: 0.9;
|
| 49 |
+
border-radius: 12px;
|
| 50 |
+
padding: 10px;
|
| 51 |
+
font-family: 'Segoe UI', sans-serif;
|
| 52 |
+
color: #1a1a1a;
|
| 53 |
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
| 54 |
+
display: none;
|
| 55 |
+
position: absolute;
|
| 56 |
+
text-align: center;
|
| 57 |
+
z-index: 1000;
|
| 58 |
+
transition: left 0.1s ease-out, top 0.1s ease-out;
|
| 59 |
+
pointer-events: none;
|
| 60 |
+
max-height: 80vh;
|
| 61 |
+
overflow-y: auto;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.tooltip-box.active {
|
| 65 |
+
display: block !important;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.tooltip-box h2 {
|
| 69 |
+
text-align: center;
|
| 70 |
+
color: #2b55b4;
|
| 71 |
+
font-size: 25px;
|
| 72 |
+
margin-bottom: 20px;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
.tooltip-box .highlight {
|
| 76 |
+
color: #2b55b4;
|
| 77 |
+
font-weight: bold;
|
| 78 |
+
font-size: 16px;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
.tooltip-box hr {
|
| 82 |
+
margin: 20px 0;
|
| 83 |
+
border: none;
|
| 84 |
+
border-top: 1px solid #ccc;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
/* Media queries cho điện thoại */
|
| 88 |
+
@media screen and (max-width: 768px) {
|
| 89 |
+
.tooltip-box {
|
| 90 |
+
width: 85vw;
|
| 91 |
+
/* Giảm xuống để phù hợp với màn hình điện thoại */
|
| 92 |
+
min-width: 150px;
|
| 93 |
+
max-width: 300px;
|
| 94 |
+
font-size: 14px;
|
| 95 |
+
padding: 8px;
|
| 96 |
+
max-height: 60vh;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
.tooltip-box h2 {
|
| 100 |
+
font-size: 16px;
|
| 101 |
+
margin-bottom: 10px;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
.tooltip-box h3 {
|
| 105 |
+
font-size: 14px;
|
| 106 |
+
margin: 8px 0;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.tooltip-box p {
|
| 110 |
+
margin: 5px 0;
|
| 111 |
+
font-size: 13px;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.tooltip-box hr {
|
| 115 |
+
margin: 5px 0;
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
.tooltip-box .highlight {
|
| 119 |
+
font-size: 13px;
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
/* Media queries cho điện thoại nhỏ hơn */
|
| 124 |
+
@media screen and (max-width: 375px) {
|
| 125 |
+
.tooltip-box {
|
| 126 |
+
width: 90vw;
|
| 127 |
+
min-width: 120px;
|
| 128 |
+
max-width: 250px;
|
| 129 |
+
font-size: 12px;
|
| 130 |
+
padding: 6px;
|
| 131 |
+
}
|
| 132 |
+
}
|
vietnam_map.jfif
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:966cbddf0bb4b28486b51b81f93df86c45a4f6addecc8d88ab3ca39a6cb6ac2a
|
| 3 |
+
size 140208
|