javascript - amCharts 光标缩放在 OpenLayers map 叠加层中不起作用

标签 javascript openlayers amcharts openlayers-5 amcharts4

我将 amCharts 图表添加到 OpenLayers map 叠加层,但图表光标缩放无法像下面提供的图像那样工作:

enter image description here

下面提供的示例:

// 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>

如您所见,我创建了一个动态叠加层并将其添加到 map ,当用户单击 map 时,叠加层弹出窗口将在该图表创建后向用户显示,并且图表光标缩放不起作用,但在其他地方我的网站运行完美。

最佳答案

这是由于 OpenLayers Overlay 实体停止了事件传播(例如图表上的点击和拖动事件)

这可以很容易地通过 stopEvent: false 禁用;

overlay = new ol.Overlay({
  element: container,
  stopEvent: false,
  autoPan: true,
  autoPanMargin: 20,
  autoPanAnimation: {
    duration: 50
  }
});

更多关于 OpenLayers Overlay

这样做的问题是,相同的点击和拖动事件将传播到后面的 map ,并且无法选择图表。这个问题的例子可以在这个 fiddle 上看到.还有a ticket关于这个确切问题的 Github。


为了解决这个问题,我使用了一个非常简单的想法,跟踪光标何时位于叠加层上,并在那些时间禁用 map 事件;

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
}

禁用新的覆盖创建事件。

Final perfectly working fiddle can be found here

Pirooz bashi 哥们

关于javascript - amCharts 光标缩放在 OpenLayers map 叠加层中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56984380/

相关文章:

javascript - OpenLayers.Popup closeBoxCallback 未触发

jquery - OpenLayers 4 - 适合所选要素的范围

javascript - Uncaught Error : unsupported number: 00940155. 184155.1840040

javascript - 如何在 AmCharts 的值轴中设置连续整数步长?

javascript - GetElementByID() 与 QuerySelector()

javascript - 在 AngularJS 应用程序中从服务器检索数据很慢

javascript - 将 Garmin GPS 坐标获取到 JavaScript 变量中

javascript - 将总和文本移动到 amcharts 序列图中的最右侧

javascript - 将对象数组中两个属性的唯一值存储到单个数组中

javascript - 如何配置 Bootstrap 输入微调器以仅在按下 + 或 - 按钮时更改输入值?