image map: overlapping areas, highlighting and IE - javascript

Please take a look at http://jsfiddle.net/6WNQM/1/ which combines normal imagemap HTML, CSS and jQuery 1.9.
The jquery code:
jQuery(document).ready(function ($) {
$('#regions_fr').mapster({
mapKey: 'name',
singleSelect: true,
fillOpacity: 0.6,
fillColor: 'FF0000',
onMouseover: function (evt) {
var parts = evt.key.split('-');
var part = parts[1];
highlightArea(part);
}
});
$('a').hover(function () {
var parts = $(this).closest('li').attr('class').split('-');
var part = parts[2];
highlightArea(part);
});
});
function highlightArea(key) {
$('area[name=part-' + key + ']').mouseenter();
$('a').removeClass('hover');
$('li.menu-item-' + key + ' a').addClass('hover');
}
You see the map of France which is divided in several (geographical) regions. Overlapping you see some tourist areas that are overlapping 1 or more regions and also overlapping each other.
I'm stuck right now. I want to see specific functionality, but after trying several plugins and CSS techniques, I'm wondering if it's even possible what I want:
First desired functionality is that the hover over a region highlights the corresponding textlink and vise versa. This works :)
Second is that the geographical region "Bourgogne" can be hovered, but in IE only the top part can be hovered and becomes highlighted. Any idea?
Then we have the overlapping part of the two touristregions'. I want them to work as a group when the overlapping part is hovered. In other words, when I click on the overlapping part I want to see the overlapping part being highlighted and the selectbox of "tour-regio 1" and "tour-regio 2" both being checked.
I'm very curious if someone can help me out here, I'm stuck. Thanks in advance.

Related

leaflet layer interrupting interactivity of base layer

I am working on a project based on the Leaflet Choropleth Tutorial.
In my map, I have three base layers that the user switches between
var basemaps= {
"layer1": layer1,
"layer2": layer 2,
"layer3": layer 3
};
Each of these layers highlights and displays popup information just like in the Choropleth template.
I also have layers that display labels(values) for each region, depending which one is active.
var activelabel = L.layerGroup();
var showlabels = {
"labels": activelabel
};
map.on('baselayerchange', function (event) {
activelabel.clearLayers();
switch (event.layer) {
case layer1:
label1.addTo(activelabel);
break;
case layer2:
label2.addTo(activelabel);
break;
case layer3:
label3.addTo(activelabel);
break;
}
});
My problem, is that when the labels are active, if the user hovers over the part of the region where the label is, the highlight feature and info box do not display any information.
I am trying to find a way to make the activelabel layer invisible, so that the hover still works.
I found the tutorial on Map Panes, which seems like the solution to my problem, but it doesn't seem to do anything.
I'm not sure if i'm putting the pane information in the wrong spot, or if this doesn't actually work like I think it should? I've tried changing the xIndex everywhere from 0 to 700 and it doesn't seem to make a difference?
map.createPane('labels');
map.getPane('labels').style.zIndex = 700;
map.getPane('labels').style.pointerevents = 'none';
I've tried putting the pane: 'labels' code here, where I format my labels
var createLabelIcon = function(labelClass,labelText){
return L.divIcon({
className: labelClass,
html: labelText
})
};
as well as here, where I create the layer group.
var label1 = new L.layerGroup();
makelabel1();
Any help would be appreciated. Thank you.
I figured out a solution to this. I have three separate .js files where I add all the layers containing labels to my layergroups.
If I add {interactive: false} to each instance of .addLayer in each file, the labels to not interrupt the mouse hover.
I'm not sure why this doesnt work when I add interactive:false to the layer group as opposed to each addLayer line, but it seems to be working.

Highcharts scatter marker translation error

I have made a highcharts graph which is intended to mirror the following:
I am using a triangle image as a marker for the graph, but by default, the marker is being situated in the center of the bar. I have tried to use the translation function
chart.series[1].data.graphic.translate(0, 20);
but this does not seem to be helping.
Here is my full code:
barchartFiddle
I was also wondering how I would add the percentage to the top of as it would move along with the bar.
Furthermore, I have tried using (multiple versions with different css properties + high zIndex - I will be listing the basic)
chart.renderer.text('blah',50,50).add();
to add the bottom 3 criteria, but for some odd reason, no text shows up.
Finally, I was wondering what logic to add in order to change the appearance of the text, depending on the data, to mirror the one shown in the image (Note difference between acceptable and healthy)
In your jsFiddle you have added your callback function in wrong place, when you will add it correctly it should work fine.
function(chart) {
var marker = chart.series[1].data[0];
marker.graphic.translate(-20, 0);
}
You can use dataLabels for showing the percent value near your marker.
dataLabels: {
enabled: true,
x: -5,
y: 10,
style: {
fontSize: 20
},
formatter: function() {
return this.y + '%'
}
}
Here you can find an example how it can work: http://jsfiddle.net/2TuCW/341/

Enlarge SVG group on click, then minimize

