简体   繁体   中英

amCharts cursor zoom not working in OpenLayers map overlay

I added amCharts chart to OpenLayers map overlay but chart cursor zoom not work like the image provided below:

在此输入图像描述

The example provided below:

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

As you can see, I created a dynamic overlay and add it to map and when user click on map then overlay popup will be shown to the user after that chart created and the chart cursor zoom not work but in the other place of my website it works perfectly.

This occurs due to OpenLayers Overlay entity stopping the event propagation (eg click & drag event on chart)

This can be disabled very easily via stopEvent: false ;

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

More on OpenLayers Overlay

The problem with this is that, the same click & drag event will be propagated to the map in the back, and the selection of the chart will be impossible to do. Example of this trouble can be seen on this fiddle . Also there is a ticket on Github regarding this exact issue.


To resolve this I've used a very simple idea, to track when the cursor is on the overlay, and disable map events during those times;

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
  };
  ...
}

Then using this boolean as following;

map.on("pointerdrag", function(e) {
  if (mouseOver) {
    e.stopPropagation();
    return;
  }
});

to disable dragging event, and;

map.on("click", function(e) {
  if (mouseOver) {
    return;
  }
  // rest of chart creation logic here
}

to disable a new overlay creation event.

Final perfectly working fiddle can be found here

Pirooz bashi buddy

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM