charts3D地球--添加航线

要在地球视角下画出海运路线图

方案

  1. 添加 globl 地球
  2. 创建geo地理坐标系
  3. 创建canvas对象用于承载地图世界地图this.worldChart
javascript 复制代码
//初始化canvas节点
      let cav = document.createElement("canvas");
      this.$echarts.registerMap("world", geoJson);
      this.worldChart = this.$echarts.init(cav, null, {
        width: 4096,
        height: 2048,
      });
      this.worldChart.setOption(this.worldChartOption);
  1. 设置globl 的baseTexture为this.worldChart
  2. 添加lines3D飞线效果

上组件源码

javascript 复制代码
<template>
  <div>
    <div id="box" @click="showAll"></div>
  </div>
</template>
<script>
import geoJson from "./mapJson.js";
import { nameMap, startPoint, changKu, chuan, gongChang } from "./data.js";
import { points, line } from "./lines.js";
export default {
  data() {
    return {
      worldChart: null,
      // map贴图配置
      worldChartOption: {
        backgroundColor: "rgba(3,28,72,1)",
        // backgroundColor: "transparent",
        geo: {
          type: "map",
          map: "world",
          nameMap: nameMap,
          left: 0,
          top: 0,
          right: 0,
          bottom: 0,
          boundingCoords: [
            [-180, 90],
            [180, -90],
          ],
          zoom: 0,
          roam: true,
          itemStyle: {
            areaColor: "#174f87", //地图区域的颜色
            color: "#fff", //图形的颜色
            borderColor: "#2578cb",
            opacity: 0.9,
          },
          emphasis: {
            //高亮状态下的多边形和标签样式
            itemStyle: {
              areaColor: "#31deff",
              color: "#174f87",
              borderColor: "#318ED2",
              borderWidth: 2,
              shadowColor: "#15629A",
              shadowBlur: 1,
              shadowOffsetX: 3,
              shadowOffsetY: 5,
            },
          },
          label: {
            fontSize: 28,
          },
        },
        series: [],
      },
      globleChart: null,
      // 地球配置
      globleChartOption: {
        globe: {
          show: true,
          globeRadius: 120,
          globeOuterRadius: 150,
          // baseTexture: require("./assets/earth.jpg"),
          // environment: require("@/assets/img/bg.png"),
          environment: require("./assets/starfield.jpg"),
          shading: "lambert",
          zlevel: 10,
          light: {
            ambient: {
              // 设置环境光
              intensity: 1,
            },
            main: {
              // 设置主光源
              intensity: 1.6,
              shadow: false, // 开启阴影
            },
          },
          atmosphere: {
            show: true,
            offset: 6,
            color: "rgba(61,149,248,0.6)",
            glowPower: 5,
            innerGlowPower: 8,
          },

          viewControl: {
            distance: 240,
            autoRotate: true,
            // 开启球体自旋转
            // 设置地球的自转速度: 单位为 度/秒,默认值为10,也就是36秒转一圈!
            autoRotateSpeed: 5,
            // 在鼠标停止操纵后,球体恢复自转的事件
            autoRotateAfterStill: 5,
          },
        },
        series: [],
      },
    };
  },
  mounted() {
    this.initData();
  },
  methods: {
    // 绘制图表
    initData() {
      //初始化canvas节点
      let cav = document.createElement("canvas");
      this.$echarts.registerMap("world", geoJson);
      this.worldChart = this.$echarts.init(cav, null, {
        width: 4096,
        height: 2048,
      });

      this.worldChart.setOption(this.worldChartOption);
      this.globleChart = this.$echarts.init(document.getElementById("box"));

      // // 指定图标的配置项和数据
      this.globleChartOption.globe.baseTexture = this.worldChart;
      this.globleChart.setOption(this.globleChartOption, true);
      // 初始化点和路线
      this.addLines(line);
      this.addPoint(points);
      this.worldChart.on("click", (params) => {
        console.log(params);
      });
      this.globleChart.on("click", (params) => {
        console.log(params);
      });
    },
    // 添加路线
    addLines(list) {
      // 路线
      // 获取飞线两端点
      let flyLineList = [];
      list.forEach((li) => {
        for (let index = 0; index < li.coords.length - 1; index++) {
          flyLineList.push({
            coords: [li.coords[index], li.coords[index + 1]],
            // 数据值
            value: "",
          });
        }
      });
      const luxian = {
        type: "lines",
        // type: "lines3D",
        id: "line",
        coordinateSystem: "geo",
        // coordinateSystem: "globe",
        blendMode: "lighter",
        polyline: true,
        zlevel: 10,
        effect: {
          show: true,
          period: 4, //速度
          trailLength: 0.2, //尾部阴影
        },
        lineStyle: {
          //航线的视图效果
          color: "#CCA343",
          width: 4,
          curveness: 0.5,
          opacity: 0.4,
        },

        // convertData
        data: list,
        // data: flyLineList,
      };
      // 路线上的点
      let startPoint = []; // 取第一个点作为仓库
      let endPoint = []; // 取最后一个作为起工厂
      let chuanPoint = []; // 取中间点作为轮船
      list.forEach((el) => {
        el.coords.forEach((em, i) => {
          if (i === 0) {
            const haveSamePoint = startPoint.find(
              (item) => item && item.name == el.name.split("-")[0]
            );
            if (!haveSamePoint) {
              startPoint.push({
                name: el.name.split("-")[0],
                value: em,
                symbolSize: 30,
                symbol: changKu,
              });
            }
          } else if (i === el.coords.length - 1) {
            const haveSamePointEnd = endPoint.find(
              (item) => item && item.name == el.name.split("-")[1]
            );
            if (!haveSamePointEnd) {
              endPoint.push({
                name: el.name.split("-")[1],
                value: em,
                symbolSize: 30,
                symbol: gongChang,
              });
            }
          } else {
            chuanPoint.push({
              name: "",
              value: em,
              symbolSize: 60,
              symbol: chuan,
            });
          }
        });
      });
      const linePoint = {
        // type: "scatter3D",
        // type: "effectScatter",
        type: "scatter",
        id: "onlinePoint",
        coordinateSystem: "geo",
        zlevel: 16,
        rippleEffect: {
          brushType: "stroke",
        },
        label: {
          fontSize: 16,
          show: true,
          position: "right",
          formatter: "{b}",
        },
        itemStyle: {
          normal: {
            color: "#f5f802",
          },
        },
        data: [...startPoint, ...endPoint, ...chuanPoint],
      };
      console.log([...startPoint, ...endPoint, ...chuanPoint], 787);

      // this.updataGlobleSerise("line", luxian);

      this.updataSerise("line", luxian);
      this.updataSerise("onlinePoint", linePoint);

      setTimeout(() => {
        this.updataChart();
      }, 10);
    },
    // 添加标点
    addPoint(list) {
      const areaPion = {
        type: "effectScatter",
        // type: "scatter3D",
        // type: 'scatter',
        id: "areaPoint",
        coordinateSystem: "geo", //globe
        zlevel: 11,
        symbol: startPoint,
        rippleEffect: {
          brushType: "stroke",
        },
        label: {
          fontSize: 18,
          show: true,
          position: "right",
          formatter: "{b}",
        },
        itemStyle: {
          normal: {
            color: "#f5f802",
          },
        },
        data: list,
      };
      this.updataSerise("areaPoint", areaPion);
      // this.updataGlobleSerise("areaPoint", areaPion);

      setTimeout(() => {
        this.updataChart();
        this.changeView();
      }, 10);
    },
    updataGlobleSerise(id, item) {
      let ind = this.globleChartOption.series.findIndex((el) => el.id === id);
      if (ind > -1) {
        this.globleChartOption.series[ind] = item;
      } else {
        this.globleChartOption.series.push(item);
      }
    },
    updataSerise(id, item) {
      let ind = this.worldChartOption.series.findIndex((el) => el.id === id);
      if (ind > -1) {
        this.worldChartOption.series[ind] = item;
      } else {
        this.worldChartOption.series.push(item);
      }
    },

    // 更新
    updataChart() {
      this.worldChart.setOption(this.worldChartOption);
      this.globleChart.setOption(this.globleChartOption, true);
    },
    showAll() {
      this.$emit("no-act");
    },
    // 切换视角依据国家名称
    changeViewByCountry(country) {
      const targ = points.find((el) => el.name == country);
      if (targ) {
        this.changeView(targ.value);
      }
    },
    // 切换视角
    changeView(point) {
      // 定位到北京
      let coord = point || [116.46, 39.92];
      this.globleChartOption.globe.viewControl.targetCoord = coord;
      this.globleChart.setOption(this.globleChartOption);
    },
    resize() {
      this.worldChart.resize();
      this.globleChart.resize();
    },
  },
  watch: {},
  created() {},
};
</script>

