I recently started using the map plugin. And Faced the problem of creating markers on click and displaying latitude and longitude on world map. Maybe someone has an example of how to implement this. Thank you for your assistance.
You can use the click event for a chart and series, calculate lat and lon values and add new point to the mappoint series.
Highcharts.mapChart('container', {
chart: {
map: 'custom/world-continents',
events: {
click: function(e) {
const latlon = this.fromPointToLatLon({
x: e.xAxis[0].value,
y: e.yAxis[0].value
});
this.series[1].addPoint(latlon);
}
}
},
plotOptions: {
map: {
events: {
click: function(e) {
const {
chart,
xAxis,
yAxis
} = this;
const latlon = chart.fromPointToLatLon({
x: xAxis.toValue(e.x),
y: yAxis.toValue(e.y)
});
chart.series[1].addPoint(latlon);
}
}
}
},
...
series: [{
...
}, {
type: 'mappoint',
colorAxis: null,
enableMouseTracking: false,
color: 'red',
dataLabels: {
allowOverlap: true,
formatter: function() {
const {
lat,
lon
} = this.point;
return 'Lat: ' + (lat.toFixed(2)) + '<br>Lon: ' + (lon.toFixed(2))
}
}
}]
});
Live demo: https://jsfiddle.net/BlackLabel/6p1bv0jn/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.Chart#transformToLatLon
https://api.highcharts.com/highmaps/chart.events.click
https://api.highcharts.com/highmaps/plotOptions.map.events.click
Here is the ajax code, am doubting the resource section because it has 645 data's in the array. when i put small amount of static data's it works. Chrome, firefox and safari works fin only in IE it takes time to generate the calendar.
any one can help me on this please.
//get vehicle to calendar
$.ajax({
method: "GET",
url: '#Url.Action("WP", "WeeklyPlan")',
cache: false,
data: {
}, success: function (data) {
resource = []
events = []
var vehiclesWithReserations = data.vehicles;
if (vehiclesWithReserations == null) {
hideLoader();
toastr.warning(data.message);
return;
} else if (vehiclesWithReserations.length == 0) {
hideLoader();
}
var holidayList = data.holidays;
$.each(vehiclesWithReserations, function (i, v) {
resource.push({
id: v.FuhrparkFahrzeugID,
title: v.ModellName,
field: v.LocationId,
zuteilung: v.ZutName,
nvx: v.NVX
});
for (var q = 0; q < v.Reservations.length; q++) {
events.push({
id: v.Reservations[q].ReservationID,
resourceId: v.FuhrparkFahrzeugID,
start: moment(v.Reservations[q].DateFrom).toDate(),
end: moment(v.Reservations[q].DateTo).toDate()
})
}
});
generatecalender(holidayList);
}
Here, my javascript code to render markers in map and after that fitBounds of that map.
Map bounds are get fit according to geojson, but problem is that when there is any marker
on map and I try to fit bound, map tiles images are not get render.
In map it display only markers, no tile images.
var latLongCollection = [];
var map;
$(document).ready(function() {
map();
});
function map() {
map = L.mapbox.map('DivId', 'ProjectId');
GetData();
}
function GetData() {
$.ajax({
type: "GET",
url: someUrl,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: AjaxSuccess,
error: function () {
}
});
}
function AjaxSuccess(data) {
if (data == null || data.length == 0) {
return;
}
var geoJson = {
"type": "FeatureCollection",
"features": []
};
$.each(data, function (index, value) {
var latitude = parseFloat(value.Latitude),
longitude = parseFloat(value.Longitude);
if (latitude && longitude) {
var dataJson = {
type: "Feature",
geometry: { type: "Point", coordinates: [longitude, latitude] },
properties: {
someProp: value.SomeProperty,
}
};
geoJson.features.push(vehicleJson);
}
});
var markerLayer = L.mapbox.featureLayer(geoJson).addTo(map);
markerLayer.eachLayer(function (marker) {
var feature = marker.feature;
var featureProperty = feature.properties;
if (featureProperty.someProp) {
marker.setIcon(L.divIcon({
html: 'htmlstring',
iconSize: [35, 75]
}));
}
else {
marker.setIcon(L.divIcon({
html: 'anotherhtmlstring',
iconSize: [35, 75]
}));
}
latLongCollection.push(marker._latlng);
});
markerLayer.on('click', function (e) {
map.panTo(e.layer.getLatLng());
});
if (latLongCollection.length > 0) {
map.fitBounds(latLongCollection);
}
}
If anyone is still struggling with this, it appears to be a bug in Leaflet: https://github.com/Leaflet/Leaflet/issues/2021
It has been fixed in the latest version, but if you can't update you can work around the race condition by setting a timeout:
setTimeout(function () {
map.fitBounds(latLongCollection);
}, 0);
How did you try debug the problem? What's your network and js console saying?
Try to zoom out, maybe fitBounds zooms your map too much. I had this problem. The solution was using maxSize option in fitBounds, see leaflet docs.
I've created the following testcase in JSFiddle: http://jsfiddle.net/4Wtb3/15/. When I check a checkbox for route A or route B, the routes are displayed. So far, so good ...
if (routes.length > 0) {
for (var i = 0; i < routes.length; i++) {
var route = routes[i];
var request = {
origin: route.origin,
destination: route.destination,
travelMode: google.maps.TravelMode.WALKING
};
var directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: true,
preserveViewport: true,
polylineOptions: {
strokeColor: '#C6D300'
}
});
directionsDisplay.setMap(map);
directionsDisplays.push(directionsDisplay);
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
}
But when I uncheck them, I want to clear the selected route. I keep track of all directionDisplay's using an array (to put the map value to 'null'). First I clear everything, then I redraw every route which is still in the list.
The problem: routes are still in the map, even if I uncheck them ...
Any idea's what exactly is going wrong?
There is no length of array in for loop so setMap(null) is never called. Code should be changed from
if (directionsDisplays.length > 0) {
for(var i = 0; i < directionsDisplays; i++) {
directionsDisplays[i].setMap(null);
}
}
to
if (directionsDisplays.length > 0) {
for(var i = 0; i < directionsDisplays.length; i++) {
directionsDisplays[i].setMap(null);
}
}
...
And additional fix for closure problem:
// Draw all routes
if (routes.length > 0) {
for (var i = 0; i < routes.length; i++) {
(function(i){
var route = routes[i];
var request = {
origin: route.origin,
destination: route.destination,
travelMode: google.maps.TravelMode.WALKING
};
....
})(i);
}
}
Updated example at jsfiddle
I have a Kendo UI grid and a Kendo UI Window on the same page. The window contains form elements for record insertion, a record being represented by a row in the grid. But for reasons not known by me, when I opened the window and closed it again and then reopened, Kendo UI scaled it to be 100x smaller. I didn't want to hack the window, so I've looked for alternative solution.
I've used jQuery 1.7.2. I've updated jQuery to version 1.8.0. and window opening, closing and reopening worked. I was very happy until I realized that now the grid filters are not working. When I click on a grid filter, nothing happens, no popup, nothing. What is the cause of this and what would be the solution?
EDIT:
This is my code (I've replaced the values of the Urls). Grid filters are working with jQuery 1.7.2. and window reopen works with new versions of jQuery. Also, if I remove the sort hack, the grid filter popup still doesn't show up.
var hshflt = {};
var addWindow;
var editWindow;
var init = false;
//Sort Hack
/*
Changes all dataSources to case insensitive sorting (client side sorting).
This snipped enable case insensitive sorting on Kendo UI grid, too.
The original case sensitive comparer is a private and can't be accessed without modifying the original source code.
tested with Kendo UI version 2012.2.710 (Q2 2012 / July 2012).
*/
var CaseInsensitiveComparer = {
getterCache: {},
getter: function (expression) {
return this.getterCache[expression] = this.getterCache[expression] || new Function("d", "return " + kendo.expr(expression));
},
selector: function (field) {
return jQuery.isFunction(field) ? field : this.getter(field);
},
asc: function (field) {
var selector = this.selector(field);
return function (a, b) {
if ((selector(a).toLowerCase) && (selector(b).toLowerCase)) {
a = selector(a).toLowerCase(); // the magical part
b = selector(b).toLowerCase();
}
return a > b ? 1 : (a < b ? -1 : 0);
};
},
desc: function (field) {
var selector = this.selector(field);
return function (a, b) {
if ((selector(a).toLowerCase) && (selector(b).toLowerCase)) {
a = selector(a).toLowerCase(); // the magical part
b = selector(b).toLowerCase();
}
return a < b ? 1 : (a > b ? -1 : 0);
};
},
create: function (descriptor) {
return this[descriptor.dir.toLowerCase()](descriptor.field);
},
combine: function (comparers) {
return function (a, b) {
var result = comparers[0](a, b),
idx,
length;
for (idx = 1, length = comparers.length; idx < length; idx++) {
result = result || comparers[idx](a, b);
}
return result;
};
}
};
kendo.data.Query.prototype.normalizeSort = function (field, dir) {
if (field) {
var descriptor = typeof field === "string" ? { field: field, dir: dir} : field,
descriptors = jQuery.isArray(descriptor) ? descriptor : (descriptor !== undefined ? [descriptor] : []);
return jQuery.grep(descriptors, function (d) { return !!d.dir; });
}
};
kendo.data.Query.prototype.sort = function (field, dir, comparer) {
var idx,
length,
descriptors = this.normalizeSort(field, dir),
comparers = [];
comparer = comparer || CaseInsensitiveComparer;
if (descriptors.length) {
for (idx = 0, length = descriptors.length; idx < length; idx++) {
comparers.push(comparer.create(descriptors[idx]));
}
return this.orderBy({ compare: comparer.combine(comparers) });
}
return this;
};
kendo.data.Query.prototype.orderBy = function (selector) {
var result = this.data.slice(0),
comparer = jQuery.isFunction(selector) || !selector ? CaseInsensitiveComparer.asc(selector) : selector.compare;
return new kendo.data.Query(result.sort(comparer));
};
kendo.data.Query.prototype.orderByDescending = function (selector) {
return new kendo.data.Query(this.data.slice(0).sort(CaseInsensitiveComparer.desc(selector)));
};
//Sort Hack
$("#refresh-btn").click(function () {
refreshGrid();
});
var grid;
function getPageIndex() {
if (!(grid)) {
return 0;
}
return grid.pager.page() - 1;
}
function getPageSize() {
if (!(grid)) {
return 10;
}
return grid.pager.pageSize();
}
function getFilters() {
if (!(grid)) {
return "";
}
return grid.dataSource.filter();
}
function getSorts() {
if (!(grid)) {
return "";
}
var arr = grid.dataSource.sort();
if ((arr) && (arr.length == 0)) {
return "";
}
var returnValue = "";
for (var index in arr) {
var type = "";
for (var col in grid.columns) {
if (grid.columns[col].field === arr[index].field) {
type = grid.columns[col].type;
}
}
returnValue += ((returnValue.length > 0) ? (";") : ("")) + arr[index].field + "," + (arr[index].dir === "asc") + "," + type;
}
return returnValue;
}
function getColumns() {
if (!(grid)) {
return "";
}
var columns = "";
for (var col in grid.columns) {
if (columns.length > 0) {
columns += ";";
}
columns += grid.columns[col].field + "," + grid.columns[col].type;
}
return columns;
}
var initGrid = true;
var grid2Data;
function getDataSource() {
$.ajax({
type: 'POST',
url: 'mydsurl' + getParams(),
data: "filter=" + JSON.stringify(getFilters()) + "&columns=" + getColumns(),
success: function (param) { grid2Data = param; },
//dataType: dataType,
async: false
});
return grid2Data.Data;
}
var shouldClickOnRefresh = false;
function refreshGrid() {
shouldClickOnRefresh = false;
$.ajax({
type: 'POST',
url: 'mydsurl' + getParams(),
data: "filter=" + JSON.stringify(getFilters()) + "&columns=" + getColumns(),
success: function (param) { grid2Data = param; },
//dataType: dataType,
async: false
});
grid.dataSource.total = function () {
return grid2Data.Total;
}
for (var col in grid.columns) {
if ((grid.columns[col].type) && (grid.columns[col].type === "Date")) {
for (var row in grid2Data.Data) {
grid2Data.Data[row][grid.columns[col].field] = new Date(parseInt((grid2Data.Data[row][grid.columns[col].field] + "").replace("/Date(", "").replace(")/", "")));
}
}
}
grid.dataSource.data(grid2Data.Data);
shouldClickOnRefresh = true;
}
function getParams() {
return getPageSize() + "|" + getPageIndex() + "|" + getSorts();
}
function bindGrid() {
var editUrl = 'myediturl';
if (!(editWindow)) {
editWindow = $("#edit-window");
}
$(".k-button.k-button-icontext.k-grid-edit").each(function (index) {
$(this).click(function () {
if (!editWindow.data("kendoWindow")) {
editWindow.kendoWindow({
title: "Edit User",
width: "60%",
height: "60%",
close: onClose,
open: onEditOpen,
content: editUrl + $("#grid").data().kendoGrid.dataSource.view()[index]["ID"]
});
}
else {
editWindow.data("kendoWindow").refresh(editUrl + $("#grid").data().kendoGrid.dataSource.view()[index]["ID"]);
editWindow.data("kendoWindow").open();
}
editWindow.data("kendoWindow").center();
return false;
})
});
$(".k-button.k-button-icontext.k-grid-delete").each(function (index) {
$(this).click(function () {
var r = confirm("Are you sure you want to delete this user?");
if (r == true) {
$.ajax({
type: 'POST',
url: 'mydelurl' + $("#grid").data().kendoGrid.dataSource.view()[index]["ID"],
success: function (param) { refreshGrid(); },
async: false
});
}
return false;
});
});
}
function onDataBound() {
if (!(shouldClickOnRefresh)) {
shouldClickOnRefresh = true;
bindGrid();
}
else {
refreshGrid();
}
}
$(function () {
$("#grid").kendoGrid({
dataBound: onDataBound,
dataSource: {
autoSync: true,
data: getDataSource(),
serverPaging: true,
schema: {
model: {
fields: {
Email: { type: "string" },
FullName: { type: "string" },
LogCreateDate: { type: "date" },
RoleName: { type: "string" },
UserName: { type: "string" }
}
},
total: function (response) {
return grid2Data.Total;
}
},
pageSize: 10
},
toolbar: ["create"],
scrollable: true,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false,
pageSizes: true
},
columns: [
{
command: ["edit", "destroy"],
title: " "
},
{
field: "Email",
title: "Email",
type: "String"
},
{
field: "FullName",
title: "Full Name",
type: "String"
},
{
field: "LogCreateDate",
title: "Created",
type: "Date",
template: '#= kendo.toString(LogCreateDate,"MM/dd/yyyy") #'
},
{
field: "RoleName",
title: "Role",
type: "Custom"
},
{
field: "UserName",
type: "String"
}
],
editable: "popup"
});
grid = $("#grid").data("kendoGrid");
function onAddOpen() {
}
addWindow = $("#add-window");
$(".k-button.k-button-icontext.k-grid-add").click(function () {
if (!addWindow.data("kendoWindow")) {
addWindow.kendoWindow({
title: "Add User",
width: "60%",
height: "60%",
close: onClose,
open: onAddOpen,
content: 'myaddurl'
});
}
else {
addWindow.data("kendoWindow").open();
}
addWindow.data("kendoWindow").center();
addWindow.data("kendoWindow").refresh();
return false;
});
});
function onClose() {
$("#refresh-btn").click();
}
function onEditOpen() {
//editWindow.data("kendoWdinow").center();
}
I've hacked Kendo UI for the second time, this time I've solved its incompatibility with jQuery 1.8.3. using the following hack:
$(".k-grid-filter").each(function(index) {
$(this).click(function() {
$($(".k-filter-menu.k-popup.k-group.k-reset")[index]).offset({
left: $($(".k-grid-filter")[index]).offset().left - $($(".k-filter-menu.k-popup.k-group.k-reset")[index]).width(),
top: $($(".k-grid-filter")[index]).offset().top + $($(".k-grid-filter")[index]).height()})
})
});
I've put this hack into the document load event of the page an voila, it works. It surely looks ugly as hell with this hack, but after designing it will look good as new. I'm happy I found a work around, but I'm unhappy I had to hack Kendo UI twice. It is a very nice tool except the bugs.
jQuery 1.8.# is only compatible with Kendo UI - Q2 2012 SP1 (2012.2 913) or later..
If your kendo UI version is earlier, you should update it.