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

React Next项目中导入Echart世界航线图 并配置中文

公司业务要求做世界航线图,跑了三个ai未果,主要是引入world.json失败,echart包中并不携带该文件,源码的world.json文件页面404找不到。需要自己寻找。这是整个问题卡壳的关键点,特此贴出资源网址。

目录

一、安装

二、下载world.json

三、创建地图组件WorldMap.js

四、引入地图组件到页面上

五、配置中文 

六、中文转换函数


一、安装

npm install echarts

二、下载world.json

world.json在最下面,点开直接粘贴到自己项目中引入

Index of /examples/data/asset/geo

三、创建地图组件WorldMap.js

import React, { useRef, useEffect } from "react";
import * as echarts from "echarts";

const geoCoordMap = {
    "New York": [-74.0060, 40.7128],
    "London": [-0.1278, 51.5074],
    "Tokyo": [139.6917, 35.6895],
    "Beijing": [116.4074, 39.9092],
};

const SHData = [
    [{ name: "Beijing", value: 105 }, { name: "New York", value: 105 }],
    [{ name: "Beijing", value: 105 }, { name: "London", value: 105 }],
    [{ name: "Beijing", value: 105 }, { name: "Tokyo", value: 105 }],
];

const convertData = (data) => {
    const res = [];
    for (let i = 0; i < data.length; i++) {
        const dataItem = data[i];
        const fromCoord = geoCoordMap[dataItem[0].name];
        const toCoord = geoCoordMap[dataItem[1].name];
        if (fromCoord && toCoord) {
            res.push({
                fromName: dataItem[0].name,
                toName: dataItem[1].name,
                coords: [fromCoord, toCoord],
            });
        }
    }
    return res;
};

const WorldMap = () => {
    const chartRef = useRef(null);

    useEffect(() => {
        // 动态加载世界地图数据
        fetch("/world.json") // 确保文件路径正确,这里假设 world.json 放在 public 文件夹下
            .then((res) => res.json())
            .then((mapData) => {
                echarts.registerMap("world", mapData); // 注册地图数据

                const myChart = echarts.init(chartRef.current);

                const seriesData = [
                    {
                        type: "lines",
                        zlevel: 1,
                        effect: {
                            show: true,
                            period: 6,
                            trailLength: 0.7,
                            color: "#fff",
                            symbolSize: 3,
                        },
                        lineStyle: {
                            color: "#46bee9",
                            width: 0,
                            curveness: 0.2,
                        },
                        data: convertData(SHData),
                    },
                    {
                        type: "lines",
                        zlevel: 2,
                        symbol: ["none", "arrow"],
                        symbolSize: 10,
                        effect: {
                            show: true,
                            period: 6,
                            trailLength: 0,
                            symbol: "path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z",
                            symbolSize: 15,
                        },
                        lineStyle: {
                            color: "#46bee9",
                            width: 1,
                            opacity: 0.6,
                            curveness: 0.2,
                        },
                        data: convertData(SHData),
                    },
                    {
                        type: "effectScatter",
                        coordinateSystem: "geo",
                        zlevel: 2,
                        rippleEffect: {
                            brushType: "stroke",
                        },
                        label: {
                            show: true,
                            position: "right",
                            formatter: "{b}",
                        },
                        symbolSize: (val) => val[2] / 8,
                        itemStyle: {
                            color: "#46bee9",
                        },
                        data: SHData.map((dataItem) => ({
                            name: dataItem[1].name,
                            value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value]),
                        })),
                    },
                ];

                myChart.setOption({
                    geo: {
                        map: "world",
                        roam: true,
                        itemStyle: {
                            areaColor: "#404a59",
                            borderColor: "#61727a",
                        },
                        emphasis: {
                            itemStyle: {
                                areaColor: "#7acfd6",
                            },
                        },
                    },
                    series: seriesData,
                });
            })
            .catch((error) => {
                console.error("Failed to load world map data:", error);
            });
    }, []);

    return <div ref={chartRef} style={{ width: "100%", height: "600px" }} />;
};

export default WorldMap;

四、引入地图组件到页面上

import React from "react";
import styles from "../styles/AfterSalesPage.module.css";
import WorldMap from "../components/WorldMap"; // 确保使用默认导入

const AfterSales = () => {
	return (
		<div className={styles.newsContainer}>
			<WorldMap />
		</div>
	);
};

export default AfterSales;

成果展示:

五、配置中文 

中文映射文件mapZHName.js

