当前位置: 首页 > article >正文

vue3+ts 使用amCharts展示地图,1.点击左侧国家,可以高亮并放大右侧地图对应的国家。 2.展示数据球。

效果图展示:
1.点击左侧国家,可以高亮并放大右侧地图对应的国家。
2.展示数据球。
在这里插入图片描述
在这里插入图片描述
下载依赖

yarn add @amcharts/amcharts5

其中,props.countryData的数据格式为
[{
“country”: “加拿大”,
“code”: “CA”,
“deviceCount”: 1
},{
“country”: “瑞士”,
“code”: “CH”,
“deviceCount”: 29
},{
“country”: “中国”,
“code”: “CN”,
“deviceCount”: 10774
},{
“country”: “德国”,
“code”: “DE”,
“deviceCount”: 42
}]

<template>
  <div class="device-distribution-box">
    <div class="header-title">{{ $t('countryDistributionDevice') }}</div>
    <section class="flex-box">
      <div class="country-box">
        <div class="country-list" v-for="country in mapData">
          <div
            :class="activeCountry == country.code ? 'active-country' : ''"
            @click="clickCountry(country.code)"
            class="sf-ellipsis"
            :title="country.country + '(' + country.deviceCount + ')'"
          >
            {{ country.country }}({{ country.deviceCount }})
          </div>
        </div>
      </div>
      <div id="chartdiv"></div> // 地图展示容器
    </section>
  </div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, watch } from 'vue';
import useLocale from '@/utils/i18n/store';
import { storeToRefs } from 'pinia';
import am5geodata_lang_EN from '@amcharts/amcharts5-geodata/lang/EN';// 地图语言包
import am5geodata_lang_cn_ZH from '@amcharts/amcharts5-geodata/lang/cn_ZH';//地图语言包
import am5geodata_lang_PT from '@amcharts/amcharts5-geodata/lang/PT'; // 地图语言包
import * as am5map from '@amcharts/amcharts5/map'; 
import am5geodata_worldLow from '@amcharts/amcharts5-geodata/worldLow';
import * as am5 from '@amcharts/amcharts5';
import am5themes_Animated from '@amcharts/amcharts5/themes/Animated';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const localeStore = useLocale(); //获取本地语言
const { locale } = storeToRefs(localeStore); //获取本地语言

interface Props {
  countryData: Array<any>;
}
const props = withDefaults(defineProps<Props>(), {
  countryData: () => {
    return [];
  },
});

// 数据接口
interface MapData {
  code: string;
  deviceCount: number;
  name: string;
  country: string;
  id?: string;
}
const mapData = ref<Array<MapData>>([]);
const activeCountry = ref<string>('');
let polygonSeries = reactive({}); // 地图数据
let root = reactive({}); // 地图根

// 数据更新,更新地图
watch(
  () => props.countryData,
  (newValue, oldValue) => {
    mapData.value = props.countryData.map((item) => {
      item.id = item.code;
      return item;
    });
    refreshAmchartsMap();
  },
);

