LaravelTest

Форк
0
/
jquery.vmap.js 
1289 строк · 33.5 Кб
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('&#x2212;').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
  this.zoomCurStep = 1;
889
};
890

891
JQVMap.prototype.resize = function () {
892
  var curBaseScale = this.baseScale;
893
  if (this.width / this.height > this.defaultWidth / this.defaultHeight) {
894
    this.baseScale = this.height / this.defaultHeight;
895
    this.baseTransX = Math.abs(this.width - this.defaultWidth * this.baseScale) / (2 * this.baseScale);
896
  } else {
897
    this.baseScale = this.width / this.defaultWidth;
898
    this.baseTransY = Math.abs(this.height - this.defaultHeight * this.baseScale) / (2 * this.baseScale);
899
  }
900
  this.scale *= this.baseScale / curBaseScale;
901
  this.transX *= this.baseScale / curBaseScale;
902
  this.transY *= this.baseScale / curBaseScale;
903
};
904

905
JQVMap.prototype.select = function (cc, path) {
906
  cc = cc.toLowerCase();
907
  path = path || jQuery('#' + this.getCountryId(cc))[0];
908

909
  if (!this.isSelected(cc)) {
910
    if (this.multiSelectRegion) {
911
      this.selectedRegions.push(cc);
912
    } else {
913
      this.selectedRegions = [cc];
914
    }
915

916
    jQuery(this.container).trigger('regionSelect.jqvmap', [cc]);
917
    if (this.selectedColor && path) {
918
      path.currentFillColor = this.selectedColor;
919
      path.setFill(this.selectedColor);
920
    }
921
  }
922
};
923

924
JQVMap.prototype.selectIndex = function (cc) {
925
  cc = cc.toLowerCase();
926
  for (var i = 0; i < this.selectedRegions.length; i++) {
927
    if (cc === this.selectedRegions[i]) {
928
      return i;
929
    }
930
  }
931
  return -1;
932
};
933

934
JQVMap.prototype.setBackgroundColor = function (backgroundColor) {
935
  this.container.css('background-color', backgroundColor);
936
};
937

938
JQVMap.prototype.setColors = function (key, color) {
939
  if (typeof key === 'string') {
940
    this.countries[key].setFill(color);
941
    this.countries[key].setAttribute('original', color);
942
  } else {
943
    var colors = key;
944

945
    for (var code in colors) {
946
      if (this.countries[code]) {
947
        this.countries[code].setFill(colors[code]);
948
        this.countries[code].setAttribute('original', colors[code]);
949
      }
950
    }
951
  }
952
};
953

954
JQVMap.prototype.setNormalizeFunction = function (f) {
955
  this.colorScale.setNormalizeFunction(f);
956

957
  if (this.values) {
958
    this.setValues(this.values);
959
  }
960
};
961

962
JQVMap.prototype.setScale = function (scale) {
963
  this.scale = scale;
964
  this.applyTransform();
965
};
966

967
JQVMap.prototype.setScaleColors = function (colors) {
968
  this.colorScale.setColors(colors);
969

970
  if (this.values) {
971
    this.setValues(this.values);
972
  }
973
};
974

975
JQVMap.prototype.setValues = function (values) {
976
  var max = 0,
977
    min = Number.MAX_VALUE,
978
    val;
979

980
  for (var cc in values) {
981
    cc = cc.toLowerCase();
982
    val = parseFloat(values[cc]);
983

984
    if (isNaN(val)) {
985
      continue;
986
    }
987
    if (val > max) {
988
      max = values[cc];
989
    }
990
    if (val < min) {
991
      min = val;
992
    }
993
  }
994

995
  if (min === max) {
996
    max++;
997
  }
998

999
  this.colorScale.setMin(min);
1000
  this.colorScale.setMax(max);
1001

1002
  var colors = {};
1003
  for (cc in values) {
1004
    cc = cc.toLowerCase();
1005
    val = parseFloat(values[cc]);
1006
    colors[cc] = isNaN(val) ? this.color : this.colorScale.getColor(val);
1007
  }
1008
  this.setColors(colors);
1009
  this.values = values;
1010
};
1011

1012
JQVMap.prototype.unhighlight = function (cc, path) {
1013
  cc = cc.toLowerCase();
1014
  path = path || jQuery('#' + this.getCountryId(cc))[0];
1015
  path.setOpacity(1);
1016
  if (path.currentFillColor) {
1017
    path.setFill(path.currentFillColor);
1018
  }
1019
};
1020

1021
JQVMap.prototype.zoomIn = function () {
1022
  var map = this;
1023
  var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
1024

1025
  if (map.zoomCurStep < map.zoomMaxStep) {
1026
    map.transX -= (map.width / map.scale - map.width / (map.scale * map.zoomStep)) / 2;
1027
    map.transY -= (map.height / map.scale - map.height / (map.scale * map.zoomStep)) / 2;
1028
    map.setScale(map.scale * map.zoomStep);
1029
    map.zoomCurStep++;
1030

1031
    var $slider = jQuery('#zoomSlider');
1032

1033
    $slider.css('top', parseInt($slider.css('top'), 10) - sliderDelta);
1034

1035
    map.container.trigger('zoomIn');
1036
  }
1037
};
1038

