/* * @Author: hisense.wuhongjian * @Date: 2022-03-22 14:40:05 * @LastEditors: hisense.wuhongjian * @LastEditTime: 2022-03-22 14:40:05 * @Description: 告诉大家这是什么 */ (function(factory, window) { if (typeof define === 'function' && define.amd) { define(['leaflet'], factory); } else if (typeof exports === 'object') { module.exports = factory(require('leaflet')); } if (typeof window !== 'undefined' && window.L) { window.L.tooltipLayout = factory(L); } })(function(L) { var TooltipLayout = {}; // global variables let map; let markerList = []; // all markers here let polylineList = []; // all polylines here // events let _onPolylineCreated = null; // will be called after polyline has been created function initialize(leafletMap, onPolylineCreated) { map = leafletMap; polylineList = []; //default style if (onPolylineCreated) { _onPolylineCreated = onPolylineCreated; } else { _onPolylineCreated = ply => { ply.setStyle({ color: '#90A4AE' }); }; } setRandomPos(map); layoutByForce(); setEdgePosition(); drawLine(map); // event registrations map.on('zoomstart', function() { removeAllPolyline(map); }); map.on('zoomend', function() { setRandomPos(map); layoutByForce(); setEdgePosition(); drawLine(map); }); map.on('dragend', function() { removeAllPolyline(map); setRandomPos(map); layoutByForce(); setEdgePosition(); drawLine(map); }); map.on('resize', function() { removeAllPolyline(map); setRandomPos(map); layoutByForce(); setEdgePosition(); drawLine(map); }); } function resetMarker(marker) { var name = marker.getTooltip().getContent(); var options = marker.getTooltip().options; marker.unbindTooltip(); marker.bindTooltip(name, { pane: options.pane, offset: options.offset, classname: 'heading', permanent: true, interactive: true, direction: 'left', sticky: 'none', opacity: options.opacity }); markerList.push(marker); } function getMarkers() { return markerList; } function getLine(marker) { return marker.__ply; } function removeAllPolyline(map) { var i; for (i = 0; i < polylineList.length; i++) { map.removeLayer(polylineList[i]); } polylineList = []; } /** * Draw lines between markers and tooltips * @param map leaflet map */ function drawLine(map) { removeAllPolyline(map); for (var i = 0; i < markerList.length; i++) { var marker = markerList[i]; var markerDom = marker._icon; var markerPosition = getPosition(markerDom); var label = marker.getTooltip(); var labelDom = label._container; var labelPosition = getPosition(labelDom); var x1 = labelPosition.x; var y1 = labelPosition.y; var x = markerPosition.x; var y = markerPosition.y; x1 -= 5; y1 += 2; if (x1 - x !== 0 || y1 - y !== 0) { if (x1 + labelDom.offsetWidth < markerPosition.x) { x1 += labelDom.offsetWidth; } if (y1 + labelDom.offsetHeight < markerPosition.y) { y1 += labelDom.offsetHeight; } var lineDest = L.point(x1, y1); var destLatLng = map.layerPointToLatLng(lineDest); setTimeout( ((marker, destLatLng) => () => { let ply = L.polyline([marker.getLatLng(), destLatLng]); _onPolylineCreated && _onPolylineCreated(ply); marker.__ply = ply; polylineList.push(ply); ply.addTo(map); })(marker, destLatLng), 0 ); } } } function setRandomPos() { for (var i = 0; i < markerList.length; i++) { var marker = markerList[i]; var label = marker.getTooltip(); var labelDom = label._container; var markerDom = marker._icon; var markerPosition = getPosition(markerDom); // var angle = Math.floor(Math.random() * 19 + 1) * 2 * Math.PI / 20; var angle = ((2 * Math.PI) / 6) * i; var x = markerPosition.x; var y = markerPosition.y; var dest = L.point( Math.ceil(x + 50 * Math.sin(angle)), Math.ceil(y + 50 * Math.cos(angle)) ); L.DomUtil.setPosition(labelDom, dest); } } function scaleTo(a, b) { return L.point(a.x * b.x, a.y * b.y); } function normalize(a) { var l = a.distanceTo(L.point(0, 0)); if (l === 0) { return a; } return L.point(a.x / l, a.y / l); } function fa(x, k) { return (x * x) / k; } function fr(x, k) { return (k * k) / x; } /** * get position form el.style.transform */ function getPosition(el) { var translateString = el.style.transform .split('(')[1] .split(')')[0] .split(','); return L.point(parseInt(translateString[0]), parseInt(translateString[1])); } /** * t is the temperature in the system */ function computePositionStep(t) { var area = (window.innerWidth * window.innerHeight) / 10; var k = Math.sqrt(area / markerList.length); var dpos = L.point(0, 0); var v_pos; var v; var i; for (i = 0; i < markerList.length; i++) { v = markerList[i]; // get position of label v v.disp = L.point(0, 0); v_pos = getPosition(v.getTooltip()._container); // compute gravitational force for (var j = 0; j < markerList.length; j++) { var u = markerList[j]; if (i !== j) { var u_pos = getPosition(u.getTooltip()._container); dpos = v_pos.subtract(u_pos); if (dpos !== 0) { v.disp = v.disp.add( normalize(dpos).multiplyBy(fr(dpos.distanceTo(L.point(0, 0)), k)) ); } } } } // compute force between marker and tooltip for (i = 0; i < markerList.length; i++) { v = markerList[i]; v_pos = getPosition(v.getTooltip()._container); dpos = v_pos.subtract(getPosition(v._icon)); v.disp = v.disp.subtract( normalize(dpos).multiplyBy(fa(dpos.distanceTo(L.point(0, 0)), k)) ); } // calculate layout for (i = 0; i < markerList.length; i++) { var disp = markerList[i].disp; var p = getPosition(markerList[i].getTooltip()._container); var d = scaleTo( normalize(disp), L.point(Math.min(Math.abs(disp.x), t), Math.min(Math.abs(disp.y), t)) ); p = p.add(d); p = L.point(Math.ceil(p.x), Math.ceil(p.y)); L.DomUtil.setTransform(markerList[i].getTooltip()._container, p); } } function layoutByForce() { var start = Math.ceil(window.innerWidth / 10); var times = 50; var t; for (var i = 0; i < times; i += 1) { t = start * (1 - i / (times - 1)); computePositionStep(t); } for (i = 0; i < markerList.length; i++) { var disp = markerList[i].disp; var p = getPosition(markerList[i].getTooltip()._container); var width = markerList[i].getTooltip()._container.offsetWidth; var height = markerList[i].getTooltip()._container.offsetHeight; p = L.point(Math.ceil(p.x - width / 2), Math.ceil(p.y - height / 2)); L.DomUtil.setTransform(markerList[i].getTooltip()._container, p); } } function setEdgePosition() { var bounds = map.getBounds(); var northWest = map.latLngToLayerPoint(bounds.getNorthWest()); var southEast = map.latLngToLayerPoint(bounds.getSouthEast()); for (let i = 0; i < markerList.length; i++) { var tooltip = getPosition(markerList[i].getTooltip()._container); var marker = getPosition(markerList[i]._icon); var width = markerList[i].getTooltip()._container.offsetWidth; var height = markerList[i].getTooltip()._container.offsetHeight; var isEdge = false; if (marker.x > northWest.x && tooltip.x < northWest.x) { tooltip.x = northWest.x; isEdge = true; } else if (marker.x < southEast.x && tooltip.x > southEast.x - width) { tooltip.x = southEast.x - width; isEdge = true; } if (marker.y > northWest.y && tooltip.y < northWest.y) { tooltip.y = northWest.y; isEdge = true; } else if (marker.y < southEast.y && tooltip.y > southEast.y - height) { tooltip.y = southEast.y - height; isEdge = true; } if (!isEdge) { if (marker.x < northWest.x && tooltip.x > northWest.x - width) { tooltip.x = northWest.x - width; } else if (marker.x > southEast.x && tooltip.x < southEast.x) { tooltip.x = southEast.x; } if (marker.y < northWest.y && tooltip.y > northWest.y - height) { tooltip.y = northWest.y - height; } else if (marker.y > southEast.y && tooltip.y < southEast.y) { tooltip.y = southEast.y; } } L.DomUtil.setTransform(markerList[i].getTooltip()._container, tooltip); } } TooltipLayout['initialize'] = initialize; TooltipLayout['resetMarker'] = resetMarker; TooltipLayout['getMarkers'] = getMarkers; TooltipLayout['getLine'] = getLine; TooltipLayout['removeAllPolyline'] = removeAllPolyline; return TooltipLayout; }, window);