echart+react实现中国地图点击切换省份(使用react hooks封装echart)

实现效果如下:

在这里插入图片描述

一、echart封装(react hooks)

  • 实现容器大小发生改变,重新绘制
  • 在页面卸载时清理监听以及清除图例
  • 实现代码如下
//index.js
import React, { useEffect, useCallback, useRef, useImperativeHandle, useState } from "react";
import './index.less'
import * as echarts from 'echarts';
import * as Map from './map'    //中国地图数据

// let chartDom;
// let echartIns;//echarts实例
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;
        // console.log(option,echartIns);
        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])

    // 初始化echarts
    const init = () => {
        chartRef.current.chartDom = document.getElementById(id);
        if (!chartRef.current.chartDom) return;
        const { option } = props;

        echarts.registerMap('chinaMap', { geoJSON: Map.chinaMap });
        // echarts.registerMap('guangDongMap', { geoJSON: Map.guangDongMap });
        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类型值
  • 实现代码如下:
//map文件
//1.中国地图
import chinaMap from './china.json'
//2.台湾省地图
import taiWanMap from "./台湾省.json";
//3.海南省地图
import haiNanMap from "./海南省.json";
//4.安徽省地图
import anHuiMap from "./安徽省.json";
//5.江西省地图
import jiangXiMap from "./江西省.json";
//6.湖南省地图
import huNanMap from "./湖南省.json";
//7.云南省地图
import yunNanMap from "./云南省.json";
//8.贵州省地图
import guiZhouMap from "./贵州省.json";
//9.广东省地图
import guangDongMap from "./广东省.json";
//10.福建省地图
import fuJianMap from "./福建省.json";

//11.浙江省地图
import zheJiangMap from "./浙江省.json";
//12.江苏省地图
import jiangSuMap from "./江苏省.json";
//13.四川省地图
import siChuanMap from "./四川省.json";
//14.重庆市市地图
import chongQingMap from "./重庆市.json";
//15.湖北省地图
import huBeiMap from "./湖北省.json";
//16.河南省地图
import heNanMap from "./河南省.json";
//17.山东省地图

import shanDongMap from "./山东省.json";
//18.吉林省地图
import jiLinMap from "./吉林省.json";
//19.辽宁省地图
import liaoNingMap from "./辽宁省.json";
//20.天津市市地图
import tianJinMap from "./天津市.json";
//21.北京市市地图
import beiJingMap from "./北京市.json";
//22.河北省地图
import heBeiMap from "./河北省.json";
//23.山西省地图
import shanXiMap from "./山西省.json";
//24.陕西省地图
import shanXi2Map from "./陕西省.json";
//25.宁夏回族自治区省地图
import ningXiaMap from "./宁夏回族自治区.json";
//26.青海省地图
import qingHaiMap from "./青海省.json";
//27.西藏自治区地图
import xiZangMap from "./西藏自治区.json";
//28.黑龙江省地图
import heiLongJiangMap from "./黑龙江省.json";

//29.内蒙古自治区地图
import neiMengGuMap from "./内蒙古自治区.json";
//30.甘肃省地图
import ganSuMap from "./甘肃省.json";
//31.新疆维吾尔自治区省地图
import xinJiangMap from "./新疆维吾尔自治区.json";
//32.广西壮族自治区地图
import guangXiMap from "./广西壮族自治区.json";
//33.香港
import xiangGangMap from "./香港特别行政区.json";
//34.澳门
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 './Echarts/index.js'

import { mapJson } from './map'
import { method } from 'method'       //其他方法

// import { legend_1, legend_3, legend_4 } from "../img";//legend_2, 
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>
                销售量  &nbsp;  &nbsp; ${params?.data?.value ?? 0}
          </div>`
          //<span οnclick=window.onClickTooltipMore("${params.name}")>查看更多</span>
        },
      },
      series: [
        {
          type: 'map',
          map: type,
          // geoIndex: 0,
          aspectScale: 0.75, //长宽比
          showLegendSymbol: false, // 存在legend时显示
          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数据,可点击小编主页资源下载压缩包

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,您可以使用以下步骤实现这个功能: 1. 在使用 Echarts 绘制图表时,将图表的数据保存在一个 state 中。 2. 创建一个按钮组件,使用 React 的 useState 钩子来创建一个状态变量,用于控制按钮点击事件。 3. 在按钮的点击事件中,使用 FileSaver.js 库将图表数据导出到 Word 文档中。 4. 将导出按钮组件和 Echarts 组件一起渲染,以便用户可以点击按钮导出数据。 下面是一个简单的代码示例: ```jsx import React, { useState } from 'react'; import ReactEcharts from 'echarts-for-react'; import * as FileSaver from 'file-saver'; const MyEcharts = () => { const [chartData, setChartData] = useState(null); const [exporting, setExporting] = useState(false); const handleExportClick = () => { setExporting(true); const chartDataStr = JSON.stringify(chartData); const blob = new Blob([chartDataStr], { type: 'application/json' }); FileSaver.saveAs(blob, 'chart-data.json'); setExporting(false); }; const options = { // Echarts 配置项 }; return ( <> <ReactEcharts option={options} onChartReady={e => setChartData(e.getOption())} /> <button disabled={exporting} onClick={handleExportClick}> {exporting ? 'Exporting...' : 'Export to Word'} </button> </> ); }; ``` 在这个示例中,我们使用ReactEcharts 组件来绘制图表,并使用 onChartReady 回调将图表数据保存到 state 中。然后,我们创建了一个按钮组件,并在点击事件中使用 FileSaver.js 库将图表数据导出到 Word 文档中。最后,我们将导出按钮组件和 Echarts 组件一起渲染,以便用户可以点击按钮导出数据。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

名字还没想好☜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值