export let mapZHName = {
    'Afghanistan': '阿富汗',
    'Angola': '安哥拉',
    'Albania': '阿尔巴尼亚',
    'United Arab Emirates': '阿联酋',
    'Argentina': '阿根廷',
    'Armenia': '亚美尼亚',
    'Australia': '澳大利亚',
    'Austria': '奥地利',
    'Azerbaijan': '阿塞拜疆',
    'Burundi': '布隆迪',
    'Belgium': '比利时',
    'Benin': '贝宁',
    'Burkina Faso': '布基纳法索',
    'Bangladesh': '孟加拉',
    'Bulgaria': '保加利亚',
    'Belarus': '白俄罗斯',
    'Belize': '伯利兹',
    'Bermuda': '百慕大',
    'Bolivia': '玻利维亚',
    'Brazil': '巴西',
    'Brunei': '文莱',
    'Bhutan': '不丹',
    'Botswana': '博茨瓦纳',
    'Canada': '加拿大',
    'Switzerland': '瑞士',
    'Chile': '智利',
    'China': '中国',
    'Cameroon': '喀麦隆',
    'Colombia': '哥伦比亚',
    'Costa Rica': '哥斯达黎加',
    'Cuba': '古巴',
    'Cyprus': '塞浦路斯',
    'Germany': '德国',
    'Djibouti': '吉布提',
    'Denmark': '丹麦',
    'Algeria': '阿尔及利亚',
    'Ecuador': '厄瓜多尔',
    'Egypt': '埃及',
    'Eritrea': '厄立特里亚',
    'Spain': '西班牙',
    'Estonia': '爱沙尼亚',
    'Ethiopia': '埃塞俄比亚',
    'Finland': '芬兰',
    'Fiji': '斐济',
    'France': '法国',
    'Gabon': '加蓬',
    'United Kingdom': '英国',
    'Georgia': '格鲁吉亚',
    'Ghana': '加纳',
    'Guinea': '几内亚',
    'Gambia': '冈比亚',
    'Greece': '希腊',
    'Greenland': '格陵兰',
    'Guatemala': '危地马拉',
    'Guyana': '圭亚那',
    'Honduras': '洪都拉斯',
    'Croatia': '克罗地亚',
    'Haiti': '海地',
    'Hungary': '匈牙利',
    'Indonesia': '印度尼西亚',
    'India': '印度',
    'Ireland': '爱尔兰',
    'Iran': '伊朗',
    'Iraq': '伊拉克',
    'Iceland': '冰岛',
    'Israel': '以色列',
    'Italy': '意大利',
    'Jamaica': '牙买加',
    'Jordan': '约旦',
    'Japan': '日本',
    'Kazakhstan': '哈萨克斯坦',
    'Kenya': '肯尼亚',
    'Kyrgyzstan': '吉尔吉斯斯坦',
    'Cambodia': '柬埔寨',
    'Korea': '韩国',
    'Kuwait': '科威特',
    'Lebanon': '黎巴嫩',
    'Liberia': '利比里亚',
    'Libya': '利比亚',
    'Sri Lanka': '斯里兰卡',
    'Lesotho': '莱索托',
    'Lithuania': '立陶宛',
    'Luxembourg': '卢森堡',
    'Latvia': '拉脱维亚',
    'Morocco': '摩洛哥',
    'Moldova': '摩尔多瓦',
    'Madagascar': '马达加斯加',
    'Mexico': '墨西哥',
    'Macedonia': '马其顿',
    'Mali': '马里',
    'Myanmar': '缅甸',
    'Montenegro': '黑山',
    'Mongolia': '蒙古',
    'Mozambique': '莫桑比克',
    'Mauritania': '毛里塔尼亚',
    'Malawi': '马拉维',
    'Malaysia': '马来西亚',
    'Namibia': '纳米比亚',
    'New Caledonia': '新喀里多尼亚',
    'Niger': '尼日尔',
    'Nigeria': '尼日利亚',
    'Nicaragua': '尼加拉瓜',
    'Netherlands': '荷兰',
    'Norway': '挪威',
    'Nepal': '尼泊尔',
    'New Zealand': '新西兰',
    'Oman': '阿曼',
    'Pakistan': '巴基斯坦',
    'Panama': '巴拿马',
    'Peru': '秘鲁',
    'Philippines': '菲律宾',
    'Papua New Guinea': '巴布亚新几内亚',
    'Poland': '波兰',
    'Puerto Rico': '波多黎各',
    'Portugal': '葡萄牙',
    'Paraguay': '巴拉圭',
    'Qatar': '卡塔尔',
    'Romania': '罗马尼亚',
    'Russia': '俄罗斯',
    'Rwanda': '卢旺达',
    'Saudi Arabia': '沙特阿拉伯',
    'Sudan': '苏丹',
    'Senegal': '塞内加尔',
    'Sierra Leone': '塞拉利昂',
    'El Salvador': '萨尔瓦多',
    'Somalia': '索马里',
    'Suriname': '苏里南',
    'Slovakia': '斯洛伐克',
    'Slovenia': '斯洛文尼亚',
    'Sweden': '瑞典',
    'Swaziland': '斯威士兰',
    'Syria': '叙利亚',
    'Chad': '乍得',
    'Togo': '多哥',
    'Thailand': '泰国',
    'Tajikistan': '塔吉克斯坦',
    'Turkmenistan': '土库曼斯坦',
    'Trinidad and Tobago': '特立尼达和多巴哥',
    'Tunisia': '突尼斯',
    'Turkey': '土耳其',
    'Uganda': '乌干达',
    'Ukraine': '乌克兰',
    'Uruguay': '乌拉圭',
    'United States': '美国',
    'Uzbekistan': '乌兹别克斯坦',
    'Venezuela': '委内瑞拉',
    'Vietnam': '越南',
    'Vanuatu': '瓦努阿图',
    'Yemen': '也门',
    'South Africa': '南非',
    'Zambia': '赞比亚',
    'Zimbabwe': '津巴布韦',
    'Liechtenstein':'列支敦士登',
    'Serbia':'塞尔维亚',
    "Aland": "奥兰群岛",
    "Andorra": "安道尔",
    "American Samoa": "美属萨摩亚",
    "Antigua and Barb.": "安提瓜和巴布达",
    "Bahrain": "巴林",
    "Bahamas": "巴哈马",
    "Bosnia and Herz.": "波斯尼亚和黑塞哥维那",
    "Barbados": "巴巴多斯",
    "Central African Rep.": "中非",
    "Dem. Rep. Congo": "刚果民主共和国",
    "Congo": "刚果",
    "Comoros": "科摩罗",
    "Cape Verde": "佛得角",
    "Curaçao": "库拉索",
    "Cayman Is.": "开曼群岛",
    "Czech Rep.": "捷克",
    "Dominica": "多米尼克",
    "Falkland Is.": "福克兰群岛",
    "Faeroe Is.": "法罗群岛",
    "Micronesia": "密克罗尼西亚联邦",
    "Guinea-Bissau": "几内亚比绍",
    "Eq. Guinea": "赤道几内亚",
    "Grenada": "格林纳达",
    "Guam": "关岛",
    "Isle of Man": "马恩岛",
    "Br. Indian Ocean Ter.": "英属印度洋领地",
    "Jersey": "泽西岛",
    "Kiribati": "基里巴斯",
    "Lao PDR": "老挝",
    "Saint Lucia": "圣卢西亚",
    "Malta": "马耳他",
    "N. Mariana Is.": "北马里亚纳群岛",
    "Montserrat": "蒙特塞拉特岛",
    "Mauritius": "毛里求斯",
    "Niue": "纽埃岛",
    "Palau": "帕劳",
    "Dem. Rep. Korea":"韩国",
    "Palestine": "巴勒斯坦",
    "Fr. Polynesia": "法属波利尼西亚",
    "S. Sudan": "南苏丹",
    "Singapore": "新加坡",
    "Saint Helena":"圣赫勒拿",
    "Solomon Is.": "所罗门群岛",
    "St. Pierre and Miquelon": "圣皮埃尔和密克隆群岛",
    "São Tomé and Principe": "圣多美和普林西比",
    "Seychelles": "塞舌尔",
    "Turks and Caicos Is.": "特克斯和凯科斯群岛",
    "Timor-Leste": "东帝汶",
    "Tonga": "汤加",
    "Tanzania": "坦桑尼亚",
    "St. Vin. and Gren.": "圣文森特和格林纳丁斯",
    "U.S. Virgin Is.": "美属维尔京群岛",
    "Samoa": "萨摩亚",
    "W. Sahara":"西撒哈拉",
    "Fr. S. Antarctic Lands":"马提尼克岛",
    "Côte d'Ivoire":"科特迪瓦",
    "N. Cyprus":"东塞浦路斯",
    "Dominican Rep.": "多米尼加",
    "Heard I. and McDonald Is.":"赫德岛和麦克唐纳群岛",
    "Siachen Glacier":"锡亚琴冰川",
    "S. Geo. and S. Sandw. Is.":"南乔治亚岛与南桑威奇群岛"
  };
  

