PageSourceSearch

https://trainfo.ca/wp-content/plugins/relish-freemium//js/public-front-script.js?ver=6.5.12

js trainfo.ca collected 2026-10-03 21:01:40 UTC 15,806 bytes, 581 lines download raw bytes

1jQuery(document).ready(function($) {
2	Freemium.init();
3});
4function numberWithCommas(x) {
5    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
6}
7var Freemium = {};
8
9Freemium.init = function() {
10	
11	
12	
13	if(jQuery('#gform_wrapper_7').length>0)
14	{
15		Freemium.registerForm();
16	}
17	
18	if(jQuery('.fixed-report-gen').length > 0)
19	{
20		Freemium.getCrossingData();
21	}
22	
23	
24	if(jQuery('.view-freemium-report-btn').length>0)
25	{
26		jQuery('.view-freemium-report-btn').on('click',function(e){
27			
28			if(!jQuery(this).hasClass('active'))
29			{
30				e.preventDefault();
31				return false;
32			}
33		});
34		
35	}
36	
37	if(jQuery('#crossing-map').length >0)
38	{
39		var data = {
40			action:'freemium_load_crossing_json'
41		};
42		jQuery.post(freemiumVars.ajax_url,data,function(res){
43			
44		Freemium.crossingData = JSON.parse(res);
45			
46			Freemium.DC();
47			
48			jQuery('.reset-table-data-after-click').on('click',function(){
49				
50				Freemium.resetDataTableAfterClick();
51				
52			});
53			
54			jQuery('.freemium-filter-reset').on('click',function(e){
55				
56				Freemium.countySelect.replaceFilter([[]]);
57				Freemium.citySelect.replaceFilter([[]]);
58				
59				Freemium.choro.replaceFilter([[]]); 
60				dc.redrawAll();
61				Freemium.fitMap();
62				e.preventDefault();
63				Freemium.CheckReset();
64				return false;
65			});
66		});
67	}
68}
69
70Freemium.getCrossingData = function() {
71	
72	var data = {
73		action:'freemium_get_crossing_data'
74	}
75	jQuery.post(freemiumVars.ajax_url,data,function(res){
76		
77		
78		jQuery('.view-freemium-report-btn').addClass('active');
79		jQuery('.report-gen-progress').fadeOut('fast');
80	});
81	
82	
83}
84
85Freemium.registerForm = function() {
86	
87	jQuery('#input_7_14').prepend('<option value="" selected="selected">All Counties</option>');
88	jQuery('#input_7_16').prepend('<option value="" selected="selected">All Cities</option>');
89	
90	jQuery('#gform_7').on('change','#input_7_14',function(){
91		
92		var data = {
93			action:'freemium_get_cities',
94			county:jQuery('#input_7_14').val()
95		};
96		jQuery.post(freemiumVars.ajax_url,data,function(res){
97			res = '<option value="">All Cities</option>'+res;
98			jQuery('#input_7_16').empty().append(res)
99		});
100	});
101	
102	
103}
104
105
106Freemium.DC = function(){
107	
108	
109	var data = [];
110	
111	if(Freemium.crossingData)
112	{
113		
114		Freemium.crossingData.value.lstCrossing.forEach(function(crossing,i){
115			
116			var crossProductFormatted = numberWithCommas(crossing.crossProduct);
117			data.push({
118					name:'<span class="crossing-name-label">'+crossing.street + '</span> <span class="crossing-id-label">' + crossing.code + '</span>',
119					id:crossing.code,
120					city:crossing.city.name,
121					county:crossing.city.county.name,
122					crossProduct:crossProductFormatted,
123					aadt:numberWithCommas(crossing.aadt),
124					blockages:crossing.dailyVolume,
125					vehicleImpact:numberWithCommas(crossing.vehImpacted),
126					hoursDelay:numberWithCommas(crossing.vehDelayHour),
127					accidents:crossing.numAccident,
128					fatalities:crossing.numFatality,
129					fraIncidents:crossing.numFraReported,
130					geo:[crossing.latitude,crossing.longitude],
131				});
132		});
133		
134		
135	}
136/*
137	data.push({
138		name:'test',
139		id:'1234',
140		city:'Chicago',
141		county:'kankalee',
142		crossProduct:1950000,
143		aadt:31600,
144		blockages:4,
145		vehicleImpact:7000,
146		hoursDelay:1600,
147		accidents:0,
148		fatalities:0,
149		fraIncidents:0,
150		geo:[41.833871,-87.8967701],
151	});
152	data.push({
153		name:'test2',
154		id:'12345',
155		city:'Casper',
156		county:'Natrona',
157		crossProduct:1950000,
158		aadt:31600,
159		blockages:8,
160		vehicleImpact:7000,
161		hoursDelay:800,
162		accidents:0,
163		fatalities:0,
164		fraIncidents:0,
165		geo:[42.8546679,-106.3655912],
166	});
167	data.push({
168		name:'test3',
169		id:'123456',
170		city:'Douglas',
171		county:'Converse',
172		crossProduct:1250000,
173		aadt:32600,
174		blockages:16,
175		vehicleImpact:7000,
176		hoursDelay:400,
177		accidents:0,
178		fatalities:0,
179		fraIncidents:0,
180		geo:[42.7542784,-105.4180932],
181	});
182
183	
184	
185*/
186	
187	var xf = crossfilter(data);// primary data
188
189	
190	Freemium.xf = xf;
191	
192	/////// select fields //////////////
193	Freemium.countySelect = new dc.SelectMenu('#county-select'),
194	Freemium.citySelect = new dc.SelectMenu('#city-select');
195	
196	var countyDimension = xf.dimension(function(d) { return d.county; });
197	var cityDimension = xf.dimension(function(d) { return d.city; });
198	
199	Freemium.countySelect
200		.dimension(countyDimension)
201		.group(countyDimension.group())
202		.controlsUseVisibility(true);
203	
204	Freemium.citySelect
205		.dimension(cityDimension)
206		.group(cityDimension.group())
207		.controlsUseVisibility(true);
208	
209	// fly to crossings upon select field change
210	
211	
212	jQuery('.freemium-flexbox').on('change','#city-select select',function(){
213		var filtered = Freemium.xf.allFiltered();
214		//Freemium.choro.map().flyTo(filtered[0].geo);
215		// Freemium.choro.map().setZoom(16);		
216		
217		Freemium.CheckReset();
218		Freemium.fitMap();
219	});
220	jQuery('.freemium-flexbox').on('change','#county-select select',function(){
221		var filtered = Freemium.xf.allFiltered();
222		//Freemium.choro.map().flyTo(filtered[0].geo);
223		// Freemium.choro.map().setZoom(16);
224		Freemium.CheckReset();
225		Freemium.fitMap();
226	});
227
228
229	 ////////// DataTable /////////////
230	 
231	 Freemium.crossingTable = new dc.tableview('#crossing-table');
232	 var fmt = d3.format('02d');
233	 
234	 var crossingTableDimension = xf.dimension(function(d) {return fmt(+d.name);});
235	 var group = crossingTableDimension.group();
236
237	Freemium.crossingTable
238		.dimension(crossingTableDimension)
239		.group(group)
240		.columns([
241		    { title: "CROSSING NAME", data: "name" },
242		    { title: "CITY", data: "city" },
243		    { title: "COUNTY", data: "county" },
244		    { title: "CROSS PRODUCT", data: "crossProduct" },
245		    { title: "AADT", data: "aadt" },
246		    { title: "AVG. TRAINS PER DAY", data: "blockages" },
247		    { title: "AVG. NUMBER OF VEHICLES IMPACTED PER DAY", data: "vehicleImpact" },
248		    { title: "AVG. NUMBER OF VEHICLE DELAY PER DAY IN HOURS", data: "hoursDelay" },
249		    { title: "ACCIDENTS (LAST 5 YEARS)", data: "accidents" },
250		    { title: "FATALITIES (LAST 5 YEARS)", data: "fatalities" },
251		    { title: "FRA Blocked Crossing Reports (Since 2021)", data: "fraIncidents" },
252		])
253		.enableColumnReordering(false)
254		.enablePaging(true)
255		//.enablePagingSizeChange(false)
256		//.enableSearch(false)
257	//	.enableScrolling(false)
258/*
259		.scrollingOptions({
260		    scrollY: "31rem",
261		    scrollX: "31rem",
262		    scrollCollapse: false,
263		    deferRender: true,
264		})
265*/
266		.rowId("id")
267		// .showGroups(true)
268		// .groupBy("Expt")
269	//	.responsive(false)
270	//	.select(false)
271	//	.fixedHeader(false)
272		//.buttons(["pdf", "csv", "excel", "print"])
273		.sortBy([["crossProduct"]])
274		.order('asc')
275		.listeners({
276		    rowClicked: function (row, data, index) {
277
278		       filterCrossing(`Click on row ${index}!`, data);
279		    },
280		    rowDblClicked: function (row, data, index) {
281
282		        filterCrossing(`Double click on row ${index}!`, data);
283		    },
284		    rowEnter: function (row, data, index) {
285		        row.style.backgroundColor = "#eff9ff";
286		    },
287		    rowLeave: function (row, data, index) {
288		        row.style.backgroundColor = "";
289		    }
290		});
291	 
292	 
293	 
294	 ////// filter crossing on table row click
295	 
296	 
297	 filterCrossing = function(event,data){
298		 
299		if(Freemium.xf.allFiltered().length < Freemium.xf.all().length)
300		{
301	 		Freemium.tempData = Freemium.xf.allFiltered();
302	 		jQuery('.reset-table-data-after-click').show();
303	 	}
304
305	 	
306		 Freemium.choro.replaceFilter([[data.geo]]);
307		 
308		 Freemium.countySelect.filter([[data.county]]);
309		 Freemium.citySelect.filter([[data.city]]);
310		 dc.redrawAll();
311
312		 Freemium.fitMap();
313		 
314
315
316		 Freemium.CheckReset();
317
318
319	 };
320	 
321	 Freemium.resetDataTableAfterClick = function(){
322		 
323		if(Freemium.tempData)
324		{
325			var tempMap = Freemium.tempData.map((x)=> x.geo);
326			
327			Freemium.choro.replaceFilter([tempMap]);		 
328			dc.redrawAll();
329			Freemium.fitMap();
330			jQuery('.reset-table-data-after-click').hide();
331
332		}
333		Freemium.CheckReset();
334	 }
335	 ///////// Map ////////////
336
337	 var groupname = "Bubbles";
338      var crossings = xf.dimension(function(d) { return d.geo; });
339      crossingsGroup = crossings.group().reduceSum(function(d) { return d.blockages;});
340      var delayGroup = crossingsGroup
341	  var max = 12;
342	  
343	  
344	  
345	  
346	  dataP = [];
347      var pos = {};
348      var dataByLoc = [];
349      data.forEach(function(d) {
350
351          var points = d.geo;
352
353/*
354          if(Array.isArray(points[0][0]))
355              points = geo.geometry.coordinates.reduce(function(p, v) {
356                  return p.concat(v);
357              }, []);
358*/
359        //  var p = [d3.sum(points, p => +p[1])/points.length, d3.sum(points, p => +p[0])/points.length];
360
361          pos[d.id] = points;
362          d.sum = 0;
363          
364          dataByLoc[d.geo] = d;
365          
366          
367          for(var p in d)
368              if (p && p!="id" && p!="sum") {
369                  dataP.push({'id':d.id,'type':p,'hoursDelay':d.hoursDelay,'value':+d[p]});
370                  d.sum+=+d[p];
371              }
372          if(d.sum > max)
373              max = d.sum;
374      });
375	  
376	  
377	  
378	  var startingPosition = [40.4236726,-96.6671147];
379	  
380	  if(Freemium.crossingData.value.lstCrossing.length>0)
381	  {
382		  startingPosition = [Freemium.crossingData.value.lstCrossing[0].latitude,
383		  Freemium.crossingData.value.lstCrossing[0].longitude];
384	  }
385	  
386	
387	
388	// guess zoom level based on number of crossings, hope to zoom to boun
388ds at some point, this will work for now
389	var defaultMapZoom = 12;
390/*
391	if(xf.allFiltered().length>10) defaultMapZoom = 10;
392	if(xf.allFiltered().length>30) defaultMapZoom = 8;
393	if(xf.allFiltered().length>60) defaultMapZoom = 6;
394	
395*/
396	
397	
398	
399	  
400	Freemium.choro = dc_leaflet.bubbleChart("#crossing-map")
401          .dimension(crossings)
402          .group(crossingsGroup)
403          .width(100)
404          .height(600)
405          .center(startingPosition)
406          .renderPopup(true)
407          .colors(colorbrewer.Reds[3])
408          .colorDomain([
409              d3.min(crossingsGroup.all(), dc.pluck('value')),
410              Freemium.crossingData.value.blockageMetric.average
411          ])
412          .colorAccessor(function(d,i) {
413		  		
414              return d.value;
415          })
416          .popup(function(d){
417
418	          return 'crossing ' + dataByLoc[d.key].id;
419          })
420          .zoom(defaultMapZoom)
421          .valueAccessor(function(d,i){
422
423	          
424	          // if the data is currently filtered, check to see if the crossing should be showing on the map
425	          if(Freemium.xf.allFiltered().length < Freemium.xf.all().length)
426	          {
427		          var found = Freemium.xf.allFiltered().find(o => o.geo == d.key  );
428		          if(!found) return 0;
429	          }
430	          
431	          
432		  		if(d.value ==0) return 0;
433		  		var val = dataByLoc[d.key].hoursDelay * 100;
434
435// 		  		console.log(d3.scaleLog().domain([2, 8]).range([2,8])(val));
436	          return val;
437          })
438          .locationAccessor(d => pos[d.id])
439          .r(d3.scaleLog().domain([1, 4]).range([2,5]))
440         // .legend(dc_leaflet.legend().position('bottomright').legendTitle("Bubble"));
441
442    //  var types = xf.dimension(function(d) { return d.type; });
443    //  var typesGroup = types.group().reduceSum(function(d) { return d.value;});
444
445	
446	/////////////////////////////////////////////////////////////////
447	Freemium.map = Freemium.choro.map;
448	Freemium.choro.on('filtered',function(e){
449		Freemium.CheckReset(); 
450	});
451
452	
453	dc.renderAll();
454	
455	setTimeout(function(){
456		Freemium.fitMap();
457		
458		  if(typeof mapImageData == 'undefined')
459		    {
460		    	Freemium.getScreenshotOfElement();
461			}
462			else {
463				jQuery('.freemium-report-card-summary-btn').addClass('active');
464				jQuery('.freemium-report-card-summary-btn').attr('target','_blank');
465				jQuery('.freemium-report-card-summary-btn').attr('href',jQuery('.freemium-report-card-summary-btn').data('href'));
466				
467				
468			}
469
470		
471	}, 300);
472    //  dc.renderAll(groupname);
473    
474  }
475/*
476	
477	Freemium.getScreenshotOfElement(jQuery("div#crossing-map").get(0), 0, 0, 1920, 400, function(data) {
478	    // in the data variable there is the base64 image
479	    // exmaple for displaying the image in an <img>
480	    jQuery("img#capture").attr("src", "data:image/png;base64,"+data);
481	});
482*/
483
484Freemium.fitMap = function() {
485	
486	if(typeof Freemium.choro.layerGroup().getLayers() !='undefined'){
487		_featureGroup = new L.featureGroup(Freemium.choro.layerGroup().getLayers());
488		Freemium.choro.map().fitBounds(_featureGroup.getBounds());
489	}
490
491}
492Freemium.getScreenshotOfElement = function() {
493	
494	
495		
496		
497	var pluginOptions = {
498	   cropImageByInnerWH: true, // crop blank opacity from image borders
499	   hidden: false, // hide screen icon
500	   preventDownload: false, // prevent download on button click
501	   domtoimageOptions: {}, // see options for dom-to-image
502	   position: 'topleft', // position of take screen icon
503	   screenName: 'screen', // string or function
504	   hideElementsWithSelectors: ['.leaflet-control-container'], // by default hide map controls All els must be child of _map._container
505	   mimeType: 'image/png', // used if format == image,
506	   caption: null, // string or function, added caption to bottom of screen
507	   captionFontSize: 15,
508	   captionFont: 'Arial',
509	   captionColor: 'black',
510	   captionBgColor: 'white',
511	   captionOffset: 5,
512	   // callback for manually edit map if have warn: "May be map size very big on that zoom level, we have error"
513	   // and screenshot not created
514	   onPixelDataFail: async function({ node, plugin, error, mapPane, domtoimageOptions }) {
515	       // Solutions:
516	       // decrease size of map
517	       // or decrease zoom level
518	       // or remove elements with big distanses
519	       // and after that return image in Promise - plugin._getPixelDataOfNormalMap
520	       return plugin._getPixelDataOfNormalMap(domtoimageOptions)
521	   }
522	}
523	
524	var simpleMapScreenshoter = L.simpleMapScreenshoter(pluginOptions).addTo(Freemium.map())
525	var format = 'canvas' // 'image' - return base64, 'canvas' - return canvas
526	var overridedPluginOptions = {
527	  mimeType: 'image/jpeg'
528	}
529	simpleMapScreenshoter.takeScreen(format, overridedPluginOptions).then(canvas => {
530	
531	   var context = canvas.getContext('2d');
532	            var imageData = context.getImageData(jQuery(window).width()/2-400, 0, 800, 400).data;
533	            var outputCanvas = document.createElement('canvas');
534	            var outputContext = outputCanvas.getContext('2d');
535	            outputCanvas.width = 800;
536	            outputCanvas.height = 400;
537	
538	            var idata = outputContext.createImageData(800, 400);
539	            idata.data.set(imageData);
540	            outputContext.putImageData(idata, 0, 0);
541	            var data = outputCanvas.toDataURL().replace("data:image/png;base64,", "");
542	           // jQuery("img.capture").attr("src", "data:image/png;base64,"+data);
543	  
544				var ajax_data = {
545					action:'freemium_save_map_image',
546					map_image_data:data,
547				};
548				jQuery.post(freemiumVars.ajax_url,ajax_data,function(res){
549					
550					jQuery('.freemium-report-card-summary-btn').addClass('active');
551					jQuery('.freemium-report-card-summary-btn').attr('target','_blank');
552
553						jQuery('.freemium-report-card-summary-btn').attr('href',jQuery('.freemium-report-card-summary-btn').data('href'));
554				});
555				
556	  // FileSaver.saveAs(blob, 'screen.png')
557	}).catch(e => {
558	   console.error(e);
559	   	jQuery('.freemium-report-card-summary-btn').addClass('active');
560					jQuery('.freemium-report-card-summary-btn').attr('target','_blank');
561
562						jQuery('.freemium-report-card-summary-btn').attr('href',jQuery('.freemium-report-card-summary-btn').data('href'));
563			
564	})	
565}
566
567
568Freemium.CheckReset = function(){
569	
570	var filtered = Freemium.xf.allFiltered();
571		//Freemium.choro.map().flyTo(filtered[0].geo);
572		// Freemium.choro.map().setZoom(16);		
573
574		if(filtered.length<Freemium.xf.all().length)
575		{
576			jQuery('.freemium-filter-reset').addClass('active');
577		} 
578		else {
579			jQuery('.freemium-filter-reset').removeClass('active');
580		}
581}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.