Current File : //home/tradevaly/www/node_modules/leaflet/src/layer/Tooltip.js |
import * as Browser from '../core/Browser';
import {DivOverlay} from './DivOverlay';
import {toPoint} from '../geometry/Point';
import {Map} from '../map/Map';
import {Layer} from './Layer';
import * as Util from '../core/Util';
import * as DomUtil from '../dom/DomUtil';
/*
* @class Tooltip
* @inherits DivOverlay
* @aka L.Tooltip
* Used to display small texts on top of map layers.
*
* @example
*
* ```js
* marker.bindTooltip("my tooltip text").openTooltip();
* ```
* Note about tooltip offset. Leaflet takes two options in consideration
* for computing tooltip offsetting:
* - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
* Add a positive x offset to move the tooltip to the right, and a positive y offset to
* move it to the bottom. Negatives will move to the left and top.
* - the `tooltipAnchor` Icon option: this will only be considered for Marker. You
* should adapt this value if you use a custom icon.
*/
// @namespace Tooltip
export var Tooltip = DivOverlay.extend({
// @section
// @aka Tooltip options
options: {
// @option pane: String = 'tooltipPane'
// `Map pane` where the tooltip will be added.
pane: 'tooltipPane',
// @option offset: Point = Point(0, 0)
// Optional offset of the tooltip position.
offset: [0, 0],
// @option direction: String = 'auto'
// Direction where to open the tooltip. Possible values are: `right`, `left`,
// `top`, `bottom`, `center`, `auto`.
// `auto` will dynamically switch between `right` and `left` according to the tooltip
// position on the map.
direction: 'auto',
// @option permanent: Boolean = false
// Whether to open the tooltip permanently or only on mouseover.
permanent: false,
// @option sticky: Boolean = false
// If true, the tooltip will follow the mouse instead of being fixed at the feature center.
sticky: false,
// @option interactive: Boolean = false
// If true, the tooltip will listen to the feature events.
interactive: false,
// @option opacity: Number = 0.9
// Tooltip container opacity.
opacity: 0.9
},
onAdd: function (map) {
DivOverlay.prototype.onAdd.call(this, map);
this.setOpacity(this.options.opacity);
// @namespace Map
// @section Tooltip events
// @event tooltipopen: TooltipEvent
// Fired when a tooltip is opened in the map.
map.fire('tooltipopen', {tooltip: this});
if (this._source) {
// @namespace Layer
// @section Tooltip events
// @event tooltipopen: TooltipEvent
// Fired when a tooltip bound to this layer is opened.
this._source.fire('tooltipopen', {tooltip: this}, true);
}
},
onRemove: function (map) {
DivOverlay.prototype.onRemove.call(this, map);
// @namespace Map
// @section Tooltip events
// @event tooltipclose: TooltipEvent
// Fired when a tooltip in the map is closed.
map.fire('tooltipclose', {tooltip: this});
if (this._source) {
// @namespace Layer
// @section Tooltip events
// @event tooltipclose: TooltipEvent
// Fired when a tooltip bound to this layer is closed.
this._source.fire('tooltipclose', {tooltip: this}, true);
}
},
getEvents: function () {
var events = DivOverlay.prototype.getEvents.call(this);
if (Browser.touch && !this.options.permanent) {
events.preclick = this._close;
}
return events;
},
_close: function () {
if (this._map) {
this._map.closeTooltip(this);
}
},
_initLayout: function () {
var prefix = 'leaflet-tooltip',
className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
this._contentNode = this._container = DomUtil.create('div', className);
},
_updateLayout: function () {},
_adjustPan: function () {},
_setPosition: function (pos) {
var subX, subY,
map = this._map,
container = this._container,
centerPoint = map.latLngToContainerPoint(map.getCenter()),
tooltipPoint = map.layerPointToContainerPoint(pos),
direction = this.options.direction,
tooltipWidth = container.offsetWidth,
tooltipHeight = container.offsetHeight,
offset = toPoint(this.options.offset),
anchor = this._getAnchor();
if (direction === 'top') {
subX = tooltipWidth / 2;
subY = tooltipHeight;
} else if (direction === 'bottom') {
subX = tooltipWidth / 2;
subY = 0;
} else if (direction === 'center') {
subX = tooltipWidth / 2;
subY = tooltipHeight / 2;
} else if (direction === 'right') {
subX = 0;
subY = tooltipHeight / 2;
} else if (direction === 'left') {
subX = tooltipWidth;
subY = tooltipHeight / 2;
} else if (tooltipPoint.x < centerPoint.x) {
direction = 'right';
subX = 0;
subY = tooltipHeight / 2;
} else {
direction = 'left';
subX = tooltipWidth + (offset.x + anchor.x) * 2;
subY = tooltipHeight / 2;
}
pos = pos.subtract(toPoint(subX, subY, true)).add(offset).add(anchor);
DomUtil.removeClass(container, 'leaflet-tooltip-right');
DomUtil.removeClass(container, 'leaflet-tooltip-left');
DomUtil.removeClass(container, 'leaflet-tooltip-top');
DomUtil.removeClass(container, 'leaflet-tooltip-bottom');
DomUtil.addClass(container, 'leaflet-tooltip-' + direction);
DomUtil.setPosition(container, pos);
},
_updatePosition: function () {
var pos = this._map.latLngToLayerPoint(this._latlng);
this._setPosition(pos);
},
setOpacity: function (opacity) {
this.options.opacity = opacity;
if (this._container) {
DomUtil.setOpacity(this._container, opacity);
}
},
_animateZoom: function (e) {
var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center);
this._setPosition(pos);
},
_getAnchor: function () {
// Where should we anchor the tooltip on the source layer?
return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]);
}
});
// @namespace Tooltip
// @factory L.tooltip(options?: Tooltip options, source?: Layer)
// Instantiates a Tooltip object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers.
export var tooltip = function (options, source) {
return new Tooltip(options, source);
};
// @namespace Map
// @section Methods for Layers and Controls
Map.include({
// @method openTooltip(tooltip: Tooltip): this
// Opens the specified tooltip.
// @alternative
// @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this
// Creates a tooltip with the specified content and options and open it.
openTooltip: function (tooltip, latlng, options) {
if (!(tooltip instanceof Tooltip)) {
tooltip = new Tooltip(options).setContent(tooltip);
}
if (latlng) {
tooltip.setLatLng(latlng);
}
if (this.hasLayer(tooltip)) {
return this;
}
return this.addLayer(tooltip);
},
// @method closeTooltip(tooltip?: Tooltip): this
// Closes the tooltip given as parameter.
closeTooltip: function (tooltip) {
if (tooltip) {
this.removeLayer(tooltip);
}
return this;
}
});
/*
* @namespace Layer
* @section Tooltip methods example
*
* All layers share a set of methods convenient for binding tooltips to it.
*
* ```js
* var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map);
* layer.openTooltip();
* layer.closeTooltip();
* ```
*/
// @section Tooltip methods
Layer.include({
// @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this
// Binds a tooltip to the layer with the passed `content` and sets up the
// necessary event listeners. If a `Function` is passed it will receive
// the layer as the first argument and should return a `String` or `HTMLElement`.
bindTooltip: function (content, options) {
if (content instanceof Tooltip) {
Util.setOptions(content, options);
this._tooltip = content;
content._source = this;
} else {
if (!this._tooltip || options) {
this._tooltip = new Tooltip(options, this);
}
this._tooltip.setContent(content);
}
this._initTooltipInteractions();
if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) {
this.openTooltip();
}
return this;
},
// @method unbindTooltip(): this
// Removes the tooltip previously bound with `bindTooltip`.
unbindTooltip: function () {
if (this._tooltip) {
this._initTooltipInteractions(true);
this.closeTooltip();
this._tooltip = null;
}
return this;
},
_initTooltipInteractions: function (remove) {
if (!remove && this._tooltipHandlersAdded) { return; }
var onOff = remove ? 'off' : 'on',
events = {
remove: this.closeTooltip,
move: this._moveTooltip
};
if (!this._tooltip.options.permanent) {
events.mouseover = this._openTooltip;
events.mouseout = this.closeTooltip;
if (this._tooltip.options.sticky) {
events.mousemove = this._moveTooltip;
}
if (Browser.touch) {
events.click = this._openTooltip;
}
} else {
events.add = this._openTooltip;
}
this[onOff](events);
this._tooltipHandlersAdded = !remove;
},
// @method openTooltip(latlng?: LatLng): this
// Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed.
openTooltip: function (layer, latlng) {
if (this._tooltip && this._map) {
latlng = this._tooltip._prepareOpen(this, layer, latlng);
// open the tooltip on the map
this._map.openTooltip(this._tooltip, latlng);
// Tooltip container may not be defined if not permanent and never
// opened.
if (this._tooltip.options.interactive && this._tooltip._container) {
DomUtil.addClass(this._tooltip._container, 'leaflet-clickable');
this.addInteractiveTarget(this._tooltip._container);
}
}
return this;
},
// @method closeTooltip(): this
// Closes the tooltip bound to this layer if it is open.
closeTooltip: function () {
if (this._tooltip) {
this._tooltip._close();
if (this._tooltip.options.interactive && this._tooltip._container) {
DomUtil.removeClass(this._tooltip._container, 'leaflet-clickable');
this.removeInteractiveTarget(this._tooltip._container);
}
}
return this;
},
// @method toggleTooltip(): this
// Opens or closes the tooltip bound to this layer depending on its current state.
toggleTooltip: function (target) {
if (this._tooltip) {
if (this._tooltip._map) {
this.closeTooltip();
} else {
this.openTooltip(target);
}
}
return this;
},
// @method isTooltipOpen(): boolean
// Returns `true` if the tooltip bound to this layer is currently open.
isTooltipOpen: function () {
return this._tooltip.isOpen();
},
// @method setTooltipContent(content: String|HTMLElement|Tooltip): this
// Sets the content of the tooltip bound to this layer.
setTooltipContent: function (content) {
if (this._tooltip) {
this._tooltip.setContent(content);
}
return this;
},
// @method getTooltip(): Tooltip
// Returns the tooltip bound to this layer.
getTooltip: function () {
return this._tooltip;
},
_openTooltip: function (e) {
var layer = e.layer || e.target;
if (!this._tooltip || !this._map) {
return;
}
this.openTooltip(layer, this._tooltip.options.sticky ? e.latlng : undefined);
},
_moveTooltip: function (e) {
var latlng = e.latlng, containerPoint, layerPoint;
if (this._tooltip.options.sticky && e.originalEvent) {
containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent);
layerPoint = this._map.containerPointToLayerPoint(containerPoint);
latlng = this._map.layerPointToLatLng(layerPoint);
}
this._tooltip.setLatLng(latlng);
}
});