JVectorMap: drill-down for custom regions - javascript

Is there a way to make combined map which could use "drill-down" behaviour for some areas and "select" behaviour for other ones areas?

I believe that what you are asking can be achieved also with some of the standard functionalities provided by jVectorMap. In my example below, all US regions other than Texas can be selected, whereby the normal multimap drill-down is performed just only for US-TX.
$(document).ready(function () {
new jvm.MultiMap({
container: $('#map'),
maxLevel: 1,
main: {
map: 'us_lcc',
regionsSelectable: true,
regionStyle: {
selected: {
fill: 'green'
}
},
onRegionClick: function(event, code) {
if(code == "US-TX") {
return false;
} else {
event.stopImmediatePropagation();
}
}
}
});
});
Explanation:
As the documentation says here, the main Map of the MultiMap object can be configured the same way as the "normal" Map.
Inside the multi-map onRegionClick handler, the region selection can be avoided by returning false, and the drilldown can be stopped by invoking stopImmediatePropagation(). I tested this snippet with jVectorMap version 2.0.2 but it should work also with the latest versions.
BTW, thanks to bjornd for the great jVectorMap.

There's no standart behaviour to reach this.
To handle this I had to modify MultiMap file. In addMap function you could add
hardcode check region code or add it to config and pass or deny drilling down.

Related

Force-directed graph in Highcharts has lost its lines

First of all, here's the standard JSFiddle for a Force-Directed Graph.
Here's the JSFiddle for my (perhaps misuse of) Force-Directed Graph.
My JSFiddle is throwing a larger-than-usual lump of data at Highcharts (scroll right to the bottom of the JS panel to see actual code) which may be the reason why I'm having the problem that I am having, namely that the lines joining the nodes are missing.
Other non-standard things are happening, e.g.
series: [{
dataLabels: {
enabled: true
},
data: Data.DAT,
formatting: Data.FMT
}
]
The formatting tag is permitted (according to Highcharts themselves) as it doesn't clash with anything in Highcharts API. In subsequent iterations of the main code base, I put everything into data and refer to DAT and FMT deeper in.
It is possible that something in the node management is amiss
e.options.data.forEach(function (link, i) {
if (!e.options.formatting[link.from]) {
console.log("No formatting given for FROM %s", link.from);
} else {
nodes[link.from] = {
id: link.from,
marker: {
radius: e.options.formatting[link.from].size
},
plotX: e.options.formatting[link.from].x,
plotY: e.options.formatting[link.from].y,
fixedPosition: true,
name: e.options.formatting[link.from].name,
color: e.options.formatting[link.from].colour
};
}
if (!e.options.formatting[link.to]) {
console.log("No formatting given for TO %s", link.to);
} else {
nodes[link.to] = {
id: link.to,
marker: {
radius: e.options.formatting[link.to].size
},
plotX: e.options.formatting[link.to].x,
plotY: e.options.formatting[link.to].y,
fixedPosition: true,
name: e.options.formatting[link.to].name,
color: e.options.formatting[link.to].colour
};
}
});
However, I'm at a loss trying to work out how to gets the lines to reappear, thus this posting.
The reason your lines disappear is because you are above turboThreshold. You can see this by looking at console which gives the following error:
Highcharts error #12: www.highcharts.com/errors/12
The fix for this, is either to comply with turbo threshold, that is format your series as an array (which could improve performance). Or to increase the turbo threshold. The latter will make it work, but performance will not be great.
Working example: https://jsfiddle.net/ewolden/3qLdmut8/

Cannot read property '_leaflet_mousedown5' of null when attempting to enable marker dragging in Mapbox/Leaflet

