瀏覽代碼

词云改为平面

liyongli 4 年之前
父節點
當前提交
6da33938da
共有 2 個文件被更改,包括 142 次插入31 次删除
  1. 1 1
      src/utils/request.js
  2. 141 30
      src/view/index/index.vue

+ 1 - 1
src/utils/request.js

@@ -47,7 +47,7 @@ service.interceptors.response.use(
     error => {
         console.log('error', error);
         Toast.clear();
-        Toast.fail('服务器可能出了点问题',error);
+        // Toast.fail('服务器可能出了点问题',error);
         return Promise.reject(error)//千万不能去掉,,,否则请求超时会进入到then方法,导致逻辑错误。
     }
 );

+ 141 - 30
src/view/index/index.vue

@@ -139,22 +139,35 @@
       :width="client.width"
       :height="client.height"
     ></canvas>
-    <div v-if="baseData.word_cloud_url || list.length" class="title">词云</div>
-    <van-image v-if="baseData.word_cloud_url && !list.length" :src="baseData.word_cloud_url">
+    <div v-if="baseData.word_cloud_url || contentEle.length" class="title">
+      词云
+    </div>
+    <van-image
+      v-if="baseData.word_cloud_url && !contentEle.length"
+      :src="baseData.word_cloud_url"
+    >
       <template v-slot:loading>
         <van-loading type="spinner" size="20" />
       </template>
     </van-image>
-    <div
+    <canvas
+      v-if="baseData.word_cloud_url && contentEle.length"
+      id="cloud"
+      ref="cloud"
+      class="canvas"
+      :width="client.width"
+      :height="client.height"
+    ></canvas>
+    <!-- <div
       ref="div1"
       id="div1"
-      v-if="baseData.word_cloud_url && list.length"
+      v-if="baseData.word_cloud_url && contentEle.length"
       class="wordCloud__tagBall"
       :style="{ width: client.width + 'px', height: client.height + 'px' }"
     >
       <span
         v-for="(item, i) in contentEle"
-        :key="item.name"
+        :key="i"
         class="wordCloud__tag"
         :style="{
           color: color[i % color.length],
@@ -163,9 +176,10 @@
           zIndex: item.style.zIndex,
           fontSize: item.style.fontSize + 'px',
         }"
-        >{{ item.name }}</span
       >
-    </div>
+        {{ item.name }}
+      </span>
+    </div> -->
     <div v-if="douyin.length" class="title">抖音-评论排行</div>
     <canvas
       v-if="douyin.length"
@@ -326,7 +340,7 @@ import "vant/lib/popup/style";
 import "vant/lib/dialog/style";
 import "vant/lib/button/style";
 import F2 from "@antv/f2/lib/index-all";
-
+import DataSet from "@antv/data-set";
 import btnGroup from "./components/btnGroup/index";
 
 export default {
@@ -366,7 +380,6 @@ export default {
       color: ["#2D4DB6", "#04B67C", "#D1AF07", "#E27914", "#CB4A4D", "#B02690"],
       minFontSize: 12,
       maxFontSize: 18,
-      list: [],
     };
   },
   created() {
@@ -786,35 +799,133 @@ export default {
         ".json"
       );
       getCould(url).then(res => {
-        this.list = res || [];
-        if (!this.list.length) return;
-        const RADIUSX = (this.client.width - 100) / 2;
-        const RADIUSY = (this.client.height - 50) / 2;
+        let list = res.length ? res : [];
+        // const RADIUSX = (this.client.width - 100) / 2;
+        // const RADIUSY = (this.client.height - 50) / 2;
         let contentEle = [];
-        for (let i = 0; i < this.list.length; i += 1) {
-          const k = -1 + (2 * (i + 1) - 1) / this.list.length;
-          const a = Math.acos(k);
-          const b = a * Math.sqrt(this.list.length * Math.PI);
-          const x = RADIUSX * Math.sin(a) * Math.cos(b);
-          const y = RADIUSY * Math.sin(a) * Math.sin(b);
-          const z = RADIUSX * Math.cos(a);
-          const fotnS = (this.maxFontSize - this.minFontSize) * Math.random();
+        for (let i = 0; i < list.length; i += 1) {
+          // const k = -1 + (2 * (i + 1) - 1) / list.length;
+          // const a = Math.acos(k);
+          // const b = a * Math.sqrt(list.length * Math.PI);
+          // const x = RADIUSX * Math.sin(a) * Math.cos(b);
+          // const y = RADIUSY * Math.sin(a) * Math.sin(b);
+          // const z = RADIUSX * Math.cos(a);
+          // const fotnS = (this.maxFontSize - this.minFontSize) * Math.random();
           const singleEle = {
-            name: this.list[i].name,
-            value: this.list[i].value,
-            x,
-            y,
-            z,
-            style: {
-              fontSize: fotnS + this.minFontSize,
-            },
+            x: list[i].name,
+            value: list[i].value,
+            // x,
+            // y,
+            // z,
+            // style: {
+            //   fontSize: fotnS + this.minFontSize,
+            // },
           };
           contentEle.push(singleEle);
         }
         this.contentEle = contentEle;
-        this.animate();
+        this.$nextTick(() => {
+          // 普通词云
+          this.baseCloud();
+        });
+        // 动态词云
+        // this.animate();
+      });
+    },
+    // 普通慈云
+    baseCloud() {
+      const Util = F2.Util;
+      // 给point注册一个词云的shape
+      F2.Shape.registerShape("point", "cloud", {
+        draw: function draw(cfg, container) {
+          const attrs = Util.mix(
+            {},
+            {
+              fillOpacity: cfg.opacity,
+              fontSize: cfg.origin._origin.size,
+              rotate: (cfg.origin._origin.rotate * Math.PI) / 180,
+              text: cfg.origin._origin.text,
+              textAlign: "center",
+              fontFamily: cfg.origin._origin.font,
+              fill: cfg.color,
+              textBaseline: "Alphabetic",
+            },
+            cfg.style
+          );
+          const x = cfg.x;
+          const y = this._coord.y.start - cfg.y;
+          return container.addShape("text", {
+            attrs: Util.mix(attrs, {
+              x,
+              y,
+            }),
+          });
+        },
       });
+      const dv = new DataSet.View().source( this.contentEle);
+      const range = dv.range("value");
+      const min = range[0];
+      const max = range[1];
+      const MAX_FONTSIZE = 36; // 最大的字体
+      const MIN_FONTSIZE = 12; // 最小的字体
+      // 生成词云的布局
+      dv.transform({
+        type: "tag-cloud",
+        fields: ["x", "value"],
+        size: [375, 260], // 同 canvas 画布保持一致
+        font: "Verdana",
+        padding: 0,
+        timeInterval: 5000, // max execute time
+        rotate: function rotate() {
+          let random = ~~(Math.random() * 4) % 4;
+          if (random === 2) {
+            random = 0;
+          }
+          return random * 90; // 0, 90, 270
+        },
+        fontSize: function fontSize(d) {
+          if (d.value) {
+            return (
+              ((d.value - min) / (max - min)) * (MAX_FONTSIZE - MIN_FONTSIZE) +
+              MIN_FONTSIZE
+            );
+          }
+          return 0;
+        },
+      });
+      
+      let chart = undefined;
+      if (this.initCanvas['cloud']) {
+        chart = this.initCanvas['cloud'];
+        chart.destroy();
+        chart = undefined;
+      }
+      chart = new F2.Chart({
+        id: "cloud",
+        padding: 0,
+        pixelRatio: window.devicePixelRatio,
+      });
+      chart.source(dv.rows, {
+        x: {
+          nice: false,
+        },
+        y: {
+          nice: false,
+        },
+      });
+      chart.legend(false);
+      chart.axis(false);
+      chart.tooltip(false);
+
+      chart
+        .point()
+        .position("x*y")
+        .color("x")
+        .shape("cloud");
+      chart.render();
+      this.initCanvas['cloud'] = chart;
     },
+    // 动态词云
     animate() {
       let newContentEle = this.rotateXY(this.contentEle);
       newContentEle = this.move(newContentEle);