<style scoped>
#box {
  width: 100vw;
  height: 100vh;
}
.tootipbox {
  position: fixed;
  left: 50%;
  top: 500%;
  z-index: 9999;

  background-image: url("../../../../assets/img/screen6/label_bg.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  width: 200px;
  height: 125px;
  background-position: center center;
  padding: 10px 20px;
  font-size: 10px;
}
</style>
相关推荐
mirrornan4 小时前
3D和AR技术在电商行业的应用有哪些?
3d·ar·3d建模·3d模型·三维建模
工业3D_大熊6 小时前
3D开发工具HOOPS助力造船业加速设计与数字化转型
3d
zaf赵6 小时前
3D 高斯溅射 (Gaussian Splatting)技术,一种实现超写实、高效渲染的突破性技术
3d
前端Hardy10 小时前
HTML&CSS:酷炫的3D开关控件
前端·javascript·css·3d·html
Debroon1 天前
M3D: 基于多模态大模型的新型3D医学影像分析框架,将3D医学图像分析从“看图片“提升到“理解空间“的层次,支持检索、报告生成、问答、定位和分割等8类任务
3d
广东数字化转型2 天前
Three.js相机Camera控件知识梳理
3d·three.js
CASAIM2 天前
模具制造之三维扫描和逆向建模
目标检测·3d·汽车·制造
工业3D_大熊2 天前
HOOPS Communicator功能剖析:3D Web模型树交互的实用指南!
linux·windows·macos·3d·docker·c#·.net
番茄电脑全能王2 天前
电脑玩《刺客信条》时中,遇到找不到d3dx9_42.dll的问题是什么原因?缺失d3dx9_42.dll应该怎么解决呢?下面一起来看看吧!
3d
战场小包3 天前
小米su7 or 保时捷怎么选?使用 Three 实现 3D 汽车展示平台比比看
前端·vue.js·3d·aigc