阅读 2064
vue中使用 d3-cloud 词云

vue中使用 d3-cloud 词云

前言: 在vue项目中使用d3-cloud词云,从官网源码拔下来发现有些地方报错,经过一番研究操作终于弄出来了,增加了单词可点击调用方法

  1. npm i d3 d3-dispatch -S 下载 d3 和 d3-dispatch 两个包

  2. 复制github项目主目录下的 index.js 文件,我这里命名为 d3.layout.cloud.js .

  • 注意点

    如果出现错误: Cannot assign to read only property 'exports' of object '#';

    需要把 module.exports 改成 export default 的导出方式;

    因为我用的是webpack4.0版本,在以前的版本不需要改动配置了babel也不会报错;因为webpack4.0现在统一使用的是es6的 export | import 模块语法.

  • 关于 module.exports 和 exports | export 和 export default | import | require 语法区别可以参考文章

  • require: node 和 es6 都支持的引入
    export / import : 只有es6 支持的导出引入
    module.exports / exports: 只有 node 支持的导出

    // d3.layout.cloud.js 
    
    // import {dispatch} from 'd3-dispatch' 或
    var dispatch = require("d3-dispatch").dispatch;
    var cloudRadians = Math.PI / 180,
      cw = 1 << 11 >> 5,
      ch = 1 << 11;
    
    // module.exports =  
    export default
      function () {
        var size = [256, 256],
          text = cloudText,
          font = cloudFont,
          ......
    复制代码
    1. 复制examples目录下的 browserify.js 我这里命名为 myCloud.js
    • 注意点一:

      如果用的是 export defalut 导出引入cloud 需要在require后加上 .default ; 如果用的是 module.exports 导出引入cloud 则不需要加 .default ,但在webpack4.0可能报错 或者用 import 方式引入;

    • 注意点二:

      d3.schemeCategory20 这个属性会报错,目前d3的官方api好像没有这个属性,可以用d3.schemeCategory10 或 d3.schemePaired 表示的都是不同的几种颜色

      // myCloud.js
      
      // import * as d3 from 'd3'
      // import cloud from '@/assets/js/d3.layout.cloud.js'
      var d3 = require('d3'),
          cloud = require('@/assets/js/d3.layout.cloud.js').default  
      
      export default function (option,callback) {
          //传入的option参数对象和回调函数
           let theSize = option.size,
              theWordList = option.wordList,
              theSvgElement = option.svgElement
           
           var layout = cloud()
             .size(theSize)
             .words(theWordList)
             .padding(5)
             //配置随机旋转的角度
             .rotate(function () {return ~~(Math.random() * 3) * 30;})
             .font("Impact")
             .fontSize(function (d) {return d.size;})
             .on("end", draw);
      
           layout.start();
      
           function draw(words) {
             let color = d3.scaleOrdinal(d3.schemePaired);
            // let color = d3.scaleOrdinal(d3.schemeCategory10);
            // 注意点: 如果使用的是 d3.schemeCategory20 会报错,可能是最新的d3删除了这个属性;可以去d3官方文档查看下;
             d3.select(theSvgElement)
               .append("svg")
               .attr("width", layout.size()[0])
               .attr("height", layout.size()[1])
               .append("g")
               .attr("transform", "translate(" + layout.size()[0] / 2 + "," + layout.size()[1] / 2 + ")")
               .selectAll("text")
               .data(words)
               .enter().append("text")
               .style("font-size", function (d) {return d.size + "px";})
               .style("font-family", "Impact")
               .style("cursor", "pointer")
               .style("fill", function (d, i) {return color(i);})
               .attr("text-anchor", "middle")
               .attr("transform", function (d) {return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";})
               .text(function (d) {return d.text;})
               // 添加点击的回调方法
               .on("click", function (d) {  
                 callback(d.text)
               });
           }
      }
      
       
      复制代码
    1. 调用

      //词云组件.vue
      <template>
        <div class="siderBar">
          <!-- 词云 -->
          <div ref='wordCloudBox'></div> 
        </div>
      </template>
      
      <script>
        import myCloud from '@/assets/js/myCloud.js' 
        export default {
          name:'siderBar',
          data () {
            return {};
          },
      
          methods: {
            //生成词云
            getWordCloud(wordList){
               let wordOption = {  
                        wordList, 
                        size:[257,257],  // 盒子的宽高
                        svgElement: this.$refs.wordCloudBox  //使用ref选择节点
                      }
                myCloud(wordOption,this.getArticleList)
              })
            },
            //回调
            getArticleList(){
                ...
            }
          },
      
          mounted() {
               let wordList = [
                           {text:'vue',size:20},
                           {text:'html',size:25},
                           {text:'js',size:30},
                       ]
               this.getWordCloud(wordList)
          },
      
        }
      </script>
      复制代码
    2. 大功告成!

    有什么问题和不对的地方欢迎指教和留言 !

文章分类
前端
文章标签