当前位置:   article > 正文

react项目二次封装echarts组件(包含地图)_react地图组件

react地图组件

项目需要先引入echarts组件

npm install echarts --save

然后封装的EchartsComponent组件文件 如下

  1. /* eslint-disable */
  2. import React, { Component } from "react";
  3. import PropTypes from "prop-types";
  4. /*引入 ECharts 主模块**/
  5. import echarts, { dispose } from "echarts/lib/echarts";
  6. import "echarts/lib/chart/pie";
  7. import "echarts/lib/chart/bar";
  8. import "echarts/lib/chart/line";
  9. import "echarts/lib/chart/tree";
  10. import "echarts/lib/component/tooltip";
  11. import "echarts/lib/component/legend";
  12. import "echarts/lib/component/title";
  13. import "echarts/lib/component/legendScroll";
  14. import 'echarts/map/js/china';
  15. class EchartsComponent extends Component {
  16. chart = null;
  17. componentDidMount() {
  18. const { chartId, option } = this.props; /**继承父级传递的值*/
  19. const chartIdDiv = document.getElementById(chartId);
  20. if (chartIdDiv) {
  21. this.chart = echarts.init(chartIdDiv); /**实例化echats画布*/
  22. if (this.chart) {
  23. this.renderChart(this.chart, option); /**加载数据*/
  24. }
  25. }
  26. window.addEventListener(
  27. "resize",
  28. this.handleResize,
  29. false
  30. ); /**监听改变画布大小*/
  31. }
  32. /**
  33. * @description: 根据父级传递的值,是否更新画布
  34. * @param {type}
  35. * @return {type}
  36. */
  37. componentDidUpdate(prevProps) {
  38. const { option } = this.props;
  39. if (prevProps.option !== option && this.chart) {
  40. this.renderChart(this.chart, option);
  41. }
  42. }
  43. /**
  44. * @description: 注销时,去除监听事件以及销毁echats
  45. * @param {type}
  46. * @return {type}
  47. **/
  48. componentWillUnmount() {
  49. window.removeEventListener("resize", this.handleResize, false);
  50. if (this.chart) {
  51. this.chart.dispose();
  52. this.chart = null;
  53. }
  54. }
  55. /**放大缩小重新布局*/
  56. handleResize = () => {
  57. if (this.chart) {
  58. setTimeout(() => {
  59. this.chart.resize();
  60. });
  61. }
  62. };
  63. /**图表配置及渲染*/
  64. renderChart = (chart, option) => {
  65. const { handleClick } = this.props;
  66. chart.clear();
  67. chart.setOption(option);
  68. chart.off("click"); /**要是不加上这行,事件会重复n次*/
  69. chart.on("click", (params) => {
  70. if (handleClick) {
  71. handleClick(params);
  72. }
  73. });
  74. };
  75. render() {
  76. const { chartId, width, height, margin } = this.props;
  77. return (
  78. <div
  79. id={chartId}
  80. style={{
  81. minWidth: width,
  82. minHeight: height,
  83. height: height,
  84. width: width,
  85. margin,
  86. }}
  87. />
  88. );
  89. }
  90. }
  91. EchartsComponent.defaultProps = {
  92. margin: "0 auto",
  93. width: "556px",
  94. height: "430px",
  95. };
  96. export default EchartsComponent;
  97. /* eslint-disable */

项目中引用如下文件:

