javascript - amCharts 光标缩放在 OpenLayers 地图叠加层中不起作用
问题描述
我将amCharts
图表添加到OpenLayers
地图叠加层,但图表光标缩放不像下面提供的图像那样工作:
下面提供的示例:
// Overlays init variables and function
var container;
var content;
var closer = document.getElementById('popup-closer');
var overlay;
function createOverlay(width) {
container = document.getElementById('popup');
container.style.width = width;
content = document.getElementById('popup-content');
closer = document.getElementById('popup-closer');
return container;
}
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([51.338076, 35.699756]),
zoom: 12
})
});
map.on("click", function(e) {
let coordinates = e.coordinate;
createOverlay("500px");
content.innerHTML = '<div id="chartdiv" class="ltr"></div>';
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var chart = am4core.create("chartdiv", am4charts.XYChart);
var data = [];
var value = 50;
for(let i = 0; i < 300; i++){
let date = new Date();
date.setHours(0,0,0,0);
date.setDate(i);
value -= Math.round((Math.random() < 0.5 ? 1 : -1) * Math.random() * 10);
data.push({date:date, value: value});
}
chart.data = data;
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.minGridDistance = 60;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = "value";
series.dataFields.dateX = "date";
series.tooltipText = "{value}"
series.tooltip.pointerOrientation = "vertical";
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series;
chart.cursor.xAxis = dateAxis;
//chart.scrollbarY = new am4core.Scrollbar();
chart.scrollbarX = new am4core.Scrollbar();
}); // end am4core.ready()
$(".ol-popup").show();
overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanMargin: 20,
autoPanAnimation: {
duration: 50
}
});
map.addOverlay(overlay);
overlay.setPosition(coordinates);
});
/* ol PopUp */
.ol-popup {
text-align: right;
position: absolute;
background-color: white;
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
border-radius: 10px;
bottom: 12px;
transform: translateX(50%);
display: none;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 50%;
transform: translateX(-50%);
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 50%;
transform: translateX(-50%);
}
.ol-popup-closer {
text-decoration: none !important;
font-size: 16px;
position: absolute;
top: 5px;
right: 8px;
cursor: pointer;
}
.map {
height: 400px;
width: 100%;
}
#chartdiv {
width: 100%;
height: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet"/>
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="map" class="map"></div>
<div id="popup" class="ol-popup">
<i class="fas fa-times ol-popup-closer" id="popup-closer"></i>
<div id="popup-content" class="p-4"></div>
</div>
如您所见,我创建了一个动态叠加层并将其添加到地图中,当用户单击地图时,将在创建该图表后向用户显示叠加层弹出窗口,并且图表光标缩放不起作用,但在我网站的其他地方它完美运行。
解决方案
这是由于OpenLayers Overlay
实体停止了事件传播(例如图表上的单击和拖动事件)
这可以通过stopEvent: false
;很容易地禁用。
overlay = new ol.Overlay({
element: container,
stopEvent: false,
autoPan: true,
autoPanMargin: 20,
autoPanAnimation: {
duration: 50
}
});
这样做的问题是,同样的点击拖拽事件会传播到后面的地图,无法选择图表。这个麻烦的例子可以在这个小提琴上看到。Github 上也有一张关于这个确切问题的票。
为了解决这个问题,我使用了一个非常简单的想法,即跟踪光标何时位于叠加层上,并在这些时间禁用地图事件;
var mouseOver = false;
function createOverlay(width) {
container = document.getElementById('popup');
container.style.width = width;
container.onmouseover = function() {
mouseOver = true; // when cursor is targeting overlay we enable this boolean
};
container.onmouseout = function() {
mouseOver = false; // and disable when out
};
...
}
然后使用它boolean
如下;
map.on("pointerdrag", function(e) {
if (mouseOver) {
e.stopPropagation();
return;
}
});
禁用拖动事件,以及;
map.on("click", function(e) {
if (mouseOver) {
return;
}
// rest of chart creation logic here
}
禁用新的叠加创建事件。
最终完美工作的小提琴可以在 这里找到
皮鲁兹巴什哥们
推荐阅读
- c - 是否可以使用动态内存创建任意大小的整数?
- javascript - 如何打印过滤后的元素?
- c++ - 如何加载 C++ 模块并将编译标志作为 Rcpp 包编译的一部分?
- jupyter-notebook - 在 Pycharm 将环境设为解释器后,jupyter notebook 无法访问 anaconda 虚拟环境
- scala - 我是斯卡拉的新手。有人可以告诉我为什么在编写 def recur 函数时我得到一个错误非法启动简单函数
- qt - 无法在我的 QML 视图中使用 QTLocation 和 QTPositioning
- python - 按钮存在并显示单击了 Selenium python
- visual-studio-code - subprocess.Popen 将打开记事本然后立即关闭它与代码
- python - 是否有根据上面行中的日期在熊猫中估算日期的功能?
- c# - Acumatica - 将合并报告添加到电子邮件附件