amCharts 地图在纬度对数坐标上带有气泡

amCharts Map with Bubbles on lat log coordinates

完全可以创建这种地图:

https://www.amcharts.com/demos/map-bubbles/

但不是使用国家/地区 ID 通过纬度和经度坐标来定位气泡?我需要为我有数据的每个城市放置一个气泡,因此每个国家/地区可能不止一个气泡。

我有这样的数据结构:

Array (
        "name" => $row["city"],
        "latitude" => $row["latitude"],
        "longitude" => $row["longitude"],
        "value" => $row["count"],
    );

我遇到了同样的问题,设法解决了。

所以你分配给图像系列的数据需要属性latitudelongitudevalue,这样才能放置气泡并确定大小。

imageSeries.dataFields.value 将从您的数据中分配 value 属性,而 imageTemplate.propertyFields.latitudeimageTemplate.propertyFields.longitude 将从 longitudelatitude 来自您的数据。

函数写在JavaScript中,看起来有点像下面:

import * as am4core from "@amcharts/amcharts4/core";
import * as am4maps from "@amcharts/amcharts4/maps";
import am4geodata_worldLow from "@amcharts/amcharts4-geodata/worldLow";

/* This is what the data looks like  
[
  {
    latitude: 48.856614,
    longitude: 2.352222,
    value: 100,
    title: "Paris",
  },
  {
    latitude: 40.712775,
    longitude: -74.005973,
    value: 200,
    title: "New York",
  },
  {
    latitude: 49.282729,
    longitude: -123.120738,
    value: 1000,
    title: "Vancouver",
  },
];
*/

const setupBubbleMap = ({ elementId }) => {
  let amChart = am4core.create(elementId, am4maps.MapChart);

  let title = amChart.titles.create();
  title.text = "[bold font-size: 20]Hotspots[/]";
  title.textAlign = "middle";

  amChart.geodata = am4geodata_worldLow;
  amChart.projection = new am4maps.projections.Miller();

  let polygonSeries = amChart.series.push(new am4maps.MapPolygonSeries());
  polygonSeries.exclude = ["AQ"];
  polygonSeries.useGeodata = true;
  polygonSeries.nonScalingStroke = true;
  polygonSeries.strokeWidth = 0.5;

  const polygonTemplate = polygonSeries.mapPolygons.template;
  polygonTemplate.tooltipText = "{title}";
  polygonSeries.calculateVisualCenter = true;

  let imageSeries = amChart.series.push(new am4maps.MapImageSeries());
  imageSeries.dataFields.value = "value";

  let imageTemplate = imageSeries.mapImages.template;
  imageTemplate.nonScaling = true;
  imageTemplate.propertyFields.latitude = "latitude";
  imageTemplate.propertyFields.longitude = "longitude";

  imageSeries.data = data;

  let circle = imageTemplate.createChild(am4core.Circle);
  circle.fillOpacity = 0.7;
  circle.fill = am4core.color("#B27799");
  circle.tooltipText = "{title}: [bold]{value}[/]";

  imageSeries.heatRules.push({
    target: circle,
    property: "radius",
    min: 4,
    max: 30,
    dataField: "value",
  });

  imageTemplate.adapter.add("latitude", function (latitude, target) {
    let polygon = polygonSeries.getPolygonById(target.dataItem.dataContext.id);
    if (polygon) {
      return polygon.visualLatitude;
    }
    return latitude;
  });

  imageTemplate.adapter.add("longitude", function (longitude, target) {
    let polygon = polygonSeries.getPolygonById(target.dataItem.dataContext.id);
    if (polygon) {
      return polygon.visualLongitude;
    }
    return longitude;
  });

  return amChart;
};

export default setupBubbleMap;