Refreshing a custom linestring layer in MapBox GL JS on Geocoder event - ajax

I am working with MapBox GL JS and want to redraw a linestring layer based on a Geocoder.on event.
I have the following by way of code and what I am finding is that my linestring draws on the first .on event but nothing happens on subsequent events. Not really sure what I am missing here. I have validated that my Ajax call is returning the desired data point but can't quite figure how to update my linestring layer.
map.on('load', function() {
// Listen for the `result` event from the Geocoder
// `result` event is triggered when a user makes a selection
// Add a linestring based on an Ajax call to a Django model
geocoder.on('result', function(e) {
$.ajax({
url: 'map',
type: 'get',
data: {
longitude: e.result.geometry.coordinates[0],
latitude: e.result.geometry.coordinates[1]
},
success: function(response) {
map.addSource('linestring_layer', {
type: 'geojson',
data: {
type: 'Feature',
properties: {},
geometry: {
'type': 'LineString',
'coordinates': response.linestring
}
}
});
map.addLayer({
id: 'linestring_layer',
type: 'line',
source: 'linestring_layer',
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#00FF00',
'line-width': 4
}
});
map.getSource('linestring_layer').setData({
type: 'Feature',
properties: {},
geometry: {
'type': 'LineString',
'coordinates': response.linestring
}
});
}
});
});
});

At a guess, the second time your event triggers, map.addSource() throws an exception because that source has already been defined, and the rest of the handler is skipped.
You should add your source and layer once, outside the handler. And only call setData() within the handler.

Related

How to apply colours for each events in full calendar js?

I want to show multiple events with different colour for each. Here two ajax response have displayed in calendar. But all the events shows only green. The Second events also visible in green colour. How to show each events with different colours?
My code is as follows:
$('#calendar').fullCalendar({
events: function(start, end, timezone, callback) {
$.ajax({
url: url1,
dataType: 'json',
success: function(response) {
var events = [];
$(response.data).each(function() {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start'), // will be parsed
color: 'green'
});
});
callback(events);
}
});
$.ajax({
url: url2,
dataType: 'json',
success: function(response) {
var events = [];
$(response.data).each(function() {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start'), // will be parsed
color: 'red'
});
});
callback(events);
}
});
}
});

Backbone - rest POST service is called more than once