// 左侧国家点击事件-点击高亮国家
const clickCountry = (countryCode: string) => {
  activeCountry.value = countryCode;
  // 根据点击的国家,添加该国家的颜色数据,去除无关国家的颜色数据
  let tempData = mapData.value.map((item) => {
    if (item.id == countryCode) item.polygonSettings = { fill: am5.color(0x3a70d3) };
    else item.polygonSettings = {};
    return item;
  });
  // 绑定数据 高亮该国家颜色
  polygonSeries.data.setAll(tempData);
  // 地图放大到该国家
  polygonSeries.events.on('datavalidated', function () {
    const zoomTargets = [countryCode];
    const zoomDataItems = [];
    zoomTargets.forEach(function (id) {
      zoomDataItems.push(polygonSeries.getDataItemById(id));
    });
    polygonSeries.zoomToDataItems(zoomDataItems);
  });
};
// 更新相关数据
const refreshAmchartsMap = () => {
  root.setThemes([am5themes_Animated.new(root)]);
  // Create the map chart 地图的样式不一样
  let chart = root.container.children.push(
    am5map.MapChart.new(root, {
      projection: am5map.geoNaturalEarth1(),
    }),
  );
  polygonSeries = chart.series.push(
    am5map.MapPolygonSeries.new(root, {
      geoJSON: am5geodata_worldLow, // 地图展示的国家区域
      exclude: ['AQ'], //该操作将会从地图上删除南极洲。
      fill: am5.color(0xbbbbbb),
      geodataNames: // 根据本地语言配置地图语言
        locale.value == 'zh'
          ? am5geodata_lang_cn_ZH
          : locale.value == 'en'
            ? am5geodata_lang_EN
            : locale.value == 'pt'
              ? am5geodata_lang_PT
              : '',
    }),
  );
  // ====================================
  // Create pins
  // ====================================
  // 点符号
  let pointSeries = chart.series.push(
    am5map.MapPointSeries.new(root, {
      // ...
      // autoScale: true,
      polygonIdField: 'code', // 根据code值来映射点的位置,code的值就是地图中类似“CN“的国家代码
    }),
  );
  let colorSet = am5.ColorSet.new(root, { step: 2 });
  // 点符号样式设置
  pointSeries.bullets.push(function (root, series, dataItem) {
    let value = dataItem.dataContext.value;
    let container = am5.Container.new(root, {});
    let color = colorSet.next();
    let radius = value / 5 < 15 ? 15 : value / 5 > 50 ? 50 : value / 5; //球的大小!!!!!!!!!!!!需求动态修改
    let circle = container.children.push(
      am5.Circle.new(root, {
        radius: radius,
        fill: color,
        dy: -radius * 2,
      }),
    );
    let pole = container.children.push(
      am5.Line.new(root, {
        stroke: color,
        height: -radius * 2,
        strokeGradient: am5.LinearGradient.new(root, {
          stops: [{ opacity: 1 }, { opacity: 1 }, { opacity: 0 }],
        }),
      }),
    );
    let label = container.children.push(
      am5.Label.new(root, {
        text: value,
        fill: am5.color(0xffffff),
        fontWeight: '400',
        centerX: am5.p50,
        centerY: am5.p50,
        dy: -radius * 2,
      }),
    );
    let titleLabel = container.children.push(
      am5.Label.new(root, {
        text: dataItem.dataContext.title,
        fill: color,
        fontWeight: '500',
        fontSize: '1em',
        centerY: am5.p50,
        dy: -radius * 2,
        dx: radius,
      }),
    );

    return am5.Bullet.new(root, {
      sprite: container,
    });
  });
  // 映射点数据
  for (var i = 0; i < mapData.value.length; i++) {
    let d = mapData.value[i];
    pointSeries.data.push({
      code: d.code,
      value: d.deviceCount,
    });
  }
  // 鼠标移入和点击的效果
  polygonSeries.mapPolygons.template.setAll({
    tooltipText: '{name}',
    toggleKey: 'active',
    interactive: true,
    templateField: 'polygonSettings', //多边形也可以使用模板字段从数据中获取其设置的值。模板字段允许将系列数据中的对象属性绑定到多边形模板的设置。
  });
  // 绑定数据
  polygonSeries.data.setAll(mapData.value);

  // hover及active高亮颜色
  polygonSeries.mapPolygons.template.states.create('hover', {
    fill: root.interfaceColors.get('primaryButtonHover'),
  });
  polygonSeries.mapPolygons.template.states.create('active', {
    fill: root.interfaceColors.get('primaryButtonHover'),
  });
  // Set clicking on "water" to zoom out
  // 点击背景空白处,恢复到初始大小
  chart.chartContainer.get('background').events.on('click', function () {
    chart.goHome();
  });

  // Make stuff animate on load
  chart.appear(1000, 100);
};

//新建国家地图  Create root element
const newAmchartsMap = () => {
  root = am5.Root.new('chartdiv');
};
onMounted(() => {
  newAmchartsMap();
});
</script>
<style lang="scss" scoped>
.device-distribution-box {
  .header-title {
    font-family:
      PingFang SC,
      PingFang SC;
    font-weight: 500;
    font-size: 16px;
    color: #191919;
    line-height: 24px;
    margin-bottom: 16px;
  }
  .flex-box {
    display: flex;
    height: calc(100% - 40px);

    .country-box {
      // height: 328px;
      overflow-y: auto;
      overflow-x: hidden;
      .country-list {
        min-width: 160px;
        max-width: 200px;
        div {
          cursor: pointer;
          margin-bottom: 16px;
          font-family:
            PingFang SC,
            PingFang SC;
          font-weight: 500;
          font-size: 14px;
          color: #7f7f7f;
          line-height: 22px;
        }
        .active-country {
          font-weight: bold;
          font-size: 14px;
          color: #3a70d3 !important;
          line-height: 22px;
        }
      }
    }
  }
  #chartdiv {
    width: 100%;
    // height: 328px;
    background-color: #fbfbfb;
  }
}
</style>


http://www.kler.cn/a/307246.html

相关文章:

  • Chrome使用IE内核
  • 编译ffmpeg动态库时设置RPATH为$ORIGIN
  • react的创建与书写
  • 网页web无插件播放器EasyPlayer.js点播播放器遇到视频地址播放不了的现象及措施
  • 使用HTML、CSS和JavaScript创建动态圣诞树
  • 基于BILSTM及其他RNN序列模型的人名分类器
  • python tkinter
  • 物联网智能项目
  • Android Tools | 如何使用Draw.io助力Android开发:从UI设计到流程优化
  • 腾讯云使用
  • 将jar包作为lib导入和maven依赖导入有什么区别?
  • seafaring靶场渗透测试
  • 【C语言】(指针系列2)指针运算+指针与数组的关系+二级指针+指针数组+《剑指offer面试题》
  • 重塑科普展厅魅力,以用户体验为核心的策略性规划新探索!
  • 『功能项目』切换职业面板【48】
  • php部署到apach服务器上遇到的问题
  • 萤石举办2024清洁机器人新品发布会 多维智能再造行业标杆
  • 2024.9.15周报
  • Kubernetes标签与标签选择器
  • 容器技术--Docker应用部署
  • Redis——常用数据类型List
  • C# 入坑JAVA 潜规则 大小写敏感文件名和类名 枚举等 入门系列2
  • 机器学习--神经网络
  • 【裸机装机系列】4.kali(ubuntu)-配置个人用户的sudo权限并进行bashrc的其他配置
  • Qt常用控件——QComboBox
  • Redisson分布式锁实现及原理详解