Scroll control in jVectorMap - javascript

I am using jVectorMap, everything works fine without zooming.
But when a user zoomed in the page I need to allow the user to scroll the the map using a vertical and horizontal scroll bar.
I have tried to add overflow-y: scroll; And other many options to do the scrolling but nothing works perfectly.
I can set the width and height of div to get the scroll bar but it is not related with map zoom in and zoom out.
So I am expecting a scroll bar horizontally and vertically which using that user can see the full map if even it is zoomed.
I have seen a map with below image in the internet
But No idea how can I add a scroll button control like this in jVector map.
Can someone help me to resolve this issue.?

You need two steps:
To understand how the map is translated inside the container, initialize the Map with the onViewportChange event:
$("#map").vectorMap({
map: "world_mill",
// set map properties, series, and so on
//...
onViewportChange: function(event, scaleFactor,transX,transY){
// look at the values here:
console.log("Viewport changed",scaleFactor,transX,transY);
}
});
To the point:
to apply a map translation, set your desired X and Y panning, at the end invoke the applyTransform function:
Example:
var worldMap = $("#map").vectorMap("get", "mapObject");
worldMap.transX = -100;
worldMap.applyTransform();
Additional information:
Luckily, jVectorMap will do the range checking for you, so for your pan buttons you can also simply use somethng like:
worldMap.transX -= (10 * worldMap.scale); // move left
worldMap.transX += (10 * worldMap.scale); // move right
worldMap.transY -= (10 * worldMap.scale); // move up
worldMap.transY += (10 * worldMap.scale); // move down
You will find the range check in the applyTransform function in jVectorMap source code.
Credits: Kirill Lebedev, the great author of jVectorMap.
Lastly, the re-center button:
You can get the center of the map as follows:
var mapCX = (worldMap.width / 2) * worldMap.scale + worldMap.transX * worldMap.scale;
var mapCY = (worldMap.height / 2) * worldMap.scale + worldMap.transY * worldMap.scale;
As you haven't provide any source code, I can't help further, but if you have understand the concept, the transformation between your scrollbar range and the map translation is trivial easy.

Related

Offset a LatLngBounds in a Leaflet map

I have a map that fills the screen, and a horizontal overlay of non-map content displayed in the bottom portion of the screen. I want to display a polyline on the map so that it as large as possible within the map view but not hidden below the overlaid content.
Below is what I am trying and it nearly works but gives different results depending on the zoom / position of the map's current view. I need something independent of the current view of the map.
// `map` is the leaflet map
// `polyline` is a leaflet polyline
function fitBounds (latLngBounds, offsetY) { // offsetY in pixels
var zoom, southeast, southeastOffset, newBounds;
if (offsetY) {
zoom = map.getBoundsZoom(latLngBounds);
southeast = map.project(latLngBounds.getSouthEast(), zoom);
southeastOffset = new L.Point(southeast.x, southeast.y + offsetY);
newBounds = latLngBounds.extend(map.unproject(southeastOffset, zoom));
}
map.fitBounds(newBounds || latLngBounds);
}
var contentHeight = 350;
// this will be calculated and is the distance from the top of the
// overlaid content to the bottom of the map
fitBounds(polyline.getBounds(), contentHeight);
The map.getBoundsZoom(latLngBounds) and project/unproject seem to return different values when the map is panned or zoomed differently. I understood from the docs that they'd be independent of the current map view.
Am I using the methods wrong, or is there a different strategy to achieve what I need? Thanks.
getBoundsZoom is dependent on the current map view port size. Therefore if you test with different sizes (e.g. your map container fills the whole page width and you have varying browser window width, possibly because of the console), the results will be different.
If you are sure the map container size has not changed, and you can reproduce the problem on JSBin / Plunker / JSFiddle, then there might be a bug in Leaflet; feel free to report it in the issue tracker.

Can the crosshair in a Highcharts chart set and be moved programmatically?

I am working on a web application displaying multiple charts over the same categories. If you want an example, think population for different cities over time. The charts all have crosshairs enabled for the X axis.
I've been asked if, when a user hovers over a chart and moves the mouse - therefore moving the crosshairs - it is possible to have the crosshairs of all the other charts as well, in parallel, kinda mirroring the movement.
Off the top of my head it should not be impossible - capture the position on the X axis whenever the mouse is moved, then set/move the crosshairs on all charts to the same value for all the other charts - but that would work only if moving crosshairs programmatically is possible.
Is this possible in a non trivial way?
Edit: I created a partially working version on jsfiddle, based on the jsfiddle linked to in the answer, and replicating the two column layout of the charts in our web app: http://jsfiddle.net/basiliosz/sgc8jg34/
The crosshairs are moved only in charts directly above and below the one where the user is hovering the mouse cursor, but not in the other column. This is the crucial code snippet from the event handler:
for (i = 0; i < noOfCharts; i = i + 1) {
chart = separateCharts[i]
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(event);
}
}
where Point.prototype.highlight is defined as this:
Highcharts.Point.prototype.highlight = function (ev) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(ev, this); // Show the crosshair
};
There is an internal function for drawing crosshair which can be used (it is not part of the official API)
/**
* Draw the crosshair
*
* #param {Object} e The event arguments from the modified pointer event
* #param {Object} point The Point object
*/
Axis.prototype.drawCrosshair: function(e, point) {}
example: http://jsfiddle.net/6rbhxmrp/
You can also the official demo with synchronizing charts https://www.highcharts.com/demo/synchronized-charts
The example with a disabled tooltip: http://jsfiddle.net/vwm4oe6k/

