实现效果如下:
一、echart封装(react hooks)
- 实现容器大小发生改变,重新绘制
- 在页面卸载时清理监听以及清除图例
- 实现代码如下
import React, { useEffect, useCallback, useRef, useImperativeHandle, useState } from "react";
import './index.less'
import * as echarts from 'echarts';
import * as Map from 'yssfbp/map'
const Echarts = React.forwardRef((props, ref) => {
const { extra, extraClassName, extraStyle, click } = props
const chartRef = useRef({ chartDom: null, echartIns: null })
const id = `echart-wrap-${+new Date()}-${props.className}`;
const [flag, setFlag] = useState(false)
useEffect(() => {
init();
window.addEventListener("resize", resizeChart);
if (click) {
let myChart = echarts.init(document.getElementById(id))
myChart.on('click', (params) => {
click(params)
});
}
return () => {
window.removeEventListener("resize", resizeChart);
chartRef.current.echartIns && chartRef.current.echartIns.dispose();
}
}, [ref])
useEffect(() => {
const { option } = props;
if (chartRef.current.echartIns && Object.keys(option).length) {
chartRef.current.echartIns.clear();
chartRef.current.echartIns.setOption(option);
chartRef.current.echartIns.resize();
}
}, [JSON.stringify(props.option)])
useImperativeHandle(ref, () => {
return {
echartIns: chartRef.current.echartIns
}
})
const resizeChart = useCallback(() => {
console.log('object', chartRef.current.echartIns)
if (chartRef.current.echartIns) {
chartRef.current.echartIns.resize()
};
}, [flag])
const init = () => {
chartRef.current.chartDom = document.getElementById(id);
if (!chartRef.current.chartDom) return;
const { option } = props;
echarts.registerMap('chinaMap', { geoJSON: Map.chinaMap });
Map.mapJson.map(item => {
echarts.registerMap(item.key, { geoJSON: Map?.[item.key] });
})
setTimeout(() => {
chartRef.current.echartIns = echarts.init(chartRef.current.chartDom);
chartRef.current.echartIns.setOption(option);
chartRef.current.echartIns.resize();
setFlag(true)
}, 350);
}
const renderEchart = () => {
const { className = "" } = props;
return <div className={`yss-echart--wrap ${className}`}>
{extra && <div className={`extra-echarts ${extraClassName}`} style={extraStyle}>
{extra()}
</div>}
<div id={id} style={{ width: "100%", height: "100%" }} ref={ref} />
</div>
}
return renderEchart()
})
export default React.memo(Echarts)
二、引入中国地图数据Json文件,实现统一导出
- 导入json数据并以变量名导出
- 定义mapJson数组,记录每个省份的json名称,用户实现点击切换以及注册地图map类型值
- 实现代码如下:
import chinaMap from './china.json'
import taiWanMap from "./台湾省.json";
import haiNanMap from "./海南省.json";
import anHuiMap from "./安徽省.json";
import jiangXiMap from "./江西省.json";
import huNanMap from "./湖南省.json";
import yunNanMap from "./云南省.json";
import guiZhouMap from "./贵州省.json";
import guangDongMap from "./广东省.json";
import fuJianMap from "./福建省.json";
import zheJiangMap from "./浙江省.json";
import jiangSuMap from "./江苏省.json";
import siChuanMap from "./四川省.json";
import chongQingMap from "./重庆市.json";
import huBeiMap from "./湖北省.json";
import heNanMap from "./河南省.json";
import shanDongMap from "./山东省.json";
import jiLinMap from "./吉林省.json";
import liaoNingMap from "./辽宁省.json";
import tianJinMap from "./天津市.json";
import beiJingMap from "./北京市.json";
import heBeiMap from "./河北省.json";
import shanXiMap from "./山西省.json";
import shanXi2Map from "./陕西省.json";
import ningXiaMap from "./宁夏回族自治区.json";
import qingHaiMap from "./青海省.json";
import xiZangMap from "./西藏自治区.json";
import heiLongJiangMap from "./黑龙江省.json";
import neiMengGuMap from "./内蒙古自治区.json";
import ganSuMap from "./甘肃省.json";
import xinJiangMap from "./新疆维吾尔自治区.json";
import guangXiMap from "./广西壮族自治区.json";
import xiangGangMap from "./香港特别行政区.json";
import aoMenMap from "./澳门特别行政区.json";
let mapJson = [
{
name: "台湾省",
json: taiWanMap,
key: 'taiWanMap',
},
{
name: "海南省",
json: haiNanMap,
key: 'haiNanMap'
},
{
name: "安徽省",
json: anHuiMap,
key: 'anHuiMap'
},
{
name: "江西省",
json: jiangXiMap,
key: 'jiangXiMap'
},
{
name: "湖南省",
json: huNanMap,
key: 'huNanMap'
},
{
name: "云南省",
json: yunNanMap,
key: 'yunNanMap'
},
{
name: "贵州省",
json: guiZhouMap,
key: 'guiZhouMap'
},
{
name: "广东省",
json: guangDongMap,
key: 'guangDongMap'
},
{
name: "福建省",
json: fuJianMap,
key: 'fuJianMap'
},
{
name: "浙江省",
json: zheJiangMap,
key: 'zheJiangMap'
},
{
name: "江苏省",
json: jiangSuMap,
key: 'jiangSuMap'
},
{
name: "四川省",
json: siChuanMap,
key: 'siChuanMap'
},
{
name: "重庆市",
json: chongQingMap,
key: 'chongQingMap'
},
{
name: "湖北省",
json: huBeiMap,
key: 'huBeiMap'
},
{
name: "河南省",
json: heNanMap,
key: 'heNanMap'
},
{
name: "山东省",
json: shanDongMap,
key: 'shanDongMap'
},
{
name: "吉林省",
json: jiLinMap,
key: 'jiLinMap'
},
{
name: "辽宁省",
json: liaoNingMap,
key: 'liaoNingMap'
},
{
name: "天津市",
json: tianJinMap,
key: 'tianJinMap'
},
{
name: "北京市",
json: beiJingMap,
key: 'beiJingMap'
},
{
name: "河北省",
json: heBeiMap,
key: 'heBeiMap'
},
{
name: "山西省",
json: shanXiMap,
key: 'shanXiMap'
},
{
name: "陕西省",
json: shanXi2Map,
key: 'shanXi2Map'
},
{
name: "宁夏回族自治区",
json: ningXiaMap,
key: 'ningXiaMap'
},
{
name: "青海省",
json: qingHaiMap,
key: 'qingHaiMap'
},
{
name: "西藏自治区",
json: xiZangMap,
key: 'xiZangMap',
},
{
name: "黑龙江省",
json: heiLongJiangMap,
key: 'heiLongJiangMap'
},
{
name: "内蒙古自治区",
json: neiMengGuMap,
key: 'neiMengGuMap'
},
{
name: "甘肃省",
json: ganSuMap,
key: 'ganSuMap'
},
{
name: "新疆维吾尔自治区",
json: xinJiangMap,
key: 'xinJiangMap'
},
{
name: "广西壮族自治区",
json: guangXiMap, key:
'guangXiMap'
},
{
name: "香港特别行政区",
json: xiangGangMap,
key: 'xiangGangMap'
},
{
name: "澳门特别行政区",
json: aoMenMap,
key: 'aoMenMap'
},
];
export {
mapJson, chinaMap, taiWanMap, haiNanMap, anHuiMap, jiangXiMap, huNanMap, yunNanMap, guiZhouMap, guangDongMap, fuJianMap, zheJiangMap, jiangSuMap, siChuanMap, chongQingMap, huBeiMap, heNanMap, shanDongMap, jiLinMap, tianJinMap, beiJingMap, heBeiMap, shanXiMap, shanXi2Map, ningXiaMap, qingHaiMap, xiZangMap, heiLongJiangMap, ganSuMap, xinJiangMap, guangXiMap, neiMengGuMap, aoMenMap, xiangGangMap, liaoNingMap
}
三、配置地图的option以及点击切换事件
- 使用点击事件切换map类型,实现省份切换
- 实现代码如下:
import React, { useState, useEffect } from "react";
import { Row } from "antd";
import "./index.less";
import { Echarts } from 'yssfbp-base'
import { mapJson } from 'yssfbp/map'
import { method } from 'yssfbp'
const Map = (props) => {
const Data = [
{
name: "广东省",
value: 123,
},
]
const getMapOption = (data = [], type) => {
return {
title: type == 'chinaMap' ? {
text: "产品类型范围",
textStyle: {
color: "#fff"
}
} : {
text: mapJson.select(type, 'key')?.name,
textStyle: {
color: "#fff",
fontSize: 15,
},
left: "2%",
top: "1%"
},
legend: {
show: false
},
tooltip: {
trigger: 'item',
padding: 0,
enterable: true,
className: 'g2-tooltip',
formatter(params) {
if (method.IsEmpty(params)) return
return `<div class="g2-tooltip-title">${params.name}</div>
<div class="g2-tooltip-list">
<span class='g2-icon'></span>
销售量 ${params?.data?.value ?? 0}
</div>`
},
},
series: [
{
type: 'map',
map: type,
aspectScale: 0.75,
showLegendSymbol: false,
layoutCenter: type == 'chinaMap' ? ["50%", "65%"] : ["52%", "50%"],
layoutSize: '100%',
zoom: type == 'chinaMap' ? 1.3 : 1,
label: {
normal: {
show: true,
color: "#00bbff",
fontSize: 8,
},
emphasis: {
show: true,
color: "#00bbff",
fontSize: 8,
},
},
roam: true,
itemStyle: {
normal: {
areaColor: '#0A2D61',
borderColor: '#0270BD',
borderWidth: 1.5,
},
emphasis: {
areaColor: '#005799',
borderColor: '#00BBFF',
borderWidth: 2.5,
},
},
select: {
itemStyle: {
areaColor: '#005799',
borderColor: '#00BBFF',
borderWidth: 2.5,
},
label: {
show: true,
color: "#00bbff",
fontSize: 8,
},
},
animation: false,
data: Data
},
]
}
}
const [type, setType] = useState("");
const [mapOption1, setMapOption1] = useState(() => getMapOption([], "chinaMap"));
const [mapOption2, setMapOption2] = useState(() => getMapOption([], "guangDongMap"));
useEffect(() => {
const { mapDataList = [] } = props;
if (!mapDataList?.length) return;
setMapOption1(() => getMapOption(mapDataList, "chinaMap"));
}, [JSON.stringify(props.mapDataList)])
useEffect(() => {
setMapOption2(() => getMapOption([], type))
}, [type])
const click = (info) => {
let res = mapJson.select(info?.name, 'name')?.key
setType(res)
}
return <div className="map">
<Echarts option={mapOption1} className='china-chart' click={click} />
<Echarts option={mapOption2} className='province-chart' />
</div>
}
export default Map
代码仅供参考,如需要地图json数据,可点击小编主页资源下载压缩包
|