Динамически обновлять карту мира amCharts 4 с анимацией (Javascript)? - PullRequest
2 голосов
/ 21 марта 2020

Я пытаюсь создать карту с amCharts, в которой есть анимированные круги, как в примере, представленном на странице ниже. Если я добавляю данные в основную функцию (код ниже - на am4core.ready (..)), она работает нормально, но я хочу динамически добавлять данные на карту и сохранять анимацию.

У меня есть отдельная функция, которая опрашивает данные каждую секунду или около того (второй код приведен ниже) и обновляет imageSeries новыми данными. Это прекрасно работает и добавляет круг к моей карте, но не оживляет его.

Пример исходного кода: https://www.amcharts.com/demos/map-with-pulsating-bullets/

Мой код:

<script>
  var colorSet = new am4core.ColorSet();
  var imageSeriesData = [];
  var chart;
  var imageSeries;

  am4core.ready(function() {
    am4core.useTheme(am4themes_animated);
    chart = am4core.create("mapcontainer", am4maps.MapChart);
    chart.geodata = am4geodata_worldLow;
    chart.projection = new am4maps.projections.Miller();
    var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
    polygonSeries.exclude = ["AQ"];
    polygonSeries.useGeodata = true;
    var polygonTemplate = polygonSeries.mapPolygons.template;
    polygonTemplate.tooltipText = "{name}";
    polygonTemplate.polygon.fillOpacity = 0.6;
    var hs = polygonTemplate.states.create("hover");
    hs.properties.fill = chart.colors.getIndex(0);
    imageSeries = chart.series.push(new am4maps.MapImageSeries());
    imageSeries.mapImages.template.propertyFields.longitude = "longitude";
    imageSeries.mapImages.template.propertyFields.latitude = "latitude";
    imageSeries.mapImages.template.tooltipText = "{title}";
    imageSeries.mapImages.template.propertyFields.url = "url";
    var circle = imageSeries.mapImages.template.createChild(am4core.Circle);
    circle.radius = 5;
    circle.propertyFields.fill = "color";
    var circle2 = imageSeries.mapImages.template.createChild(am4core.Circle);
    circle2.radius = 5;
    circle2.propertyFields.fill = "color";
    circle2.propertyFields.scale = "scale";
    circle2.events.on("inited", function(event) {
      animateBullet(event.target);
    });

    function animateBullet(circle) {
      var animation = circle.animate([{
        property: "scale",
        from: 1,
        to: circle.scale
      }, {
        property: "opacity",
        from: 1,
        to: 0
      }], 1000, am4core.ease.circleOut);
      animation.events.on("animationended", function(event) {
        animateBullet(event.target.object);
      })
    }

    imageSeries.data = imageSeriesData;

  });
</script>

Функция, которая отправляет данные в файл imageSeries.data и на карту:

imageSeriesData.push({
  "title": data.country,
  "latitude": latlong[data.country].latitude,
  "longitude": latlong[data.country].longitude,
  "color":colorSet.next()
});

imageSeries.data = imageSeriesData;

Этот код, приведенный выше, работает и обновляет карту. Но она не оживляет точку, как в приведенном ими примере.

Что мне здесь не хватает? Как я могу поместить данные sh на карту динамически, а также анимировать маленькие точки, как в приведенном ими примере? Я также попытался переместить функцию animateBullet (..) в глобальное местоположение, но ничего не вышло.

Есть идеи?

Понятия данных: https://www.amcharts.com/docs/v4/concepts/data/

К сожалению, прочитайте этот документ выше, и он не предоставляет ничего о картах мира.

1 Ответ

0 голосов
/ 21 марта 2020

Я понял это ... Я показал несколько глобальных переменных в верхней части моего скрипта, чтобы они были доступны для моей функции обновления. Но я не понял, что это:

  1. Я неправильно объявлял colorSet до инициализации am4core внутри функции am4core.ready (..).
  2. Исходный пример кода с их сайта объявляет colorSet после кружков. Я по ошибке полностью удалил это объявление.

Плохой код:

<script>
  var colorSet = new am4core.ColorSet();
  var imageSeriesData = [];
  var chart;
  var imageSeries;
...

Теперь новый код и работает, все еще выставляя imageSeries (для обновлений данных) и colorSet (для записи, которая включает в себя переменная цвета):

<script>
  var imageSeries;
  var colorSet;
  am4core.ready(function() {
    am4core.useTheme(am4themes_animated);
    var chart = am4core.create("mapcontainer", am4maps.MapChart);
    chart.geodata = am4geodata_worldLow;
    chart.projection = new am4maps.projections.Miller();
    var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
    polygonSeries.exclude = ["AQ"];
    polygonSeries.useGeodata = true;
    var polygonTemplate = polygonSeries.mapPolygons.template;
    polygonTemplate.tooltipText = "{name}";
    polygonTemplate.polygon.fillOpacity = 0.6;
    var hs = polygonTemplate.states.create("hover");
    hs.properties.fill = chart.colors.getIndex(0);
    imageSeries = chart.series.push(new am4maps.MapImageSeries());
    imageSeries.mapImages.template.propertyFields.longitude = "longitude";
    imageSeries.mapImages.template.propertyFields.latitude = "latitude";
    imageSeries.mapImages.template.tooltipText = "{title}";
    imageSeries.mapImages.template.propertyFields.url = "url";
    var circle = imageSeries.mapImages.template.createChild(am4core.Circle);
    circle.radius = 4;
    circle.propertyFields.fill = "color";
    var circle2 = imageSeries.mapImages.template.createChild(am4core.Circle);
    circle2.radius = 4;
    circle2.propertyFields.fill = "color";
    circle2.events.on("inited", function(event) {
      animateBullet(event.target);
    })
    function animateBullet(circle) {
      var animation = circle.animate([{
        property: "scale",
        from: 1,
        to: 10
      }, {
        property: "opacity",
        from: 1,
        to: 0
      }], 1000, am4core.ease.circleOut);
      animation.events.on("animationended", function(event) {
        animateBullet(event.target.object);
      })
    }

    colorSet = new am4core.ColorSet();

    imageSeries.data = [];

  });
</script>

Надеюсь, это поможет всем, кто испытывает ту же проблему!

...