| 4 |
lars |
1 |
/*!
|
|
|
2 |
* JQVMap: jQuery Vector Map Library
|
|
|
3 |
* @author JQVMap <me@peterschmalfeldt.com>
|
|
|
4 |
* @version 1.5.1
|
|
|
5 |
* @link http://jqvmap.com
|
|
|
6 |
* @license https://github.com/manifestinteractive/jqvmap/blob/master/LICENSE
|
|
|
7 |
* @builddate 2016/06/02
|
|
|
8 |
*/
|
|
|
9 |
|
|
|
10 |
var VectorCanvas = function (width, height, params) {
|
|
|
11 |
this.mode = window.SVGAngle ? 'svg' : 'vml';
|
|
|
12 |
this.params = params;
|
|
|
13 |
|
|
|
14 |
if (this.mode === 'svg') {
|
|
|
15 |
this.createSvgNode = function (nodeName) {
|
|
|
16 |
return document.createElementNS(this.svgns, nodeName);
|
|
|
17 |
};
|
|
|
18 |
} else {
|
|
|
19 |
try {
|
|
|
20 |
if (!document.namespaces.rvml) {
|
|
|
21 |
document.namespaces.add('rvml', 'urn:schemas-microsoft-com:vml');
|
|
|
22 |
}
|
|
|
23 |
this.createVmlNode = function (tagName) {
|
|
|
24 |
return document.createElement('<rvml:' + tagName + ' class="rvml">');
|
|
|
25 |
};
|
|
|
26 |
} catch (e) {
|
|
|
27 |
this.createVmlNode = function (tagName) {
|
|
|
28 |
return document.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
|
|
|
29 |
};
|
|
|
30 |
}
|
|
|
31 |
|
|
|
32 |
document.createStyleSheet().addRule('.rvml', 'behavior:url(#default#VML)');
|
|
|
33 |
}
|
|
|
34 |
|
|
|
35 |
if (this.mode === 'svg') {
|
|
|
36 |
this.canvas = this.createSvgNode('svg');
|
|
|
37 |
} else {
|
|
|
38 |
this.canvas = this.createVmlNode('group');
|
|
|
39 |
this.canvas.style.position = 'absolute';
|
|
|
40 |
}
|
|
|
41 |
|
|
|
42 |
this.setSize(width, height);
|
|
|
43 |
};
|
|
|
44 |
|
|
|
45 |
VectorCanvas.prototype = {
|
|
|
46 |
svgns: 'http://www.w3.org/2000/svg',
|
|
|
47 |
mode: 'svg',
|
|
|
48 |
width: 0,
|
|
|
49 |
height: 0,
|
|
|
50 |
canvas: null
|
|
|
51 |
};
|
|
|
52 |
|
|
|
53 |
var ColorScale = function (colors, normalizeFunction, minValue, maxValue) {
|
|
|
54 |
if (colors) {
|
|
|
55 |
this.setColors(colors);
|
|
|
56 |
}
|
|
|
57 |
if (normalizeFunction) {
|
|
|
58 |
this.setNormalizeFunction(normalizeFunction);
|
|
|
59 |
}
|
|
|
60 |
if (minValue) {
|
|
|
61 |
this.setMin(minValue);
|
|
|
62 |
}
|
|
|
63 |
if (minValue) {
|
|
|
64 |
this.setMax(maxValue);
|
|
|
65 |
}
|
|
|
66 |
};
|
|
|
67 |
|
|
|
68 |
ColorScale.prototype = {
|
|
|
69 |
colors: []
|
|
|
70 |
};
|
|
|
71 |
|
|
|
72 |
var JQVMap = function (params) {
|
|
|
73 |
params = params || {};
|
|
|
74 |
var map = this;
|
|
|
75 |
var mapData = JQVMap.maps[params.map];
|
|
|
76 |
var mapPins;
|
|
|
77 |
|
|
|
78 |
if( !mapData){
|
|
|
79 |
throw new Error('Invalid "' + params.map + '" map parameter. Please make sure you have loaded this map file in your HTML.');
|
|
|
80 |
}
|
|
|
81 |
|
|
|
82 |
this.selectedRegions = [];
|
|
|
83 |
this.multiSelectRegion = params.multiSelectRegion;
|
|
|
84 |
|
|
|
85 |
this.container = params.container;
|
|
|
86 |
|
|
|
87 |
this.defaultWidth = mapData.width;
|
|
|
88 |
this.defaultHeight = mapData.height;
|
|
|
89 |
|
|
|
90 |
this.color = params.color;
|
|
|
91 |
this.selectedColor = params.selectedColor;
|
|
|
92 |
this.hoverColor = params.hoverColor;
|
|
|
93 |
this.hoverColors = params.hoverColors;
|
|
|
94 |
this.hoverOpacity = params.hoverOpacity;
|
|
|
95 |
this.setBackgroundColor(params.backgroundColor);
|
|
|
96 |
|
|
|
97 |
this.width = params.container.width();
|
|
|
98 |
this.height = params.container.height();
|
|
|
99 |
|
|
|
100 |
this.resize();
|
|
|
101 |
|
|
|
102 |
jQuery(window).resize(function () {
|
|
|
103 |
var newWidth = params.container.width();
|
|
|
104 |
var newHeight = params.container.height();
|
|
|
105 |
|
|
|
106 |
if(newWidth && newHeight){
|
|
|
107 |
map.width = newWidth;
|
|
|
108 |
map.height = newHeight;
|
|
|
109 |
map.resize();
|
|
|
110 |
map.canvas.setSize(map.width, map.height);
|
|
|
111 |
map.applyTransform();
|
|
|
112 |
|
|
|
113 |
var resizeEvent = jQuery.Event('resize.jqvmap');
|
|
|
114 |
jQuery(params.container).trigger(resizeEvent, [newWidth, newHeight]);
|
|
|
115 |
|
|
|
116 |
if(mapPins){
|
|
|
117 |
jQuery('.jqvmap-pin').remove();
|
|
|
118 |
map.pinHandlers = false;
|
|
|
119 |
map.placePins(mapPins.pins, mapPins.mode);
|
|
|
120 |
}
|
|
|
121 |
}
|
|
|
122 |
});
|
|
|
123 |
|
|
|
124 |
this.canvas = new VectorCanvas(this.width, this.height, params);
|
|
|
125 |
params.container.append(this.canvas.canvas);
|
|
|
126 |
|
|
|
127 |
this.makeDraggable();
|
|
|
128 |
|
|
|
129 |
this.rootGroup = this.canvas.createGroup(true);
|
|
|
130 |
|
|
|
131 |
this.index = JQVMap.mapIndex;
|
|
|
132 |
this.label = jQuery('<div/>').addClass('jqvmap-label').appendTo(jQuery('body')).hide();
|
|
|
133 |
|
|
|
134 |
if (params.enableZoom) {
|
|
|
135 |
jQuery('<div/>').addClass('jqvmap-zoomin').text('+').appendTo(params.container);
|
|
|
136 |
jQuery('<div/>').addClass('jqvmap-zoomout').html('−').appendTo(params.container);
|
|
|
137 |
}
|
|
|
138 |
|
|
|
139 |
map.countries = [];
|
|
|
140 |
|
|
|
141 |
for (var key in mapData.paths) {
|
|
|
142 |
var path = this.canvas.createPath({
|
|
|
143 |
path: mapData.paths[key].path
|
|
|
144 |
});
|
|
|
145 |
|
|
|
146 |
path.setFill(this.color);
|
|
|
147 |
path.id = map.getCountryId(key);
|
|
|
148 |
map.countries[key] = path;
|
|
|
149 |
|
|
|
150 |
if (this.canvas.mode === 'svg') {
|
|
|
151 |
path.setAttribute('class', 'jqvmap-region');
|
|
|
152 |
} else {
|
|
|
153 |
jQuery(path).addClass('jqvmap-region');
|
|
|
154 |
}
|
|
|
155 |
|
|
|
156 |
jQuery(this.rootGroup).append(path);
|
|
|
157 |
}
|
|
|
158 |
|
|
|
159 |
jQuery(params.container).delegate(this.canvas.mode === 'svg' ? 'path' : 'shape', 'mouseover mouseout', function (e) {
|
|
|
160 |
var containerPath = e.target,
|
|
|
161 |
code = e.target.id.split('_').pop(),
|
|
|
162 |
labelShowEvent = jQuery.Event('labelShow.jqvmap'),
|
|
|
163 |
regionMouseOverEvent = jQuery.Event('regionMouseOver.jqvmap');
|
|
|
164 |
|
|
|
165 |
code = code.toLowerCase();
|
|
|
166 |
|
|
|
167 |
if (e.type === 'mouseover') {
|
|
|
168 |
jQuery(params.container).trigger(regionMouseOverEvent, [code, mapData.paths[code].name]);
|
|
|
169 |
if (!regionMouseOverEvent.isDefaultPrevented()) {
|
|
|
170 |
map.highlight(code, containerPath);
|
|
|
171 |
}
|
|
|
172 |
if (params.showTooltip) {
|
|
|
173 |
map.label.text(mapData.paths[code].name);
|
|
|
174 |
jQuery(params.container).trigger(labelShowEvent, [map.label, code]);
|
|
|
175 |
|
|
|
176 |
if (!labelShowEvent.isDefaultPrevented()) {
|
|
|
177 |
map.label.show();
|
|
|
178 |
map.labelWidth = map.label.width();
|
|
|
179 |
map.labelHeight = map.label.height();
|
|
|
180 |
}
|
|
|
181 |
}
|
|
|
182 |
} else {
|
|
|
183 |
map.unhighlight(code, containerPath);
|
|
|
184 |
|
|
|
185 |
map.label.hide();
|
|
|
186 |
jQuery(params.container).trigger('regionMouseOut.jqvmap', [code, mapData.paths[code].name]);
|
|
|
187 |
}
|
|
|
188 |
});
|
|
|
189 |
|
|
|
190 |
jQuery(params.container).delegate(this.canvas.mode === 'svg' ? 'path' : 'shape', 'click', function (regionClickEvent) {
|
|
|
191 |
|
|
|
192 |
var targetPath = regionClickEvent.target;
|
|
|
193 |
var code = regionClickEvent.target.id.split('_').pop();
|
|
|
194 |
var mapClickEvent = jQuery.Event('regionClick.jqvmap');
|
|
|
195 |
|
|
|
196 |
code = code.toLowerCase();
|
|
|
197 |
|
|
|
198 |
jQuery(params.container).trigger(mapClickEvent, [code, mapData.paths[code].name]);
|
|
|
199 |
|
|
|
200 |
if ( !params.multiSelectRegion && !mapClickEvent.isDefaultPrevented()) {
|
|
|
201 |
for (var keyPath in mapData.paths) {
|
|
|
202 |
map.countries[keyPath].currentFillColor = map.countries[keyPath].getOriginalFill();
|
|
|
203 |
map.countries[keyPath].setFill(map.countries[keyPath].getOriginalFill());
|
|
|
204 |
}
|
|
|
205 |
}
|
|
|
206 |
|
|
|
207 |
if ( !mapClickEvent.isDefaultPrevented()) {
|
|
|
208 |
if (map.isSelected(code)) {
|
|
|
209 |
map.deselect(code, targetPath);
|
|
|
210 |
} else {
|
|
|
211 |
map.select(code, targetPath);
|
|
|
212 |
}
|
|
|
213 |
}
|
|
|
214 |
});
|
|
|
215 |
|
|
|
216 |
if (params.showTooltip) {
|
|
|
217 |
params.container.mousemove(function (e) {
|
|
|
218 |
if (map.label.is(':visible')) {
|
|
|
219 |
var left = e.pageX - 15 - map.labelWidth;
|
|
|
220 |
var top = e.pageY - 15 - map.labelHeight;
|
|
|
221 |
|
|
|
222 |
if(left < 0) {
|
|
|
223 |
left = e.pageX + 15;
|
|
|
224 |
}
|
|
|
225 |
if(top < 0) {
|
|
|
226 |
top = e.pageY + 15;
|
|
|
227 |
}
|
|
|
228 |
|
|
|
229 |
map.label.css({
|
|
|
230 |
left: left,
|
|
|
231 |
top: top
|
|
|
232 |
});
|
|
|
233 |
}
|
|
|
234 |
});
|
|
|
235 |
}
|
|
|
236 |
|
|
|
237 |
this.setColors(params.colors);
|
|
|
238 |
|
|
|
239 |
this.canvas.canvas.appendChild(this.rootGroup);
|
|
|
240 |
|
|
|
241 |
this.applyTransform();
|
|
|
242 |
|
|
|
243 |
this.colorScale = new ColorScale(params.scaleColors, params.normalizeFunction, params.valueMin, params.valueMax);
|
|
|
244 |
|
|
|
245 |
if (params.values) {
|
|
|
246 |
this.values = params.values;
|
|
|
247 |
this.setValues(params.values);
|
|
|
248 |
}
|
|
|
249 |
|
|
|
250 |
if (params.selectedRegions) {
|
|
|
251 |
if (params.selectedRegions instanceof Array) {
|
|
|
252 |
for(var k in params.selectedRegions) {
|
|
|
253 |
this.select(params.selectedRegions[k].toLowerCase());
|
|
|
254 |
}
|
|
|
255 |
} else {
|
|
|
256 |
this.select(params.selectedRegions.toLowerCase());
|
|
|
257 |
}
|
|
|
258 |
}
|
|
|
259 |
|
|
|
260 |
this.bindZoomButtons();
|
|
|
261 |
|
|
|
262 |
if(params.pins) {
|
|
|
263 |
mapPins = {
|
|
|
264 |
pins: params.pins,
|
|
|
265 |
mode: params.pinMode
|
|
|
266 |
};
|
|
|
267 |
|
|
|
268 |
this.pinHandlers = false;
|
|
|
269 |
this.placePins(params.pins, params.pinMode);
|
|
|
270 |
}
|
|
|
271 |
|
|
|
272 |
if(params.showLabels){
|
|
|
273 |
this.pinHandlers = false;
|
|
|
274 |
|
|
|
275 |
var pins = {};
|
|
|
276 |
for (key in map.countries){
|
|
|
277 |
if (typeof map.countries[key] !== 'function') {
|
|
|
278 |
if( !params.pins || !params.pins[key] ){
|
|
|
279 |
pins[key] = key.toUpperCase();
|
|
|
280 |
}
|
|
|
281 |
}
|
|
|
282 |
}
|
|
|
283 |
|
|
|
284 |
mapPins = {
|
|
|
285 |
pins: pins,
|
|
|
286 |
mode: 'content'
|
|
|
287 |
};
|
|
|
288 |
|
|
|
289 |
this.placePins(pins, 'content');
|
|
|
290 |
}
|
|
|
291 |
|
|
|
292 |
JQVMap.mapIndex++;
|
|
|
293 |
};
|
|
|
294 |
|
|
|
295 |
JQVMap.prototype = {
|
|
|
296 |
transX: 0,
|
|
|
297 |
transY: 0,
|
|
|
298 |
scale: 1,
|
|
|
299 |
baseTransX: 0,
|
|
|
300 |
baseTransY: 0,
|
|
|
301 |
baseScale: 1,
|
|
|
302 |
width: 0,
|
|
|
303 |
height: 0,
|
|
|
304 |
countries: {},
|
|
|
305 |
countriesColors: {},
|
|
|
306 |
countriesData: {},
|
|
|
307 |
zoomStep: 1.4,
|
|
|
308 |
zoomMaxStep: 4,
|
|
|
309 |
zoomCurStep: 1
|
|
|
310 |
};
|
|
|
311 |
|
|
|
312 |
JQVMap.xlink = 'http://www.w3.org/1999/xlink';
|
|
|
313 |
JQVMap.mapIndex = 1;
|
|
|
314 |
JQVMap.maps = {};
|
|
|
315 |
|
|
|
316 |
(function(){
|
|
|
317 |
|
|
|
318 |
var apiParams = {
|
|
|
319 |
colors: 1,
|
|
|
320 |
values: 1,
|
|
|
321 |
backgroundColor: 1,
|
|
|
322 |
scaleColors: 1,
|
|
|
323 |
normalizeFunction: 1,
|
|
|
324 |
enableZoom: 1,
|
|
|
325 |
showTooltip: 1,
|
|
|
326 |
borderColor: 1,
|
|
|
327 |
borderWidth: 1,
|
|
|
328 |
borderOpacity: 1,
|
|
|
329 |
selectedRegions: 1,
|
|
|
330 |
multiSelectRegion: 1
|
|
|
331 |
};
|
|
|
332 |
|
|
|
333 |
var apiEvents = {
|
|
|
334 |
onLabelShow: 'labelShow',
|
|
|
335 |
onLoad: 'load',
|
|
|
336 |
onRegionOver: 'regionMouseOver',
|
|
|
337 |
onRegionOut: 'regionMouseOut',
|
|
|
338 |
onRegionClick: 'regionClick',
|
|
|
339 |
onRegionSelect: 'regionSelect',
|
|
|
340 |
onRegionDeselect: 'regionDeselect',
|
|
|
341 |
onResize: 'resize'
|
|
|
342 |
};
|
|
|
343 |
|
|
|
344 |
jQuery.fn.vectorMap = function (options) {
|
|
|
345 |
|
|
|
346 |
var defaultParams = {
|
|
|
347 |
map: 'world_en',
|
|
|
348 |
backgroundColor: '#a5bfdd',
|
|
|
349 |
color: '#f4f3f0',
|
|
|
350 |
hoverColor: '#c9dfaf',
|
|
|
351 |
hoverColors: {},
|
|
|
352 |
selectedColor: '#c9dfaf',
|
|
|
353 |
scaleColors: ['#b6d6ff', '#005ace'],
|
|
|
354 |
normalizeFunction: 'linear',
|
|
|
355 |
enableZoom: true,
|
|
|
356 |
showTooltip: true,
|
|
|
357 |
borderColor: '#818181',
|
|
|
358 |
borderWidth: 1,
|
|
|
359 |
borderOpacity: 0.25,
|
|
|
360 |
selectedRegions: null,
|
|
|
361 |
multiSelectRegion: false
|
|
|
362 |
}, map = this.data('mapObject');
|
|
|
363 |
|
|
|
364 |
if (options === 'addMap') {
|
|
|
365 |
JQVMap.maps[arguments[1]] = arguments[2];
|
|
|
366 |
} else if (options === 'set' && apiParams[arguments[1]]) {
|
|
|
367 |
map['set' + arguments[1].charAt(0).toUpperCase() + arguments[1].substr(1)].apply(map, Array.prototype.slice.call(arguments, 2));
|
|
|
368 |
} else if (typeof options === 'string' &&
|
|
|
369 |
typeof map[options] === 'function') {
|
|
|
370 |
return map[options].apply(map, Array.prototype.slice.call(arguments, 1));
|
|
|
371 |
} else {
|
|
|
372 |
jQuery.extend(defaultParams, options);
|
|
|
373 |
defaultParams.container = this;
|
|
|
374 |
this.css({ position: 'relative', overflow: 'hidden' });
|
|
|
375 |
|
|
|
376 |
map = new JQVMap(defaultParams);
|
|
|
377 |
|
|
|
378 |
this.data('mapObject', map);
|
|
|
379 |
|
|
|
380 |
this.unbind('.jqvmap');
|
|
|
381 |
|
|
|
382 |
for (var e in apiEvents) {
|
|
|
383 |
if (defaultParams[e]) {
|
|
|
384 |
this.bind(apiEvents[e] + '.jqvmap', defaultParams[e]);
|
|
|
385 |
}
|
|
|
386 |
}
|
|
|
387 |
|
|
|
388 |
var loadEvent = jQuery.Event('load.jqvmap');
|
|
|
389 |
jQuery(defaultParams.container).trigger(loadEvent, map);
|
|
|
390 |
|
|
|
391 |
return map;
|
|
|
392 |
}
|
|
|
393 |
};
|
|
|
394 |
|
|
|
395 |
})(jQuery);
|
|
|
396 |
|
|
|
397 |
ColorScale.arrayToRgb = function (ar) {
|
|
|
398 |
var rgb = '#';
|
|
|
399 |
var d;
|
|
|
400 |
for (var i = 0; i < ar.length; i++) {
|
|
|
401 |
d = ar[i].toString(16);
|
|
|
402 |
rgb += d.length === 1 ? '0' + d : d;
|
|
|
403 |
}
|
|
|
404 |
return rgb;
|
|
|
405 |
};
|
|
|
406 |
|
|
|
407 |
ColorScale.prototype.getColor = function (value) {
|
|
|
408 |
if (typeof this.normalize === 'function') {
|
|
|
409 |
value = this.normalize(value);
|
|
|
410 |
}
|
|
|
411 |
|
|
|
412 |
var lengthes = [];
|
|
|
413 |
var fullLength = 0;
|
|
|
414 |
var l;
|
|
|
415 |
|
|
|
416 |
for (var i = 0; i < this.colors.length - 1; i++) {
|
|
|
417 |
l = this.vectorLength(this.vectorSubtract(this.colors[i + 1], this.colors[i]));
|
|
|
418 |
lengthes.push(l);
|
|
|
419 |
fullLength += l;
|
|
|
420 |
}
|
|
|
421 |
|
|
|
422 |
var c = (this.maxValue - this.minValue) / fullLength;
|
|
|
423 |
|
|
|
424 |
for (i = 0; i < lengthes.length; i++) {
|
|
|
425 |
lengthes[i] *= c;
|
|
|
426 |
}
|
|
|
427 |
|
|
|
428 |
i = 0;
|
|
|
429 |
value -= this.minValue;
|
|
|
430 |
|
|
|
431 |
while (value - lengthes[i] >= 0) {
|
|
|
432 |
value -= lengthes[i];
|
|
|
433 |
i++;
|
|
|
434 |
}
|
|
|
435 |
|
|
|
436 |
var color;
|
|
|
437 |
if (i === this.colors.length - 1) {
|
|
|
438 |
color = this.vectorToNum(this.colors[i]).toString(16);
|
|
|
439 |
} else {
|
|
|
440 |
color = (this.vectorToNum(this.vectorAdd(this.colors[i], this.vectorMult(this.vectorSubtract(this.colors[i + 1], this.colors[i]), (value) / (lengthes[i]))))).toString(16);
|
|
|
441 |
}
|
|
|
442 |
|
|
|
443 |
while (color.length < 6) {
|
|
|
444 |
color = '0' + color;
|
|
|
445 |
}
|
|
|
446 |
return '#' + color;
|
|
|
447 |
};
|
|
|
448 |
|
|
|
449 |
ColorScale.rgbToArray = function (rgb) {
|
|
|
450 |
rgb = rgb.substr(1);
|
|
|
451 |
return [parseInt(rgb.substr(0, 2), 16), parseInt(rgb.substr(2, 2), 16), parseInt(rgb.substr(4, 2), 16)];
|
|
|
452 |
};
|
|
|
453 |
|
|
|
454 |
ColorScale.prototype.setColors = function (colors) {
|
|
|
455 |
for (var i = 0; i < colors.length; i++) {
|
|
|
456 |
colors[i] = ColorScale.rgbToArray(colors[i]);
|
|
|
457 |
}
|
|
|
458 |
this.colors = colors;
|
|
|
459 |
};
|
|
|
460 |
|
|
|
461 |
ColorScale.prototype.setMax = function (max) {
|
|
|
462 |
this.clearMaxValue = max;
|
|
|
463 |
if (typeof this.normalize === 'function') {
|
|
|
464 |
this.maxValue = this.normalize(max);
|
|
|
465 |
} else {
|
|
|
466 |
this.maxValue = max;
|
|
|
467 |
}
|
|
|
468 |
};
|
|
|
469 |
|
|
|
470 |
ColorScale.prototype.setMin = function (min) {
|
|
|
471 |
this.clearMinValue = min;
|
|
|
472 |
|
|
|
473 |
if (typeof this.normalize === 'function') {
|
|
|
474 |
this.minValue = this.normalize(min);
|
|
|
475 |
} else {
|
|
|
476 |
this.minValue = min;
|
|
|
477 |
}
|
|
|
478 |
};
|
|
|
479 |
|
|
|
480 |
ColorScale.prototype.setNormalizeFunction = function (f) {
|
|
|
481 |
if (f === 'polynomial') {
|
|
|
482 |
this.normalize = function (value) {
|
|
|
483 |
return Math.pow(value, 0.2);
|
|
|
484 |
};
|
|
|
485 |
} else if (f === 'linear') {
|
|
|
486 |
delete this.normalize;
|
|
|
487 |
} else {
|
|
|
488 |
this.normalize = f;
|
|
|
489 |
}
|
|
|
490 |
this.setMin(this.clearMinValue);
|
|
|
491 |
this.setMax(this.clearMaxValue);
|
|
|
492 |
};
|
|
|
493 |
|
|
|
494 |
ColorScale.prototype.vectorAdd = function (vector1, vector2) {
|
|
|
495 |
var vector = [];
|
|
|
496 |
for (var i = 0; i < vector1.length; i++) {
|
|
|
497 |
vector[i] = vector1[i] + vector2[i];
|
|
|
498 |
}
|
|
|
499 |
return vector;
|
|
|
500 |
};
|
|
|
501 |
|
|
|
502 |
ColorScale.prototype.vectorLength = function (vector) {
|
|
|
503 |
var result = 0;
|
|
|
504 |
for (var i = 0; i < vector.length; i++) {
|
|
|
505 |
result += vector[i] * vector[i];
|
|
|
506 |
}
|
|
|
507 |
return Math.sqrt(result);
|
|
|
508 |
};
|
|
|
509 |
|
|
|
510 |
ColorScale.prototype.vectorMult = function (vector, num) {
|
|
|
511 |
var result = [];
|
|
|
512 |
for (var i = 0; i < vector.length; i++) {
|
|
|
513 |
result[i] = vector[i] * num;
|
|
|
514 |
}
|
|
|
515 |
return result;
|
|
|
516 |
};
|
|
|
517 |
|
|
|
518 |
ColorScale.prototype.vectorSubtract = function (vector1, vector2) {
|
|
|
519 |
var vector = [];
|
|
|
520 |
for (var i = 0; i < vector1.length; i++) {
|
|
|
521 |
vector[i] = vector1[i] - vector2[i];
|
|
|
522 |
}
|
|
|
523 |
return vector;
|
|
|
524 |
};
|
|
|
525 |
|
|
|
526 |
ColorScale.prototype.vectorToNum = function (vector) {
|
|
|
527 |
var num = 0;
|
|
|
528 |
for (var i = 0; i < vector.length; i++) {
|
|
|
529 |
num += Math.round(vector[i]) * Math.pow(256, vector.length - i - 1);
|
|
|
530 |
}
|
|
|
531 |
return num;
|
|
|
532 |
};
|
|
|
533 |
|
|
|
534 |
JQVMap.prototype.applyTransform = function () {
|
|
|
535 |
var maxTransX, maxTransY, minTransX, minTransY;
|
|
|
536 |
if (this.defaultWidth * this.scale <= this.width) {
|
|
|
537 |
maxTransX = (this.width - this.defaultWidth * this.scale) / (2 * this.scale);
|
|
|
538 |
minTransX = (this.width - this.defaultWidth * this.scale) / (2 * this.scale);
|
|
|
539 |
} else {
|
|
|
540 |
maxTransX = 0;
|
|
|
541 |
minTransX = (this.width - this.defaultWidth * this.scale) / this.scale;
|
|
|
542 |
}
|
|
|
543 |
|
|
|
544 |
if (this.defaultHeight * this.scale <= this.height) {
|
|
|
545 |
maxTransY = (this.height - this.defaultHeight * this.scale) / (2 * this.scale);
|
|
|
546 |
minTransY = (this.height - this.defaultHeight * this.scale) / (2 * this.scale);
|
|
|
547 |
} else {
|
|
|
548 |
maxTransY = 0;
|
|
|
549 |
minTransY = (this.height - this.defaultHeight * this.scale) / this.scale;
|
|
|
550 |
}
|
|
|
551 |
|
|
|
552 |
if (this.transY > maxTransY) {
|
|
|
553 |
this.transY = maxTransY;
|
|
|
554 |
} else if (this.transY < minTransY) {
|
|
|
555 |
this.transY = minTransY;
|
|
|
556 |
}
|
|
|
557 |
if (this.transX > maxTransX) {
|
|
|
558 |
this.transX = maxTransX;
|
|
|
559 |
} else if (this.transX < minTransX) {
|
|
|
560 |
this.transX = minTransX;
|
|
|
561 |
}
|
|
|
562 |
|
|
|
563 |
this.canvas.applyTransformParams(this.scale, this.transX, this.transY);
|
|
|
564 |
};
|
|
|
565 |
|
|
|
566 |
JQVMap.prototype.bindZoomButtons = function () {
|
|
|
567 |
var map = this;
|
|
|
568 |
this.container.find('.jqvmap-zoomin').click(function(){
|
|
|
569 |
map.zoomIn();
|
|
|
570 |
});
|
|
|
571 |
this.container.find('.jqvmap-zoomout').click(function(){
|
|
|
572 |
map.zoomOut();
|
|
|
573 |
});
|
|
|
574 |
};
|
|
|
575 |
|
|
|
576 |
JQVMap.prototype.deselect = function (cc, path) {
|
|
|
577 |
cc = cc.toLowerCase();
|
|
|
578 |
path = path || jQuery('#' + this.getCountryId(cc))[0];
|
|
|
579 |
|
|
|
580 |
if (this.isSelected(cc)) {
|
|
|
581 |
this.selectedRegions.splice(this.selectIndex(cc), 1);
|
|
|
582 |
|
|
|
583 |
jQuery(this.container).trigger('regionDeselect.jqvmap', [cc]);
|
|
|
584 |
path.currentFillColor = path.getOriginalFill();
|
|
|
585 |
path.setFill(path.getOriginalFill());
|
|
|
586 |
} else {
|
|
|
587 |
for (var key in this.countries) {
|
|
|
588 |
this.selectedRegions.splice(this.selectedRegions.indexOf(key), 1);
|
|
|
589 |
this.countries[key].currentFillColor = this.color;
|
|
|
590 |
this.countries[key].setFill(this.color);
|
|
|
591 |
}
|
|
|
592 |
}
|
|
|
593 |
};
|
|
|
594 |
|
|
|
595 |
JQVMap.prototype.getCountryId = function (cc) {
|
|
|
596 |
return 'jqvmap' + this.index + '_' + cc;
|
|
|
597 |
};
|
|
|
598 |
|
|
|
599 |
JQVMap.prototype.getPin = function(cc){
|
|
|
600 |
var pinObj = jQuery('#' + this.getPinId(cc));
|
|
|
601 |
return pinObj.html();
|
|
|
602 |
};
|
|
|
603 |
|
|
|
604 |
JQVMap.prototype.getPinId = function (cc) {
|
|
|
605 |
return this.getCountryId(cc) + '_pin';
|
|
|
606 |
};
|
|
|
607 |
|
|
|
608 |
JQVMap.prototype.getPins = function(){
|
|
|
609 |
var pins = this.container.find('.jqvmap-pin');
|
|
|
610 |
var ret = {};
|
|
|
611 |
jQuery.each(pins, function(index, pinObj){
|
|
|
612 |
pinObj = jQuery(pinObj);
|
|
|
613 |
var cc = pinObj.attr('for').toLowerCase();
|
|
|
614 |
var pinContent = pinObj.html();
|
|
|
615 |
ret[cc] = pinContent;
|
|
|
616 |
});
|
|
|
617 |
return JSON.stringify(ret);
|
|
|
618 |
};
|
|
|
619 |
|
|
|
620 |
JQVMap.prototype.highlight = function (cc, path) {
|
|
|
621 |
path = path || jQuery('#' + this.getCountryId(cc))[0];
|
|
|
622 |
if (this.hoverOpacity) {
|
|
|
623 |
path.setOpacity(this.hoverOpacity);
|
|
|
624 |
} else if (this.hoverColors && (cc in this.hoverColors)) {
|
|
|
625 |
path.currentFillColor = path.getFill() + '';
|
|
|
626 |
path.setFill(this.hoverColors[cc]);
|
|
|
627 |
} else if (this.hoverColor) {
|
|
|
628 |
path.currentFillColor = path.getFill() + '';
|
|
|
629 |
path.setFill(this.hoverColor);
|
|
|
630 |
}
|
|
|
631 |
};
|
|
|
632 |
|
|
|
633 |
JQVMap.prototype.isSelected = function(cc) {
|
|
|
634 |
return this.selectIndex(cc) >= 0;
|
|
|
635 |
};
|
|
|
636 |
|
|
|
637 |
JQVMap.prototype.makeDraggable = function () {
|
|
|
638 |
var mouseDown = false;
|
|
|
639 |
var oldPageX, oldPageY;
|
|
|
640 |
var self = this;
|
|
|
641 |
|
|
|
642 |
self.isMoving = false;
|
|
|
643 |
self.isMovingTimeout = false;
|
|
|
644 |
|
|
|
645 |
var lastTouchCount;
|
|
|
646 |
var touchCenterX;
|
|
|
647 |
var touchCenterY;
|
|
|
648 |
var touchStartDistance;
|
|
|
649 |
var touchStartScale;
|
|
|
650 |
var touchX;
|
|
|
651 |
var touchY;
|
|
|
652 |
|
|
|
653 |
this.container.mousemove(function (e) {
|
|
|
654 |
|
|
|
655 |
if (mouseDown) {
|
|
|
656 |
self.transX -= (oldPageX - e.pageX) / self.scale;
|
|
|
657 |
self.transY -= (oldPageY - e.pageY) / self.scale;
|
|
|
658 |
|
|
|
659 |
self.applyTransform();
|
|
|
660 |
|
|
|
661 |
oldPageX = e.pageX;
|
|
|
662 |
oldPageY = e.pageY;
|
|
|
663 |
|
|
|
664 |
self.isMoving = true;
|
|
|
665 |
if (self.isMovingTimeout) {
|
|
|
666 |
clearTimeout(self.isMovingTimeout);
|
|
|
667 |
}
|
|
|
668 |
|
|
|
669 |
self.container.trigger('drag');
|
|
|
670 |
}
|
|
|
671 |
|
|
|
672 |
return false;
|
|
|
673 |
|
|
|
674 |
}).mousedown(function (e) {
|
|
|
675 |
|
|
|
676 |
mouseDown = true;
|
|
|
677 |
oldPageX = e.pageX;
|
|
|
678 |
oldPageY = e.pageY;
|
|
|
679 |
|
|
|
680 |
return false;
|
|
|
681 |
|
|
|
682 |
}).mouseup(function () {
|
|
|
683 |
|
|
|
684 |
mouseDown = false;
|
|
|
685 |
|
|
|
686 |
clearTimeout(self.isMovingTimeout);
|
|
|
687 |
self.isMovingTimeout = setTimeout(function () {
|
|
|
688 |
self.isMoving = false;
|
|
|
689 |
}, 100);
|
|
|
690 |
|
|
|
691 |
return false;
|
|
|
692 |
|
|
|
693 |
}).mouseout(function () {
|
|
|
694 |
|
|
|
695 |
if(mouseDown && self.isMoving){
|
|
|
696 |
|
|
|
697 |
clearTimeout(self.isMovingTimeout);
|
|
|
698 |
self.isMovingTimeout = setTimeout(function () {
|
|
|
699 |
mouseDown = false;
|
|
|
700 |
self.isMoving = false;
|
|
|
701 |
}, 100);
|
|
|
702 |
|
|
|
703 |
return false;
|
|
|
704 |
}
|
|
|
705 |
});
|
|
|
706 |
|
|
|
707 |
jQuery(this.container).bind('touchmove', function (e) {
|
|
|
708 |
|
|
|
709 |
var offset;
|
|
|
710 |
var scale;
|
|
|
711 |
var touches = e.originalEvent.touches;
|
|
|
712 |
var transformXOld;
|
|
|
713 |
var transformYOld;
|
|
|
714 |
|
|
|
715 |
if (touches.length === 1) {
|
|
|
716 |
if (lastTouchCount === 1) {
|
|
|
717 |
|
|
|
718 |
if(touchX === touches[0].pageX && touchY === touches[0].pageY){
|
|
|
719 |
return;
|
|
|
720 |
}
|
|
|
721 |
|
|
|
722 |
transformXOld = self.transX;
|
|
|
723 |
transformYOld = self.transY;
|
|
|
724 |
|
|
|
725 |
self.transX -= (touchX - touches[0].pageX) / self.scale;
|
|
|
726 |
self.transY -= (touchY - touches[0].pageY) / self.scale;
|
|
|
727 |
|
|
|
728 |
self.applyTransform();
|
|
|
729 |
|
|
|
730 |
if (transformXOld !== self.transX || transformYOld !== self.transY) {
|
|
|
731 |
e.preventDefault();
|
|
|
732 |
}
|
|
|
733 |
|
|
|
734 |
self.isMoving = true;
|
|
|
735 |
if (self.isMovingTimeout) {
|
|
|
736 |
clearTimeout(self.isMovingTimeout);
|
|
|
737 |
}
|
|
|
738 |
}
|
|
|
739 |
|
|
|
740 |
touchX = touches[0].pageX;
|
|
|
741 |
touchY = touches[0].pageY;
|
|
|
742 |
|
|
|
743 |
} else if (touches.length === 2) {
|
|
|
744 |
|
|
|
745 |
if (lastTouchCount === 2) {
|
|
|
746 |
scale = Math.sqrt(
|
|
|
747 |
Math.pow(touches[0].pageX - touches[1].pageX, 2) +
|
|
|
748 |
Math.pow(touches[0].pageY - touches[1].pageY, 2)
|
|
|
749 |
) / touchStartDistance;
|
|
|
750 |
|
|
|
751 |
self.setScale(
|
|
|
752 |
touchStartScale * scale,
|
|
|
753 |
touchCenterX,
|
|
|
754 |
touchCenterY
|
|
|
755 |
);
|
|
|
756 |
|
|
|
757 |
e.preventDefault();
|
|
|
758 |
|
|
|
759 |
} else {
|
|
|
760 |
|
|
|
761 |
offset = jQuery(self.container).offset();
|
|
|
762 |
if (touches[0].pageX > touches[1].pageX) {
|
|
|
763 |
touchCenterX = touches[1].pageX + (touches[0].pageX - touches[1].pageX) / 2;
|
|
|
764 |
} else {
|
|
|
765 |
touchCenterX = touches[0].pageX + (touches[1].pageX - touches[0].pageX) / 2;
|
|
|
766 |
}
|
|
|
767 |
|
|
|
768 |
if (touches[0].pageY > touches[1].pageY) {
|
|
|
769 |
touchCenterY = touches[1].pageY + (touches[0].pageY - touches[1].pageY) / 2;
|
|
|
770 |
} else {
|
|
|
771 |
touchCenterY = touches[0].pageY + (touches[1].pageY - touches[0].pageY) / 2;
|
|
|
772 |
}
|
|
|
773 |
|
|
|
774 |
touchCenterX -= offset.left;
|
|
|
775 |
touchCenterY -= offset.top;
|
|
|
776 |
touchStartScale = self.scale;
|
|
|
777 |
|
|
|
778 |
touchStartDistance = Math.sqrt(
|
|
|
779 |
Math.pow(touches[0].pageX - touches[1].pageX, 2) +
|
|
|
780 |
Math.pow(touches[0].pageY - touches[1].pageY, 2)
|
|
|
781 |
);
|
|
|
782 |
}
|
|
|
783 |
}
|
|
|
784 |
|
|
|
785 |
lastTouchCount = touches.length;
|
|
|
786 |
});
|
|
|
787 |
|
|
|
788 |
jQuery(this.container).bind('touchstart', function () {
|
|
|
789 |
lastTouchCount = 0;
|
|
|
790 |
});
|
|
|
791 |
|
|
|
792 |
jQuery(this.container).bind('touchend', function () {
|
|
|
793 |
lastTouchCount = 0;
|
|
|
794 |
});
|
|
|
795 |
};
|
|
|
796 |
|
|
|
797 |
JQVMap.prototype.placePins = function(pins, pinMode){
|
|
|
798 |
var map = this;
|
|
|
799 |
|
|
|
800 |
if(!pinMode || (pinMode !== 'content' && pinMode !== 'id')) {
|
|
|
801 |
pinMode = 'content';
|
|
|
802 |
}
|
|
|
803 |
|
|
|
804 |
if(pinMode === 'content') {//treat pin as content
|
|
|
805 |
jQuery.each(pins, function(index, pin){
|
|
|
806 |
if(jQuery('#' + map.getCountryId(index)).length === 0){
|
|
|
807 |
return;
|
|
|
808 |
}
|
|
|
809 |
|
|
|
810 |
var pinIndex = map.getPinId(index);
|
|
|
811 |
var $pin = jQuery('#' + pinIndex);
|
|
|
812 |
if($pin.length > 0){
|
|
|
813 |
$pin.remove();
|
|
|
814 |
}
|
|
|
815 |
map.container.append('<div id="' + pinIndex + '" for="' + index + '" class="jqvmap-pin" style="position:absolute">' + pin + '</div>');
|
|
|
816 |
});
|
|
|
817 |
} else { //treat pin as id of an html content
|
|
|
818 |
jQuery.each(pins, function(index, pin){
|
|
|
819 |
if(jQuery('#' + map.getCountryId(index)).length === 0){
|
|
|
820 |
return;
|
|
|
821 |
}
|
|
|
822 |
var pinIndex = map.getPinId(index);
|
|
|
823 |
var $pin = jQuery('#' + pinIndex);
|
|
|
824 |
if($pin.length > 0){
|
|
|
825 |
$pin.remove();
|
|
|
826 |
}
|
|
|
827 |
map.container.append('<div id="' + pinIndex + '" for="' + index + '" class="jqvmap-pin" style="position:absolute"></div>');
|
|
|
828 |
$pin.append(jQuery('#' + pin));
|
|
|
829 |
});
|
|
|
830 |
}
|
|
|
831 |
|
|
|
832 |
this.positionPins();
|
|
|
833 |
if(!this.pinHandlers){
|
|
|
834 |
this.pinHandlers = true;
|
|
|
835 |
var positionFix = function(){
|
|
|
836 |
map.positionPins();
|
|
|
837 |
};
|
|
|
838 |
this.container.bind('zoomIn', positionFix)
|
|
|
839 |
.bind('zoomOut', positionFix)
|
|
|
840 |
.bind('drag', positionFix);
|
|
|
841 |
}
|
|
|
842 |
};
|
|
|
843 |
|
|
|
844 |
JQVMap.prototype.positionPins = function(){
|
|
|
845 |
var map = this;
|
|
|
846 |
var pins = this.container.find('.jqvmap-pin');
|
|
|
847 |
jQuery.each(pins, function(index, pinObj){
|
|
|
848 |
pinObj = jQuery(pinObj);
|
|
|
849 |
var countryId = map.getCountryId(pinObj.attr('for').toLowerCase());
|
|
|
850 |
var countryObj = jQuery('#' + countryId);
|
|
|
851 |
var bbox = countryObj[0].getBBox();
|
|
|
852 |
|
|
|
853 |
var scale = map.scale;
|
|
|
854 |
var rootCoords = map.canvas.rootGroup.getBoundingClientRect();
|
|
|
855 |
var mapCoords = map.container[0].getBoundingClientRect();
|
|
|
856 |
var coords = {
|
|
|
857 |
left: rootCoords.left - mapCoords.left,
|
|
|
858 |
top: rootCoords.top - mapCoords.top
|
|
|
859 |
};
|
|
|
860 |
|
|
|
861 |
var middleX = (bbox.x * scale) + ((bbox.width * scale) / 2);
|
|
|
862 |
var middleY = (bbox.y * scale) + ((bbox.height * scale) / 2);
|
|
|
863 |
|
|
|
864 |
pinObj.css({
|
|
|
865 |
left: coords.left + middleX - (pinObj.width() / 2),
|
|
|
866 |
top: coords.top + middleY - (pinObj.height() / 2)
|
|
|
867 |
});
|
|
|
868 |
});
|
|
|
869 |
};
|
|
|
870 |
|
|
|
871 |
JQVMap.prototype.removePin = function(cc) {
|
|
|
872 |
cc = cc.toLowerCase();
|
|
|
873 |
jQuery('#' + this.getPinId(cc)).remove();
|
|
|
874 |
};
|
|
|
875 |
|
|
|
876 |
JQVMap.prototype.removePins = function(){
|
|
|
877 |
this.container.find('.jqvmap-pin').remove();
|
|
|
878 |
};
|
|
|
879 |
|
|
|
880 |
JQVMap.prototype.reset = function () {
|
|
|
881 |
for (var key in this.countries) {
|
|
|
882 |
this.countries[key].setFill(this.color);
|
|
|
883 |
}
|
|
|
884 |
this.scale = this.baseScale;
|
|
|
885 |
this.transX = this.baseTransX;
|
|
|
886 |
this.transY = this.baseTransY;
|
|
|
887 |
this.applyTransform();
|
|
|
888 |
};
|
|
|
889 |
|
|
|
890 |
JQVMap.prototype.resize = function () {
|
|
|
891 |
var curBaseScale = this.baseScale;
|
|
|
892 |
if (this.width / this.height > this.defaultWidth / this.defaultHeight) {
|
|
|
893 |
this.baseScale = this.height / this.defaultHeight;
|
|
|
894 |
this.baseTransX = Math.abs(this.width - this.defaultWidth * this.baseScale) / (2 * this.baseScale);
|
|
|
895 |
} else {
|
|
|
896 |
this.baseScale = this.width / this.defaultWidth;
|
|
|
897 |
this.baseTransY = Math.abs(this.height - this.defaultHeight * this.baseScale) / (2 * this.baseScale);
|
|
|
898 |
}
|
|
|
899 |
this.scale *= this.baseScale / curBaseScale;
|
|
|
900 |
this.transX *= this.baseScale / curBaseScale;
|
|
|
901 |
this.transY *= this.baseScale / curBaseScale;
|
|
|
902 |
};
|
|
|
903 |
|
|
|
904 |
JQVMap.prototype.select = function (cc, path) {
|
|
|
905 |
cc = cc.toLowerCase();
|
|
|
906 |
path = path || jQuery('#' + this.getCountryId(cc))[0];
|
|
|
907 |
|
|
|
908 |
if (!this.isSelected(cc)) {
|
|
|
909 |
if (this.multiSelectRegion) {
|
|
|
910 |
this.selectedRegions.push(cc);
|
|
|
911 |
} else {
|
|
|
912 |
this.selectedRegions = [cc];
|
|
|
913 |
}
|
|
|
914 |
|
|
|
915 |
jQuery(this.container).trigger('regionSelect.jqvmap', [cc]);
|
|
|
916 |
if (this.selectedColor && path) {
|
|
|
917 |
path.currentFillColor = this.selectedColor;
|
|
|
918 |
path.setFill(this.selectedColor);
|
|
|
919 |
}
|
|
|
920 |
}
|
|
|
921 |
};
|
|
|
922 |
|
|
|
923 |
JQVMap.prototype.selectIndex = function (cc) {
|
|
|
924 |
cc = cc.toLowerCase();
|
|
|
925 |
for (var i = 0; i < this.selectedRegions.length; i++) {
|
|
|
926 |
if (cc === this.selectedRegions[i]) {
|
|
|
927 |
return i;
|
|
|
928 |
}
|
|
|
929 |
}
|
|
|
930 |
return -1;
|
|
|
931 |
};
|
|
|
932 |
|
|
|
933 |
JQVMap.prototype.setBackgroundColor = function (backgroundColor) {
|
|
|
934 |
this.container.css('background-color', backgroundColor);
|
|
|
935 |
};
|
|
|
936 |
|
|
|
937 |
JQVMap.prototype.setColors = function (key, color) {
|
|
|
938 |
if (typeof key === 'string') {
|
|
|
939 |
this.countries[key].setFill(color);
|
|
|
940 |
this.countries[key].setAttribute('original', color);
|
|
|
941 |
} else {
|
|
|
942 |
var colors = key;
|
|
|
943 |
|
|
|
944 |
for (var code in colors) {
|
|
|
945 |
if (this.countries[code]) {
|
|
|
946 |
this.countries[code].setFill(colors[code]);
|
|
|
947 |
this.countries[code].setAttribute('original', colors[code]);
|
|
|
948 |
}
|
|
|
949 |
}
|
|
|
950 |
}
|
|
|
951 |
};
|
|
|
952 |
|
|
|
953 |
JQVMap.prototype.setNormalizeFunction = function (f) {
|
|
|
954 |
this.colorScale.setNormalizeFunction(f);
|
|
|
955 |
|
|
|
956 |
if (this.values) {
|
|
|
957 |
this.setValues(this.values);
|
|
|
958 |
}
|
|
|
959 |
};
|
|
|
960 |
|
|
|
961 |
JQVMap.prototype.setScale = function (scale) {
|
|
|
962 |
this.scale = scale;
|
|
|
963 |
this.applyTransform();
|
|
|
964 |
};
|
|
|
965 |
|
|
|
966 |
JQVMap.prototype.setScaleColors = function (colors) {
|
|
|
967 |
this.colorScale.setColors(colors);
|
|
|
968 |
|
|
|
969 |
if (this.values) {
|
|
|
970 |
this.setValues(this.values);
|
|
|
971 |
}
|
|
|
972 |
};
|
|
|
973 |
|
|
|
974 |
JQVMap.prototype.setValues = function (values) {
|
|
|
975 |
var max = 0,
|
|
|
976 |
min = Number.MAX_VALUE,
|
|
|
977 |
val;
|
|
|
978 |
|
|
|
979 |
for (var cc in values) {
|
|
|
980 |
cc = cc.toLowerCase();
|
|
|
981 |
val = parseFloat(values[cc]);
|
|
|
982 |
|
|
|
983 |
if (isNaN(val)) {
|
|
|
984 |
continue;
|
|
|
985 |
}
|
|
|
986 |
if (val > max) {
|
|
|
987 |
max = values[cc];
|
|
|
988 |
}
|
|
|
989 |
if (val < min) {
|
|
|
990 |
min = val;
|
|
|
991 |
}
|
|
|
992 |
}
|
|
|
993 |
|
|
|
994 |
if (min === max) {
|
|
|
995 |
max++;
|
|
|
996 |
}
|
|
|
997 |
|
|
|
998 |
this.colorScale.setMin(min);
|
|
|
999 |
this.colorScale.setMax(max);
|
|
|
1000 |
|
|
|
1001 |
var colors = {};
|
|
|
1002 |
for (cc in values) {
|
|
|
1003 |
cc = cc.toLowerCase();
|
|
|
1004 |
val = parseFloat(values[cc]);
|
|
|
1005 |
colors[cc] = isNaN(val) ? this.color : this.colorScale.getColor(val);
|
|
|
1006 |
}
|
|
|
1007 |
this.setColors(colors);
|
|
|
1008 |
this.values = values;
|
|
|
1009 |
};
|
|
|
1010 |
|
|
|
1011 |
JQVMap.prototype.unhighlight = function (cc, path) {
|
|
|
1012 |
cc = cc.toLowerCase();
|
|
|
1013 |
path = path || jQuery('#' + this.getCountryId(cc))[0];
|
|
|
1014 |
path.setOpacity(1);
|
|
|
1015 |
if (path.currentFillColor) {
|
|
|
1016 |
path.setFill(path.currentFillColor);
|
|
|
1017 |
}
|
|
|
1018 |
};
|
|
|
1019 |
|
|
|
1020 |
JQVMap.prototype.zoomIn = function () {
|
|
|
1021 |
var map = this;
|
|
|
1022 |
var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
|
|
|
1023 |
|
|
|
1024 |
if (map.zoomCurStep < map.zoomMaxStep) {
|
|
|
1025 |
map.transX -= (map.width / map.scale - map.width / (map.scale * map.zoomStep)) / 2;
|
|
|
1026 |
map.transY -= (map.height / map.scale - map.height / (map.scale * map.zoomStep)) / 2;
|
|
|
1027 |
map.setScale(map.scale * map.zoomStep);
|
|
|
1028 |
map.zoomCurStep++;
|
|
|
1029 |
|
|
|
1030 |
var $slider = jQuery('#zoomSlider');
|
|
|
1031 |
|
|
|
1032 |
$slider.css('top', parseInt($slider.css('top'), 10) - sliderDelta);
|
|
|
1033 |
|
|
|
1034 |
map.container.trigger('zoomIn');
|
|
|
1035 |
}
|
|
|
1036 |
};
|
|
|
1037 |
|
|
|
1038 |
JQVMap.prototype.zoomOut = function () {
|
|
|
1039 |
var map = this;
|
|
|
1040 |
var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
|
|
|
1041 |
|
|
|
1042 |
if (map.zoomCurStep > 1) {
|
|
|
1043 |
map.transX += (map.width / (map.scale / map.zoomStep) - map.width / map.scale) / 2;
|
|
|
1044 |
map.transY += (map.height / (map.scale / map.zoomStep) - map.height / map.scale) / 2;
|
|
|
1045 |
map.setScale(map.scale / map.zoomStep);
|
|
|
1046 |
map.zoomCurStep--;
|
|
|
1047 |
|
|
|
1048 |
var $slider = jQuery('#zoomSlider');
|
|
|
1049 |
|
|
|
1050 |
$slider.css('top', parseInt($slider.css('top'), 10) + sliderDelta);
|
|
|
1051 |
|
|
|
1052 |
map.container.trigger('zoomOut');
|
|
|
1053 |
}
|
|
|
1054 |
};
|
|
|
1055 |
|
|
|
1056 |
VectorCanvas.prototype.applyTransformParams = function (scale, transX, transY) {
|
|
|
1057 |
if (this.mode === 'svg') {
|
|
|
1058 |
this.rootGroup.setAttribute('transform', 'scale(' + scale + ') translate(' + transX + ', ' + transY + ')');
|
|
|
1059 |
} else {
|
|
|
1060 |
this.rootGroup.coordorigin = (this.width - transX) + ',' + (this.height - transY);
|
|
|
1061 |
this.rootGroup.coordsize = this.width / scale + ',' + this.height / scale;
|
|
|
1062 |
}
|
|
|
1063 |
};
|
|
|
1064 |
|
|
|
1065 |
VectorCanvas.prototype.createGroup = function (isRoot) {
|
|
|
1066 |
var node;
|
|
|
1067 |
if (this.mode === 'svg') {
|
|
|
1068 |
node = this.createSvgNode('g');
|
|
|
1069 |
} else {
|
|
|
1070 |
node = this.createVmlNode('group');
|
|
|
1071 |
node.style.width = this.width + 'px';
|
|
|
1072 |
node.style.height = this.height + 'px';
|
|
|
1073 |
node.style.left = '0px';
|
|
|
1074 |
node.style.top = '0px';
|
|
|
1075 |
node.coordorigin = '0 0';
|
|
|
1076 |
node.coordsize = this.width + ' ' + this.height;
|
|
|
1077 |
}
|
|
|
1078 |
|
|
|
1079 |
if (isRoot) {
|
|
|
1080 |
this.rootGroup = node;
|
|
|
1081 |
}
|
|
|
1082 |
return node;
|
|
|
1083 |
};
|
|
|
1084 |
|
|
|
1085 |
VectorCanvas.prototype.createPath = function (config) {
|
|
|
1086 |
var node;
|
|
|
1087 |
if (this.mode === 'svg') {
|
|
|
1088 |
node = this.createSvgNode('path');
|
|
|
1089 |
node.setAttribute('d', config.path);
|
|
|
1090 |
|
|
|
1091 |
if (this.params.borderColor !== null) {
|
|
|
1092 |
node.setAttribute('stroke', this.params.borderColor);
|
|
|
1093 |
}
|
|
|
1094 |
if (this.params.borderWidth > 0) {
|
|
|
1095 |
node.setAttribute('stroke-width', this.params.borderWidth);
|
|
|
1096 |
node.setAttribute('stroke-linecap', 'round');
|
|
|
1097 |
node.setAttribute('stroke-linejoin', 'round');
|
|
|
1098 |
}
|
|
|
1099 |
if (this.params.borderOpacity > 0) {
|
|
|
1100 |
node.setAttribute('stroke-opacity', this.params.borderOpacity);
|
|
|
1101 |
}
|
|
|
1102 |
|
|
|
1103 |
node.setFill = function (color) {
|
|
|
1104 |
this.setAttribute('fill', color);
|
|
|
1105 |
if (this.getAttribute('original') === null) {
|
|
|
1106 |
this.setAttribute('original', color);
|
|
|
1107 |
}
|
|
|
1108 |
};
|
|
|
1109 |
|
|
|
1110 |
node.getFill = function () {
|
|
|
1111 |
return this.getAttribute('fill');
|
|
|
1112 |
};
|
|
|
1113 |
|
|
|
1114 |
node.getOriginalFill = function () {
|
|
|
1115 |
return this.getAttribute('original');
|
|
|
1116 |
};
|
|
|
1117 |
|
|
|
1118 |
node.setOpacity = function (opacity) {
|
|
|
1119 |
this.setAttribute('fill-opacity', opacity);
|
|
|
1120 |
};
|
|
|
1121 |
} else {
|
|
|
1122 |
node = this.createVmlNode('shape');
|
|
|
1123 |
node.coordorigin = '0 0';
|
|
|
1124 |
node.coordsize = this.width + ' ' + this.height;
|
|
|
1125 |
node.style.width = this.width + 'px';
|
|
|
1126 |
node.style.height = this.height + 'px';
|
|
|
1127 |
node.fillcolor = JQVMap.defaultFillColor;
|
|
|
1128 |
node.stroked = false;
|
|
|
1129 |
node.path = VectorCanvas.pathSvgToVml(config.path);
|
|
|
1130 |
|
|
|
1131 |
var scale = this.createVmlNode('skew');
|
|
|
1132 |
scale.on = true;
|
|
|
1133 |
scale.matrix = '0.01,0,0,0.01,0,0';
|
|
|
1134 |
scale.offset = '0,0';
|
|
|
1135 |
|
|
|
1136 |
node.appendChild(scale);
|
|
|
1137 |
|
|
|
1138 |
var fill = this.createVmlNode('fill');
|
|
|
1139 |
node.appendChild(fill);
|
|
|
1140 |
|
|
|
1141 |
node.setFill = function (color) {
|
|
|
1142 |
this.getElementsByTagName('fill')[0].color = color;
|
|
|
1143 |
if (this.getAttribute('original') === null) {
|
|
|
1144 |
this.setAttribute('original', color);
|
|
|
1145 |
}
|
|
|
1146 |
};
|
|
|
1147 |
|
|
|
1148 |
node.getFill = function () {
|
|
|
1149 |
return this.getElementsByTagName('fill')[0].color;
|
|
|
1150 |
};
|
|
|
1151 |
node.getOriginalFill = function () {
|
|
|
1152 |
return this.getAttribute('original');
|
|
|
1153 |
};
|
|
|
1154 |
node.setOpacity = function (opacity) {
|
|
|
1155 |
this.getElementsByTagName('fill')[0].opacity = parseInt(opacity * 100, 10) + '%';
|
|
|
1156 |
};
|
|
|
1157 |
}
|
|
|
1158 |
return node;
|
|
|
1159 |
};
|
|
|
1160 |
|
|
|
1161 |
VectorCanvas.prototype.pathSvgToVml = function (path) {
|
|
|
1162 |
var result = '';
|
|
|
1163 |
var cx = 0, cy = 0, ctrlx, ctrly;
|
|
|
1164 |
|
|
|
1165 |
return path.replace(/([MmLlHhVvCcSs])((?:-?(?:\d+)?(?:\.\d+)?,?\s?)+)/g, function (segment, letter, coords) {
|
|
|
1166 |
coords = coords.replace(/(\d)-/g, '$1,-').replace(/\s+/g, ',').split(',');
|
|
|
1167 |
if (!coords[0]) {
|
|
|
1168 |
coords.shift();
|
|
|
1169 |
}
|
|
|
1170 |
|
|
|
1171 |
for (var i = 0, l = coords.length; i < l; i++) {
|
|
|
1172 |
coords[i] = Math.round(100 * coords[i]);
|
|
|
1173 |
}
|
|
|
1174 |
|
|
|
1175 |
switch (letter) {
|
|
|
1176 |
case 'm':
|
|
|
1177 |
cx += coords[0];
|
|
|
1178 |
cy += coords[1];
|
|
|
1179 |
result = 't' + coords.join(',');
|
|
|
1180 |
break;
|
|
|
1181 |
|
|
|
1182 |
case 'M':
|
|
|
1183 |
cx = coords[0];
|
|
|
1184 |
cy = coords[1];
|
|
|
1185 |
result = 'm' + coords.join(',');
|
|
|
1186 |
break;
|
|
|
1187 |
|
|
|
1188 |
case 'l':
|
|
|
1189 |
cx += coords[0];
|
|
|
1190 |
cy += coords[1];
|
|
|
1191 |
result = 'r' + coords.join(',');
|
|
|
1192 |
break;
|
|
|
1193 |
|
|
|
1194 |
case 'L':
|
|
|
1195 |
cx = coords[0];
|
|
|
1196 |
cy = coords[1];
|
|
|
1197 |
result = 'l' + coords.join(',');
|
|
|
1198 |
break;
|
|
|
1199 |
|
|
|
1200 |
case 'h':
|
|
|
1201 |
cx += coords[0];
|
|
|
1202 |
result = 'r' + coords[0] + ',0';
|
|
|
1203 |
break;
|
|
|
1204 |
|
|
|
1205 |
case 'H':
|
|
|
1206 |
cx = coords[0];
|
|
|
1207 |
result = 'l' + cx + ',' + cy;
|
|
|
1208 |
break;
|
|
|
1209 |
|
|
|
1210 |
case 'v':
|
|
|
1211 |
cy += coords[0];
|
|
|
1212 |
result = 'r0,' + coords[0];
|
|
|
1213 |
break;
|
|
|
1214 |
|
|
|
1215 |
case 'V':
|
|
|
1216 |
cy = coords[0];
|
|
|
1217 |
result = 'l' + cx + ',' + cy;
|
|
|
1218 |
break;
|
|
|
1219 |
|
|
|
1220 |
case 'c':
|
|
|
1221 |
ctrlx = cx + coords[coords.length - 4];
|
|
|
1222 |
ctrly = cy + coords[coords.length - 3];
|
|
|
1223 |
cx += coords[coords.length - 2];
|
|
|
1224 |
cy += coords[coords.length - 1];
|
|
|
1225 |
result = 'v' + coords.join(',');
|
|
|
1226 |
break;
|
|
|
1227 |
|
|
|
1228 |
case 'C':
|
|
|
1229 |
ctrlx = coords[coords.length - 4];
|
|
|
1230 |
ctrly = coords[coords.length - 3];
|
|
|
1231 |
cx = coords[coords.length - 2];
|
|
|
1232 |
cy = coords[coords.length - 1];
|
|
|
1233 |
result = 'c' + coords.join(',');
|
|
|
1234 |
break;
|
|
|
1235 |
|
|
|
1236 |
case 's':
|
|
|
1237 |
coords.unshift(cy - ctrly);
|
|
|
1238 |
coords.unshift(cx - ctrlx);
|
|
|
1239 |
ctrlx = cx + coords[coords.length - 4];
|
|
|
1240 |
ctrly = cy + coords[coords.length - 3];
|
|
|
1241 |
cx += coords[coords.length - 2];
|
|
|
1242 |
cy += coords[coords.length - 1];
|
|
|
1243 |
result = 'v' + coords.join(',');
|
|
|
1244 |
break;
|
|
|
1245 |
|
|
|
1246 |
case 'S':
|
|
|
1247 |
coords.unshift(cy + cy - ctrly);
|
|
|
1248 |
coords.unshift(cx + cx - ctrlx);
|
|
|
1249 |
ctrlx = coords[coords.length - 4];
|
|
|
1250 |
ctrly = coords[coords.length - 3];
|
|
|
1251 |
cx = coords[coords.length - 2];
|
|
|
1252 |
cy = coords[coords.length - 1];
|
|
|
1253 |
result = 'c' + coords.join(',');
|
|
|
1254 |
break;
|
|
|
1255 |
|
|
|
1256 |
default:
|
|
|
1257 |
break;
|
|
|
1258 |
}
|
|
|
1259 |
|
|
|
1260 |
return result;
|
|
|
1261 |
|
|
|
1262 |
}).replace(/z/g, '');
|
|
|
1263 |
};
|
|
|
1264 |
|
|
|
1265 |
VectorCanvas.prototype.setSize = function (width, height) {
|
|
|
1266 |
if (this.mode === 'svg') {
|
|
|
1267 |
this.canvas.setAttribute('width', width);
|
|
|
1268 |
this.canvas.setAttribute('height', height);
|
|
|
1269 |
} else {
|
|
|
1270 |
this.canvas.style.width = width + 'px';
|
|
|
1271 |
this.canvas.style.height = height + 'px';
|
|
|
1272 |
this.canvas.coordsize = width + ' ' + height;
|
|
|
1273 |
this.canvas.coordorigin = '0 0';
|
|
|
1274 |
if (this.rootGroup) {
|
|
|
1275 |
var paths = this.rootGroup.getElementsByTagName('shape');
|
|
|
1276 |
for (var i = 0, l = paths.length; i < l; i++) {
|
|
|
1277 |
paths[i].coordsize = width + ' ' + height;
|
|
|
1278 |
paths[i].style.width = width + 'px';
|
|
|
1279 |
paths[i].style.height = height + 'px';
|
|
|
1280 |
}
|
|
|
1281 |
this.rootGroup.coordsize = width + ' ' + height;
|
|
|
1282 |
this.rootGroup.style.width = width + 'px';
|
|
|
1283 |
this.rootGroup.style.height = height + 'px';
|
|
|
1284 |
}
|
|
|
1285 |
}
|
|
|
1286 |
this.width = width;
|
|
|
1287 |
this.height = height;
|
|
|
1288 |
};
|