Mouse movement parallax on Google Map?

Is it possible to add something like this to Google Maps?
This demo has parallax with multiple layers, I would need only one
for map itself.
I don't nessessarily need the code because there are few tutorials how to achieve mouse movement parallax. Im more interested how to apply this to Google Maps.
My current ideas / questions?
Would it be somehow possible to move map tiles in the background without moving Google logo?
If not, how to make map bigger (out of browser viewport) without messing up tiles so that I could move whole map and use overflow { hidden; }?
Don't worry about hiding Google's credentials or messing up controls, I could add all the divs, controls and logo myself via JS.
I would be very grateful if you used my provided jsFiddle example to make your point.
You can do this using the panTo() function. I gave it some default numbers for the scroll effect that you can change to meet your needs.
$( "#map-cover" ).on( "mousemove", function( event ) {
var newLatlng = new google.maps.LatLng(
myLatlng.lat() + event.pageY / 1000,
myLatlng.lng() + event.pageX / 1000)
map.panTo(newLatlng);
});
Make sure to add a div above the map and disable the controls on the map
Updated JSFiddle
Upon, getting additional clarification, you can add a listener to check if the map is being dragged.
map.addListener("drag", function() {
dragging = true;
});
map.addListener("dragend", function() {
dragging = false;
});
Draggable map with mouse scroll

Google Maps fit markers in custom bounds

I have a Google Maps canvas that stretches the full width and height of the page. Overlaid on top of it is a header which is fixed height (100 pixels) and a sidebar which is a responsive width (20% + 5% margin).
Fiddle for demonstration: http://jsfiddle.net/L9yjvdLv/1/
The problem I'm facing is making sure that all the markers on the map are visible.
I tried playing around with fitBounds, but the problem is that the map doesn't take into account the overlaid elements, meaning markers will be behind the sidebar or header elements, or very close to them.
How do I zoom and center the map so that all markers are visible in the "usable" area of the map?
You will need to use the map projection and fromLatLngToPoint to translate between coordinates and points to be able to take into account your different overlay elements.
For a full explanation, please check this answer.
function fromLatLngToPoint(latLng) {
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(map.getBounds().getNorthEast().lat(), map.getBounds().getSouthWest().lng());
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(latLng);
return new google.maps.Point(Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale), Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale));
}
My example only has a left sidebar overlay but you should be able to adapt the functions to your needs.
JSFiddle demo
Hope this helps.

Google Maps custom content boxes?

I can't seem to find andthing in the Google Maps V3 docs about creating custom content boxes for Google maps.
Below is an example of a custom content box:
http://www.apple.com/retail/alamoana/map/
My question is... how do you go about changing the default white balloon popup?
Cheers!
Look at the InfoBox toolkit in the v3 utility libraries. I'm using them on dev.mapfaire.com, if you want to take a look.
Personally, i don't use any of google's custom overlay scripts and such. I made a custom php page which hold the iframe, where I can load custom css files, and also I create custom DIVs that go over top of the map, which are then repositioned while dragging when opened.
You can use the "Drag,Dragstart,Dragend" events to help you reposition elements that you have created.
If you have custom markers set onto you page you can get their pixel position with this function:
getPosition: function (marker) {
var map = this.map /* Your map, in my case is part of my controller object linked to this.map */;
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(marker.getPosition());
var pixelOffset = new google.maps.Point(
Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);
return pixelOffset; /* Returns the top left pixel of the specified marker on the specified map */
}
And then I use a setPosition function which is used when the window is dragging, it sets your custom element's position to the marker's position.
The dragging event can be set in such manner:
google.maps.addEventListener(map,'drag',function () { setPosition(marker,element); });
The setPosition Function simply gathers the width,height of the element, and the pixel offset associated to the marker using the getPosition(marker) function:
setPosition: function (marker,element) {
var p = this.getPosition(marker),
s = {width:element.offsetWidth,height:element.offsetHeight},
markerOffset = {width:58,height:58};
element.style.left = p.x - (s.width/2) + (markerOffset.width/2) + "px"; /* We set the element's left position to the marker's position + half of our element's width + half of the marker's width's so it is centered */
element.style.top = p.y - s.height - (markerOffset.height) + 10 + "px"; /* We set the element's top position to the marker's position + our element's height + markers height so it is 10px above our marker vertically */
},
Sometimes you just have to think a bit outside the box
That example is using the second version of google maps. That features might not be available in the 3rd one.
But you can add any html code in the infowindows and personalize them. I'm not sure if you can change how they look directly, but you can definitely change how the content looks like.
Edit: I found some sample code: http://gmaps-samples-v3.googlecode.com/svn/trunk/infowindow_custom/infowindow-custom.html
Take a look at gmaps-utility-library-dev and more specific in the ExtInfoWindow utility and PopupMarker utility
As Sudhir pointed out, the Infobox Plugin is one way to do what you want. I've recently answered a similar question about using the infobox plugin for google maps api 3 and provided a complete example.

Categories

Resources