Failed Conditions
Branch master (9b4e85)
by Markus
03:02
created

pokemon.maps.js ➔ addPokemonMarker   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
c 1
b 0
f 0
nc 8
nop 3
dl 0
loc 77
rs 8.4456

5 Functions

Rating   Name   Duplication   Size   Complexity  
A pokemon.maps.js ➔ ... ➔ marker.addListener(ꞌclickꞌ) 0 4 1
A pokemon.maps.js ➔ ... ➔ setTimeout 0 1 1
A pokemon.maps.js ➔ ... ➔ marker.addListener(ꞌmouseoverꞌ) 0 3 1
A pokemon.maps.js ➔ ... ➔ marker.addListener(ꞌmouseoutꞌ) 0 5 2
A pokemon.maps.js ➔ ... ➔ google.maps.event.addListener 0 3 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/** global: google */
2
/** global: pokemon_id */
3
/** global: navigator */
4
var map, heatmap;
5
var pokemonMarkers = [];
6
var updateLiveTimeout;
7
8
var ivMin = 80;
9
var ivMax = 100;
10
11
function initMap() {
12
	$.getJSON( "core/json/variables.json", function( variables ) {
13
		var latitude = Number(variables['system']['map_center_lat']);
14
		var longitude = Number(variables['system']['map_center_long']);
15
		var zoom_level = Number(variables['system']['zoom_level']);
16
		var pokeimg_suffix = variables['system']['pokeimg_suffix'];
17
18
		map = new google.maps.Map(document.getElementById('map'), {
19
			center: {
20
				lat: latitude,
21
				lng: longitude
22
			},
23
			zoom: zoom_level,
24
			zoomControl: true,
25
			scaleControl: false,
26
			scrollwheel: true,
27
			disableDoubleClickZoom: false,
28
			streetViewControl: false,
29
			mapTypeControlOptions: {
30
				mapTypeIds: [
31
					google.maps.MapTypeId.ROADMAP,
32
					'pogo_style',
33
					'dark_style',
34
				]
35
			}
36
		});
37
38
		$.getJSON( 'core/json/pogostyle.json', function( data ) {
39
			var styledMap_pogo = new google.maps.StyledMapType(data, {name: 'PoGo'});
40
			map.mapTypes.set('pogo_style', styledMap_pogo);
41
		});
42
		$.getJSON( 'core/json/darkstyle.json', function( data ) {
43
			var styledMap_dark = new google.maps.StyledMapType(data, {name: 'Dark'});
44
			map.mapTypes.set('dark_style', styledMap_dark);
45
		});
46
		$.getJSON( 'core/json/defaultstyle.json', function( data ) {
47
			map.set('styles', data);
48
		});
49
		
50
		initHeatmap();
51
		initSelector(pokeimg_suffix);
52
	});
53
}
54
55
function initSelector(pokeimg_suffix){
56
	$('#heatmapSelector').click(function(){
57
		hideLive();
58
		showHeatmap();
59
		$('#heatmapSelector').addClass('active');
60
		$('#liveSelector').removeClass('active');
61
	});
62
	$('#liveSelector').click(function(){
63
		hideHeatmap();
64
		map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
65
		initLive(pokeimg_suffix);
66
		
67
		
68
		$('#liveSelector').addClass('active');
69
		$('#heatmapSelector').removeClass('active');
70
	});
71
}
72
73
function initLive(pokeimg_suffix){
74
	showLive();
75
	$("#liveFilterSelector").rangeSlider({
76
		bounds:{
77
			min: 0,
78
			max: 100
79
		},
80
		defaultValues:{
81
			min: ivMin,
82
			max: ivMax
83
		},
84
		formatter:function(val) {
85
			return "IV: "+Math.round(val)+"%";
86
		}
87
	});
88
	
89
	$("#liveFilterSelector").bind("valuesChanged",function(e, data){
90
		clearTimeout(updateLiveTimeout);
91
		removePokemonMarkerByIv(data.values.min,data.values.max);
92
		ivMin = data.values.min;
93
		ivMax = data.values.max;
94
		updateLive(pokeimg_suffix);
95
	});
96
	updateLive(pokeimg_suffix);
97
	
98
}
99
100
function initHeatmap(){
101
	$.ajax({
102
		'async': true,
103
		'type': "GET",
104
		'global': false,
105
		'dataType': 'json',
106
		'url': "core/process/aru.php",
107
		'data': {
108
			'request': "",
109
			'target': 'arrange_url',
110
			'method': 'method_target',
111
			'type' : 'pokemon_slider_init'
112
		}
113
	}).done(function(bounds){
114
		initHeatmapData(bounds);
115
	});
116
	
117
}
118
119
function initHeatmapData(bounds){
120
	var boundMin = new Date(bounds.min.replace(/-/g, "/"));
121
	var boundMax = new Date(bounds.max.replace(/-/g, "/"));
122
	var selectorMax = boundMax;
123
	var selectorMin = boundMin;
124
125
	// two weeks in millisec
126
	var twoWeeks = 12096e5;
127
	var maxMinus2Weeks = new Date(selectorMax.getTime() - twoWeeks);
128
	if(selectorMin < maxMinus2Weeks){
129
		selectorMin = maxMinus2Weeks;
130
	}
131
132
	// dict with millisec => migration nr.
133
	var migrations = {};
134
	// start at 4 because 06. Oct 2016 was the 4th migration
135
	var migr_nr = 4;
136
	$("#timeSelector").dateRangeSlider({
137
		bounds:{
138
			min: boundMin,
139
			max: boundMax
140
		},
141
		defaultValues:{
142
			min: selectorMin,
143
			max: selectorMax
144
		},
145
		scales: [{
146
			first: function(value) {
147
				// 06. Oct 2016 (4th migration). 2 week schedule starts with this migration
148
				var migrationStart = new Date("2016-10-06");
149
				var now = new Date();
150
				var result = new Date();
151
				for (var migration = migrationStart; migration <= now; migration.setTime(migration.getTime() + twoWeeks)) {
152
					if (migration >= value) {
153
						result = migration;
154
						migrations[result.getTime()] = migr_nr;
155
						break;
156
					}
157
					migr_nr++;
158
				}
159
				return result;
160
			},
161
			next: function(value){
162
				var next = new Date(new Date(value).setTime(value.getTime() + twoWeeks));
163
				migr_nr++;
164
				migrations[next.getTime()] = migr_nr;
165
				return next;
166
			},
167
			label: function(value){
168
				if (isMobileDevice() && isTouchDevice()) {
169
					return "#" + migrations[value.getTime()];
170
				}
171
				return "Migration #" + migrations[value.getTime()];
172
			},
173
		}]
174
	});
175
	createHeatmap();
176
177
}
178
179
function createHeatmap() {
180
	
181
	heatmap = new google.maps.visualization.HeatmapLayer({
182
		data: [],
183
		map: map
184
	});
185
186
	var gradient = [
187
		'rgba(0, 255, 255, 0)',
188
		'rgba(0, 255, 255, 1)',
189
		'rgba(0, 191, 255, 1)',
190
		'rgba(0, 127, 255, 1)',
191
		'rgba(0, 63, 255, 1)',
192
		'rgba(0, 0, 255, 1)',
193
		'rgba(0, 0, 223, 1)',
194
		'rgba(0, 0, 191, 1)',
195
		'rgba(0, 0, 159, 1)',
196
		'rgba(0, 0, 127, 1)',
197
		'rgba(63, 0, 91, 1)',
198
		'rgba(127, 0, 63, 1)',
199
		'rgba(191, 0, 31, 1)',
200
		'rgba(255, 0, 0, 1)'
201
	];
202
	heatmap.set('gradient', gradient);
203
	heatmap.setMap(map);
204
	$("#timeSelector").bind("valuesChanged",function(){updateHeatmap()});
205
	$("#timeSelector").dateRangeSlider("min"); // will trigger valuesChanged
206
}
207
208
function updateHeatmap() {
209
	var dateMin = $("#timeSelector").dateRangeSlider("min");
210
	var dateMax = $("#timeSelector").dateRangeSlider("max");
211
	$("#loaderContainer").show();
212
	$.ajax({
213
		'async': true,
214
		'type': "GET",
215
		'global': false,
216
		'dataType': 'json',
217
		'url': "core/process/aru.php",
218
		'data': {
219
			'request': "",
220
			'target': 'arrange_url',
221
			'method': 'method_target',
222
			'type' : 'pokemon_heatmap_points',
223
			'pokemon_id' : pokemon_id,
224
			'start' : Math.floor(dateMin.getTime()/1000),
225
			'end' : Math.floor(dateMax.getTime()/1000)
226
		}
227
	}).done(function(points){
228
		var googlePoints = [];
229
		for (var i = 0; i < points.length; i++) {
230
			googlePoints.push(new google.maps.LatLng(points[i].latitude,points[i].longitude))
231
		}
232
		var newPoints = new google.maps.MVCArray(googlePoints);
233
		heatmap.set('data', newPoints);
234
		$("#loaderContainer").hide();
235
	});
236
}
237
238
function hideHeatmap() {
239
	$("#timeFilterContainer").hide();
240
	heatmap.set('map', null);
241
}
242
243
function showHeatmap() {
244
	$("#timeFilterContainer").show();
245
	heatmap.set('map', map);
246
	hideLive();
247
}
248
249
function hideLive() {
250
	$("#liveFilterContainer").hide();
251
	clearTimeout(updateLiveTimeout);
252
	clearPokemonMarkers();
253
}
254
255
function showLive() {
256
	hideHeatmap();
257
	clearTimeout(updateLiveTimeout);
258
	$("#liveFilterContainer").show();
259
	
260
}
261
262
function updateLive(pokeimg_suffix){
263
	$.ajax({
264
		'async': true,
265
		'type': "POST",
266
		'global': false,
267
		'dataType': 'json',
268
		'url': "core/process/aru.php",
269
		'data': {
270
			'request': "",
271
			'target': 'arrange_url',
272
			'method': 'method_target',
273
			'type' : 'pokemon_live',
274
			'pokemon_id' : pokemon_id,
275
			'inmap_pokemons' : extractEncountersId(),
276
			'ivMin' : ivMin,
277
			'ivMax' : ivMax
278
		}
279
	}).done(function(pokemons){
280
		for (var i = 0; i < pokemons.points.length; i++) {
281
			addPokemonMarker(pokemons.points[i],pokeimg_suffix, pokemons.locale)
282
		}
283
		updateLiveTimeout=setTimeout(function(){ updateLive(pokeimg_suffix) },5000);
284
	});
285
}
286
287
function addPokemonMarker(pokemon,pokeimg_suffix, locale) {
288
	var image = {
289
		url:'core/pokemons/'+pokemon.pokemon_id+pokeimg_suffix,
290
		scaledSize: new google.maps.Size(32, 32),
291
		origin: new google.maps.Point(0,0),
292
		anchor: new google.maps.Point(16, 16),
293
		labelOrigin : new google.maps.Point(16, 36)
294
	};
295
	var encounter = false;
296
	var ivPercent = 100;
297
	if (pokemon.individual_attack != null) {
0 ignored issues
show
Best Practice introduced by
Comparing pokemon.individual_attack to null using the != operator is not safe. Consider using !== instead.
Loading history...
298
		encounter = true;
299
		ivPercent = ((100/45)*(parseInt(pokemon.individual_attack)+parseInt(pokemon.individual_defense)+parseInt(pokemon.individual_stamina))).toFixed(2);
300
	}
301
	var marker = new google.maps.Marker({
302
		position: {lat: parseFloat(pokemon.latitude), lng:parseFloat(pokemon.longitude)},
303
		map: map,
304
		icon: image,
305
		encounterId: pokemon.encounter_id,
306
		ivPercent: ivPercent
307
	});
308
	if (encounter) {
309
		marker.setLabel({
310
			color:getIvColor(ivPercent),
311
			text:ivPercent+"%"
312
		});
313
	}
314
	var contentString = '<div>'+
315
			'<h4> '+pokemon.name+' #'+pokemon.pokemon_id+ (encounter?' IV: '+ivPercent+'% ':'')+'</h4>'+
316
			'<div id="bodyContent">'+
317
				'<p class="disappear_time_display text-center">'+pokemon.disappear_time_real+'<span class="disappear_time_display_timeleft"></span></p>';
318
	if (encounter) {
319
		contentString +=
320
				'<p></p>'+
321
				'<div class="progress" style="height: 6px; width: 120px; margin-bottom: 10px; margin-top: 2px; margin-left: auto; margin-right: auto">'+
322
					'<div title="'+locale.ivAttack+': '+pokemon.individual_attack+'" class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="'+pokemon.individual_attack+'" aria-valuemin="0" aria-valuemax="45" style="width: '+(((100/15)*pokemon.individual_attack)/3)+'%">'+
323
						'<span class="sr-only">'+locale.ivAttack+': '+pokemon.individual_attack+'</span>'+
324
					'</div>'+
325
					'<div title="'+locale.ivDefense+': '+pokemon.individual_defense+'" class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="'+pokemon.individual_defense+'" aria-valuemin="0" aria-valuemax="45" style="width: '+(((100/15)*pokemon.individual_defense)/3)+'%">'+
326
						'<span class="sr-only">'+locale.ivDefense+': '+pokemon.individual_defense+'</span>'+
327
					'</div>'+
328
					'<div title="'+locale.ivStamina+': '+pokemon.individual_stamina+'" class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="'+pokemon.individual_stamina+'" aria-valuemin="0" aria-valuemax="45" style="width: '+(((100/15)*pokemon.individual_stamina)/3)+'%">'+
329
						'<span class="sr-only">'+locale.ivStamina+': '+pokemon.individual_stamina+'</span>'+
330
					'</div>'+
331
				'</div>'+
332
				'<p class="text-center">('+pokemon.individual_attack+"/"+pokemon.individual_defense+"/"+pokemon.individual_stamina+')</p>'+
333
				'<p class="text-center">'+pokemon.quick_move+"/"+pokemon.charge_move+'</p>';
334
		}
335
		contentString +='</div>';
336
337
	var infoWindow = new google.maps.InfoWindow({
338
		content: contentString
339
	});
340
	infoWindow.isClickOpen = false;
341
	marker.addListener('click', function() {
342
		infoWindow.isClickOpen = true;
343
		infoWindow.open(map, this);
344
	});
345
	google.maps.event.addListener(infoWindow,'closeclick',function(){
346
		this.isClickOpen = false;
347
	});
348
	marker.addListener('mouseover', function() {
349
		infoWindow.open(map, this);
350
	});
351
352
	// assuming you also want to hide the infowindow when user mouses-out
353
	marker.addListener('mouseout', function() {
354
		if(infoWindow.isClickOpen === false){
355
			infoWindow.close();
356
		}
357
	});
358
	pokemonMarkers.push(marker);
359
	var now = new Date().getTime();
360
	var endTime = new Date(pokemon.disappear_time_real.replace(/-/g, "/")).getTime();
361
	
362
	setTimeout(function(){ removePokemonMarker(pokemon.encounter_id) },endTime-now);
363
}
364
365
366
function getIvColor(ivPercent){
367
	var ivColor="rgba(0, 0, 0, 0)";
368
	if(ivPercent>80){
369
		ivColor="rgba(0, 0, 255, 0.70)";
370
	}
371
	if(ivPercent>90){
372
		ivColor="rgba(246, 178, 107, 0.90)";
373
	}
374
	if(ivPercent>99){
375
		ivColor="rgba(255, 0, 0, 1)";
376
	}
377
	return ivColor;
378
}
379
380
function clearPokemonMarkers() {
381
	for (var i = 0; i < pokemonMarkers.length; i++) {
382
		pokemonMarkers[i].setMap(null);
383
	}
384
	pokemonMarkers = [];
385
}
386
function removePokemonMarker(encounter_id) {
387
	for (var i = 0; i < pokemonMarkers.length; i++) {
388
		if(pokemonMarkers[i].encounterId == encounter_id){
389
			pokemonMarkers[i].setMap(null);
390
			pokemonMarkers.splice(i,1);
391
			break;
392
		}
393
		
394
	}
395
	
396
}
397
398
function removePokemonMarkerByIv(ivMin,ivMax) {
399
	var cleanMarkers=[];
400
	for (var i = 0; i < pokemonMarkers.length; i++) {
401
		if(pokemonMarkers[i].ivPercent < ivMin || pokemonMarkers[i].ivPercent > ivMax){
402
			pokemonMarkers[i].setMap(null);
403
		}
404
		else{
405
			cleanMarkers.push(pokemonMarkers[i]);
406
		}
407
		
408
	}
409
	pokemonMarkers = cleanMarkers;
410
}
411
412
function extractEncountersId(){
413
	var inmapEncounter = [];
414
	for (var i = 0; i < pokemonMarkers.length; i++) {
415
		inmapEncounter[i]=pokemonMarkers[i].encounterId;
416
	}
417
	
418
	return inmapEncounter;
419
}
420
421
function isTouchDevice() {
422
    // Should cover most browsers
423
    return 'ontouchstart' in window || navigator.maxTouchPoints
424
}
425
426
function isMobileDevice() {
427
    //  Basic mobile OS (not browser) detection
428
    return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))
429
}
430