六、中文转换函数

在WorldMap.js这个地图组件中,引入mapZHName.js,并添加转化函数,和航线地名的映射表。

完整代码如下:

import React, { useRef, useEffect } from 'react';
import * as echarts from 'echarts';
import { mapZHName } from '../public/mapZHName'; // 确保正确导入映射文件

const geoCoordMap = {
  中国: [104.195397, 35.86166],
  纽约: [-74.006, 40.7128],
  伦敦: [-0.1278, 51.5074],
  东京: [139.6917, 35.6895],
};

//配置航线
const SHData = [
  [
    { name: '中国', value: 105 },
    { name: '中国', value: 105 },
  ],
  [
    { name: '中国', value: 105 },
    { name: '伦敦', value: 105 },
  ],
  [
    { name: '中国', value: 105 },
    { name: '东京', value: 105 },
  ],
];

// 将 SHData 中的城市名称和对应的值转换为 ECharts 地图所需的连线数据格式
const convertData = (data) => {
  const res = [];
  for (let i = 0; i < data.length; i++) {
    const dataItem = data[i];
    const fromCoord = geoCoordMap[dataItem[0].name];
    const toCoord = geoCoordMap[dataItem[1].name];
    if (fromCoord && toCoord) {
      res.push({
        fromName: dataItem[0].name,
        toName: dataItem[1].name,
        coords: [fromCoord, toCoord],
      });
    }
  }
  return res;
};

