美文网首页
动态词云图

动态词云图

作者: 衬fzy | 来源:发表于2024-01-31 09:11 被阅读0次
微信截图_20240223171340.png

引入使用必须is模式才可以清除之前的效果!调整两个样式搜索:“圆的大小”“字体大小”

<component :is="activeComponentName" :datas="right4Data" />
import Word3D from './components/Word3D'

activeComponentName: '',
right4Data: {},

//开始请求部分
this.activeComponentName = '';
let arr = []
daPing({ act: 'szClueKeyList' }).then((res) => {
        res.data.forEach((v) => {
          arr.push({ name: v.keyword, value: v.number })
        })
        this.right4Data = arr
        this.activeComponentName = 'Word3D';
})

组件

<template>
  <section class="cloud-bed">
    <div class="cloud-box">
      <span v-for="(item, index) in dataList" :key="index" :style="{ color: item.code, background: item.background }"
        @click="getDataInfo(item)">
        {{ item.name }}
      </span>
    </div>
  </section>
</template>

<script>
export default {
  name: "WordCloud",
  props: {
    datas: {
      type: [Array, Object],
      default: null
    }
  },
  data() {
    return {
      timer: 50, //
      radius: 0, //
      dtr: 0.008, // 鼠标滑过球体转动速度:0.005到0.1
      active: false, // 默认加载是否开启转动
      lasta: 0.2, // 上下转动
      lastb: 0.5, // 左右转动
      distr: true,
      tspeed: 0, // 鼠标移动上去时球体转动
      mouseX: 0,
      mouseY: 0,
      tagAttrList: [],
      tagContent: null,
      cloudContent: null,
      sinA: '',
      cosA: '',
      sinB: '',
      cosB: '',
      sinC: '',
      cosC: '',
      dataList: [
      ]
    }
  },
  watch: {
    // 这是监听json值变化
    datas: {
      // json为监听参数名
      handler: function (val, oldVal) {
        let arr = []
        this.dataList = []
        clearInterval(this.timer)
        let getRandomColor = function () {
          var r = Math.floor(Math.random() * 256);
          var g = Math.floor(Math.random() * 256);
          var b = Math.floor(Math.random() * 256);
          return {
            code: "rgba(" + r + "," + g + "," + b + ",1)",
            back: "rgba(" + r + "," + g + "," + b + ",0.1)"
          };
        }
        val.forEach((v) => {
          if (v.keyword != '') {
            let c = getRandomColor()
            arr.push({ name: v.name, value: v.value, background: c.back, code: c.code })
          }
        })
        this.dataList = arr
        if (this.dataList.length > 0) {
          this.$nextTick(() => {
            this.radius = document.querySelector('.cloud-box').offsetWidth / 2
            this.initWordCloud()
          })
        }
      },
      immediate: true
    }
  },
  mounted() {
  },
  beforeDestroy() {
    clearInterval(this.timer)
  },
  methods: {
    // 获取点击文本信息
    getDataInfo(item) {
      console.log(item, 'item')
    },
    initWordCloud() {
      this.cloudContent = document.querySelector('.cloud-box');
      this.tagContent = this.cloudContent.getElementsByTagName('span');
      for (let i = 0; i < this.tagContent.length; i++) {
        let tagObj = {};
        tagObj.offsetWidth = this.tagContent[i].offsetWidth;
        tagObj.offsetHeight = this.tagContent[i].offsetHeight;
        this.tagAttrList.push(tagObj);
      }
      this.sineCosine(0, 0, 0);
      this.positionAll();
      this.cloudContent.onmouseover = () => {
        this.active = true;
      };
      this.cloudContent.onmouseout = () => {
        this.active = false;
      };
      this.cloudContent.onmousemove = (ev) => {
        let oEvent = window.event || ev;
        this.mouseX = oEvent.clientX - (this.cloudContent.offsetLeft + this.cloudContent.offsetWidth / 2);
        this.mouseY = oEvent.clientY - (this.cloudContent.offsetTop + this.cloudContent.offsetHeight / 2);
        this.mouseX /= 5;
        this.mouseY /= 5;
      };
      setInterval(this.update, this.timer);
    },
    positionAll() {
      let phi = 0;
      let theta = 0;
      let max = this.tagAttrList.length;
      let aTmp = [];
      let oFragment = document.createDocumentFragment();
      // 随机排序
      for (let i = 0; i < this.tagContent.length; i++) {
        aTmp.push(this.tagContent[i]);
      }
      aTmp.sort(() => {
        return Math.random() < 0.5 ? 1 : -1;
      });
      for (let i = 0; i < aTmp.length; i++) {
        oFragment.appendChild(aTmp[i]);
      }
      this.cloudContent.appendChild(oFragment);
      for (let i = 1; i < max + 1; i++) {
        if (this.distr) {
          phi = Math.acos(-1 + (2 * i - 1) / max);
          theta = Math.sqrt(max * Math.PI) * phi;
        } else {
          phi = Math.random() * (Math.PI);
          theta = Math.random() * (2 * Math.PI);
        }
        // 坐标变换
        this.tagAttrList[i - 1].cx = this.radius * Math.cos(theta) * Math.sin(phi);
        this.tagAttrList[i - 1].cy = this.radius * Math.sin(theta) * Math.sin(phi);
        this.tagAttrList[i - 1].cz = this.radius * Math.cos(phi);
        this.tagContent[i - 1].style.left = this.tagAttrList[i - 1].cx + this.cloudContent.offsetWidth / 2 - this.tagAttrList[i - 1].offsetWidth / 2 + 'px';
        this.tagContent[i - 1].style.top = this.tagAttrList[i - 1].cy + this.cloudContent.offsetHeight / 2 - this.tagAttrList[i - 1].offsetHeight / 2 + 'px';
      }
    },
    update() {
      let angleBasicA;
      let angleBasicB;

      if (this.active) {
        angleBasicA = (-Math.min(Math.max(-this.mouseY, -200), 200) / this.radius) * this.tspeed;
        angleBasicB = (Math.min(Math.max(-this.mouseX, -200), 200) / this.radius) * this.tspeed;
      } else {
        angleBasicA = this.lasta * 0.98;
        angleBasicB = this.lastb * 0.98;
      }

      // 默认转动是后是否需要停下
      // lasta=a;
      // lastb=b;

      // if(Math.abs(a)<=0.01 && Math.abs(b)<=0.01)
      // {
      // return;
      // }
      this.sineCosine(angleBasicA, angleBasicB, 0);
      for (let j = 0; j < this.tagAttrList.length; j++) {
        let rx1 = this.tagAttrList[j].cx;
        let ry1 = this.tagAttrList[j].cy * this.cosA + this.tagAttrList[j].cz * (-this.sinA);
        let rz1 = this.tagAttrList[j].cy * this.sinA + this.tagAttrList[j].cz * this.cosA;

        let rx2 = rx1 * this.cosB + rz1 * this.sinB;
        let ry2 = ry1;
        let rz2 = rx1 * (-this.sinB) + rz1 * this.cosB;

        let rx3 = rx2 * this.cosC + ry2 * (-this.sinC);
        let ry3 = rx2 * this.sinC + ry2 * this.cosC;
        let rz3 = rz2;
        this.tagAttrList[j].cx = rx3;
        this.tagAttrList[j].cy = ry3;
        this.tagAttrList[j].cz = rz3;

        let per = 0.8;// 字体大小
        // let per = 350 / (350 + rz3);

        this.tagAttrList[j].x = rx3 * per - 2;
        this.tagAttrList[j].y = ry3 * per;
        this.tagAttrList[j].scale = per;
        this.tagAttrList[j].alpha = per;

        this.tagAttrList[j].alpha = (this.tagAttrList[j].alpha - 0.6) * (10 / 6);
      }
      this.doPosition();
      this.depthSort();
    },
    doPosition() {
      let len = this.cloudContent.offsetWidth / 2;
      let height = this.cloudContent.offsetHeight / 2;
      for (let i = 0; i < this.tagAttrList.length; i++) {
        this.tagContent[i].style.left = this.tagAttrList[i].cx + len - this.tagAttrList[i].offsetWidth / 2 + 'px';
        this.tagContent[i].style.top = this.tagAttrList[i].cy + height - this.tagAttrList[i].offsetHeight / 2 + 'px';
        // this.tagContent[i].style.fontSize = Math.ceil(12 * this.tagAttrList[i].scale/2) + 8 + 'px';
        this.tagContent[i].style.fontSize = Math.ceil(12 * this.tagAttrList[i].scale / 2) + 10 + 'px';
        this.tagContent[i].style.filter = "alpha(opacity=" + 100 * this.tagAttrList[i].alpha + ")";
        // this.tagContent[i].style.opacity = this.tagAttrList[i].alpha + 0.5;
        this.tagContent[i].style.opacity = 1
      }
    },
    depthSort() {
      let aTmp = [];
      for (let i = 0; i < this.tagContent.length; i++) {
        aTmp.push(this.tagContent[i]);
      }
      aTmp.sort((item1, item2) => item2.cz - item1.cz);
      for (let i = 0; i < aTmp.length; i++) {
        aTmp[i].style.zIndex = i;
      }
    },
    sineCosine(a, b, c) {
      this.sinA = Math.sin(a * this.dtr);
      this.cosA = Math.cos(a * this.dtr);
      this.sinB = Math.sin(b * this.dtr);
      this.cosB = Math.cos(b * this.dtr);
      this.sinC = Math.sin(c * this.dtr);
      this.cosC = Math.cos(c * this.dtr);
    }
  }
};
</script>

<style scoped>
.cloud-bed {
  width: 100%;
  height: 100%;
}

.cloud-box {
  position: relative;
  width: 100%;
  height: 100%;
  background: #00000000;
}

.cloud-box span {
  position: absolute;
  padding: 3px 6px;
  top: 0px;
  font-weight: bold;
  text-decoration: none;
  left: 0px;
  background-image: linear-gradient(to bottom, red, #fff);
  background-clip: text;
  color: transparent;
  /* 圆的大小 */
  width: 50px;
  height: 50px;
  border-radius: 50%;
  text-align: center;

  display: flex;
  align-items: center;
  justify-content: center;

  /* line-height: 50px;
      overflow:hidden;
      white-space: nowrap;
      text-overflow: ellipsis; */
}
</style>

相关文章

  • Python 画好看的云词图

    一、词云图 (WordCloud) 词云图是数据分析中比较常见的一种可视化手段。词云图,也叫文字云,是对文本中出现...

  • 词云图

    Python2.7wordcloud- 英文,jieba-中文,但是不严谨matplotlibjieba 词云图,...

  • 词云图

    词云图 词云图是一款可以将文章内容转为词云图的小工具,可以用于制作ppt、统计分析等。app简约、免费、无广告,快...

  • 【10分钟】如何快速生成词云图(Word Cloud)

    你是不是也见过高大上的词云图呢? 词云图,就是文字云,是对文本中出现频率较高的关键词予以视觉化的展现,词云图过滤掉...

  • 利用简书首页文章标题数据生成词云

    1.词云图 词云图,也叫文字云,是对文本中出现频率较高的“关键词”予以视觉化的展现,词云图过滤掉大量的低频低质的文...

  • 制作公众号内容词云图

    上一篇文章介绍了如何制作公众号标题的词云图。 这篇文章介绍制作公众号文章词云图 同样的,制作公众号文章词云图,也要...

  • < 制作词云 序 >—准备(QQ聊天)素材

    1. 词云图 相信大家在生活中也看过下面这样的图形吧?想必对于词云图也不是很陌生吧?词云图,顾名思义,就是一些...

  • Python爬虫:动态爬取QQ说说并生成词云,分析朋友状况

    跟着@逆水寒大佬学爬虫,Python动态爬取QQ空间说说,把内容存入txt文档,然后将内容生成词云图。可以清晰看出...

  • python:生成词云图

    文本分析相关的问题经常会用到词云图这种可视化形式,因此特意开一个博客记录一下词云图相关。 首先推荐几个词云图生成网...

  • R语言可视化(二十六):词云图绘制

    26. 词云图绘制 清除当前环境中的变量 设置工作目录 使用wordcloud2包绘制词云图 使用wordclou...

网友评论

      本文标题:动态词云图

      本文链接:https://www.haomeiwen.com/subject/jwwoodtx.html