JvectorMap Region Selection - javascript

I am trying to reuse the region selection feature of JVectorMap. I am using a custom map (js) file. I have tested it in and it works fine for region selection.
Now I need to pass the regions which are selected by the user to the back end vb code. In this case maps.getSelectedRegions() gives an array of the user selected regions. I am not clear on how to pass a javascript array to back end vb code. The window.localstorage as how it is given in the example don't seem to work out here. Can somebody help me out on how this an be done?
This is the link of JVectorMap Region Selection - http://jvectormap.com/examples/regions-selection/
Following is the code I have used so far.
<script>
$(function(){ var maps; maps = new jvm.WorldMap({
container: $('#map'),
map: 'xyz_map',
regionsSelectable: true,
regionStyle: {
initial: {
fill: '#B8E186'
},
selected: {
fill: '#F4A582'
}
},
series: {
},
onRegionSelected: function(){
if (window.localStorage) {
window.localStorage.setItem(
'jvectormap-selected-regions',
JSON.stringify(maps.getSelectedRegions())
);
}
}
}); maps.setSelectedRegions( JSON.parse( window.localStorage.getItem('jvectormap-selected-regions') || '[]' )
); });
</script>
Thanks in advance
Sina

Managed to get a solution for this myself. You can add a hidden control in your asp code and assign the variable to this control.
$(function(){ var maps,temp; var hiddenControl = '<%=
inpHide.ClientID %>'; maps = new jvm.WorldMap({
container: $('#map'),
map: 'xyz_map',
regionsSelectable: true,
regionStyle: {
initial: {
fill: '#B8E186'
},
selected: {
fill: '#F4A582'
}
},
series: {
},
onRegionSelected: function(){
document.getElementById(hiddenControl).value=maps.getSelectedRegions();
} });
});

Related

Data driven styling errors using client-side join - Mapbox GL JS

