Hide map elements when user click on the related legend label

This commit is contained in:
Vincent Broute
2013-07-29 22:30:16 +02:00
parent 6914d7c906
commit bb2a0a675f

View File

@@ -3,7 +3,7 @@
* Jquery Mapael - Dynamic maps jQuery plugin (based on raphael.js) * Jquery Mapael - Dynamic maps jQuery plugin (based on raphael.js)
* Requires jQuery and raphael.js * Requires jQuery and raphael.js
* *
* Version: 0.3.0 (15-07-2013) * Version: 0.4.0 (29-07-2013)
* *
* Copyright (c) 2013 Vincent Brouté (http://www.neveldo.fr/mapael) * Copyright (c) 2013 Vincent Brouté (http://www.neveldo.fr/mapael)
* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php). * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php).
@@ -22,11 +22,13 @@
, $container = $('.' + options.map.cssClass, this).empty().append($tooltip) , $container = $('.' + options.map.cssClass, this).empty().append($tooltip)
, mapConf = $.fn.mapael.maps[options.map.name] , mapConf = $.fn.mapael.maps[options.map.name]
, paper = new Raphael($container[0], mapConf.width, mapConf.height) , paper = new Raphael($container[0], mapConf.width, mapConf.height)
, elemParams = {} , elemOptions = {}
, coords = {} , coords = {}
, resizeTO = 0 , resizeTO = 0
, areas = {} , areas = {}
, plots = {} , plots = {}
, areaLegend = {}
, plotLegend = {}
, id = 0; , id = 0;
options.map.tooltip.css && $tooltip.css(options.map.tooltip.css); options.map.tooltip.css && $tooltip.css(options.map.tooltip.css);
@@ -34,56 +36,71 @@
// Draw map areas // Draw map areas
for (id in mapConf.elems) { for (id in mapConf.elems) {
elemParams = $.fn.mapael.getElemParams( elemOptions = $.fn.mapael.getElemOptions(
options.map.defaultArea options.map.defaultArea
, (options.areas[id] ? options.areas[id] : {}) , (options.areas[id] ? options.areas[id] : {})
, options.legend.area , options.legend.area
); );
areas[id] = {'mapElem' : paper.path(mapConf.elems[id]).attr(elemParams.attrs)}; areas[id] = {'mapElem' : paper.path(mapConf.elems[id]).attr(elemOptions.attrs)};
$.fn.mapael.initElem(paper, areas[id], elemParams, $tooltip); $.fn.mapael.initElem(paper, areas[id], elemOptions, $tooltip);
} }
// Draw plots // Draw plots
for (id in options.plots) { for (id in options.plots) {
elemParams = $.fn.mapael.getElemParams( elemOptions = $.fn.mapael.getElemOptions(
options.map.defaultPlot options.map.defaultPlot
, (options.plots[id] ? options.plots[id] : {}) , (options.plots[id] ? options.plots[id] : {})
, options.legend.plot , options.legend.plot
); );
if (elemParams.x && elemParams.y) if (elemOptions.x && elemOptions.y)
coords = {x : elemParams.x, y : elemParams.y}; coords = {x : elemOptions.x, y : elemOptions.y};
else else
coords = mapConf.getCoords(elemParams.latitude, elemParams.longitude); coords = mapConf.getCoords(elemOptions.latitude, elemOptions.longitude);
if ("square" == elemParams.type) { if ("square" == elemOptions.type) {
plots[id] = {'mapElem' : paper.rect( plots[id] = {'mapElem' : paper.rect(
coords.x - (elemParams.size / 2) coords.x - (elemOptions.size / 2)
, coords.y - (elemParams.size / 2) , coords.y - (elemOptions.size / 2)
, elemParams.size , elemOptions.size
, elemParams.size , elemOptions.size
).attr(elemParams.attrs)}; ).attr(elemOptions.attrs)};
} else { // Default = circle } else { // Default = circle
plots[id] = {'mapElem' : paper.circle(coords.x, coords.y, elemParams.size / 2).attr(elemParams.attrs)}; plots[id] = {'mapElem' : paper.circle(coords.x, coords.y, elemOptions.size / 2).attr(elemOptions.attrs)};
} }
$.fn.mapael.initElem(paper, plots[id], elemParams, $tooltip); $.fn.mapael.initElem(paper, plots[id], elemOptions, $tooltip);
} }
// Create the legends for areas and plots
if (options.legend.area.slices && options.legend.area.display)
areaLegend = $.fn.mapael.createLegend($(this), options, 'area', areas);
if (options.legend.plot.slices && options.legend.plot.display)
plotLegend = $.fn.mapael.createLegend($(this), options, 'plot', plots);
/** /**
* *
* Update the current map * Update the current map
* Refresh attributes and tooltips for areas and plots * Refresh attributes and tooltips for areas and plots
* @params options options to refresh * @param options options to refresh
* @params reset true to reset previous areas and plots individual options * @param resetAreas true to reset previous areas options
* @param resetPlots true to reset previous plots options
* @param animDuration animation duration in ms
* @param easing easing type
*/ */
$(this).bind('update', function(e, updateOptions, resetAreas, resetPlots, animDuration, easing) { $(this).on('update', function(e, updateOptions, resetAreas, resetPlots, animDuration, easing) {
var elemParams = {} var elemOptions = {}
, legend = {} , legend = {}
, id = 0 , id = 0
, bbox = {} , bbox = {}
, textPosition = {} , textPosition = {}
, plotOffset = 0; , plotOffset = 0
, resetHiddenElem = function(el) {
if(typeof el.hidden != "undefined" && el.hidden == true) {
$(el.node).trigger('click');
}
};
if (!animDuration) animDuration = 300; if (!animDuration) animDuration = 300;
if (!easing) easing = 'linear'; if (!easing) easing = 'linear';
@@ -92,82 +109,84 @@
$.extend(true, options, updateOptions); $.extend(true, options, updateOptions);
areaLegend.forEach && areaLegend.forEach(resetHiddenElem);
plotLegend.forEach && plotLegend.forEach(resetHiddenElem);
// Update areas attributes and tooltips // Update areas attributes and tooltips
for (id in areas) { for (id in areas) {
elemParams = $.fn.mapael.getElemParams( elemOptions = $.fn.mapael.getElemOptions(
options.map.defaultArea options.map.defaultArea
, (options.areas[id] ? options.areas[id] : {}) , (options.areas[id] ? options.areas[id] : {})
, options.legend.area , options.legend.area
); );
$.fn.mapael.paramHover(areas[id].mapElem, elemParams.attrs, areas[id].mapElem.attrsHover); if (elemOptions.value)
areas[id].mapElem.animate(elemParams.attrs, animDuration, easing); areas[id].value = elemOptions.value;
if (elemParams.tooltip && elemParams.tooltip.content) { $.fn.mapael.setHoverOptions(areas[id].mapElem, elemOptions.attrs, areas[id].mapElem.attrsHover);
areas[id].mapElem.tooltipContent = elemParams.tooltip.content; areas[id].mapElem.animate(elemOptions.attrs, animDuration, easing);
if (elemOptions.tooltip && elemOptions.tooltip.content) {
areas[id].mapElem.tooltipContent = elemOptions.tooltip.content;
if (areas[id].textElem) { if (areas[id].textElem) {
areas[id].textElem.tooltipContent = elemParams.tooltip.content; areas[id].textElem.tooltipContent = elemOptions.tooltip.content;
} }
} }
} }
// Update plots attributes and tooltips // Update plots attributes and tooltips
for (id in plots) { for (id in plots) {
elemParams = $.fn.mapael.getElemParams( elemOptions = $.fn.mapael.getElemOptions(
options.map.defaultPlot options.map.defaultPlot
, (options.plots[id] ? options.plots[id] : {}) , (options.plots[id] ? options.plots[id] : {})
, options.legend.plot , options.legend.plot
); );
if (elemOptions.value)
plots[id].value = elemOptions.value;
// Update text position // Update text position
if (plots[id].textElem) { if (plots[id].textElem) {
bbox = plots[id].mapElem.getBBox(); bbox = plots[id].mapElem.getBBox();
plotOffset = (elemParams.size - bbox.height) / 2; plotOffset = (elemOptions.size - bbox.height) / 2;
bbox.x -= plotOffset; bbox.x -= plotOffset;
bbox.x2 += plotOffset; bbox.x2 += plotOffset;
bbox.y -= plotOffset; bbox.y -= plotOffset;
bbox.y2 += plotOffset; bbox.y2 += plotOffset;
textPosition = $.fn.mapael.getTextPosition(bbox, elemParams.textPosition); textPosition = $.fn.mapael.getTextPosition(bbox, elemOptions.textPosition);
plots[id].textElem.animate({x : textPosition.x, y : textPosition.y}, animDuration, easing); plots[id].textElem.animate({x : textPosition.x, y : textPosition.y}, animDuration, easing);
} }
// Update plot size // Update plot size
if ("square" == elemParams.type) { if ("square" == elemOptions.type) {
elemParams.attrs.width = elemParams.size; elemOptions.attrs.width = elemOptions.size;
elemParams.attrs.height = elemParams.size; elemOptions.attrs.height = elemOptions.size;
} else { // Default : circle } else { // Default : circle
elemParams.attrs.r = elemParams.size / 2; elemOptions.attrs.r = elemOptions.size / 2;
} }
$.fn.mapael.paramHover(plots[id].mapElem, elemParams.attrs, plots[id].mapElem.attrsHover); $.fn.mapael.setHoverOptions(plots[id].mapElem, elemOptions.attrs, plots[id].mapElem.attrsHover);
plots[id].mapElem.animate(elemParams.attrs, animDuration, easing); plots[id].mapElem.animate(elemOptions.attrs, animDuration, easing);
if (elemParams.tooltip && elemParams.tooltip.content) { if (elemOptions.tooltip && elemOptions.tooltip.content) {
plots[id].mapElem.tooltipContent = elemParams.tooltip.content; plots[id].mapElem.tooltipContent = elemOptions.tooltip.content;
if (plots[id].textElem) { if (plots[id].textElem) {
plots[id].textElem.tooltipContent = elemParams.tooltip.content; plots[id].textElem.tooltipContent = elemOptions.tooltip.content;
} }
} }
} }
}); });
// Create the legends for areas and plots // Handle resizing of the map
if (options.legend.area.slices && options.legend.area.display)
$.fn.mapael.createLegend($(this), options, 'area');
if (options.legend.plot.slices && options.legend.plot.display)
$.fn.mapael.createLegend($(this), options, 'plot');
// Handle size of the map
if (options.map.width) { if (options.map.width) {
paper.setSize(options.map.width, mapConf.height * (options.map.width / mapConf.width)); paper.setSize(options.map.width, mapConf.height * (options.map.width / mapConf.width));
} else { } else {
$(window).bind('resize', function(){ $(window).on('resize', function(){
clearTimeout(resizeTO); clearTimeout(resizeTO);
resizeTO = setTimeout(function(){$container.trigger('resizeEnd');}, 150); resizeTO = setTimeout(function(){$container.trigger('resizeEnd');}, 150);
}); });
$(document).bind('ready', function(){$container.trigger('resizeEnd');}); $(document).on('ready', function(){$container.trigger('resizeEnd');});
$container.bind('resizeEnd', function(e) { $container.on('resizeEnd', function(e) {
var containerWidth = $container.width(); var containerWidth = $container.width();
if (paper.width != containerWidth) { if (paper.width != containerWidth) {
paper.setSize(containerWidth, mapConf.height * (containerWidth / mapConf.width)); paper.setSize(containerWidth, mapConf.height * (containerWidth / mapConf.width));
@@ -181,52 +200,275 @@
}; };
/** /**
* Get element parameters by merging default params, element params and legend params * Init the element of the map (drawing, setting attributes, events, tooltip, ...)
* @param paper
* @param elem
* @param params
* @param $tooltip
*/ */
$.fn.mapael.getElemParams = function(defaultParams, elemParams, legendOptions) { $.fn.mapael.initElem = function(paper, elem, options, $tooltip) {
var elemParams = $.extend(true, {}, defaultParams, elemParams);
if (elemParams.value) {
$.extend(true, elemParams, $.fn.mapael.getLegendEl(elemParams.value, legendOptions));
}
return elemParams;
}
/**
* Init the element of the map (draw it, set attributes, events, tooltip, ...)
*/
$.fn.mapael.initElem = function(paper, elem, params, $tooltip) {
var bbox = {}, textPosition = {}; var bbox = {}, textPosition = {};
$.fn.mapael.paramHover(elem.mapElem, params.attrs, params.attrsHover); $.fn.mapael.setHoverOptions(elem.mapElem, options.attrs, options.attrsHover);
// Set a text label in the area if (options.text) {
if (params.text) { // Set a text label in the area
bbox = elem.mapElem.getBBox(); bbox = elem.mapElem.getBBox();
textPosition = $.fn.mapael.getTextPosition(bbox, params.textPosition); textPosition = $.fn.mapael.getTextPosition(bbox, options.textPosition);
params.textAttrs['text-anchor'] = textPosition.textAnchor; options.textAttrs['text-anchor'] = textPosition.textAnchor;
elem.textElem = paper.text(textPosition.x, textPosition.y, params.text).attr(params.textAttrs); elem.textElem = paper.text(textPosition.x, textPosition.y, options.text).attr(options.textAttrs);
params.attrs.href && (elem.textElem.attr({href: params.attrs.href})); options.attrs.href && (elem.textElem.attr({href: options.attrs.href}));
$.fn.mapael.paramHover(elem.textElem, params.textAttrs, params.textAttrsHover); $.fn.mapael.setHoverOptions(elem.textElem, options.textAttrs, options.textAttrsHover);
$.fn.mapael.setHover(paper, elem.mapElem, elem.textElem); $.fn.mapael.setHover(paper, elem.mapElem, elem.textElem);
$.fn.mapael.setCallbacks(params, elem.mapElem, elem.textElem); $.fn.mapael.setCallbacks(options, elem.mapElem, elem.textElem);
} else { } else {
$.fn.mapael.setHover(paper, elem.mapElem); $.fn.mapael.setHover(paper, elem.mapElem);
$.fn.mapael.setCallbacks(params, elem.mapElem); $.fn.mapael.setCallbacks(options, elem.mapElem);
} }
if (params.tooltip && params.tooltip.content) { if (options.tooltip && options.tooltip.content) {
elem.mapElem.tooltipContent = params.tooltip.content; elem.mapElem.tooltipContent = options.tooltip.content;
$.fn.mapael.setTooltip(elem.mapElem, $tooltip); $.fn.mapael.setTooltip(elem.mapElem, $tooltip);
if (params.text) { if (options.text) {
elem.textElem.tooltipContent = params.tooltip.content; elem.textElem.tooltipContent = options.tooltip.content;
$.fn.mapael.setTooltip(elem.textElem, $tooltip); $.fn.mapael.setTooltip(elem.textElem, $tooltip);
} }
} }
if (options.value)
elem.value = options.value;
} }
/** /**
* Get the text position (x, y and text-anchor) * Set a tooltip for the areas and plots
* @param elem area or plot element
* @param $tooltip the tooltip container
* @param content the content to set in the tooltip
*/
$.fn.mapael.setTooltip = function(elem, $tooltip) {
var tooltipTO = 0;
$(elem.node).on("mouseover", function() {
tooltipTO = setTimeout(function() {$tooltip.html(elem.tooltipContent).css("display", "block");}, 120);
}).on("mouseout", function() {
clearTimeout(tooltipTO);
$tooltip.css("display", "none");
}).on("mousemove", function(e) {
$tooltip.css("left", e.pageX + 15).css("top", e.pageY + 15 - $(window).scrollTop());
});
};
/**
* Set user defined callbacks on areas and plots
* @param elemOptions the element parameters
* @param mapElem the map element to set callback on
* @param textElem the optional text within the map element
*/
$.fn.mapael.setCallbacks = function(elemOptions, mapElem, textElem) {
var availableCallbacks = ['click', 'mouseover', 'mouseout']
, callbackFct = {};
for(var i = 0, length = availableCallbacks.length; i < length; ++i) {
if (elemOptions["on" + availableCallbacks[i]]) {
callbackFct = elemOptions["on" + availableCallbacks[i]];
$(mapElem.node).on(availableCallbacks[i], function() {callbackFct(elemOptions, mapElem, textElem)});
textElem && $(textElem.node).on(availableCallbacks[i], function() {callbackFct(elemOptions, mapElem, textElem)});
}
}
}
/**
* Draw a legend for areas and / or plots
* @param $container the legend container
* @param options map options
* @param legendType the type of the legend : 'area' or 'plot'
*/
$.fn.mapael.createLegend = function ($container, options, legendType, elems) {
var legendOptions = options.legend[legendType]
, $legend = (legendType == 'plot') ? $('.' + options.legend.plot.cssClass, $container).empty() : $('.' + options.legend.area.cssClass, $container).empty()
, paper = new Raphael($legend.get(0))
, width = 5
, height = 5
, title = {}
, defaultElemOptions = {}
, elem = {}
, label = {};
if(legendOptions.title) {
title = paper.text(legendOptions.marginLeftTitle, legendOptions.marginBottom, legendOptions.title)
.attr(legendOptions.titleAttrs);
width = legendOptions.marginLeftTitle + title.getBBox().width;
height += legendOptions.marginBottom + title.getBBox().height;
}
for(var i = 0, length = legendOptions.slices.length; i < length; ++i) {
defaultElemOptions = (legendType == 'plot') ? options.map['defaultPlot'] : options.map['defaultArea'];
legendOptions.slices[i].attrs = $.extend(
{}
, defaultElemOptions.attrs
, legendOptions.slices[i].attrs
);
legendOptions.slices[i].attrsHover = $.extend(
{}
, defaultElemOptions.attrsHover
, legendOptions.slices[i].attrsHover
);
if(legendType == 'area' || legendOptions.slices[i].type == "square") {
// Draw a square for squared plots AND areas
!legendOptions.slices[i].size && (legendOptions.slices[i].size = 20);
elem = paper.rect(
legendOptions.marginLeft
, height
, legendOptions.slices[i].size
, legendOptions.slices[i].size
).attr(legendOptions.slices[i].attrs);
} else {
elem = paper.circle(
legendOptions.marginLeft + legendOptions.slices[i].size / 2
, height + legendOptions.slices[i].size / 2
, legendOptions.slices[i].size / 2
).attr(legendOptions.slices[i].attrs);
}
label = paper.text(
legendOptions.marginLeft + legendOptions.slices[i].size + legendOptions.marginLeftLabel
, height + legendOptions.slices[i].size / 2
, legendOptions.slices[i].label
).attr(legendOptions.labelAttrs);
height += legendOptions.marginBottom + legendOptions.slices[i].size;
width = Math.max(width, legendOptions.marginLeft + legendOptions.slices[i].size + legendOptions.marginLeftLabel + label.getBBox().width);
if (legendOptions.hideElemsOnClick.enabled) {
// Hide/show elements when user clicks on a legend element
label.attr({cursor:'pointer'});
$.fn.mapael.setHoverOptions(elem, legendOptions.slices[i].attrs, legendOptions.slices[i].attrsHover);
$.fn.mapael.setHoverOptions(label, legendOptions.labelAttrs, legendOptions.labelAttrs);
$.fn.mapael.setHover(paper, elem, label);
label.hidden = false;
(function(i, elem, label) {
$(label.node).on('click', function() {
if (!label.hidden) {
label.animate({'opacity':legendOptions.hideElemsOnClick.opacity}, 300);
elem.animate({'opacity':legendOptions.hideElemsOnClick.opacity}, 300);
} else {
label.animate({'opacity':typeof label.originalAttrs.opacity != "undefined" ? label.originalAttrs.opacity : 1}, 300);
elem.animate({'opacity':typeof elem.originalAttrs.opacity != "undefined" ? elem.originalAttrs.opacity : 1}, 300);
}
for (var id in elems) {
if ((!legendOptions.slices[i].min || elems[id].value >= legendOptions.slices[i].min)
&& (!legendOptions.slices[i].max || elems[id].value < legendOptions.slices[i].max)
) {
if (!label.hidden) {
elems[id].mapElem.animate({'opacity':legendOptions.hideElemsOnClick.opacity}, 300);
elems[id].textElem && elems[id].textElem.animate({'opacity':legendOptions.hideElemsOnClick.opacity}, 300);
} else {
elems[id].mapElem.animate({'opacity':typeof elems[id].mapElem.originalAttrs.opacity != "undefined" ? elems[id].mapElem.originalAttrs.opacity : 1}, 300);
elems[id].textElem && elems[id].textElem.animate({'opacity':typeof elems[id].textElem.originalAttrs.opacity != "undefined" ? elems[id].textElem.originalAttrs.opacity : 1}, 300);
}
}
}
label.hidden = !label.hidden;
});
})(i, elem, label);
}
}
// VMLWidth option allows you to set static width for the legend
// only for VML render because text.getBBox() returns wrong values on IE6/7
if (Raphael.type != 'SVG' && legendOptions.VMLWidth)
width = legendOptions.VMLWidth;
paper.setSize(width, height)
return paper;
}
/**
* Set the attributes on hover and the attributes to restore for a map element
* @param elem the map element
* @param originalAttrs the original attributes to restore on mouseout event
* @param attrsHover the attributes to set on mouseover event
*/
$.fn.mapael.setHoverOptions = function (elem, originalAttrs, attrsHover) {
// Disable transform option on hover for VML (IE<9) because of several bugs
if (Raphael.type != 'SVG') delete attrsHover.transform;
elem.attrsHover = attrsHover;
if (elem.attrsHover.transform) elem.originalAttrs = $.extend({transform : "s1"}, originalAttrs);
else elem.originalAttrs = originalAttrs;
};
/**
* Set the hover behavior (mouseover & mouseout) for plots and areas
* @param paper Raphael paper object
* @param mapElem the map element
* @param textElem the optional text element (within the map element)
*/
$.fn.mapael.setHover = function (paper, mapElem, textElem) {
var $mapElem = {}
, $textElem = {}
, hoverTO = 0
, overBehaviour = function() {hoverTO = setTimeout(function () {$.fn.mapael.elemHover(paper, mapElem, textElem);}, 120);}
, outBehaviour = function () {clearTimeout(hoverTO);$.fn.mapael.elemOut(paper, mapElem, textElem);};
$mapElem = $(mapElem.node);
$mapElem.on("mouseover", overBehaviour);
$mapElem.on("mouseout", outBehaviour);
if (textElem) {
$textElem = $(textElem.node);
$textElem.on("mouseover", overBehaviour);
$(textElem.node).on("mouseout", outBehaviour);
}
};
/**
* Set he behaviour for 'mouseover' event
* @param paper paper Raphael paper object
* @param mapElem mapElem the map element
* @param textElem the optional text element (within the map element)
*/
$.fn.mapael.elemHover = function (paper, mapElem, textElem) {
mapElem.animate(mapElem.attrsHover, mapElem.attrsHover.animDuration);
textElem && textElem.animate(textElem.attrsHover, textElem.attrsHover.animDuration);
paper.safari();
}
/**
* Set he behaviour for 'mouseout' event
* @param paper Raphael paper object
* @param mapElem the map element
* @param textElem the optional text element (within the map element)
*/
$.fn.mapael.elemOut = function (paper, mapElem, textElem) {
mapElem.animate(mapElem.originalAttrs, mapElem.attrsHover.animDuration);
textElem && textElem.animate(textElem.originalAttrs, textElem.attrsHover.animDuration);
paper.safari();
};
/**
* Get element options by merging default options, element options and legend options
* @param defaultOptions
* @param elemOptions
* @param legendOptions
*/
$.fn.mapael.getElemOptions = function(defaultOptions, elemOptions, legendOptions) {
var options = $.extend(true, {}, defaultOptions, elemOptions);
if (options.value) {
$.extend(true, options, $.fn.mapael.getLegendSlice(options.value, legendOptions));
}
return options;
}
/**
* Get the coordinates of the text relative to a bbox and a position
* @param bbox the boundary box of the element * @param bbox the boundary box of the element
* @param textPosition the wanted text position (inner, right, left, top or bottom) * @param textPosition the wanted text position (inner, right, left, top or bottom)
*/ */
@@ -264,32 +506,13 @@
return {'x' : textX, 'y' : textY, 'textAnchor' : textAnchor}; return {'x' : textX, 'y' : textY, 'textAnchor' : textAnchor};
} }
/**
* Set user defined callbacks on areas and plots
* @param elemParams the element parameters
* @param mapElem the map element to set callback on
* @param textElem the optional text within the map element
*/
$.fn.mapael.setCallbacks = function(elemParams, mapElem, textElem) {
var availableCallbacks = ['click', 'mouseover', 'mouseout']
, callbackFct = {};
for(var i = 0, length = availableCallbacks.length; i < length; ++i) {
if (elemParams["on" + availableCallbacks[i]]) {
callbackFct = elemParams["on" + availableCallbacks[i]];
$(mapElem.node).bind(availableCallbacks[i], function() {callbackFct(elemParams, mapElem, textElem)});
textElem && $(textElem.node).bind(availableCallbacks[i], function() {callbackFct(elemParams, mapElem, textElem)});
}
}
}
/** /**
* Get the legend conf matching with the value * Get the legend conf matching with the value
* @param value the value to match with a slice in the legend * @param value the value to match with a slice in the legend
* @param legend the legend params object * @param legend the legend params object
* @return the legend slice matching with the value * @return the legend slice matching with the value
*/ */
$.fn.mapael.getLegendEl = function (value, legend) { $.fn.mapael.getLegendSlice = function (value, legend) {
for(var i = 0, length = legend.slices.length; i < length; ++i) { for(var i = 0, length = legend.slices.length; i < length; ++i) {
if ((!legend.slices[i].min || value >= legend.slices[i].min) if ((!legend.slices[i].min || value >= legend.slices[i].min)
&& (!legend.slices[i].max || value < legend.slices[i].max) && (!legend.slices[i].max || value < legend.slices[i].max)
@@ -300,259 +523,107 @@
return {}; return {};
}; };
/**
* Join a tooltip to areas and plots
* @param elem area or plot element
* @param $tooltip the tooltip container
* @param content the content to set in the tooltip
*/
$.fn.mapael.setTooltip = function(elem, $tooltip) {
var tooltipTO = 0;
$(elem.node).bind("mouseover", function() {
tooltipTO = setTimeout(function() {$tooltip.html(elem.tooltipContent).css("display", "block");}, 120);
}).bind("mouseout", function() {
clearTimeout(tooltipTO);
$tooltip.css("display", "none");
}).bind("mousemove", function(e) {
$tooltip.css("left", e.pageX + 15).css("top", e.pageY + 15 - $(window).scrollTop());
});
};
/**
* Draw a legend for areas and / or plots
* @param $container the legend container
* @param options map options
* @param legendType the type of the legend : 'area' or 'plot'
*/
$.fn.mapael.createLegend = function ($container, options, legendType) {
var legendParams = options.legend[legendType]
, $legend = (legendType == 'plot') ? $('.' + options.legend.plot.cssClass, $container).empty() : $('.' + options.legend.area.cssClass, $container).empty()
, paper = new Raphael($legend.get(0))
, width = 5
, height = 5
, title = {}
, defaultElemParams = {}
, elem = {}
, label = {};
if(legendParams.title) {
title = paper.text(legendParams.marginLeftTitle, legendParams.marginBottom, legendParams.title)
.attr(legendParams.titleAttrs);
width = legendParams.marginLeftTitle + title.getBBox().width;
height += legendParams.marginBottom + title.getBBox().height;
}
for(var i = 0, length = legendParams.slices.length; i < length; ++i) {
defaultElemParams = (legendType == 'plot') ? options.map['defaultPlot'] : options.map['defaultArea'];
legendParams.slices[i].attrs = $.extend(
{}
, defaultElemParams.attrs
, legendParams.slices[i].attrs
);
legendParams.slices[i].attrsHover = $.extend(
{}
, defaultElemParams.attrsHover
, legendParams.slices[i].attrsHover
);
if(legendType == 'area' || legendParams.slices[i].type == "square") {
// Draw a square for squared plots AND areas
!legendParams.slices[i].size && (legendParams.slices[i].size = 20);
elem = paper.rect(
legendParams.marginLeft
, height
, legendParams.slices[i].size
, legendParams.slices[i].size
).attr(legendParams.slices[i].attrs);
} else {
elem = paper.circle(
legendParams.marginLeft + legendParams.slices[i].size / 2
, height + legendParams.slices[i].size / 2
, legendParams.slices[i].size / 2
).attr(legendParams.slices[i].attrs);
}
label = paper.text(
legendParams.marginLeft + legendParams.slices[i].size + legendParams.marginLeftLabel
, height + legendParams.slices[i].size / 2
, legendParams.slices[i].label
).attr(legendParams.labelAttrs);
height += legendParams.marginBottom + legendParams.slices[i].size;
width = Math.max(width, legendParams.marginLeft + legendParams.slices[i].size + legendParams.marginLeftLabel + label.getBBox().width);
$.fn.mapael.paramHover(elem, legendParams.slices[i].attrs, legendParams.slices[i].attrsHover);
$.fn.mapael.paramHover(label, legendParams.labelAttrs, legendParams.labelAttrs);
$.fn.mapael.setHover(paper, elem, label);
}
// VMLWidth option allows you to set static width for the legend
// only for VML render because text.getBBox() returns wrong values on IE6/7
if (Raphael.type != 'SVG' && legendParams.VMLWidth)
width = legendParams.VMLWidth;
paper.setSize(width, height);
}
/**
* Set he behaviour for 'mouseover' event
* @param paper paper Raphael paper object
* @param mapElem mapElem the map element
* @param textElem the optional text element (within the map element)
*/
$.fn.mapael.hoverIn = function (paper, mapElem, textElem) {
mapElem.animate(mapElem.attrsHover, mapElem.attrsHover.animDuration);
textElem && textElem.animate(textElem.attrsHover, textElem.attrsHover.animDuration);
paper.safari();
}
/**
* Set he behaviour for 'mouseout' event
* @param paper Raphael paper object
* @param mapElem the map element
* @param textElem the optional text element (within the map element)
*/
$.fn.mapael.hoverOut = function (paper, mapElem, textElem) {
mapElem.animate(mapElem.originalAttrs, mapElem.attrsHover.animDuration);
textElem && textElem.animate(textElem.originalAttrs, textElem.attrsHover.animDuration);
paper.safari();
};
/**
* Set the hover behavior (mouseover & mouseout) for plots and areas
* @param paper Raphael paper object
* @param mapElem the map element
* @param textElem the optional text element (within the map element)
*/
$.fn.mapael.setHover = function (paper, mapElem, textElem) {
var $mapElem = {}
, $textElem = {}
, hoverTO = 0
, overBehaviour = function() {hoverTO = setTimeout(function () {$.fn.mapael.hoverIn(paper, mapElem, textElem);}, 120);}
, outBehaviour = function () {clearTimeout(hoverTO);$.fn.mapael.hoverOut(paper, mapElem, textElem);};
$mapElem = $(mapElem.node);
$mapElem.bind("mouseover", overBehaviour);
$mapElem.bind("mouseout", outBehaviour);
if (textElem) {
$textElem = $(textElem.node);
$textElem.bind("mouseover", overBehaviour);
$(textElem.node).bind("mouseout", outBehaviour);
}
};
/**
* Set the attributes on hover and the attributes to restore for a map element
* @param elem the map element
* @param originalAttrs the original attributes to restore on mouseout event
* @param attrsHover the attributes to set on mouseover event
*/
$.fn.mapael.paramHover = function (elem, originalAttrs, attrsHover) {
// Disable transform option on hover for VML (IE<9) because of several bugs
if (Raphael.type != 'SVG') delete attrsHover.transform;
elem.attrsHover = attrsHover;
if (elem.attrsHover.transform) elem.originalAttrs = $.extend({transform : "s1"}, originalAttrs);
else elem.originalAttrs = originalAttrs;
};
// Default map options // Default map options
$.fn.mapael.defaultOptions = { $.fn.mapael.defaultOptions = {
map: { map : {
cssClass: "map" cssClass : "map"
, tooltip: { , tooltip : {
cssClass: "mapTooltip" cssClass : "mapTooltip"
} }
, defaultArea: { , defaultArea : {
attrs: { attrs : {
fill: "#343434" fill : "#343434"
, stroke: "#5d5d5d" , stroke : "#5d5d5d"
, "stroke-width": 1 , "stroke-width" : 1
, "stroke-linejoin": "round" , "stroke-linejoin" : "round"
} }
, attrsHover: { , attrsHover : {
fill: "#f38a03" fill : "#f38a03"
, animDuration : 300 , animDuration : 300
} }
, textPosition: 'inner' , textPosition : 'inner'
, textAttrs: { , textAttrs : {
"font-size": 15 "font-size" : 15
, fill:"#c7c7c7" , fill : "#c7c7c7"
} }
, textAttrsHover: { , textAttrsHover : {
fill:"#eaeaea" fill : "#eaeaea"
, "animDuration" : 300 , "animDuration" : 300
} }
} }
, defaultPlot: { , defaultPlot : {
type: "circle" type : "circle"
, size: 15 , size : 15
, attrs: { , attrs : {
fill: "#0088db" fill : "#0088db"
, stroke: "#fff" , stroke : "#fff"
, "stroke-width": 0 , "stroke-width" : 0
, "stroke-linejoin": "round" , "stroke-linejoin" : "round"
} }
, attrsHover: { , attrsHover : {
"stroke-width": 3 "stroke-width" : 3
, animDuration : 300 , animDuration : 300
} }
, textPosition: 'right' , textPosition : 'right'
, textAttrs: { , textAttrs : {
"font-size": 15 "font-size" : 15
, fill:"#c7c7c7" , fill : "#c7c7c7"
}, },
textAttrsHover: { textAttrsHover : {
fill:"#eaeaea" fill : "#eaeaea"
, animDuration : 300 , animDuration : 300
} }
} }
} }
, legend: { , legend : {
area: { area : {
cssClass: "areaLegend" cssClass : "areaLegend"
, display: false , display : false
, marginLeft: 15 , marginLeft : 15
, marginLeftTitle: 5 , marginLeftTitle : 5
, marginLeftLabel: 10 , marginLeftLabel : 10
, marginBottom: 15 , marginBottom : 15
, titleAttrs: { , titleAttrs : {
"font-size" : 18 "font-size" : 18
, fill : "#343434" , fill : "#343434"
, "text-anchor" : "start" , "text-anchor" : "start"
} }
, labelAttrs: { , labelAttrs : {
"font-size" : 15 "font-size" : 15
, fill : "#343434" , fill : "#343434"
, "text-anchor" : "start" , "text-anchor" : "start"
} }
, hideElemsOnClick : {
enabled : true
, opacity : 0.2
}
, slices : [] , slices : []
} }
, plot: { , plot : {
cssClass: "plotLegend" cssClass : "plotLegend"
, display: false , display : false
, marginLeft: 15 , marginLeft : 15
, marginLeftTitle: 5 , marginLeftTitle : 5
, marginLeftLabel: 10 , marginLeftLabel : 10
, marginBottom: 15 , marginBottom : 15
, titleAttrs: { , titleAttrs : {
"font-size" : 18 "font-size" : 18
, fill : "#343434" , fill : "#343434"
, "text-anchor" : "start" , "text-anchor" : "start"
} }
, labelAttrs: { , labelAttrs : {
"font-size" : 15 "font-size" : 15
, fill : "#343434" , fill : "#343434"
, "text-anchor" : "start" , "text-anchor" : "start"
} }
, hideElemsOnClick : {
enabled : true
, opacity : 0.2
}
, slices : [] , slices : []
} }
} }
, areas: {} , areas : {}
, plots: {} , plots : {}
}; };
})(jQuery); })(jQuery);