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;
成果展示: