amChart 地图 |识别移动设备上的点击行为

amChart Maps | Recognize tap behavior on mobile

当您将鼠标悬停在下面地图上的普罗旺斯时,您会看到普罗旺斯的名称。如何在移动设备上使用 amCharts 模仿这种行为?如果标签在您点击一次时出现在移动设备上,那就太好了。同一时间只能看到一个标签。

我一直在无休止地寻找答案。我也无法在文档中找到答案,例如 https://www.amcharts.com/docs/v4/concepts/touch/

最终,当您再次点击同一个省份时,我希望能够 link 到另一个页面。因此,如果您选择普罗旺斯,并且在该普罗旺斯可以看到标签,那么您将转到另一个页面。左边最大的省份(新疆)已经 link 到 google.com。但是我什至不知道如何监听第一次点击事件。

有没有人,也许是有点 AmCharts 经验的人,知道如何解决这个问题?

var chart = am4core.create("mapchina", am4maps.MapChart);
chart.geodata = am4geodata_chinaHigh;
chart.seriesContainer.draggable = false;
chart.seriesContainer.resizable = false;
chart.maxZoomLevel = 1;
chart.chartContainer.wheelable = false;

var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
polygonSeries.useGeodata = true;
polygonSeries.calculateVisualCenter = true;
polygonSeries.tooltip.getFillFromObject = false;
polygonSeries.tooltip.background.fill = am4core.color("#30302F");
polygonSeries.tooltip.background.stroke = am4core.color("#30302F");
polygonSeries.tooltip.fontSize = 14;
polygonSeries.tooltip.fontFamily = "Open sans";
polygonSeries.data = [
    {
        id: "CN-XJ",
        name: "Xinjiang",
        url: "www.google.com",
        urlTarget: "_blank"
    },
    {
        id: "CN-NM",
        name: "Neimenggu"
    },
    {
        id: "CN-GX",
        name: "Guangxi"
    },
    {
        id: "CN-NX",
        name: "Ningxia"
    }
];

var polygonTemplate = polygonSeries.mapPolygons.template;
polygonTemplate.fill = am4core.color("#F26964");
polygonTemplate.stroke = am4core.color("#fff");
polygonTemplate.strokeWidth = 1;
polygonTemplate.hoverOnFocus = true;
polygonTemplate.nonScalingStroke = true;
polygonTemplate.tooltipText = "[text-transform: uppercase; font-weight: 600; font-size: 14px]{name}";
polygonTemplate.propertyFields.url = "url";
polygonTemplate.propertyFields.urlTarget = "urlTarget";

polygonTemplate.events.on("over", function(event) {
    event.target.zIndex = Number.MAX_VALUE;
    event.target.toFront();
});

var hoverState = polygonTemplate.states.create("hover");
hoverState.properties.fill = am4core.color("#FFD464");
hoverState.properties.stroke = am4core.color("#FFD464");
hoverState.properties.strokeWidth = 1;
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#mapchina {
  width: 100%;
  height: 350px;
}
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/maps.js"></script>
<script src="https://www.amcharts.com/lib/4/geodata/chinaHigh.js"></script>

<div id="mapchina"></div>

每个省份的悬停状态可以通过将event.target.isHover设置为true/false来切换(当polygonTemplate.hoverOnFocus设置为[=15=时效果最佳) ]).每次点击都会触发 over 事件,因此可以在那里启用悬停状态(保持这种状态直到用户再次交互)。选中 event.touch 允许鼠标事件在非触摸屏上的行为不受影响。

棘手的部分是相应的 out 事件似乎不会触发触摸事件。没有这个,就很难知道一个水龙头是给定省份的第一次还是第二次水龙头。要解决此问题,可以改用 document.ontouchend 事件。在此函数中,检查 target 是否是最后点击的省份,以便它可以作为 out 事件(这样更好,因为它甚至会触发图表外的点击) .

通过跟踪上次点击的省份 (tapProvince),可以在随后的 over 事件中进行比较,以检查初始或重复点击。最后,通过将 event.target.url 设置为空字符串或预期的 URL,可以控制导航。

var chart = am4core.create("mapchina", am4maps.MapChart);
chart.geodata = am4geodata_chinaHigh;
chart.seriesContainer.draggable = false;
chart.seriesContainer.resizable = false;
chart.maxZoomLevel = 1;
chart.chartContainer.wheelable = false;

var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
polygonSeries.useGeodata = true;
polygonSeries.calculateVisualCenter = true;
polygonSeries.tooltip.getFillFromObject = false;
polygonSeries.tooltip.background.fill = am4core.color("#30302F");
polygonSeries.tooltip.background.stroke = am4core.color("#30302F");
polygonSeries.tooltip.fontSize = 14;
polygonSeries.tooltip.fontFamily = "Open sans";
polygonSeries.data = [{
    id: "CN-XJ",
    name: "Xinjiang",
    url: "www.google.com",
    urlTarget: "_blank"
  },
  {
    id: "CN-NM",
    name: "Neimenggu"
  },
  {
    id: "CN-GX",
    name: "Guangxi"
  },
  {
    id: "CN-NX",
    name: "Ningxia"
  }
];

var tapProvince;
var tapURL;

var polygonTemplate = polygonSeries.mapPolygons.template;
polygonTemplate.fill = am4core.color("#F26964");
polygonTemplate.stroke = am4core.color("#fff");
polygonTemplate.strokeWidth = 1;
polygonTemplate.hoverOnFocus = false;
polygonTemplate.nonScalingStroke = true;
polygonTemplate.tooltipText = "[text-transform: uppercase; font-weight: 600; font-size: 14px]{name}";
polygonTemplate.propertyFields.url = "url";
polygonTemplate.propertyFields.urlTarget = "urlTarget";

polygonSeries.calculateVisualCenter = true;
polygonTemplate.tooltipPosition = "fixed";

document.ontouchend = function(event) {
  if (tapProvince && !tapProvince.dom.contains(event.target)) {
    tapProvince.isHover = false;
    tapProvince.url = tapURL;
    tapProvince = undefined;
  };
};

polygonTemplate.events.on("over", function(event) {
  event.target.zIndex = Number.MAX_VALUE;
  event.target.toFront();

  if (event.touch) {
    event.target.isHover = true;

    if (tapProvince && tapProvince.dom === event.target.dom) {
      //after first tap
      event.target.url = tapURL;
    } else {
      //first tap
      tapProvince = event.target;
      tapURL = event.target.url;
      event.target.url = "";
    };
  };
});

var hoverState = polygonTemplate.states.create("hover");
hoverState.properties.fill = am4core.color("#FFD464");
hoverState.properties.stroke = am4core.color("#FFD464");
hoverState.properties.strokeWidth = 1;
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#mapchina {
  width: 100%;
  height: 350px;
}
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/maps.js"></script>
<script src="https://www.amcharts.com/lib/4/geodata/chinaHigh.js"></script>

<div id="mapchina"></div>