提示:其中options需要单独作为参数 传入,因为每个图标配置 项可能 不一样;

  1. import EchartsComponent from "Components/EchartsComponent";//注意引入方式 可能需要修改
  2. //option 可以 参考 https://echarts.apache.org/examples/zh/index.html echarts地址的所有option传入即可
  3. // 下面提供一个中国地图的option实现 了解大致逻辑 因为此地图配置根据个人需要更改
  4. import React, { useEffect, useState } from "react";
  5. function MapTravel(props) {
  6. const { loading, travelInfo, geoCoordMap } = props;
  7. const [option, setOption] = useState("");
  8. const [nowTime, setTNowTime] = useState(
  9. moment(new Date()).format("YYYY/MM/DD HH:mm:ss")
  10. );
  11. let series = [];
  12. useEffect(() => {
  13. // 获取接口数据
  14. props.getMapTravelInfo();
  15. }, []);
  16. // 监听后段接口返回的数据 props.travelInfo 因为redux逻辑调用接口传入数据 prop方式拿数据
  17. useEffect(() => {
  18. let arr = [],
  19. stationNameArr = [];
  20. if (Object.keys(props.travelInfo).length) {
  21. // 把后端返回的数据 二次调整页面显示需要的数据格式
  22. props.travelInfo.forEach((item) => {
  23. if (item.stationName) {
  24. stationNameArr.push(item.stationName);
  25. arr.push({
  26. ...item,
  27. name: item.stationName,
  28. value: 100,
  29. });
  30. }
  31. });
  32. // 调整地图地点高亮显示样式 半圆切割色
  33. arr.forEach(function(item) {
  34. let colorObj = [{}];
  35. if (item.inventoryFlag === 0 && item.departureAndArrivalFlag === 0) {
  36. // 站点库存正常,进出港浮动正常
  37. colorObj = [
  38. {
  39. offset: 0.5,
  40. color: "#249e24",
  41. },
  42. ];
  43. } else if (
  44. item.inventoryFlag === 1 &&
  45. item.departureAndArrivalFlag === 0
  46. ) {
  47. // 站点库存异常,进出港浮动正常
  48. colorObj = [
  49. {
  50. offset: 0.5,
  51. color: "#ff0000",
  52. },
  53. {
  54. offset: 0.5,
  55. color: "#249e24",
  56. },
  57. ];
  58. } else if (
  59. item.inventoryFlag === 0 &&
  60. item.departureAndArrivalFlag === 1
  61. ) {
  62. // 站点库存正常,进出港浮动异常
  63. colorObj = [
  64. {
  65. offset: 0.5,
  66. color: "#249e24",
  67. },
  68. {
  69. offset: 0.5,
  70. color: "#ff0000",
  71. },
  72. ];
  73. } else if (
  74. item.inventoryFlag === 1 &&
  75. item.departureAndArrivalFlag === 1
  76. ) {
  77. // 站点库存异常,进出港浮动异常
  78. colorObj = [
  79. {
  80. offset: 0.5,
  81. color: "#ff0000",
  82. },
  83. ];
  84. }
  85. //以上数据二次改为自己想要的格式
  86. series.push({
  87. name: item["name"],
  88. type: "effectScatter",
  89. coordinateSystem: "geo",
  90. zlevel: 2,
  91. rippleEffect: {
  92. brushType: "stroke",
  93. },
  94. label: {
  95. normal: {
  96. show: true,
  97. position: "right",
  98. formatter: "{b}",
  99. color: "#fff",
  100. },
  101. },
  102. symbolSize: function(val) {
  103. return val[2] / 8;
  104. },
  105. itemStyle: {
  106. normal: {
  107. color: new echarts.graphic.RadialGradient(
  108. 0.5,
  109. 0.5,
  110. 0.6,
  111. colorObj
  112. ),
  113. },
  114. },
  115. data: [
  116. {
  117. ...item,
  118. // 匹配到对应 地理位置名称
  119. value: geoCoordMap[item.name]
  120. ? geoCoordMap[item.name].concat([item.value])
  121. : 0,
  122. },
  123. ],
  124. });
  125. });
  126. setOption({
  127. title: {
  128. text: "",
  129. // subtext: '数据纯属虚构',
  130. left: "center",
  131. top: "20px",
  132. textStyle: {
  133. color: "#fff",
  134. },
  135. },
  136. tooltip: {
  137. trigger: "item",
  138. backgroundColor: "#0a265f",
  139. formatter: function(params, ticket, callback) {
  140. // 后端接口返回的每一项数据. 下面的数据适用我之前的项目 可根据具体项目需求调整
  141. const { data, seriesType, name } = params;
  142. if (seriesType == "effectScatter") {
  143. return (
  144. '<div class="tipBox">&nbsp;&nbsp;&nbsp;&nbsp;' +
  145. data.name +
  146. '<div><div class="contentItem"><div><div>站点库存</div><span>' +
  147. data.inventoryNumber +
  148. "</span></div><div><div>开口/无源</div><span>" +
  149. data.openingNumber +
  150. "/" +
  151. data.passiveNumber +
  152. "</span></div><div><div>进港/出港总数</div><span>" +
  153. data.arrivalNumber +
  154. "/" +
  155. data.departureNumber +
  156. '</span></div></div><div class="tip">开口餐车为前天数据,无源餐车为月初1号数据</div>'
  157. );
  158. } else if (seriesType == "lines") {
  159. return `${data.fromName}->${data.toName}${data.value}`;
  160. } else {
  161. return name;
  162. }
  163. },
  164. },
  165. legend: {
  166. orient: "vertical",
  167. top: "center",
  168. left: "right",
  169. data: stationNameArr,
  170. textStyle: {
  171. color: "#fff",
  172. },
  173. formatter: function(name) {
  174. //用来格式化图例文本,支持字符串模板和回调函数两种形式。模板变量为图例名称 {name}
  175. return ` ${name}`;
  176. },
  177. selectedMode: "multiple",
  178. },
  179. //地理位置配置
  180. geo: {
  181. map: "china",
  182. label: {
  183. emphasis: {
  184. show: true,
  185. color: "#fff",
  186. },
  187. },
  188. //中国地图放大
  189. zoom: 1.2,
  190. roam: true,
  191. itemStyle: {
  192. normal: {
  193. //区域省份背景色颜色设置
  194. areaColor: "rgba(20,41,87, .6)",
  195. borderColor: "#195BB9",
  196. borderWidth: 1,
  197. },
  198. emphasis: {
  199. areaColor: "#2B91B7",
  200. },
  201. },
  202. },
  203. series: series,
  204. });
  205. }
  206. }, [props.travelInfo]);
  207. return (
  208. <Spin
  209. spinning={loading}
  210. style={{ height: "100vh" }}
  211. className={"toggleSpin"}
  212. >
  213. <div className={style.nav}>
  214. {option ? (
  215. <EchartsComponent
  216. width={"90%"}
  217. height={"95%"}
  218. chartId="mapChartId"
  219. option={option}
  220. />
  221. ) : (
  222. ""
  223. )}
  224. </div>
  225. </Spin>
  226. );
  227. }
  228. MapTravel.propTypes = {
  229. loading: PropTypes.bool.isRequired,
  230. getMapTravelInfo: PropTypes.func.isRequired,
  231. travelInfo: PropTypes.array.isRequired,
  232. };
  233. function mapStateToProps(state) {
  234. const { loading, travelInfo } = state.mapTravel;
  235. return {
  236. geoCoordMap,
  237. loading,
  238. travelInfo,
  239. };
  240. }
  241. function mapDispatchToProps(dispatch) {
  242. return bindActionCreators(actions, dispatch);
  243. }
  244. export default connect(mapStateToProps, mapDispatchToProps)(MapTravel);