1039
JQVMap.prototype.zoomOut = function () {
1040
  var map = this;
1041
  var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
1042

1043
  if (map.zoomCurStep > 1) {
1044
    map.transX += (map.width / (map.scale / map.zoomStep) - map.width / map.scale) / 2;
1045
    map.transY += (map.height / (map.scale / map.zoomStep) - map.height / map.scale) / 2;
1046
    map.setScale(map.scale / map.zoomStep);
1047
    map.zoomCurStep--;
1048

1049
    var $slider = jQuery('#zoomSlider');
1050

1051
    $slider.css('top', parseInt($slider.css('top'), 10) + sliderDelta);
1052

1053
    map.container.trigger('zoomOut');
1054
  }
1055
};
1056

1057
VectorCanvas.prototype.applyTransformParams = function (scale, transX, transY) {
1058
  if (this.mode === 'svg') {
1059
    this.rootGroup.setAttribute('transform', 'scale(' + scale + ') translate(' + transX + ', ' + transY + ')');
1060
  } else {
1061
    this.rootGroup.coordorigin = (this.width - transX) + ',' + (this.height - transY);
1062
    this.rootGroup.coordsize = this.width / scale + ',' + this.height / scale;
1063
  }
1064
};
1065

1066
VectorCanvas.prototype.createGroup = function (isRoot) {
1067
  var node;
1068
  if (this.mode === 'svg') {
1069
    node = this.createSvgNode('g');
1070
  } else {
1071
    node = this.createVmlNode('group');
1072
    node.style.width = this.width + 'px';
1073
    node.style.height = this.height + 'px';
1074
    node.style.left = '0px';
1075
    node.style.top = '0px';
1076
    node.coordorigin = '0 0';
1077
    node.coordsize = this.width + ' ' + this.height;
1078
  }
1079

1080
  if (isRoot) {
1081
    this.rootGroup = node;
1082
  }
1083
  return node;
1084
};
1085

1086
VectorCanvas.prototype.createPath = function (config) {
1087
  var node;
1088
  if (this.mode === 'svg') {
1089
    node = this.createSvgNode('path');
1090
    node.setAttribute('d', config.path);
1091

1092
    if (this.params.borderColor !== null) {
1093
      node.setAttribute('stroke', this.params.borderColor);
1094
    }
1095
    if (this.params.borderWidth > 0) {
1096
      node.setAttribute('stroke-width', this.params.borderWidth);
1097
      node.setAttribute('stroke-linecap', 'round');
1098
      node.setAttribute('stroke-linejoin', 'round');
1099
    }
1100
    if (this.params.borderOpacity > 0) {
1101
      node.setAttribute('stroke-opacity', this.params.borderOpacity);
1102
    }
1103

1104
    node.setFill = function (color) {
1105
      this.setAttribute('fill', color);
1106
      if (this.getAttribute('original') === null) {
1107
        this.setAttribute('original', color);
1108
      }
1109
    };
1110

1111
    node.getFill = function () {
1112
      return this.getAttribute('fill');
1113
    };
1114

1115
    node.getOriginalFill = function () {
1116
      return this.getAttribute('original');
1117
    };
1118

1119
    node.setOpacity = function (opacity) {
1120
      this.setAttribute('fill-opacity', opacity);
1121
    };
1122
  } else {
1123
    node = this.createVmlNode('shape');
1124
    node.coordorigin = '0 0';
1125
    node.coordsize = this.width + ' ' + this.height;
1126
    node.style.width = this.width + 'px';
1127
    node.style.height = this.height + 'px';
1128
    node.fillcolor = JQVMap.defaultFillColor;
1129
    node.stroked = false;
1130
    node.path = VectorCanvas.pathSvgToVml(config.path);
1131

1132
    var scale = this.createVmlNode('skew');
1133
    scale.on = true;
1134
    scale.matrix = '0.01,0,0,0.01,0,0';
1135
    scale.offset = '0,0';
1136

1137
    node.appendChild(scale);
1138

1139
    var fill = this.createVmlNode('fill');
1140
    node.appendChild(fill);
1141

1142
    node.setFill = function (color) {
1143
      this.getElementsByTagName('fill')[0].color = color;
1144
      if (this.getAttribute('original') === null) {
1145
        this.setAttribute('original', color);
1146
      }
1147
    };
1148

1149
    node.getFill = function () {
1150
      return this.getElementsByTagName('fill')[0].color;
1151
    };
1152
    node.getOriginalFill = function () {
1153
      return this.getAttribute('original');
1154
    };
1155
    node.setOpacity = function (opacity) {
1156
      this.getElementsByTagName('fill')[0].opacity = parseInt(opacity * 100, 10) + '%';
1157
    };
1158
  }
1159
  return node;
1160
};
1161