I am building the functionality that allows mapbox markers to be edited from within a CMS. The functionality should open up and populate a form when a map marker is clicked, and then allow the map marker to be dragged. When the form is saved, the content is submitted via ajax and then the map is reloaded with the featureLayer.loadURL("my_geojson_endpoint").
I have added comments throughout my code below to outline how I am getting to the error.
N.B. I define a property db_id in the geojson to identify each point because when you apply a filter, _leaflet_id changes. I also have jquery included in the code.
Code:
// loop through each marker, adding a click handler
$.each(points._layers, function (item) {
var point = points._layers[item];
attachClickHandler(point);
});
function attachClickHandler(point) {
// open the edit state for the marker on click
$(point._icon).on("click", function () {
openEditState(point);
})
}
function openEditState (point) {
disableEditOthers(point);
displayContent(point);
point.dragging.enable(); // this line causes the error
$(point._icon).off("click");
}
function disableEditOthers (point) {
// hide the other markers from the map (using db_id as mentioned above)
points.setFilter(function (f) {
return f.db_id === point.feature.db_id;
})
// this functions as a callback to display the popup
// since applying the filter on click, does not show the popup
setTimeout(function () {
for (key in points._layers) {
points._layers[key].openPopup();
}
}, 0)
}
In the map creation step I have been able to call this dragging.enable() method on each of the markers and provide "draggability" to all of them, however this is undesirable from a usability point of view. I want the user to clear swap in and out of an edit state.
I discovered this issue on github, solved by the solution to this. However after swapping my mapbox.js version out to the standalone and including the latest version of leaflet (0.7.3) the same error still occured.
Am I calling the function on the wrong property of the object? dumping out the "point" variable just before the line which errors does not show that the draggable property has the enable() function defined.
Any help is much appreciated.
Ok so as a slight workaround, but still not solving the original error.
$.each(points._layers, function (item) {
points._layers[item].dragging.enable()
})
Because I have filtered out the other points, enabling dragging on all points is working around the issue.
If you can provide a fix to my original fix (avoiding the loop) I am happy to accept it.

jVectorMap - fill country on button press

Using jVectorMap, I would like to have a function that takes the country code as its parameters, then highlights that country on the map. For example:
function colorCountry(var code){
$('#world-map').vectorMap(
code : '#686868',
));
}
That is just a mockup; I'm asking here because I have little experience with Javascript / jQuery and haven't been able to find a suitable solution on Google.
I would like the function to simply color the country it is provided with, rather than clear the map so only one country is colored. For example:
colorCountry("DE");
colorCountry("US");
..would present the user with a map with both US and DE colored, rather than just one.
Try this:
$('#world-map').vectorMap({
series: {
regions: [{ values: {
"US":"#686868",
"DE":"#686868"
}, attribute: 'fill' }]
}
});

OpenLayers DrawFeature control with Point destroys double click to zoom