对应redux文件

  1. /* eslint-disable */
  2. import network from "Utils/network";
  3. const initialState = {
  4. loading: false,
  5. travelInfo: {},
  6. geoCoordMap: {
  7. // 上海: [121.4648, 31.2891],
  8. // 东莞: [113.8953, 22.901],
  9. // 东营: [118.7073, 37.5513],
  10. // 中山: [113.4229, 22.478],
  11. // 临汾: [111.4783, 36.1615],
  12. // 丹东: [124.541, 40.4242],
  13. // 丽水: [119.5642, 28.1854],
  14. // 佛山: [112.8955, 23.1097],
  15. // 保定: [115.0488, 39.0948],
  16. // 北海: [109.314, 21.6211],
  17. // 南通: [121.1023, 32.1625],
  18. // 台州: [121.1353, 28.6688],
  19. // 咸阳: [108.4131, 34.8706],
  20. // 唐山: [118.4766, 39.6826],
  21. // 嘉兴: [120.9155, 30.6354],
  22. // 大同: [113.7854, 39.8035],
  23. // 太原: [112.3352, 37.9413],
  24. // 宝鸡: [107.1826, 34.3433],
  25. // 宿迁: [118.5535, 33.7775],
  26. // 廊坊: [116.521, 39.0509],
  27. // 延安: [109.1052, 36.4252],
  28. // 张家口: [115.1477, 40.8527],
  29. // 徐州: [117.5208, 34.3268],
  30. // 德州: [116.6858, 37.2107],
  31. // 惠州: [114.6204, 23.1647],
  32. // 成都: [103.9526, 30.7617],
  33. // 扬州: [119.4653, 32.8162],
  34. // 承德: [117.5757, 41.4075],
  35. // 枣庄: [117.323, 34.8926],
  36. // 柳州: [109.3799, 24.9774],
  37. // 株洲: [113.5327, 27.0319],
  38. // 江门: [112.6318, 22.1484],
  39. // 沧州: [116.8286, 38.2104],
  40. // 河源: [114.917, 23.9722],
  41. // 泉州: [118.3228, 25.1147],
  42. // 泰安: [117.0264, 36.0516],
  43. // 泰州: [120.0586, 32.5525],
  44. // 济南: [117.1582, 36.8701],
  45. // 济宁: [116.8286, 35.3375],
  46. // 淄博: [118.0371, 36.6064],
  47. // 清远: [112.9175, 24.3292],
  48. // 渭南: [109.7864, 35.0299],
  49. // 湖州: [119.8608, 30.7782],
  50. // 湘潭: [112.5439, 27.7075],
  51. // 滨州: [117.8174, 37.4963],
  52. // 潍坊: [119.0918, 36.524],
  53. // 玉溪: [101.9312, 23.8898],
  54. // 盘锦: [121.9482, 41.0449],
  55. // 石家庄: [114.4995, 38.1006],
  56. // 秦皇岛: [119.2126, 40.0232],
  57. // 绍兴: [120.564, 29.7565],
  58. // 聊城: [115.9167, 36.4032],
  59. // 肇庆: [112.1265, 23.5822],
  60. // 舟山: [122.2559, 30.2234],
  61. // 苏州: [120.6519, 31.3989],
  62. // 莱芜: [117.6526, 36.2714],
  63. // 菏泽: [115.6201, 35.2057],
  64. // 营口: [122.4316, 40.4297],
  65. // 葫芦岛: [120.1575, 40.578],
  66. // 衡水: [115.8838, 37.7161],
  67. // 衢州: [118.6853, 28.8666],
  68. // 连云港: [119.1248, 34.552],
  69. // 邢台: [114.8071, 37.2821],
  70. // 邯郸: [114.4775, 36.535],
  71. // 金华: [120.0037, 29.1028],
  72. // 铜川: [109.0393, 35.1947],
  73. // 镇江: [119.4763, 31.9702],
  74. // 长治: [112.8625, 36.4746],
  75. // 阳泉: [113.4778, 38.0951],
  76. // 韶关: [113.7964, 24.7028],
  77. // 配置新增的机场名称
  78. '北京(大兴航食)': [116.410745, 39.510251],
  79. '虹桥': [121.34113, 31.19590],
  80. '浦东': [121.808603, 31.142363],
  81. '青岛': [120.4651, 36.3373],
  82. '齐鲁(济南)': [117.213048, 36.851644],
  83. '烟台': [120.7397, 37.5128],
  84. '武汉': [114.3896, 30.6628],
  85. '山西(太原)': [112.3352, 37.9413],
  86. '云南(昆明)': [102.9199, 25.4663],
  87. '甘肃(兰州)': [103.5901, 36.3043],
  88. '西安': [109.1162, 34.2004],
  89. '安徽(合肥)': [117.29, 32.0581],
  90. '江苏(南京)': [118.8062, 31.9208],
  91. '无锡': [120.3442, 31.5527],
  92. '江西(南昌)': [116.0046, 28.6633],
  93. '宁波': [121.5967, 29.6466],
  94. '成都(双流)': [103.951572, 30.559105],
  95. '成都(天府)': [104.432573, 30.278925],
  96. '深圳': [114.5435, 22.5439],
  97. '深圳(深圳航食)': [113.826548, 22.646759],
  98. '深圳(深圳空港)': [114.085947, 22.547],
  99. '重庆': [107.7539, 30.1904],
  100. '重庆(重庆机场)': [106.638184, 29.716311],
  101. '重庆(重庆中航)': [106.504962, 29.533155],
  102. '南宁': [108.479, 23.1152],
  103. '呼和浩特': [111.4124, 40.4901],
  104. '贵阳': [106.6992, 26.7682],
  105. '临沂': [118.3118, 35.2936],
  106. '威海': [121.9482, 37.1393],
  107. '郑州': [113.4668, 34.6234],
  108. '郑州(郑州机场)': [113.829697, 34.531751],
  109. '郑州(郑州南航)': [113.665412, 34.757975],
  110. '沈阳': [123.1238, 42.1216],
  111. '沈阳(沈阳空港)': [123.495322, 41.639496],
  112. '沈阳(沈阳南联)': [123.429096, 41.796767],
  113. '海拉尔': [119.7364, 49.2122],
  114. '包头': [110.3467, 41.4899],
  115. '天津': [117.4219, 39.4189],
  116. '绵阳': [104.741722, 31.46402],
  117. '齐齐哈尔': [123.953486, 47.348079],
  118. '张家界': [110.479921, 29.127401],
  119. '万州': [108.379050, 30.807500],
  120. '湛江': [21.191720, 110.398070],
  121. '长春(长春机场)': [125.694328, 43.996622],
  122. '长春(长春南联)': [125.212570, 43.904247],
  123. '长春': [125.8154, 44.2584],
  124. '桂林': [110.271818, 25.261428],
  125. '广州(广州汉莎)': [113.27307, 23.15787],
  126. '广州(广州南联)': [113.826548, 22.646759],
  127. '广州(广州南联)': [113.826548, 22.646759],
  128. '广州': [113.5107, 23.2196],
  129. '厦门': [118.1689, 24.6478],
  130. '哈尔滨': [127.9688, 45.368],
  131. '哈尔滨(哈尔滨机场)': [126.251133, 45.625854],
  132. '哈尔滨(哈尔滨南航)': [126.642464, 45.756967],
  133. '汕头(揭阳潮汕)': [117.1692, 23.3405],
  134. '宜昌': [30.5569, 111.48],
  135. '黄岩(台州路桥)': [28.5652778, 121.430278],
  136. '日照': [119.2786, 35.5023],
  137. '北京(国航航食)': [116.603039, 40.080525],
  138. '北京(北京空港)': [116.4551, 40.2539],
  139. '北京首都': [110.141357, 24.9716],
  140. '海口': [110.3893, 19.8516],
  141. '温州': [120.498, 27.8119],
  142. '三亚': [109.508268, 18.247872],
  143. '昆明(云南空港)': [102.998300, 25.121938],
  144. '丽江': [100.233026, 26.872108],
  145. '迪庆(香格里拉)': [99.70601, 27.82308],
  146. '大理': [100.22998, 25.59157],
  147. '腾冲': [98.49414, 25.02539],
  148. '西宁': [101.4038, 36.8207],
  149. '银川': [106.3586, 38.1775],
  150. '鄂尔多斯': [108.9734, 39.2487],
  151. '拉萨': [91.1865, 30.1465],
  152. '盐城': [120.2234, 33.5577],
  153. '乌鲁木齐': [87.9236, 43.5883],
  154. '淮安': [118.927, 33.4039],
  155. '常州': [119.4543, 31.5582],
  156. '珠海': [113.7305, 22.1155],
  157. '福州': [119.4543, 25.9222],
  158. '泸州': [105.443348, 28.889138],
  159. '西双版纳': [100.797941, 22.001724],
  160. '晋江': [118.55194, 24.78141],
  161. '芒市': [98.588641, 24.433735],
  162. '嘉峪关': [98.277304, 39.786529],
  163. '敦煌': [40.0922, 94.6817],
  164. '喀什': [76.025886, 39.540737],
  165. '库尔勒': [41.6992, 86.1303],
  166. '黄山': [118.261088, 29.730427],
  167. '大连(大连机场)': [121.555709, 38.957998],
  168. '大连(大连南联)': [121.618622, 38.91459],
  169. '大连': [122.2229, 39.4409],
  170. '榆林(榆林榆阳)': [109.599254, 38.358264],
  171. '大庆(目前不涉及)': [125.142936, 46.752023],
  172. '杭州(杭州汉莎)': [120.445531, 30.239038],
  173. '杭州(杭州中宇)': [119.5313, 29.8773],
  174. '杭州': [120.15, 30.28],
  175. '义乌': [120.03273, 29.34066],
  176. '运城': [111.038141, 35.115697],
  177. '延吉': [42.8828, 129.451],
  178. '长沙(长沙机场)': [113.226255, 28.1887],
  179. '长沙(长沙南联)': [113.0823, 28.2568],
  180. '长沙': [113.00000, 28.21667],
  181. },
  182. };
  183. export const actions = {
  184. getMapTravelInfo: (data) => ({
  185. type: 'getMapTravelInfo',
  186. promise: network.GET('/WBPM1-eaccart/statistical/mapData', data),
  187. }),
  188. };
  189. const reducers = {
  190. getMapTravelInfoRequest: (state) => ({ ...state, loading: true }),
  191. getMapTravelInfoSuccess: (state, action) => {
  192. return { ...state, loading: false, travelInfo: action.data }
  193. },
  194. getMapTravelInfoFailure: (state) => ({ ...state, loading: false, travelInfo: {} }),
  195. };
  196. export default (state = initialState, action) => {
  197. if (reducers[action.type]) {
  198. return reducers[action.type](state, action);
  199. }
  200. return state;
  201. };

对应 travelInfo 后端数据格式:

 对应以上数据展示页面如下 :

 具体option的数据data需要根据项目去灵活调整 ,整体的option是不变的

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/108868
推荐阅读