I have implemented a client-side join from a GitHub based CSV to a Mapbox tileset using a Papa-parse promise function, similar to how it is implemented in: Data Joins : Mapbox JS.
The promise is fulfilled and the data is stored correctly, the outlines of the regions I am trying to visualise show, but there is an issue with data-driven styling with the "interpolate", ['linear'] parameters I am trying to use, from my past experience. The 'accessibilityOutline' ID layer shows its data correctly, so it is confusing to why this is happening.
An error keeps coming up declaring
"Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values."
I am wondering if anyone else has had this problem, and the way it was overcome. Any help would be grateful.
The code implemented is below, this is all based off the link above. The data is read in correctly and through debug testing I can see that all the data is in the correct format as the
dynamicTyping: true,
is present in the Papa.parse function. However, mapbox looks like it is unable to read this data.
function papaPromise(url) {
return new Promise(function(resolve,reject) {
Papa.parse(url, {
download: true,
header: true,
skipEmptyLines: true,
complete: resolve,
dynamicTyping: true,
});
});
}
const accessibilityCSV = papaPromise("some random url of data");
const mapContainer = useRef();
useEffect(() => {
const map = new mapboxgl.Map({
container: mapContainer.current,
style: "mapbox://styles/mapbox/outdoors-v11",
center: [-2.597, 53.39],
zoom: 9.5,
});
map.on("load", () => {
accessibilityCSV.then(function (results) {
console.log(results.data);
results.data.forEach((row) => {
map.setFeatureState({
source: 'lsoa_ultra_generalised-3gznbd',
sourceLayer: 'lsoa_ultra_generalised-3gznbd',
id: row.lsoa_code
}, {
lsoa_name: row.lsoa_name,
Total_LSOA_population: row.Total_LSOA_population,
LSOA_population_low_income: row.LSOA_population_low_income,
airport_jt60: row.airport_jt60,
airport_jt90: row.airport_jt90,
seaport_jt60: row.seaport_jt60,
seaport_jt90: row.seaport_jt90,
city_jt60: row.city_jt60,
city_jt90: row.city_jt90,
visitor_attraction_jt60: row.visitor_attraction_jt60,
visitor_attraction_jt90: row.visitor_attraction_jt90,
beach_jt60: row.beach_jt60,
beach_jt90: row.beach_jt90,
national_park_jt60: row.national_park_jt60,
national_park_jt90: row.national_park_jt90,
biz_60: row.biz_60,
biz_90: row.biz_90,
NPIER_60: row.nPIER_60,
NPIER_90: row.nPIER_90,
uni_places_60: row.uni_places_60,
uni_places_90: row.uni_places_90
},
);
});
});
map.addSource('northOutline', {
type: "vector",
url: "vectorURL"
})
map.addSource("accessibilitySource", {
type: "vector",
url: "vectorURL",
promoteId: 'LSOA11CD'
});
map.addLayer({
id: 'accessibility',
type: 'fill',
source: 'accessibilitySource',
'source-layer': 'lsoa_ultra_generalised-3gznbd',
paint: {
"fill-color":[
"interpolate",
['linear'],
['number', ["feature-state","Total_LSOA_population"]],
0,
"#fee5d9",
2075,
"#fcae91",
4150,
"#fb6a4a",
6225,
"#de2d26",
8300,
"#a50f15",
/* other */, "#ccc",
],
},
});
map.addLayer({
id:'accessibilityOutline',
type:'line',
source: 'accessibilitySource',
'source-layer': 'lsoa_ultra_generalised-3gznbd',
paint: {
"line-color": '#000000'
},
});

Javascript page re-route after d3.js event

I experimenting with d3.js and how to implement the framework.
At this stage of experimental implementation, I would like to make the filled Countries create alerts when I click them.
The ultimate goal is to change the alert to a page re-route, using the country name to decide which page it gets routed to.
In depth explanations are greatly appreciated.
Here is the code:
var map = new Datamap({
element: document.getElementById('container'),
fills: {
PARTS:'green',
defaultFill: 'black'
},
data: {
USA: {
fillKey: 'PARTS'
},
IRL: {
fillKey: 'PARTS',
}
},
done: function(datamap) {
datamap.svg.selectAll('.datamaps-subunit').on('click', function(geography, data) {
if(data.fillKey=='PARTS'){
alert(geography.properties.name);
}
});
}
});

Jquery Function to append variables

I am trying to append the value of map and values inside this test variable using a jQuery function ( which is at the end). How do I do this?
I want to change the value of map: 'ecoMap' to map: developmentRegionMap and values: Chherti to values: testvalue
function Eco_regions() {
test = $('#world-map').vectorMap({
map: 'ecoMap',
backgroundColor: '#FFFFFF',
regionsSelectable: false,
series: {
regions: [{
values: Chhetri,
scale: ['#fffad6', '#d05300'],
normalizeFunction: 'polynomial'
}]
}
});
};
This is the jquery function which is supposed to append the variable.
$('#change_ecoregions').click(function (e) {
e.preventDefault();
test.map.setValue('developmentRegionMap');
test.series.regions[0].setValues(testvalue);
Eco_regions();
});
What you require is plugin-specific; supposing you're using the jQuery Vector Maps plugin, according to the documentation, you'd have to do this in order to change values after the creation (untested):
jQuery('#vmap').vectorMap('set', 'map', 'developmentRegionMap');
I want to change the value of map: 'ecoMap' to map: developmentRegionMap and values: Chherti to values: testvalue
Then just make them parameters of that function:
function Eco_regions(map, value) {
test = $('#world-map').vectorMap({
map: map || 'ecoMap',
backgroundColor: '#FFFFFF',
regionsSelectable: false,
series: {
regions: [{
values: value || Chhetri,
scale: ['#fffad6', '#d05300'],
normalizeFunction: 'polynomial'
}]
}
});
};
$('#change_ecoregions').click(function (e) {
e.preventDefault();
Eco_regions('developmentRegionMap', testvalue);
});
I couldn't find a great way to just change the variable and have it redraw the map. I think you might need to just blow the old map away and append a new one in.
Define an element for the map
var mapElement = '<div id="world_map" style="width:600px; height: 400px;">';
Create a container div
<div id="container"></div>
When the change event is fired, remove the old map, append a new element to the container, and call the vectorMap function with the new settings.
$('#world_map').remove();
$('#container').append(mapElement);
$('#world_map').vectorMap(options);
Here is a fiddle as an example.
You're calling a function setValues where, unless you've omitted some code, you haven't defined it. If you change it to test.series.regions[0].values = testvalue; you should have better luck. Also, without quotes, testvalue is undefined (unless it's global somewhere) so you'll either need to assign that variable some value or else surround it with quotes to make it a string.
I think it's best to rearrange your function slightly so you can easily adjust the properties:
var test= {
map: 'ecoMap',
backgroundColor: '#FFFFFF',
regionsSelectable: false,
series: {
regions: [{
values: Chhetri,
scale: ['#fffad6', '#d05300'],
normalizeFunction: 'polynomial'
}]
}
};
function Eco_regions(settings) {
$('#world-map').vectorMap(settings);
};
$('#change_ecoregions').click(function (e) {
e.preventDefault();
test.map = 'developmentRegionMap';
test.series.regions[0] = testvalue;
Eco_regions(test);
});

How to display a multi-line title in a Highslide pop-up while using Highcharts?

I'm using Highcharts to display a chart and I'm using Highslide to display additional information in a pop-up when the user clicks on a point in the chart. However, I want to add additional information to the title/heading-text in the pop-up.
I've gotten Highslide to work in displaying basic information using the following code:
$(function () {
var options = {
chart: {
renderTo: 'container',
defaultSeriesType: 'line'
}
credits: {
enabled: false
}
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
hs.htmlExpand(null, {
pageOrigin: {
x: this.pageX,
y: this.pageY
},
headingText: this.series.name,
maincontentText: Highcharts.dateFormat('%A, %b %e, %Y', this.x) +':<br/> '+
this.y +' visits',
width: 200
});
}
}
},
marker: {
lineWidth: 1
}
}
},
series: []
}
});
I've read through the API for Highslide and saw that you could use the 'heading' variable with the 'Expander.prototype.onAfterGetHeading' function, which I've displayed below, but I'm not sure how to implement it with Highcharts.
hs.Expander.prototype.onAfterGetHeading = function () {
this.heading.html = 'this.a.title';
}
HERE's a site that displays a pop-up with a multi-line title in a Highslide pop-up, as an example. However, keep in mind that I'm trying to implement this in Highcharts, possibly with dynamic text in the title.
Thanks.
Here’s a solution you can use with Highcharts: http://jsfiddle.net/roadrash/gd3xz/
Please note that this is the correct code to insert the anchor's title text in the heading, as an additional heading text:
hs.Expander.prototype.onAfterGetHeading = function (sender) {
if (sender.heading) {
sender.heading.innerHTML += this.a.title;
}
};
I’m not familiar with Highcharts, but I don’t think you can use this.a.title since a refers to the anchor tag. You can of course insert something else than this.a.title with the above code, as I've done in my demo.

