You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AM Charts JavaScript中实现国家单选?修复选中状态异常

Fix: Hover Reverts Previously Deselected Country State

Hey, I get exactly what's going on here—when you click a new country, the old one deselects like it should, but hovering back over it brings that selected state right back. The core issue is that your current code only adjusts the fill property and calls setState("default"), but you're not accounting for the map component's built-in hover behavior overriding those changes. Here's how to fix it:

Why Your Current Code Fails

When you hover over a polygon, most map libraries (like AmCharts, which this code looks like it's using) automatically trigger a hover state that applies its own styling. Your code resets the old polygon to default state, but doesn't prevent the hover event from switching it back to a highlighted state when the mouse moves over it. Plus, directly modifying properties.fill can clash with the library's state-based styling system.

Solution: Control State and Hover Behavior Explicitly

We need to:

  1. Mark the currently active country so we can distinguish it from others
  2. Prevent hover styling from affecting the active country
  3. Properly reset the previous country's state and styling

Here's the revised code (adjust default/hover colors to match your setup):

// Define your default and hover colors first
const defaultFill = "#e0e0e0"; // Replace with your actual default color
const hoverFill = "#cccccc";   // Replace with your actual hover color
let currentActive = null;

// Clear existing event listeners to avoid duplicates
polygonTemplate.events.off("hit");
polygonTemplate.events.off("over");
polygonTemplate.events.off("out");

// Handle country click
polygonTemplate.events.on("hit", function (event) {
  // Reset previously active country
  if (currentActive) {
    currentActive.setState("default");
    currentActive.properties.fill = defaultFill;
    currentActive.removeClass("active-country");
  }

  // Set new active country
  chart.maxZoomLevel = 32;
  currentActive = event.target;
  currentActive.properties.fill = colorSet.getIndex(4);
  currentActive.addClass("active-country");
});

// Handle hover: only apply to non-active countries
polygonTemplate.events.on("over", function (event) {
  const target = event.target;
  if (!target.hasClass("active-country")) {
    target.setState("hover");
    target.properties.fill = hoverFill;
  }
});

// Handle mouse out: only reset non-active countries
polygonTemplate.events.on("out", function (event) {
  const target = event.target;
  if (!target.hasClass("active-country")) {
    target.setState("default");
    target.properties.fill = defaultFill;
  }
});

Even Better: Use Built-in State Management

If your map library supports state-based styling (like AmCharts does), use that instead of directly modifying fill properties—it's more reliable:

// Define state styles upfront when setting up the polygon template
polygonTemplate.states.create("active", {
  fill: colorSet.getIndex(4)
});
polygonTemplate.states.create("hover", {
  fill: "#cccccc" // Your hover color
});

let currentActive = null;

polygonTemplate.events.on("hit", function (event) {
  if (currentActive) {
    currentActive.setState("default");
  }
  currentActive = event.target;
  currentActive.setState("active");
  chart.maxZoomLevel = 32;
});

// Block hover state for active countries
polygonTemplate.events.on("over", function (event) {
  if (event.target.getState() !== "active") {
    event.target.setState("hover");
  }
});

polygonTemplate.events.on("out", function (event) {
  if (event.target.getState() !== "active") {
    event.target.setState("default");
  }
});

This way, the library handles all styling based on the element's state, so you don't have to manually sync fill properties and states.

内容的提问来源于stack exchange,提问作者Vijayant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:58:01