I have a problem when I call a REST service by POST to updates tables in MySQL.
I'm working with BackboneJS and when click Save button, call the service and passed POST parameters
$.ajax({
type: 'POST',
url: rootURL,
data: dataJson, //data send to REST service by POST
cacheControl: "no-cache",
dataType: "json",
success: function(data){
console.log("OK");
},
error: function(data){
console.log(data.msg);
}
});
But the problem occurs when income and leave the editing screen. Assuming I made a change and it worked perfectly bringing me back a single "OK", when I go back into the editing screen and record again, I get twice the word "OK".
If I repeat this step to enter and exit the screen edition, duplicate responses are based on the number of times into the screen edition.
I don't know if it's a problem about I'm doing wrong with BackboneJS...?? I'm doing this:
editAdverts: function(){
var editAdvertsView = new EditAdvertsView ();
$('#container-page').append(editAdvertsView.render(idAdverts).el);
}
It can also be a topic of AJAX?
I hope someone can help me with this issue because I am not an expert in BackboneJS
Thanks a lot!
Diego
It's hard to tell without more code but I'm pretty sure it's because you are creating a model each time you are using editAdvert.
Instead of creating a model each time just create one at the init of your view then call the fetch/save function anytime you need an update. Creating the model once is enough.
edit: zombies views is a good thing to check too as brent noticed in comment, we can't tell without more code.
This is de code about route:
var Index = {
start: function() {
var list_view = new MainView();
}
};
var AppRouter = Backbone.Router.extend ({
routes: {
'goAdvert' : 'goAdvert'
},
goAdvert: function(){
var viewAdvertsView = new ViewAdvertsView();
$('#container-page').append(viewAdvertsView.render().el);
}
});
var MainView= Backbone.View.extend({
el: $('#contenedor-body'),
initialize: function() {
this.render();
},
render: function() {
// here is the code about main page. It's not important!
},
});
new AppRouter;
Index.start();
Backbone.history.start();
This is the viewAdvertsView.js
define([
'jquery',
'underscore',
'backbone',
'jqueryuniform',
'bootstrap',
'handlebars',
'jqueryDataTables',
'dtBootstrap',
'../../view/editAdvertsView',
], function($, _, Backbone, jqueryuniform, Bootstrap, Handlebars, JQueryDataTables, DtBootstrap, EditAdvertsView){
var viewAdverts = Backbone.View.extend({
events: {
'click #edit' : 'editAdvert'
}
editAdvert: function(){
$('#container-page').empty();
var idAdvert = $(event.target).data('id');
editAdvertView = new EditAdvertsView();
$('#container-page').append(editAdvertView.render(idAdvert).el);
},
render: function() {
// load viewAdverts
}
});
return viewAdverts;
}
);
And this is editAdvertsView.js
define([
'jquery',
'underscore',
'backbone',
'jqueryuniform',
'bootstrap',
'handlebars',
'jqueryDataTables',
'functions',
'sessionManage',
'slimscroll',
'jqueryCustomSlimscroll',
'slimscrollMin',
'jqueryblockui',
'text!../../html/editAdverts.html',
'maps',
'fancybox'
], function($, _, Backbone, jqueryuniform, Bootstrap, Handlebars, JQueryDataTables,
Functions, SessionManage, Slimscroll, JqueryCustomSlimscroll, SlimscrollMin,
Jqueryblockui, EditAdverts, Maps, Fancybox){
var Advert= Backbone.View.extend({
el: $('#container-page'),
events: {
'click #saveChanges' : 'doSaveChanges'
},
doSaveChanges: function(){
var data = null;
var rootURL = "http://localhost/php/slim/slim/advert/update" + "?date=" + $.now();
dataJson = {
id: $("#id").val(),
product: $("#product").val(),
price: $("#price").val(),
client: $("#client").val(),
country: $("#country").val(),
tel: $("#telephone").val(),
cel: $("#cellphone").val()
};
$.ajax({
type: 'POST',
url: rootURL,
data: dataJson,
cacheControl: "no-cache",
dataType: "json",
success: function(data){
console.log("OK");
error: function(data){
console.log(data.msg);
}
}
},
render: function(codInmueble) {
var self = this;
var editTemplate = Handlebars.compile(EditAdverts);
self.$el.html(editTemplate());
return this;
}
});
return Advert;
}
);

How can I generate a real-time highchart from my database data?

I have looked at the following links Binding json result in highcharts for asp.net mvc 4 , highcharts with mvc C# and sql, HighChart Demo and many others. However, I couldn't find a working demo showing how to implement a highchart using data from a database.
Objective:
I want to generate a real time highchart line graph getting data from my database. What I want is very similar to the third link which provides a real-time highchart with randomly generated values. It is also similar by X-axis and Y-axis, for I want my x-axis to be "Time" (I have a DateTime column in my database) and y-axis to be an integer (I have a variable for that as well in my database).
Please I need help in sending the model data to my razor view.
Note that I am already using SignalR to display a realtime table. I also want to know if it can be used to automatically update the highchart as well.
Below is the code snippet of my script in the view. I have used the code provided in link 3 for generating the highchart. Please tell me where should I apply the changes on my code.
#section Scripts{
<script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="~/SignalR/Hubs"></script>
<script type="text/javascript">
$(document).ready(function () {
// Declare a proxy to reference the hub.
var notifications = $.connection.dataHub;
//debugger;
// Create a function that the hub can call to broadcast messages.
notifications.client.updateMessages = function () {
getAllMessages()
};
// Start the connection.
$.connection.hub.start().done(function () {
alert("connection started")
getAllMessages();
}).fail(function (e) {
alert(e);
});
//Highchart
Highcharts.setOptions({
global: {
useUTC: false
}
});
//Fill chart
$('#container').highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.random();
series.addPoint([x, y], true, true);
}, 1000);//300000
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}]
});
});
function getAllMessages() {
var tbl = $('#messagesTable');
var data = #Html.Raw(JsonConvert.SerializeObject(this.Model))
$.ajax({
url: '/home/GetMessages',
data: {
id: data.id,
},
contentType: 'application/html ; charset:utf-8',
type: 'GET',
dataType: 'html'
}).success(function (result) {
tbl.empty().append(result);
$("#g_table").dataTable();
}).error(function (e) {
alert(e);
});
}
</script>
}
UPDATED CODE
//Highchart
Highcharts.setOptions({
global: {
useUTC: false }
});
//Fill chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
defaultSeriesType: 'spline',
events: {
load: $.connection.hub.start().done(function () {
alert("Chart connection started")
var point = getAllMessagesforChart();
var series = this.series[0];
setInterval(function (point) {
// add the point
series.addPoint([point.date_time, point.my_value], true, true)
}, 1000);
}).fail(function (e) {
alert(e);
})
}
}
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
maxZoom: 20 * 1000
},
yAxis: {
minPadding: 0.2,
maxPadding: 0.2,
title: {
text: 'Value',
margin: 80
}
},
series: [{
name: 'Random data',
data: []
}]
});
function getAllMessagesforChart() {
var data = #Html.Raw(JsonConvert.SerializeObject(this.Model))
$.ajax({
url: '/home/GetMessagesforChat',
data: {
id: data.id,
},
contentType: 'application/html ; charset:utf-8',
type: 'GET',
dataType: 'html'
}).success(function (data) {
data = JSON.parse(data);
//data_graph = [].concat(data);
//$("#debug").html(data_graph);
}).error(function (e) {
alert(e);
});
return data;
//return data_graph;
}
There is an example that might help you:
http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/line-ajax/
it uses an ajax callback function.
Well, you can also have a look at my sample where I add dynamically series by clicking add button.
http://plnkr.co/edit/Sh71yN?p=preview
You only need to add data in the right structure.
Have a look at the function
$("#btnAdd").click(function()
of my code script.js
I hope it helps.
regards,
Luis

How can I load all events on calendar using Ajax?

I want to load all events on FullCalendar using AJAX when I clicked next-previous-button in agenda-views.
I guess, when will click on next-previous-button then I'll send current date('y-m-d') to url: 'fetch-events.php' then it will return event{ id: ,title: , start: , end: , allDay: } format data for rendering on calendar
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: false,
selectHelper: false,
editable: false,
events: // on-click next-previous button load events using Ajax
// post date using Ajax, then query to fetch all events and return data
});
JSON not working in my case
From the FullCalendar Online Documentation
FullCalendar will call this function whenever it needs new event data.
This is triggered when the user clicks prev/next or switches views.
This function will be given start and end parameters, which are
Moments denoting the range the calendar needs events for.
timezone is a string/boolean describing the calendar's current
timezone. It is the exact value of the timezone option.
It will also be given callback, a function that must be called when
the custom event function has generated its events. It is the event
function's responsibility to make sure callback is being called with
an array of Event Objects.
Here is an example showing how to use an event function to fetch
events from a hypothetical XML feed:
$('#calendar').fullCalendar({
events: function(start, end, timezone, callback) {
$.ajax({
url: 'myxmlfeed.php',
dataType: 'xml',
data: {
// our hypothetical feed requires UNIX timestamps
start: start.unix(),
end: end.unix()
},
success: function(doc) {
var events = [];
$(doc).find('event').each(function() {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start') // will be parsed
});
});
callback(events);
}
});
}
});
Source
I made some little changes:
$('#calendar').fullCalendar({
events: function(start, end, timezone, callback) {
jQuery.ajax({
url: 'schedule.php/load',
type: 'POST',
dataType: 'json',
data: {
start: start.format(),
end: end.format()
},
success: function(doc) {
var events = [];
if(!!doc.result){
$.map( doc.result, function( r ) {
events.push({
id: r.id,
title: r.title,
start: r.date_start,
end: r.date_end
});
});
}
callback(events);
}
});
}
});
Notes: start and end MUST be ISO 8601. Another change was the use of format instead of unix (this made easier for me to deal with the code-behind)
There is a built in option avaliable
var calendar = new FullCalendar.Calendar(calendarEl, {
events: '/myfeed.php'
})
more details https://fullcalendar.io/docs/events-json-feed
This is perfect way to load data properly.
// if you want to empty events already in calendar.
$('#calendar').fullCalendar('destroy');
$.ajax({
url: 'ABC.com/Calendar/GetAllCalendar/',
type: 'POST',
async: false,
data: { Id: 1 },
success: function (data) {
obj = JSON.stringify(data);
},
error: function (xhr, err) {
alert("readyState: " + xhr.readyState + "\nstatus: " + xhr.status);
alert("responseText: " + xhr.responseText);
}
});
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events div.external-event').each(function () {
// create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/)
// it doesn't need to have a start or end
var eventObject = {
title: $.trim($(this).text()) // use the element's text as the event title
};
// store the Event Object in the DOM element so we can get to it later
$(this).data('eventObject', eventObject);
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
/* initialize the calendar
-----------------------------------------------------------------*/
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
//isRTL: true,
buttonHtml: {
prev: '<i class="ace-icon fa fa-chevron-left"></i>',
next: '<i class="ace-icon fa fa-chevron-right"></i>'
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
//obj that we get json result from ajax
events: JSON.parse(obj)
,
editable: true,
selectable: true
});
fullCalendar already uses ajax, so you don't have to type it. When I was starting to implement fullCalendar I used the solution of the most voted answer here:
https://stackoverflow.com/a/25404081/3927450
but then I could prove, that fullCalendar is in charge of making the ajax call the times the view changes without you having to do anything. I find this plugin very useful, although the documentation did not seem very clear to me.
So this code:
events: function(start, end, timezone, callback) {
jQuery.ajax({
url: 'schedule.php/load',
type: 'POST',
dataType: 'json',
is exactly this:
events: schedule.php/load,
you only have to provide the url. Off course you have to deal with a proper JSON response from the server. Or if you need more params you can do it like this:
events: {
url: '/myfeed.php',
method: 'POST',
extraParams: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
failure: function() {
alert('there was an error while fetching events!');
},
color: 'yellow', // a non-ajax option
textColor: 'black' // a non-ajax option
}
var events= '';
$.ajax({
url: '/eventoscalendar',
dataType: 'json',
type: 'GET',
success: function(data) {
events= JSON.stringify(data);
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
editable: true,
displayEventTime: true,
selectable: true,
droppable: false,
events: JSON.parse(events)
});
}
});
y en /eventoscalendar
public function eventoscalendar()
{
$events[]= [
"title" =>'Meeting',
"start"=> date('Y-m-d'),
"allDay"=> false,
"url"=> 'http://google.com/'
];
return JsonResponse::create($events, 200, array('Content-Type'=>'application/json; charset=utf-8' ));
}

Load data into Highcharts with Ajax

I am trying to update high charts on page load and on select menu change with JQUERY AJAX call. There is data being returned in [[10,1228800000],[10,1228800000]] format.The chart is blank and does not graph any of the data.
Tried several solutions posted on here but none worked.
var chart;
$(document).ready(function() {
var options = {
chart: {
renderTo: 'stats',
defaultSeriesType: 'spline'
},
title: {text:''},
xAxis: {
type: 'datetime'
},
yAxis: {},
series: []
};
var month = 'July';
$.ajax({
type: "POST",
data: "month="+month,
url: "update_visits_chart",
success: function (data) {
options.series.push(data);
chart = new Highcharts.Chart(options);
}
});
Any errors? thanks in advance.
EDIT:
MOST RECENT CODE STILL NOT WORKING:
var options = {
chart: {
renderTo: 'stats',
type: 'spline'
},
title: {
text: ''
},
xAxis: {
type:'datetime',
tickInterval: 30 * 24 * 3600 * 1000,
dateTimeLabelFormats: {
day: '%b %e'
},
labels: {
rotation: -45,
align: 'right'
}
},
yAxis: {
title: {
text: 'Number of visits'
},
min: 0
},
tooltip: {
formatter: function() {
return Highcharts.dateFormat('%b %e', this.x) +'<br />'+this.y+' visit(s)';
}
},
legend: {
enabled: true
},
credits: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Number of Visits',
data: []
}]
};
var month = 'July';
$.ajax({
type: "POST",
url: "update_visits_chart",
data: "month="+month,
success: function(data){
options.series[0].data = data;
chart = new Highcharts.Chart(options);
}
});
You have to use the setData methode of the series object as descriped in documentation. In your case it is options.series[0].setData(Data)
And I think you have to turn your Ajax result from string to a real object/array by using JSON.parse(data).
EDIT:
#Ricardo Lohmann: in the ajax-call he did not specify the dataType he expects in the response, so jQuery will guess the dataType. But it will not recognize a string starting with [ as JSON and I doubt his response will be served with correct mime type application/json. So specifying the correct mime type should also solve the problem. But I do not have an example of the complete ajax respons of the questioner. So I'm just guessing, too.
I'd recommend the following ajax call:
$.ajax({
type: "POST",
url: "update_visits_chart",
data: {month: month},
dataType: 'json',
success: function(data){
options.series[0].setData(data);
}
});
#Jugal Thakkar
$.getJSON is just a shortcut for the ajax-call above, but it is less flexible because you have less options.
You have to set directly data to series because data is already a multidimensional array.
The following code will fix it.
Change options.series.push(data); to options.series = data;

Resources