Gmap3 Clear Directions

I need to recalculate the directions, when another marker is clicked or when my origin marker is dragged to another location.
at the moment, I am inserting a marker when a user inserts his/her address then when the users clicks on any existing marker it calculates the directions. Unfortunately it doesn't clear the previous directions.
Any Help at all will be greatly appreciated.
Here's the code:
jQuery(document).ready(function() {
jQuery.getJSON('./index.php', {
option: "com_locate",
view: "branches",
tmpl: "component",
format: "json",
},
function(json){
jQuery(function(){
jQuery("#googleMap").gmap3({
map:{
options: {
center:[-29.8191,25.3499],
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false
}
},
marker: {
values: json,
options: {
icon: new google.maps.MarkerImage("http://maps.gstatic.com/mapfiles/icon_green.png")
},
events:{
mouseover: function(marker, event, context){
jQuery(this).gmap3(
{clear:"overlay"},
{
overlay:{
id: "tooltip",
latLng: marker.getPosition(),
options:{
content: "<div class='infobulle"+(context.data.drive ? " drive" : "")+"'>" +
"<div class='bg'></div>" +
"<div class='text'>" + context.data.city + " (" + context.data.telephone + ")</div>" +
"</div>" +
"<div class='arrow'></div>",
offset: {
x:-46,
y:-73
}
}
}
});
},
mouseout: function(){
jQuery(this).gmap3({clear:"overlay"});
},
click: function(marker, event, context){
markerSelected(context.id);
}
}
}
});
///////////////
jQuery('#test-ok').click(function(){
var addr = jQuery('#test-address').val();
if ( !addr || !addr.length ) return;
jQuery("#googleMap").gmap3({
getlatlng:{
address: addr,
callback: function(results){
if ( !results ) return;
jQuery("#googleMap").gmap3({
clear:{id:"user"}
},
{
marker:{
latLng:results[0].geometry.location,
id:"user",
name:"user",
options:{
draggable: true
}
},
map:{
center: true,
zoom: 5
}
});
}
}
});
});
jQuery('#test-address').keypress(function(e){
if (e.keyCode == 13){
jQuery('#test-ok').click();
}
});
///////////////
///////////////
function markerSelected(id){
var marker = jQuery('#googleMap').gmap3({get:id});
var usermarker = jQuery('#googleMap').gmap3({get:"user"});
jQuery("#googleMap").gmap3({
getroute:{
options:{
origin:[usermarker.getPosition().lat(),usermarker.getPosition().lng()],
destination:[marker.getPosition().lat(),marker.getPosition().lng()],
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
if (!results) return;
jQuery(this).gmap3({
map:{
options:{
}
},
directionsrenderer:{
container: jQuery(document.createElement("div")).addClass("googlemap").insertAfter(jQuery("#googleMap")),
options:{
directions:results
}
}
});
}
}
});
}
});
});
});
The code you're using creates a new DOM element each time you do a directions request, without removing any existing such elements or replacing content in any existing elements. The pertinent part of your code is this:
directionsrenderer:{
container: jQuery(document.createElement("div")).addClass("googlemap").insertAfter(jQuery("#googleMap")),
// The above creates a new DOM element every time markerSelected() is called!
options:{
directions:results
}
}
You want to create that only once. If you want, you can do it directly in the HTML markup.
Use the below as a replacement for your getroute callback function. I've plugged in a unique ID for the container element and left the "googlemap" class intact in case it's needed for CSS or other sections of code. Since you specifically want only one set of directions to be visible, though, let's select your container by ID.
callback: function(results){
if (!results) return;
if (!jQuery("#dircontainer").length>0) {
jQuery("<div id='dircontainer' class='googlemap'></div>").insertAfter("#googleMap");
} // Creates your directions container if it doesn't already exist.
else {
jQuery("#dircontainer").html("");
} /* I'm clearing the existing contents of the container in case gmap3 doesn't
automatically clear it when the new directions are inserted.
You can experiment with removing this else statement. */
jQuery(this).gmap3({
map:{
options:{
}
},
directionsrenderer:{
container: jQuery("#dircontainer"),
options:{
directions:results
}
}
});
}
I'm making some assumptions here about the way the gmap3 plugin works; I've worked with jQuery and the Google Maps JS API, but not with this plugin.

Categories