const WorldMap = () => {
  const chartRef = useRef(null);

  // 中文转换函数定义在组件内部
  const formatWorldMapToZH = (data) => {
    if (data.features) {
      data.features = data.features.map((item) => {
        if (mapZHName[item.properties.name]) {
          item.properties.name = mapZHName[item.properties.name];
        }
        return item;
      });
    }
    return data;
  };

  useEffect(() => {
    // 动态加载世界地图数据
    fetch('/world.json') // 确保文件路径正确,这里假设 world.json 放在 public 文件夹下
      .then((res) => res.json())
      .then((mapData) => {
        // 调用转换函数将地图数据中的英文地名转换为中文
        const formattedMapData = formatWorldMapToZH(mapData);

        echarts.registerMap('world', formattedMapData); // 注册地图数据

        const myChart = echarts.init(chartRef.current);

        const seriesData = [
          {
            type: 'lines',
            zlevel: 1,
            effect: {
              show: true,
              period: 6,
              trailLength: 0.7,
              color: '#fff',
              symbolSize: 3,
            },
            lineStyle: {
              color: '#46bee9',
              width: 0,
              curveness: 0.2,
            },
            data: convertData(SHData),
          },
          {
            type: 'lines',
            zlevel: 2,
            symbol: ['none', 'arrow'],
            symbolSize: 10,
            effect: {
              show: true,
              period: 6,
              trailLength: 0,
              symbol:
                'path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z',
              symbolSize: 15,
            },
            lineStyle: {
              color: '#46bee9',
              width: 1,
              opacity: 0.6,
              curveness: 0.2,
            },
            data: convertData(SHData),
          },
          {
            type: 'effectScatter',
            coordinateSystem: 'geo',
            zlevel: 2,
            rippleEffect: {
              brushType: 'stroke',
            },
            label: {
              show: true,
              position: 'right',
              formatter: '{b}',
            },
            symbolSize: (val) => val[2] / 8,
            itemStyle: {
              color: '#46bee9',
            },
            data: SHData.map((dataItem) => ({
              name: dataItem[1].name,
              value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value]),
            })),
          },
        ];

        myChart.setOption({
          geo: {
            map: 'world',
            nameMap: {
              China: '中国',
              'New York': '纽约',
              London: '伦敦',
              Tokyo: '东京',
            },
            roam: true,
            itemStyle: {
              areaColor: '#404a59',
              borderColor: '#61727a',
            },
            emphasis: {
              itemStyle: {
                areaColor: '#7acfd6',
              },
            },
          },
          series: seriesData,
        });
      })
      .catch((err) => {
        console.error('Failed to load world map data:', err);
      });
  }, []);

  return <div ref={chartRef} style={{ width: '100%', height: '600px' }} />;
};

export default WorldMap;

成果展示:


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

相关文章:

  • Flink 中RocksDB 为什么将每个键和值的限制为 2^31 字节
  • SpringCloud带你走进微服务的世界
  • 零信任架构实战手册-企业安全升级
  • 使用 Excel 实现绩效看板的自动化
  • 2024 年第四届高校大数据挑战赛-赛题 A:岩石的自动鉴定
  • css基本功
  • 手写svm primal form形式
  • kafka连问
  • 华为重拳出击!华为重拳出击!华为重拳出击!
  • Postman下载安装及简单入门
  • unity基础——地面(Physic Material)
  • 53. HarmonyOS NEXT 登录模块开发教程(七):性能优化与最佳实践
  • QT信号与槽:实现方法、技术细节、高级用法和底层机制
  • 蓝桥杯备赛-入门训练题 day1
  • 限流及熔断的场景?
  • MinIO问题总结(持续更新)
  • 游戏引擎学习第155天
  • 【医院绩效管理专题】8.医院绩效数据的收集与整理方法:洞察现状,引领未来
  • arcgis 切片分析录入mongodb
  • Linux安装Redis、远程连接Redis