公司业务要求做世界航线图,跑了三个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;
成果展示: