前言: 在vue项目中使用d3-cloud词云,从官网源码拔下来发现有些地方报错,经过一番研究操作终于弄出来了,增加了单词可点击调用方法
-
先上一张效果图:
-
npm i d3 d3-dispatch -S
下载 d3 和 d3-dispatch 两个包 -
复制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,
......
复制代码
- 复制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) }); } } 复制代码
-
调用
//词云组件.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> 复制代码
-
大功告成!
有什么问题和不对的地方欢迎指教和留言 !