WorldMap.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import React from "react";
  2. import * as echarts from "echarts";
  3. import worldJson from "../world.json";
  4. import topIcon from "../../../../assets/bigscreen/map-bar-head.svg";
  5. class WorldMap2D extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. this.chartRef = React.createRef();
  9. this.chartInstance = null;
  10. }
  11. componentDidMount() {
  12. echarts.registerMap("world", worldJson); // 注册地图
  13. this.initChart();
  14. window.addEventListener("resize", this.resizeChart);
  15. }
  16. componentWillUnmount() {
  17. if (this.chartInstance) {
  18. this.chartInstance.dispose();
  19. }
  20. window.removeEventListener("resize", this.resizeChart);
  21. }
  22. componentDidUpdate() {
  23. this.initChart();
  24. }
  25. resizeChart = () => {
  26. if (this.chartInstance) {
  27. this.chartInstance.resize();
  28. }
  29. };
  30. initChart() {
  31. if (!this.chartRef.current) return;
  32. this.chartInstance = echarts.init(this.chartRef.current);
  33. // 顶部图标数据,计算 y 偏移(柱子高度的一半)
  34. const topIconData = this.props.data.map((d) => {
  35. return {
  36. name: d.name,
  37. value: [d.value[0], d.value[1], d.value[2]], // 位置
  38. symbolOffset: [0, -d.value[2] / 2 * 30 ], // Y轴偏移(柱子高度一半 + 额外10像素)
  39. };
  40. });
  41. const option = {
  42. tooltip: {
  43. formatter: (params) => {
  44. return `${params.name} <br/>${params.value[2]}`;
  45. },
  46. textStyle: {
  47. fontSize: 20,
  48. fontWeight: "bold",
  49. },
  50. },
  51. geo: {
  52. map: "world",
  53. roam: true, // 支持缩放拖拽
  54. zoom: 1.1,
  55. itemStyle: {
  56. areaColor: "rgba(126, 206, 244, 0.1)",
  57. borderColor: "#2EA7E0",
  58. borderWidth: 2,
  59. },
  60. emphasis: {
  61. itemStyle: {
  62. areaColor: "rgba(41, 241, 250, 0.6)", // 悬浮时高亮色
  63. borderWidth: 1,
  64. borderColor: 'rgba(41, 241, 250, 1)',
  65. shadowColor: "rgba(41, 241, 250, 1)", // 阴影颜色
  66. // shadowColor: '#fff',
  67. shadowBlur: 2,
  68. shadowOffsetX: 10, // X 偏移
  69. shadowOffsetY: -10,
  70. },
  71. },
  72. },
  73. series: [
  74. {
  75. type: "scatter",
  76. coordinateSystem: "geo",
  77. symbol: "rect", // 用矩形柱代替点
  78. symbolSize: (val) => {
  79. const height = val[2] * 30;
  80. return [10, height];
  81. },
  82. itemStyle: {
  83. color: {
  84. type: "linear",
  85. x: 0,
  86. y: 0,
  87. x2: 0,
  88. y2: 1,
  89. colorStops: [
  90. { offset: 0, color: "#EC903A" },
  91. { offset: 1, color: "rgba(18,92,178,0)" },
  92. ],
  93. },
  94. shadowColor: "#4fd2dd",
  95. shadowBlur: 10,
  96. borderRadius: [8, 8, 0, 0],
  97. },
  98. encode: { tooltip: 2 }, // 提示框显示 value[2]
  99. data: this.props.data, // [lng, lat, value]
  100. },
  101. {
  102. type: "scatter",
  103. coordinateSystem: "geo",
  104. symbol: `image://${topIcon}`, // 图片 URL
  105. symbolSize: [15, 15], // 图片大小
  106. data: topIconData,
  107. },
  108. ],
  109. };
  110. this.chartInstance.setOption(option);
  111. }
  112. render() {
  113. return (
  114. <div ref={this.chartRef} style={{ width: "100%", height: "100%" }} />
  115. );
  116. }
  117. }
  118. export default WorldMap2D;