伪3D地图和3D饼图实现

页面的核心功能开发:地图的伪3D效果和3D饼图

一、3D地图实现与优化:

1. 技术实现方案

不依赖ECharts-GL,降低硬件要求,实现伪3D效果,自定义的视觉样式和交互体验。

基于 :ECharts多层geo和map组件叠加技术

核心思路 :通过三层结构(一个map图层+两个geo图层)模拟3D立体效果。

javascript 复制代码
// 三层地图结构配置
geo: [
  { // 上层地图 - 主体视觉层
    z: 2,
    map: 'my',
    roam: true,
    zoom: 1,
    layoutCenter: ['50%', '49%'],
    layoutSize: '88%',
    itemStyle: {
      shadowColor: "#1893e8",
      shadowOffsetX: 0,
      shadowOffsetY: 10,
      shadowBlur: 10
    }
  },
  { // 下层地图 - 阴影增强层
    z: 1,
    map: 'my',
    roam: true,
    zoom: 1,
    layoutCenter: ['50%', '49%'],
    layoutSize: '88%',
    itemStyle: {
      shadowColor: '#fff',
      borderColor: '#fff',
      borderWidth: 2,
      shadowOffsetY: 12,
      opacity: 1
    }
  }
],
series: [ // 数据交互层
  {
    type: 'map',
    mapType: 'my',
    roam: true,
    selectedMode: 'single',
    layoutCenter: ['50%', '49%'],
    layoutSize: '88%',
    zoom: 1
    // ... 数据和样式配置
  }
]

2. 关键技术点

  • 立体效果 :通过z轴层级、阴影偏移量和模糊度实现

  • 区域样式 :自定义背景图片、边框颜色和宽度

  • 交互功能 :支持区域选择、高亮和名称显示

    javascript 复制代码
    itemStyle: {
      areaColor: { // 地图背景图片
        image: img,
        repeat: 'no-repeat'
      },
      borderColor: '#cedef4',
      borderWidth: 1,
      shadowColor: 'transparent',
      shadowBlur: 0
    },
    emphasis: { // 鼠标悬停效果
      itemStyle: {
        areaColor: 'rgba(38, 61, 244, .8)',
      }
    }

3. 遇到的问题与解决方案

问题1:Label重叠问题

  • 背景 :天津地图中间区域(如和平区、河西区等)面积小、区域密集,直接显示分公司标签会严重重叠

  • 解决方案 :通过data数组为每个区域单独设置label偏移量

  • 实现代码 :

javascript 复制代码
data: [
  { name: '河北区', label: { offset: [that.WidthAdaptive(-55), that.WidthAdaptive(-10)] } },
  { name: '河东区', label: { offset: [that.WidthAdaptive(50), that.WidthAdaptive(-15)] } },
  { name: '南开区', label: { offset: [that.WidthAdaptive(-60), 0] } },
  { name: '东丽区', label: { offset: [that.WidthAdaptive(40), that.WidthAdaptive(12)] } },
  // ...其他区域
],

问题2:多层地图同步问题

  • 背景 :缩放或平移时,多层地图需要保持同步

  • 解决方案 :监听georoam事件,同步更新各图层的zoom和center属性.

    javascript 复制代码
    myChart.on('georoam', function (params) {
      var option = myChart.getOption();
      if (params.zoom != null) {
        // 同步缩放
        option.geo[0].zoom = option.series[0].zoom;
        option.geo[1].zoom = option.series[0].zoom;
        // 同步中心点
        option.geo[0].center = option.series[0].center;
        option.geo[1].center = option.series[0].center;
      } else {
        // 同步平移
        option.geo[0].center = option.series[0].center;
        option.geo[1].center = option.series[0].center;
      }
      myChart.setOption(option);
    });

问题3:响应式适配

  • 背景 :大屏幕不同分辨率下的显示效果不一致

  • 解决方案 :实现WidthAdaptive函数动态调整元素大小

    javascript 复制代码
    WidthAdaptive(res) {
      var windth = window.innerWidth;
      let fontSize = windth / 1920;
      return fontSize * res;
    }

4. 实现效果

二、3D饼图实现与优化

1. 技术实现方案

基于 :HighCharts + highcharts-3d插件

核心思路 :利用HighCharts原生3D支持实现立体饼图效果

javascript 复制代码
// 3D饼图基础配置
this.mychart = HighCharts.chart('echart-container', {
  chart: {
    type: 'pie',
    backgroundColor: 'transparent',
    options3d: {
      enabled: true,
      alpha: 60,  // 内旋转角度
      beta: 0     // 外旋转角度
    }
  },
  plotOptions: {
    pie: {
      size: this.WidthAdaptive(80),
      depth: this.WidthAdaptive(8), // 3D深度
      center: ['60%', '50%']
    }
  }
  // ... 数据和样式配置
});

2. 关键技术点

  • 3D效果 :通过depth属性控制立体深度

  • 图例定制 :支持HTML格式化的复杂图例样式

  • 数据标签 :个性化的百分比显示

  • 响应式设计 :窗口大小变化时自动调整

3. 核心问题与解决方案

问题1:图例样式复杂

  • 背景 :需要显示多层数据(名称、金额、用户数)

  • 解决方案 :使用useHTML:true,自定义HTML模板

javascript 复制代码
legend: {
  useHTML: true,
  labelFormat: '<div class="legend-box"><p>{name}<span><i>{y}</i>万</span></p><p>用户数<span><i>1.23</i>万人</span></p></div>'
}

问题2:性能优化

  • 背景 :窗口大小变化时频繁重绘影响性能

  • 解决方案 :使用debounce函数优化重绘频率

    javascript 复制代码
    // 窗口大小变化处理 - 防抖优化
    handleResize: debounce(() => {
      if (this.mychart) {
        this.mychart.destroy();
        this.init();
      }
    }, 100)

4. 技术优势

  • 原生3D支持,实现简单高效

  • 高度自定义的图例和数据标签

  • 完善的响应式适配机制

相关推荐
代码匠心19 小时前
AI 自动编程:一句话设计高颜值博客
前端·ai·ai编程·claude
_AaronWong20 小时前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode20 小时前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户54330814419421 小时前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo21 小时前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭21 小时前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木21 小时前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮21 小时前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github
UrbanJazzerati21 小时前
Vue3 父子组件通信完全指南
前端·面试
是一碗螺丝粉21 小时前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain