記錄使用echarts的graph類型繪制流程圖全過程(二)- 多層關系和圓形圖片的設置


本文主要記錄在使用echarts的graph類型繪制流程圖時候遇到的2個問題:對於圓形圖片的剪切和多層關系的設置

圖片的設置

如果用echarts默認的symbol參數來顯示圖片,會顯示圖片的原始狀態,即圓形就顯示圓形的,矩形就顯示矩形的,而案例中的圖片是矩形的(如上圖所示)。但是尼,我們在流程圖的繪制過程中,一般用到的又是圓形,所以這時候就需要我們自己進行剪切了。主要運用cavans的clip功能,以下是具體的代碼實現:

       let picList = [];
        let tempNodes = [];

        for (let i in this.nodesObj) {
          let item = this.nodesObj[i];
          // 設置已知的信息
          let obj = {
            x: item.x,
            y: item.y,
            name: item.name,
            id: item.id,
            symbolSize: this.size,
            category:
              item.id === this.startNode || item.id === this.endNode ? 0 : 1
          };
          
          // 如果有圖標信息,進行圖片處理,沒有的直接放到節點信息中
          if (item.icon) {
            let p = this.getImgData(item.icon);
            picList.push(p);
            tempNodes.push(obj);
          } else {
            this.nodes.push(obj);
          }
        }
        
        // 將圖片處理放在promise中,然后使用promise.all,當所有的圖片都剪切完畢后,賦值
        if (picList.length > 0) {
          let that = this;
          Promise.all(picList).then(images => {
            for (let i = 0, len = tempNodes.length; i < len; i++) {
              tempNodes[i].symbol = 'image://' + images[i];
              that.nodes.push(tempNodes[i]);
            }
            // console.log(this.nodes);

            // 再設置節點
            that.setLinks();

            // 把數據設置到Echart中data
            if (this.graphChart) {
              var option = this.graphChart.getOption();
              option.series[0].nodes = this.nodes;
              option.series[0].links = this.links;

              this.graphChart.setOption(option);
            }
          });
        } else {
          // 設置節點
          this.setLinks();
        }
// 獲取icon的圖片信息
    getImgData (imgSrc) {
      var fun = function (resolve) {
        const canvas = document.createElement('canvas');
        const contex = canvas.getContext('2d');
        const img = new Image();

        img.crossOrigin = '';
        img.onload = function () {
          // 設置圖形寬高比例
          let center = {
            x: img.width / 2,
            y: img.height / 2
          };
          let diameter = img.width;
          let radius = diameter / 2; // 半徑

          canvas.width = diameter;
          canvas.height = diameter;
          contex.clearRect(0, 0, diameter, diameter);
          contex.save();

          contex.beginPath();
          contex.arc(radius, radius, radius, 0, 2 * Math.PI); // 畫出圓
          contex.clip();

          contex.drawImage(
            img,
            center.x - radius,
            center.y - radius,
            diameter,
            diameter,
            0,
            0,
            diameter,
            diameter
          ); // 在剛剛裁剪的園上畫圖
          contex.restore(); // 還原狀態

          resolve(canvas.toDataURL('image/png', 1));
        };
        img.src = imgSrc;
      };
      var promise = new Promise(fun);
      return promise;
    }

實現效果:

多關系合並

echarts的關系最多支持2條顯示,所以當2個節點之間存在多個關系的時候,可以把同一個指向的關系合並到一起如下圖,周傑倫與劉德華的關系是偶像和同窗,劉德華和周傑倫的關系是好友

也就是獲取兩個節點之間同方向的線條的關系,然后進行合並,再顯示在一條關系線上即可。

// 設置線條
    setLinks () {
      this.links = [];
      this.relationList.forEach(item => {
        let obj = {
          source: item.source,
          target: item.target,
          value: item.relName,
          label: {
            show: true,
            formatter: '{c}'
          }
        };

        if (item.sameTotal >= 2) {
          let hasLink = this.links.find(link => {
            if (link.source === item.source && link.target === item.target) {
              return true;
            }
          });

          if (!hasLink) {
            let res = this.findSameLinkRelation(
              item.source,
              item.target,
              item.sameTotal
            );
            obj.value = res.value;
            if (res.setLineStyle) {
              obj.lineStyle = {
                normal: {
                  curveness: 0.2
                }
              };
            }
            this.links.push(obj);
          }
        } else {
          this.links.push(obj);
        }
      });
}
findSameLinkRelation (sid, tid, total) {
      let value = [];
      let setLineStyle = true;

      this.relationList.forEach(item => {
        if (item.source === sid && item.target === tid) {
          value.push(item.relName);
        }
      });

      if (total === value.length) {
        setLineStyle = false;
      }

      value = value.join('、');
      return {
        value,
        setLineStyle
      };
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM