• react d3使用循环显示多个地图


    首先需要写一个组件:

    1. import React, { useState, useEffect, useRef } from 'react';
    2. import ChinaMap from 'moment';
    3. import * as d3 from 'd3';
    4. import chinaGeoJson from 'china-geojson/src/geojson/china.json';
    5. const MyMapToShowResult = ({ realData }) => {
    6. const [data, setData] = useState({});
    7. const [loading, setLoading] = useState(true);
    8. const svgRef = useRef(null);
    9. const [hoveredProvince, setHoveredProvince] = useState(null);
    10. useEffect(() => {
    11. const backgroundColor = 'blue';
    12. const svg = d3.select(svgRef.current);
    13. svg.style('background-color', backgroundColor);
    14. let isMounted = true;
    15. const width = 780;
    16. const height = 580;
    17. const projection = d3.geoMercator()
    18. .center([105, 38])
    19. .scale(600)
    20. .translate([width / 2, height / 2]);
    21. const path = d3.geoPath().projection(projection);
    22. const features = JSON.parse(JSON.stringify(chinaGeoJson.features));
    23. //const realData = [
    24. // { province: '北京', emission: 500 },
    25. // { province: '上海', emission: 200 },
    26. // { province: '台湾', emission: 400 },
    27. // { province: '青海', emission: 200 },
    28. // { province: '辽宁', emission: 300 },
    29. // { province: '黑龙江', emission: 100 },
    30. //];
    31. features.forEach((feature, i) => {
    32. // 在 realData 中查找对应省份的数据
    33. const provinceData = realData.find(data => data.province === feature.properties.name);
    34. // 如果找到对应省份的数据,则将真实的数量赋给 emission 属性
    35. if (provinceData) {
    36. feature.properties.emission = provinceData.emission;
    37. } else {
    38. feature.properties.emission = 0;
    39. }
    40. });
    41. console.log('== 省份数据:', features);
    42. svg.selectAll('*').remove();
    43. svg.append('g')
    44. .attr('transform', `translate(${width / 2},${height / 2})`)
    45. .call(projection);
    46. svg.selectAll('path')
    47. .data(features)
    48. .join('path')
    49. .attr('d', path)
    50. .transition()
    51. .attr('fill-opacity', 0.8)
    52. .style('stroke', 'black')
    53. .style('stroke-width', '1px')
    54. .attr('data-tip', (d, i) => { return d.properties.name + " : " + d.properties.emission; })
    55. .attr('fill', (d, i) => {
    56. const colorScale = d3.scaleSequential()
    57. .interpolator(d3.interpolateRgb('#ffffff', '#008000'))
    58. .domain([0, d3.max(features, d => d.properties.emission)]);
    59. return colorScale(d.properties.emission);
    60. });
    61. // 创建比色卡
    62. const legendWidth = 200;
    63. const legendHeight = 20;
    64. const legendPadding = 10;
    65. const legend = svg.append('g')
    66. .attr('transform', `translate(${width - legendWidth - legendPadding},${height - legendHeight - legendPadding})`);
    67. const colorScale = d3.scaleSequential()
    68. .interpolator(d3.interpolateRgb('#ffffff', '#008000'))
    69. .domain([0, d3.max(features, d => d.properties.emission)]);
    70. console.log('== 比色卡前,省份数据:', features);
    71. const legendXScale = d3.scaleLinear()
    72. .domain([0, d3.max(features, d => d.properties.emission)])
    73. .range([0, legendWidth]);
    74. // 根据需要设置刻度数量
    75. const legendXAxis = d3.axisBottom(legendXScale)
    76. .ticks(5);
    77. legend.append('g')
    78. .attr('class', 'legend-axis')
    79. .attr('transform', `translate(0, ${legendHeight})`)
    80. .call(legendXAxis);
    81. const legendGradient = legend.append('linearGradient')
    82. .attr('id', 'legend-gradient')
    83. .attr('gradientUnits', 'userSpaceOnUse')
    84. .attr('x1', 0)
    85. .attr('x2', legendWidth)
    86. .selectAll('stop')
    87. .data(colorScale.ticks().map((t, i, n) => ({
    88. offset: `${100 * i / n.length}%`,
    89. color: colorScale(t)
    90. })))
    91. .join('stop')
    92. .attr('offset', d => d.offset)
    93. .attr('stop-color', d => d.color);
    94. legend.append('rect')
    95. .attr('x', 0)
    96. .attr('y', -legendHeight / 2)
    97. .attr('width', legendWidth)
    98. .attr('height', legendHeight)
    99. .style('fill', 'url(#legend-gradient)');
    100. }, [data]);
    101. return (
    102. <div>
    103. <svg ref={svgRef} width="800" height="600">svg>
    104. <div id="tooltip" style={{ display: 'none', position: 'absolute', backgroundColor: 'white', padding: '5px', borderRadius: '5px', boxShadow: '0 2px 5px rgba(0, 0, 0, 0.3)', zIndex: '999' }}>div>
    105. {hoveredProvince && (
    106. <div id="tooltip" style={{ display: 'block', position: 'absolute', backgroundColor: 'white', padding: '5px', borderRadius: '5px', boxShadow: '0 2px 5px rgba(0, 0, 0, 0.3)', zIndex: '999', left: '10px', top: '10px' }}>
    107. {hoveredProvince}
    108. div>
    109. )}
    110. div>
    111. );
    112. };
    113. export default MyMapToShowResult;

    然后在页面进行引用,并且传递数据给组件:

    引入:

    import MyMapToShowResult from "@/compontens/MyMapToShowResult";

    渲染:(注意需要把realData声明赋值)

    <MyMapToShowResult realData={realData}/

    在循环中使用:

    1. {data.map((item, index) => (
    2. <div key={index}>
    3. <p>map{index}p>
    4. <MyMapToShowResult realData={realData}/>
    5. div>
    6. ))}

  • 相关阅读:
    C++16 --- C++相关试题及相关知识点整理
    PLL锁相环设计中的VCXO性能权衡
    ARM64 MMU 映射
    [前端基础] JavaScript 基础篇(下)
    windows10连wifi提示“无Internet,开放”
    yolov8旋转目标检测部署教程(附代码c++/python)
    Docker的使用
    使用容器编译Yocto镜像
    汽车屏类产品(二):360全景环视(SVC)、多分割显示、行车记录
    交换机与路由器技术-33-静态NAT
  • 原文地址:https://blog.csdn.net/m0_67038390/article/details/132988250