I have multiple groups of svg elements in one viewport. I want users to click on one group which will hide the other groups and enlarge the selected group to fill the viewport.
So far I have:
var continents = $(".continents")
for (var i = 0; i < continents.length; i++) {
continents[i].addEventListener('click', function(){
$(".continents").css("display","none");
var currentContinent=this;
currentContinent.setAttribute("transform","scale(1.0)")
})
}
Where the groups are classed ".continents". But this does nothing.
Here is a jsfiddle
Is it possible to create a zoom effect or simply enlarge a selected group?
There are two issues with the code:
Not all the groups have the class .continents, so not all of the continents will hide when you do this:
`$(".continents").css("display","none");`
only Asia and Africa do have that class, so only those two will hide.
When you set the attribute transform here:
currentContinent.setAttribute("transform","scale(1.0)")
you are not only modifying the value of the scale(), but you are also overwriting/deleting the value of the translation.
How to fix these issues:
Add the class .continents to all the groups.
Update both the values of scale and translate for the continent that is clicked, and not only the scale. And this is the tricky part: those values may not be the same for all the continents. For example, for Asia, the target values will be: translate(-400,439) scale(0.032,-0.032), but those values will not work for the other continents. You need to play with different values to find the ones that will work for each particular group.
You can see it working on this JSFiddle (notice that only Asia will work, the other continents will be displayed outside of the picture until you adjust the translate/scale values).
To make things as generic as possible, you could store the new values in a data- attribute (e.g.: data-transform), and then update the value of the transform by using the value of that data- attribute.
You don't have class defined on all of your group elements so the click handler and css is only applied to 2 of the groups.
Also, you set all of the displays to none, and never set the display of the selected group back to inline.
The transform is no good since the paths are much larger, have an inverted y axes and are positioned absolutely, so changing the scale from 0.017, -0.017 to 1.0, 1.0 moves them far off the viewport.
JSFiddle
var prevTransform = null;
var continents = $("g");
for (var i = 0; i < continents.length; i++) {
continents[i].addEventListener('click', function () {
var currentContinent = this;
if (prevTransform == null) {
console.log("Click!");
$("g").css("display", "none");
prevTransform = currentContinent.getAttribute("transform");
currentContinent.setAttribute("transform", "translate(-20,220) scale(0.025, -0.025)");
$(currentContinent).css("display", "inline");
} else {
currentContinent.setAttribute("transform", prevTransform);
prevTransform = null;
$("g").css("display", "inline");
}
});
}
In this example, South America works best, the others move too far up and right. Australia moves out of view.

Hide Series without hiding y-Axis

There are plenty examples of hiding an Y-Axis without hiding the series - But i need the opposite of that.
I want to make a series invisible while still displaying the y-axis and i dont know how!
Why?
Because i have 2 diagrams which are perfectly aligned by their x-Axis:
But when i disable both Temperature fields, the axis will be lost, and the diagrams are incorrect in size:
I also don't like the idea, of disabling all and loosing whole diagram style:
There is no problem by having an empty diagram, but having a blank box isn't the style i want to reach.
I tried to manipulate the axis in within the legendItemClick event, but selecting the correct axis and set their value visible didn't work out. How can I solve this problem?
I think you have two options:
play around with margins - to make them fixed
set min and max for axis, so labels will remain on a chart: example
if you don't know min/max values at start you can change them within the legendItemClick as following:
plotOptions: {
series: {
events: {
legendItemClick: function() {
var temperatur = this.chart.series[0];
var taupunkt = this.chart.series[1];
var other = this.name=="Lufttemperatur"?taupunkt:temperatur;
var element = this;
if(this.name == "Lufttemperatur" || this.name == "Taupunkt") {
if(this.visible && !other.visible) {
//both will be invisible soon
this.chart.yAxis[0].update({
min:element.yAxis.min,
max:element.yAxis.max
});
} else {
//one will be visible
this.chart.yAxis[0].update({
min:null,
max:null
});
}
}
}
}
},
}
This will only set min/max if there is no one of your series visible, but deletes it if you have one visible

How to remove markers when use Leaflet Slider to show changes over time

I am using Leaflet Slider, of Dennis Wilhelm, to try to show changes in data over a period of five years in a Leaflet map.
I am trying to get that when the user move the cursor over the slider, some marker disappear and some other appear. So far, I only get that the new marker appear on top of the old marker.
So, my question is:
How can I remove markers when use Leaflet Slider to show changes over time? What changes I have to do in the original SliderControl.js?
Thanks in advance!
Below is the link to Dennis Wilhelm's Leaflet Slider code:
https://github.com/dwilhelm89/LeafletSlider/blob/master/SliderControl.js
It might be late, but for anyone who is looking for it now. If you want to show changes over time and want to show specific points at a time, pass the parameter follow as true, so the slider would show only one point at a time.
var sliderControl = L.control.sliderControl({
position: "topleft",
layer: layername,
follow: true
});
When I need to update markers in Leaflet I add my markers to a layergroup. I then add that layer group to the map once, and clear it before adding new markers. Below is a code snippet of what it might look like. That way all markers are cleared out before adding new ones. I hope that helps you.
var map = L.map('map').setView([0, 0], 2);
var markerLayerGroup = new L.LayerGroup();
map.addLayer(markerLayerGroup);
function addMarkers() {
markerLayerGroup.clearLayers();
markerLayerGroup.addLayer(markerVariable);
}
I have used the range: true property to overcome this issue in a project i'm working on.
It is suboptimal however given that you need to move 2 sliders, both a Left and right slider, which represent the limits of the period you're interested in viewing, rather than just one for say a month end snapshot.
Also one increment of the slider will add 1 point to the map rather than adding a whole lot at once.
I expect there are solutions to these problems by extending the class but i've not had the time to do that yet.
here's my code:
var sliderControl = L.control.sliderControl({
position: "topleft",
layer: membMarksCurrent,
range: true
});
map.addControl(sliderControl);
sliderControl.startSlider();

Categories

Resources