1162
VectorCanvas.prototype.pathSvgToVml = function (path) {
1163
  var result = '';
1164
  var cx = 0, cy = 0, ctrlx, ctrly;
1165

1166
  return path.replace(/([MmLlHhVvCcSs])((?:-?(?:\d+)?(?:\.\d+)?,?\s?)+)/g, function (segment, letter, coords) {
1167
    coords = coords.replace(/(\d)-/g, '$1,-').replace(/\s+/g, ',').split(',');
1168
    if (!coords[0]) {
1169
      coords.shift();
1170
    }
1171

1172
    for (var i = 0, l = coords.length; i < l; i++) {
1173
      coords[i] = Math.round(100 * coords[i]);
1174
    }
1175

1176
    switch (letter) {
1177
      case 'm':
1178
        cx += coords[0];
1179
        cy += coords[1];
1180
        result = 't' + coords.join(',');
1181
        break;
1182

1183
      case 'M':
1184
        cx = coords[0];
1185
        cy = coords[1];
1186
        result = 'm' + coords.join(',');
1187
        break;
1188

1189
      case 'l':
1190
        cx += coords[0];
1191
        cy += coords[1];
1192
        result = 'r' + coords.join(',');
1193
        break;
1194

1195
      case 'L':
1196
        cx = coords[0];
1197
        cy = coords[1];
1198
        result = 'l' + coords.join(',');
1199
        break;
1200

1201
      case 'h':
1202
        cx += coords[0];
1203
        result = 'r' + coords[0] + ',0';
1204
        break;
1205

1206
      case 'H':
1207
        cx = coords[0];
1208
        result = 'l' + cx + ',' + cy;
1209
        break;
1210

1211
      case 'v':
1212
        cy += coords[0];
1213
        result = 'r0,' + coords[0];
1214
        break;
1215

1216
      case 'V':
1217
        cy = coords[0];
1218
        result = 'l' + cx + ',' + cy;
1219
        break;
1220

1221
      case 'c':
1222
        ctrlx = cx + coords[coords.length - 4];
1223
        ctrly = cy + coords[coords.length - 3];
1224
        cx += coords[coords.length - 2];
1225
        cy += coords[coords.length - 1];
1226
        result = 'v' + coords.join(',');
1227
        break;
1228

1229
      case 'C':
1230
        ctrlx = coords[coords.length - 4];
1231
        ctrly = coords[coords.length - 3];
1232
        cx = coords[coords.length - 2];
1233
        cy = coords[coords.length - 1];
1234
        result = 'c' + coords.join(',');
1235
        break;
1236

1237
      case 's':
1238
        coords.unshift(cy - ctrly);
1239
        coords.unshift(cx - ctrlx);
1240
        ctrlx = cx + coords[coords.length - 4];
1241
        ctrly = cy + coords[coords.length - 3];
1242
        cx += coords[coords.length - 2];
1243
        cy += coords[coords.length - 1];
1244
        result = 'v' + coords.join(',');
1245
        break;
1246

1247
      case 'S':
1248
        coords.unshift(cy + cy - ctrly);
1249
        coords.unshift(cx + cx - ctrlx);
1250
        ctrlx = coords[coords.length - 4];
1251
        ctrly = coords[coords.length - 3];
1252
        cx = coords[coords.length - 2];
1253
        cy = coords[coords.length - 1];
1254
        result = 'c' + coords.join(',');
1255
        break;
1256

1257
      default:
1258
        break;
1259
    }
1260

1261
    return result;
1262

1263
  }).replace(/z/g, '');
1264
};
1265

1266
VectorCanvas.prototype.setSize = function (width, height) {
1267
  if (this.mode === 'svg') {
1268
    this.canvas.setAttribute('width', width);
1269
    this.canvas.setAttribute('height', height);
1270
  } else {
1271
    this.canvas.style.width = width + 'px';
1272
    this.canvas.style.height = height + 'px';
1273
    this.canvas.coordsize = width + ' ' + height;
1274
    this.canvas.coordorigin = '0 0';
1275
    if (this.rootGroup) {
1276
      var paths = this.rootGroup.getElementsByTagName('shape');
1277
      for (var i = 0, l = paths.length; i < l; i++) {
1278
        paths[i].coordsize = width + ' ' + height;
1279
        paths[i].style.width = width + 'px';
1280
        paths[i].style.height = height + 'px';
1281
      }
1282
      this.rootGroup.coordsize = width + ' ' + height;
1283
      this.rootGroup.style.width = width + 'px';
1284
      this.rootGroup.style.height = height + 'px';
1285
    }
1286
  }
1287
  this.width = width;
1288
  this.height = height;
1289
};
1290

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.