openlayers 结合echart 完成交互事件

前言:事先说明,以下相关代码实现了点击echart中的series line ,也就是那种标记点 包括label,然后在地图中显示该数据。同时由于封装有相关的方法我也不想写的又臭又长,希望你们能从代码中有些收获,你不能直接拿来就用,如果觉得我的思路还可以请结合自身业务进行改动,这里先交代一下我的业务:点击echart中的标记点后,在地图的要素位置中显示该数值。这其中由于这个feature里面已经存在text,所以得额外的去增加text,看图。
在这里插入图片描述
这个实现的思路让我思考了几个小时,先说说思考的路程,首先我是打算尝试一下能不能通过在Style里新增多一个newText 通过偏移去实现,如果这样能行那是最好不过的:我只需要直接控制这个已有的feature样式即可。不过很显然,这个尝试失败了。
接着我去网上搜索查看别人是怎么实现的,有直接添加一个图层的,但那样子我总感觉会有效率问题,于是想尝试别的方法。
在这里插入图片描述
这是当时去自己理解的,希望能对我接下来的代码内容有所帮助。我是在该图层中添加多一个feature,同时根据接口数据的optid设定一个唯一的id,然后在echart的点击回调中找到这个feature 对它进行设置style 让他展示。

其中最核心的需要理解的一个点在于在echart中的点击回调函数中,这个函数只能依赖于当前组件中保存的状态。我们需要在接收到点击之前将数据(如需要被渲染的feature)保存好,这就是核心。

监听事件

// chart 监听点击事件、 相关的元素是 series中的line  传进来的参数是一个包含该图表的信息对象
tempChart.on("click", "series.line", function (params) {
            let tempText = params.data;
            let featureId = _this.obtData[_this.obtDataIndex].obtid;
            _this.obtSource
              .getFeatureById(featureId)
              .setStyle(_this.autoStationStyle2(tempText + ""));
            _this.obtSource.getFeatureById(featureId).changed();
          });
          // 标注样式2 点击echart 中的数据点后 相关的差别在于 多出一个 text Style
    autoStationStyle2: function (data) {
      //返回一个样式
      return new Style({
        //文本样式
        text: new Text({
          textAlign: "center", //对齐方式
          textBaseline: "middle", //文本基线
          font: "normal 10px 微软雅黑", //字体样式
          text: data, //文本内容
          offsetY: -20, // Y轴偏置
          fill: new Fill({
            //填充样式
            color: "#ffffff",
          }),
          padding: [2, 5, 2, 5],
        }),
        zIndex: 200,
      });
    },

ol的相关事件

//  自动站数据初始化
    autoStationDataInit: async function () {
      let _this = this;
      // 需要通过 获取 工厂的点  确定需要绘制的自动站点
      const { data: factory } = await getFactoryConfigData();
      let obtids = factory?.obtid;
      const { data: obtMinut } = await getobtMinutData();
      const { data: slice } = await getRainfallHourSlideData();
      const { data: baoganggeo } = await getBaogangGeoData();
      let coordArray = baoganggeo.features[0].geometry.coordinates[0];

      // 保存在该组件的数据
      this.ddatetime = slice.ddatetime;
      this.times = slice.times;

      let needShowStationData = [];
      let stationData = [];
      for (let i = 0; i < obtids.length; i++) {
        for (let j = 0; j < obtMinut.length; j++) {
          if (obtids[i] == obtMinut[j].obtid) {
            needShowStationData.push(obtMinut[j]);
            stationData.push(slice.data[obtids[i]]);
            break;
          }
        }
      }
      this.obtData = needShowStationData;
      let positions = [];
      for (let i in needShowStationData) {
        let curData = needShowStationData[i];
        let [lon, lat] = [curData.lon, curData.lat];
        positions.push([lon, lat]);
      }
      // 这个闭包函数 借用 当前的 needshowData  这个data 没必要保存起来 使用 故。
      function autoStationCallback(feature, index) {
        // 相关的 操作 解释: factory 设定状态  设定名字 用于text展示 设置imgsrc 设置 一个是站点的信息 一个是实况的信息;
        feature.setProperties(
          {
            factory: true,
            name: needShowStationData[index].obtname,
            img: require("../../assets/images/mapmark4.png"),
            data: needShowStationData[index],
            stationChartsData: stationData[index],
            index: index,
          },
          true
        );
        feature.setStyle(_this.autoStationStyle1(feature));
      }
      // 这个函数是用于对temp text 设置属性的
      function autoStationCallback2(feature, index) {
        // 经过尝试  setProperties 可以批量设置故
        feature.setProperties(
          {
            factoryTempText: true,
            data: needShowStationData[index],
            stationChartsData: stationData[index],
            index: index,
          },
          true
        );
        feature.setStyle(null);
        // 设置一个ID  用于 点击echart的数据点后操作这个feature
        feature.setId(needShowStationData[index].obtid);
      }
      let features = this.mapObj.drawPoint(positions, autoStationCallback);
      let featuresByText = this.mapObj.drawPoint(
        positions,
        autoStationCallback2
      );
      let featurePolygon = this.mapObj.drawPolygon(coordArray[0]);

      features = features.concat(featuresByText).concat(featurePolygon);
      let source = this.mapObj.createVectorSource();
      let layer = this.mapObj.createVectorLayer();
      source.addFeatures(features);

      // 取消layer的默认样式  同时也将temptext 一开始的样式设置为null 达到隐藏默认的style 信息  通过重新设置style 让他显示
      layer.setStyle(null);
      featurePolygon.setStyle(this.areaPolygonStyle());
      layer.setSource(source);
      this.obtSource = source;
      this.map2d.addLayer(layer);
    },
    // 标注样式1 未被点击echart 中的数据点前
    autoStationStyle1: function (feature) {
      //返回一个样式
      return new Style({
        //图标样式
        image: new Icon({
          anchor: [0.5, 1], //设置图标偏移
          scale: 0.14, // 图标缩小显示
          // anchorOrigin: "top-left", //标注样式的起点位置
          anchorXUnits: "fraction", //X方向单位:分数
          anchorYUnits: "fraction", //Y方向单位:像素
          // offsetOrigin: "top-left", //偏移起点位置的方向
          // offset: [12.8,25.6],
          opacity: 1, //透明度
          src: feature.get("img"), //图片路径
          // size: [300,300],
        }),
        //文本样式
        text: new Text({
          textAlign: "center", //对齐方式
          textBaseline: "middle", //文本基线
          font: "normal 12px 微软雅黑", //字体样式
          text: feature.get("name"), //文本内容
          offsetY: -50, // Y轴偏置
          fill: new Fill({
            //填充样式
            color: "#ffffff",
          }),
          backgroundFill: new Fill({
            // 填充背景
            color: "rgba(0, 0, 0, 0.6)",
          }),
          padding: [2, 5, 2, 5],
        }),
        // 设置层级
        zIndex: 199,
      });
    },

太长了,我就说明一下这其中的逻辑,首先画出相关的要素的点,通过在第一个要素图标设置相关属性,关注点在第二个要素相关属性:我们需要 index ,这个index用于我们去找到在接口数据中的optid,然后我们可以根据这个optid找到我们需要变更的feature。通过设置style让他显示就可以了。但得注意首先得让该图层的style变为null,通过重新setStyle达到一开始隐藏默认样式的效果,算是一种取巧的方式实现吧。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值