I have some simple code that I copied from one of the openlayers examples for drawing several different types of geometries on the map. The problem is, whenever the "point" geometry is selected, I lose the ability to double-click to zoom in. The only difference between the examples and my code is I'm registering the handlers to use MOD_SHIFT, because i want to retain the ability to pan/zoom. Here is a snipit of code:
point: new OpenLayers.Control.DrawFeature(this.geometryFilterLayer,
OpenLayers.Handler.Point,
{
'done': console.info("drew point")
},
{
keyMask: OpenLayers.Handler.MOD_SHIFT
}
),
polygon: new OpenLayers.Control.DrawFeature(this.geometryFilterLayer,
OpenLayers.Handler.Polygon,
{
'done': console.info("drew polygon")
},
{
keyMask: OpenLayers.Handler.MOD_SHIFT
}
),
The funny thing about the above code is, the 'done' event only gets fired when the control/handler is created, and the keyMask doesn't work at all -- I have to loop through this object and manually set the keyMask each time, but that's not the real problem at hand.
I've tried every way I can think of to register a dblclick event, but no matter what, I can't get it to zoom in when I double click. It works fine on all the other geometries (bbox, point/radius, and polygon).
Can anybody give me some advice?
I never solved this issue, but ended up doing away with using MOD_XXX altogether. Each different draw control had too much built-in functionality for what happens when you hold shift, ctrl, alt, etc. I ended up using custom Buttons and a toolbar, that way the user can explicitly select the drawing control themselves.
this.toolbar = new OpenLayers.Control.Panel({
displayClass: 'olControlEditingToolbar'
});
map.addControl(this.toolbar);
var navButton = new OpenLayers.Control.Button({
displayClass: "olControlNavigation",
title: "Navigation",
trigger: lang.hitch(this, function(data){
this.toggleDrawControl("navigation");
navButton.activate();
pointButton.deactivate();
bboxButton.deactivate();
pointRadiusButton.deactivate();
polygonButton.deactivate();
})
});
...
this.toolbar.addControls([navButton, pointButton, bboxButton, pointRadiusButton, polygonButton]);
and my function to toggle draw controls (can be called externally, so that's why I re-call the activate and deactivate functions:
toggleDrawControl: function(geometryType){
this.currentGeometryType = geometryType;
for(key in this.drawControls) {
var control = this.drawControls[key];
if(geometryType == key) {
control.activate();
this.drawingButtons[key].activate();
} else {
control.deactivate();
this.drawingButtons[key].deactivate();
}
}
}

google maps api v3 infowindow + flot

I'm trying to draw a graph inside an infowindow, but flot is not executing—and is not throwing any errors. I read in the flot forum that often people have trouble with doing something like this because the placeholder element must be visible (that might be a red-herring here tho).
I'm able to get the following to produce the graph appropriately in a different element:
$.plot(
$("#placeholder"),
[ f_data[loc] ],
{
grid: { hoverable: true, clickable: true },
series: {
bars: { show: true },
clickable:true,
color:'#3FA9F5',
shadowSize: 0
},//series
xaxis: {
tickDecimals:0,
tickSize:1
}//xaxis
}
);//$.plot
But when I put the above into, or referenced from, the google.maps.event.addListener(), it does nothing (not even add the <canvas> elements).
I made sure to put it after infowindow.open(map,marker);, so that makes me think the placeholder element is visible. I also made sure #placeholder has substance/defined dimensions.
P.S. I tried what Mike Williamson reported as his eventual solution to Google Maps V3: Loading infowindow content via AJAX, but that didn't work either.
EDIT
Example of flot working outside of infowindow: index2.html
Example of flot not working inside of infowindow (addListener 'domready'): index3.html
Example of flot not working inside of infowindow (setTimeout): index4.html
The issue is that the content div has not been attached to the domain yet (so $("#placeholer") can't find it). You need to wait for the infowindow domready event to fire before running your code to plot the graph, something like this:
UPDATE: The code below works for me on a local copy (I did modify the css, but I don't think that was required).
google.maps.event.addListener(marker, 'click', (function(marker, locale, s, flot_data) {
return function() {
var fname = 'http://clients.frende.me/incognito/images/'+date+'_'+locale.toLowerCase().replace(/\s/g,'')+'.svg';
infowindow.setContent('<div id="gMaps_infowindow"><h3>'+locale+' ('+hour+':00): $'+s.total+'</h3><div id="flotIW" style="height:200px; width:350px;" name="'+locale+'"></div></div>');
google.maps.event.addListener(infowindow, 'domready', function() {(function(f_data,loc) {
$.plot(
$("#flotIW"),
[ f_data[loc] ],
{
grid: { hoverable: true, clickable: true },
series: {
bars: { show: true },
clickable:true,
color:'#3FA9F5',
shadowSize: 0
},//series
xaxis: {
tickDecimals:0,
tickSize:1
}//xaxis
}
);//$.plot
})(flot_data,locale)});
infowindow.open(map, marker);
//open_popUp(flot_data,locale);
//open_drawGraph(locale);
}//return
})(marker, locale, s, flot_data));//google.maps.event.addListener
(another option is to create the domain node directly, use that to render your graph, and pass that into the setContent call (which will take either a string or a DOM node).
Have you tried wrapping your $.plot in a setTimeout(function(){$.plot({stuff})}, 0) ?
Sometimes this helps give the browser time to finish drawing whatever elements it needs to before it executes.
You can find more information why this might be useful here: Why is setTimeout(fn, 0) sometimes useful?

Categories