diff --git a/components/word-cloud/WordCloud.js b/components/word-cloud/WordCloud.js
new file mode 100644
index 0000000..305db49
--- /dev/null
+++ b/components/word-cloud/WordCloud.js
@@ -0,0 +1,789 @@
+/*!
+ * wordcloud2.js
+ * http://timdream.org/wordcloud2.js/
+ *
+ * Copyright 2011 - 2013 Tim Chien
+ * Released under the MIT license
+ */
+
+'use strict';
+let drawSpan = [];
+// Find out if the browser impose minium font size by
+// drawing small texts on a canvas and measure it's width.
+function getMinFontSize(ctx) {
+
+ // start from 20
+ var size = 20;
+
+ // two sizes to measure
+ var hanWidth, mWidth;
+
+ while (size) {
+ ctx.setFontSize(size)
+ if ((ctx.measureText('\uFF37').width === hanWidth) &&
+ (ctx.measureText('m').width) === mWidth) {
+ return (size + 1);
+ }
+
+ hanWidth = ctx.measureText('\uFF37').width;
+ mWidth = ctx.measureText('m').width;
+
+ size--;
+ }
+
+ return 0;
+};
+
+// Based on http://jsfromhell.com/array/shuffle
+var shuffleArray = function shuffleArray(arr) {
+ for (var j, x, i = arr.length; i; j = Math.floor(Math.random() * i),
+ x = arr[--i], arr[i] = arr[j],
+ arr[j] = x) {}
+ return arr;
+};
+
+function WordCloud(ctx, mycanvas, options, self, callback) {
+
+ var minFontSize = getMinFontSize(ctx)
+
+ /* Default values to be overwritten by options object */
+ var settings = {
+ list: [],
+ fontFamily: '"Trebuchet MS", "Heiti TC", "微軟正黑體", ' +
+ '"Arial Unicode MS", "Droid Fallback Sans", sans-serif',
+ fontWeight: 'normal',
+ color: 'random-dark',
+ minSize: 0, // 0 to disable
+ weightFactor: 1,
+ clearCanvas: true,
+ backgroundColor: '#fff', // opaque white = rgba(255, 255, 255, 1)
+
+ gridSize: 8,
+ drawOutOfBound: false,
+ shrinkToFit: false,
+ origin: null,
+
+ maskColor: 'rgba(255,0,0,0.3)',
+ maskGapWidth: 0.3,
+
+ wait: 0,
+ abortThreshold: 0, // disabled
+ abort: function noop() {},
+
+ minRotation: -Math.PI / 2,
+ maxRotation: Math.PI / 2,
+ rotationSteps: 0,
+
+ shuffle: true,
+ rotateRatio: 0.1,
+
+ shape: 'circle',
+ ellipticity: 0.65,
+
+ classes: null,
+
+ hover: null,
+ click: null
+ };
+
+ if (options) {
+ for (var key in options) {
+ if (key in settings) {
+ settings[key] = options[key];
+ }
+ }
+ }
+
+ /* Convert weightFactor into a function */
+ if (typeof settings.weightFactor !== 'function') {
+ var factor = settings.weightFactor;
+ settings.weightFactor = function weightFactor(pt) {
+ return pt * factor; //in px
+ };
+ }
+
+ /* Convert shape into a function */
+ if (typeof settings.shape !== 'function') {
+ switch (settings.shape) {
+ case 'circle':
+ /* falls through */
+ default:
+ // 'circle' is the default and a shortcut in the code loop.
+ settings.shape = 'circle';
+ break;
+
+ case 'cardioid':
+ settings.shape = function shapeCardioid(theta) {
+ return 1 - Math.sin(theta);
+ };
+ break;
+
+ /*
+ To work out an X-gon, one has to calculate "m",
+ where 1/(cos(2*PI/X)+m*sin(2*PI/X)) = 1/(cos(0)+m*sin(0))
+ http://www.wolframalpha.com/input/?i=1%2F%28cos%282*PI%2FX%29%2Bm*sin%28
+ 2*PI%2FX%29%29+%3D+1%2F%28cos%280%29%2Bm*sin%280%29%29
+ Copy the solution into polar equation r = 1/(cos(t') + m*sin(t'))
+ where t' equals to mod(t, 2PI/X);
+ */
+
+ case 'diamond':
+ // http://www.wolframalpha.com/input/?i=plot+r+%3D+1%2F%28cos%28mod+
+ // %28t%2C+PI%2F2%29%29%2Bsin%28mod+%28t%2C+PI%2F2%29%29%29%2C+t+%3D
+ // +0+..+2*PI
+ settings.shape = function shapeSquare(theta) {
+ var thetaPrime = theta % (2 * Math.PI / 4);
+ return 1 / (Math.cos(thetaPrime) + Math.sin(thetaPrime));
+ };
+ break;
+
+ case 'square':
+ // http://www.wolframalpha.com/input/?i=plot+r+%3D+min(1%2Fabs(cos(t
+ // )),1%2Fabs(sin(t)))),+t+%3D+0+..+2*PI
+ settings.shape = function shapeSquare(theta) {
+ return Math.min(
+ 1 / Math.abs(Math.cos(theta)),
+ 1 / Math.abs(Math.sin(theta))
+ );
+ };
+ break;
+
+ case 'triangle-forward':
+ // http://www.wolframalpha.com/input/?i=plot+r+%3D+1%2F%28cos%28mod+
+ // %28t%2C+2*PI%2F3%29%29%2Bsqrt%283%29sin%28mod+%28t%2C+2*PI%2F3%29
+ // %29%29%2C+t+%3D+0+..+2*PI
+ settings.shape = function shapeTriangle(theta) {
+ var thetaPrime = theta % (2 * Math.PI / 3);
+ return 1 / (Math.cos(thetaPrime) +
+ Math.sqrt(3) * Math.sin(thetaPrime));
+ };
+ break;
+
+ case 'triangle':
+ case 'triangle-upright':
+ settings.shape = function shapeTriangle(theta) {
+ var thetaPrime = (theta + Math.PI * 3 / 2) % (2 * Math.PI / 3);
+ return 1 / (Math.cos(thetaPrime) +
+ Math.sqrt(3) * Math.sin(thetaPrime));
+ };
+ break;
+
+ case 'pentagon':
+ settings.shape = function shapePentagon(theta) {
+ var thetaPrime = (theta + 0.955) % (2 * Math.PI / 5);
+ return 1 / (Math.cos(thetaPrime) +
+ 0.726543 * Math.sin(thetaPrime));
+ };
+ break;
+
+ case 'star':
+ settings.shape = function shapeStar(theta) {
+ var thetaPrime = (theta + 0.955) % (2 * Math.PI / 10);
+ if ((theta + 0.955) % (2 * Math.PI / 5) - (2 * Math.PI / 10) >= 0) {
+ return 1 / (Math.cos((2 * Math.PI / 10) - thetaPrime) +
+ 3.07768 * Math.sin((2 * Math.PI / 10) - thetaPrime));
+ } else {
+ return 1 / (Math.cos(thetaPrime) +
+ 3.07768 * Math.sin(thetaPrime));
+ }
+ };
+ break;
+ }
+ }
+
+ /* Make sure gridSize is a whole number and is not smaller than 4px */
+ settings.gridSize = Math.max(Math.floor(settings.gridSize), 4);
+
+ /* shorthand */
+ var g = settings.gridSize;
+ var maskRectWidth = g - settings.maskGapWidth;
+
+ /* normalize rotation settings */
+ var rotationRange = Math.abs(settings.maxRotation - settings.minRotation);
+ var rotationSteps = Math.abs(Math.floor(settings.rotationSteps));
+ var minRotation = Math.min(settings.maxRotation, settings.minRotation);
+
+ /* information/object available to all functions, set when start() */
+ var grid, // 2d array containing filling information
+ ngx, ngy, // width and height of the grid
+ center, // position of the center of the cloud
+ maxRadius;
+
+ /* timestamp for measuring each putWord() action */
+ var escapeTime;
+
+ /* function for getting the color of the text */
+ var getTextColor;
+
+ function random_hsl_color(min, max) {
+ return 'rgb(' +
+ (Math.random() * 255).toFixed() + ',' +
+ (Math.random() * 30 + 70).toFixed() + ',' +
+ (Math.random() * (max - min) + min).toFixed() + ')';
+ }
+ switch (settings.color) {
+ case 'random-dark':
+ getTextColor = function getRandomDarkColor() {
+ return random_hsl_color(10, 50);
+ };
+ break;
+
+ case 'random-light':
+ getTextColor = function getRandomLightColor() {
+ return random_hsl_color(50, 90);
+ };
+ break;
+
+ default:
+ if (typeof settings.color === 'function') {
+ getTextColor = settings.color;
+ }
+ break;
+ }
+
+ /* function for getting the font-weight of the text */
+ var getTextFontWeight;
+ if (typeof settings.fontWeight === 'function') {
+ getTextFontWeight = settings.fontWeight;
+ }
+
+ /* function for getting the classes of the text */
+ var getTextClasses = null;
+ if (typeof settings.classes === 'function') {
+ getTextClasses = settings.classes;
+ }
+
+ /* Interactive */
+ var interactive = false;
+ var infoGrid = [];
+ var hovered;
+
+ /* Get points on the grid for a given radius away from the center */
+ var pointsAtRadius = [];
+ var getPointsAtRadius = function getPointsAtRadius(radius) {
+ if (pointsAtRadius[radius]) {
+ return pointsAtRadius[radius];
+ }
+
+ // Look for these number of points on each radius
+ var T = radius * 8;
+
+ // Getting all the points at this radius
+ var t = T;
+ var points = [];
+
+ if (radius === 0) {
+ points.push([center[0], center[1], 0]);
+ }
+
+ while (t--) {
+ // distort the radius to put the cloud in shape
+ var rx = 1;
+ if (settings.shape !== 'circle') {
+ rx = settings.shape(t / T * 2 * Math.PI); // 0 to 1
+ }
+
+ // Push [x, y, t]; t is used solely for getTextColor()
+ points.push([
+ center[0] + radius * rx * Math.cos(-t / T * 2 * Math.PI),
+ center[1] + radius * rx * Math.sin(-t / T * 2 * Math.PI) *
+ settings.ellipticity,
+ t / T * 2 * Math.PI
+ ]);
+ }
+
+ pointsAtRadius[radius] = points;
+ return points;
+ };
+
+ /* Return true if we had spent too much time */
+ var exceedTime = function exceedTime() {
+ return ((settings.abortThreshold > 0) &&
+ ((new Date()).getTime() - escapeTime > settings.abortThreshold));
+ };
+
+ /* Get the deg of rotation according to settings, and luck. */
+ var getRotateDeg = function getRotateDeg() {
+ if (settings.rotateRatio === 0) {
+ return 0;
+ }
+
+ if (Math.random() > settings.rotateRatio) {
+ return 0;
+ }
+
+ if (rotationRange === 0) {
+ return minRotation;
+ }
+
+ if (rotationSteps > 0) {
+ // Min rotation + zero or more steps * span of one step
+ return minRotation +
+ Math.floor(Math.random() * rotationSteps) *
+ rotationRange / (rotationSteps - 1);
+ } else {
+ return minRotation + Math.random() * rotationRange;
+ }
+ };
+
+ function getTextInfo(word, weight, rotateDeg) {
+ // calculate the acutal font size
+ // fontSize === 0 means weightFactor function wants the text skipped,
+ // and size < minSize means we cannot draw the text.
+ var debug = false;
+ var fontSize = settings.weightFactor(weight);
+ if (fontSize <= settings.minSize) {
+ return Promise.resolve(false);
+ }
+
+ // Scale factor here is to make sure fillText is not limited by
+ // the minium font size set by browser.
+ // It will always be 1 or 2n.
+ var mu = 1;
+ if (fontSize < minFontSize) {
+ mu = (function calculateScaleFactor() {
+ var mu = 2;
+ while (mu * fontSize < minFontSize) {
+ mu += 2;
+ }
+ return mu;
+ })();
+ }
+
+ // Get fontWeight that will be used to set fctx.font
+ var fontWeight;
+ if (getTextFontWeight) {
+ fontWeight = getTextFontWeight(word, weight, fontSize);
+ } else {
+ fontWeight = settings.fontWeight;
+ }
+
+
+
+ var fctx = wx.createCanvasContext("canvas",self);
+ fctx.setFontSize(fontSize * mu)
+ fctx.font = fontWeight + ' ' +
+ (fontSize * mu).toString(10) + 'px ' + settings.fontFamily;
+
+ // Estimate the dimension of the text with measureText().
+ var fw = fctx.measureText(word).width / mu;
+ var fh = Math.max(fontSize * mu,
+ fctx.measureText('m').width,
+ fctx.measureText('\uFF37').width) / mu;
+
+ // Create a boundary box that is larger than our estimates,
+ // so text don't get cut of (it sill might)
+ var boxWidth = fw + fh * 2;
+ var boxHeight = fh * 3;
+ var fgw = Math.ceil(boxWidth / g);
+ var fgh = Math.ceil(boxHeight / g);
+ boxWidth = fgw * g;
+ boxHeight = fgh * g;
+
+ // Calculate the proper offsets to make the text centered at
+ // the preferred position.
+
+ // This is simply half of the width.
+ var fillTextOffsetX = -fw / 2;
+ // Instead of moving the box to the exact middle of the preferred
+ // position, for Y-offset we move 0.4 instead, so Latin alphabets look
+ // vertical centered.
+ var fillTextOffsetY = -fh * 0.4;
+
+ // Calculate the actual dimension of the canvas, considering the rotation.
+ var cgh = Math.ceil((boxWidth * Math.abs(Math.sin(rotateDeg)) +
+ boxHeight * Math.abs(Math.cos(rotateDeg))) / g);
+ var cgw = Math.ceil((boxWidth * Math.abs(Math.cos(rotateDeg)) +
+ boxHeight * Math.abs(Math.sin(rotateDeg))) / g);
+ var width = cgw * g;
+ var height = cgh * g;
+
+ // Scale the canvas with |mu|.
+ fctx.scale(1 / mu, 1 / mu);
+ fctx.translate(width * mu / 2, height * mu / 2);
+ fctx.rotate(-rotateDeg);
+
+ // Once the width/height is set, ctx info will be reset.
+ // Set it again here.
+ fctx.font = fontWeight + ' ' +
+ (fontSize * mu).toString(10) + 'px ' + settings.fontFamily;
+
+ // Fill the text into the fcanvas.
+ // XXX: We cannot because textBaseline = 'top' here because
+ // Firefox and Chrome uses different default line-height for canvas.
+ // Please read https://bugzil.la/737852#c6.
+ // Here, we use textBaseline = 'middle' and draw the text at exactly
+ // 0.5 * fontSize lower.
+ fctx.fillStyle = '#000';
+ fctx.textBaseline = 'middle';
+ fctx.fillText(word, fillTextOffsetX * mu,
+ (fillTextOffsetY + fontSize * 0.5) * mu);
+ fctx.draw();
+ // Get the pixels of the text
+ var imageData;
+ return new Promise(resolve => {
+ wx.canvasGetImageData({
+ canvasId: 'canvas',
+ x: 0,
+ y: 0,
+ width: width,
+ height: height,
+ success(res) {
+ imageData = res.data;
+
+ if (exceedTime()) {
+ return false;
+ }
+
+ if (debug) {
+ // Draw the box of the original estimation
+ fctx.strokeRect(fillTextOffsetX * mu,
+ fillTextOffsetY, fw * mu, fh * mu);
+ fctx.restore();
+ }
+
+ // Read the pixels and save the information to the occupied array
+ var occupied = [];
+ var gx = cgw,
+ gy, x, y;
+ var bounds = [cgh / 2, cgw / 2, cgh / 2, cgw / 2];
+ while (gx--) {
+ gy = cgh;
+ while (gy--) {
+ y = g;
+ singleGridLoop: {
+ while (y--) {
+ x = g;
+ while (x--) {
+ if (imageData[((gy * g + y) * width +
+ (gx * g + x)) * 4 + 3]) {
+ occupied.push([gx, gy]);
+
+ if (gx < bounds[3]) {
+ bounds[3] = gx;
+ }
+ if (gx > bounds[1]) {
+ bounds[1] = gx;
+ }
+ if (gy < bounds[0]) {
+ bounds[0] = gy;
+ }
+ if (gy > bounds[2]) {
+ bounds[2] = gy;
+ }
+
+ if (debug) {
+ fctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
+ fctx.fillRect(gx * g, gy * g, g - 0.5, g - 0.5);
+ }
+ break singleGridLoop;
+ }
+ }
+ }
+ if (debug) {
+ fctx.fillStyle = 'rgba(0, 0, 255, 0.5)';
+ fctx.fillRect(gx * g, gy * g, g - 0.5, g - 0.5);
+ }
+ }
+ }
+ }
+
+ if (debug) {
+ fctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ fctx.fillRect(bounds[3] * g,
+ bounds[0] * g,
+ (bounds[1] - bounds[3] + 1) * g,
+ (bounds[2] - bounds[0] + 1) * g);
+ }
+
+ resolve({
+ mu: mu,
+ occupied: occupied,
+ bounds: bounds,
+ gw: cgw,
+ gh: cgh,
+ fillTextOffsetX: fillTextOffsetX,
+ fillTextOffsetY: fillTextOffsetY,
+ fillTextWidth: fw,
+ fillTextHeight: fh,
+ fontSize: fontSize
+ })
+ },
+ fail(error){
+ console.log(word, error)
+ }
+ },self)
+ })
+ };
+
+ /* Determine if there is room available in the given dimension */
+ var canFitText = function canFitText(gx, gy, gw, gh, occupied) {
+ // Go through the occupied points,
+ // return false if the space is not available.
+ var i = occupied.length;
+ while (i--) {
+ var px = gx + occupied[i][0];
+ var py = gy + occupied[i][1];
+
+ if (px >= ngx || py >= ngy || px < 0 || py < 0) {
+ if (!settings.drawOutOfBound) {
+ return false;
+ }
+ continue;
+ }
+
+ if (!grid[px][py]) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ /* Actually draw the text on the grid */
+ var drawText = function drawText(gx, gy, info, word, weight,
+ distance, theta, rotateDeg, attributes) {
+ var transformRule = '';
+ transformRule = 'rotate(' + (-rotateDeg / Math.PI * 180) + 'deg) ';
+ if (info.mu !== 1) {
+ transformRule +=
+ 'translateX(-' + (info.fillTextWidth / 4) + 'px) ' +
+ 'scale(' + (1 / info.mu) + ')';
+ }
+
+ var fontSize = info.fontSize;
+ var color;
+ if (getTextColor) {
+ color = getTextColor(word, weight, fontSize, distance, theta);
+ } else {
+ color = settings.color;
+ }
+
+ var fontWeight;
+ if (getTextFontWeight) {
+ fontWeight = getTextFontWeight(word, weight, fontSize);
+ } else {
+ fontWeight = settings.fontWeight;
+ }
+
+ var classes;
+ if (getTextClasses) {
+ classes = getTextClasses(word, weight, fontSize);
+ } else {
+ classes = settings.classes;
+ }
+
+ callback({
+ g,
+ gx,
+ gy,
+ info,
+ word,
+ weight,
+ color,
+ fontWeight,
+ fontSize,
+ distance,
+ theta,
+ rotateDeg,
+ transformRule,
+ attributes
+ }) //将要绘制的span参数通过回调函数传出
+ };
+
+ /* Help function to updateGrid */
+ var fillGridAt = function fillGridAt(x, y, dimension, item) {
+ if (x >= ngx || y >= ngy || x < 0 || y < 0) {
+ return;
+ }
+
+ grid[x][y] = false;
+
+ if (interactive) {
+ infoGrid[x][y] = {
+ item: item,
+ dimension: dimension
+ };
+ }
+ };
+
+ /* Update the filling information of the given space with occupied points.
+ Draw the mask on the canvas if necessary. */
+ var updateGrid = function updateGrid(gx, gy, gw, gh, info, item) {
+ var occupied = info.occupied;
+ var dimension;
+ if (interactive) {
+ var bounds = info.bounds;
+ dimension = {
+ x: (gx + bounds[3]) * g,
+ y: (gy + bounds[0]) * g,
+ w: (bounds[1] - bounds[3] + 1) * g,
+ h: (bounds[2] - bounds[0] + 1) * g
+ };
+ }
+
+ var i = occupied.length;
+ while (i--) {
+ var px = gx + occupied[i][0];
+ var py = gy + occupied[i][1];
+
+ if (px >= ngx || py >= ngy || px < 0 || py < 0) {
+ continue;
+ }
+
+ fillGridAt(px, py, dimension, item);
+ }
+ };
+
+ /* putWord() processes each item on the list,
+ calculate it's size and determine it's position, and actually
+ put it on the canvas. */
+ function putWord(item) {
+ var word, weight, attributes;
+ if (Array.isArray(item)) {
+ word = item[0];
+ weight = item[1];
+ } else {
+ word = item.word;
+ weight = item.weight;
+ attributes = item.attributes;
+ }
+ var rotateDeg = getRotateDeg();
+ // get info needed to put the text onto the canvas
+ return new Promise(resolve => {
+ getTextInfo(word, weight, rotateDeg).then(res => {
+ resolve(res)
+ })
+ }).then(res => {
+ let info = res;
+ // not getting the info means we shouldn't be drawing this one.
+ if (!info) {
+ return false;
+ }
+
+ if (exceedTime()) {
+ return false;
+ }
+
+ // If drawOutOfBound is set to false,
+ // skip the loop if we have already know the bounding box of
+ // word is larger than the canvas.
+ if (!settings.drawOutOfBound) {
+ var bounds = info.bounds;
+ if ((bounds[1] - bounds[3] + 1) > ngx ||
+ (bounds[2] - bounds[0] + 1) > ngy) {
+ return false;
+ }
+ }
+
+ // Determine the position to put the text by
+ // start looking for the nearest points
+ var r = maxRadius + 1;
+
+ var tryToPutWordAtPoint = function(gxy) {
+ var gx = Math.floor(gxy[0] - info.gw / 2);
+ var gy = Math.floor(gxy[1] - info.gh / 2);
+ var gw = info.gw;
+ var gh = info.gh;
+
+ // If we cannot fit the text at this position, return false
+ // and go to the next position.
+ if (!canFitText(gx, gy, gw, gh, info.occupied)) {
+ return false;
+ }
+
+ // Actually put the text on the canvas
+ drawText(gx, gy, info, word, weight,
+ (maxRadius - r), gxy[2], rotateDeg, attributes);
+ // Mark the spaces on the grid as filled
+ updateGrid(gx, gy, gw, gh, info, item);
+
+ // Return true so some() will stop and also return true.
+ return true;
+ };
+
+ while (r--) {
+ var points = getPointsAtRadius(maxRadius - r);
+
+ if (settings.shuffle) {
+ points = [].concat(points);
+ shuffleArray(points);
+ }
+
+ // Try to fit the words by looking at each point.
+ // array.some() will stop and return true
+ // when putWordAtPoint() returns true.
+ // If all the points returns false, array.some() returns false.
+ var drawn = points.some(tryToPutWordAtPoint);
+
+ if (drawn) {
+ return true;
+ }
+ }
+ // we tried all distances but text won't fit, return false
+ return false;
+ })
+ };
+
+ /* Start drawing on a canvas */
+ function start() {
+ // For dimensions, clearCanvas etc.,
+ // we only care about the first element.
+ ngx = Math.ceil(mycanvas.width / g);
+ ngy = Math.ceil(mycanvas.height / g);
+
+ // Determine the center of the word cloud
+ center = (settings.origin) ? [settings.origin[0] / g, settings.origin[1] / g] : [ngx / 2, ngy / 2];
+
+ // Maxium radius to look for space
+ maxRadius = Math.floor(Math.sqrt(ngx * ngx + ngy * ngy));
+
+ /* Clear the canvas only if the clearCanvas is set,
+ if not, update the grid to the current canvas state */
+ grid = [];
+
+ var gx, gy, i;
+ if (settings.clearCanvas) {
+ ctx.fillStyle = settings.backgroundColor;
+ ctx.clearRect(0, 0, ngx * (g + 1), ngy * (g + 1));
+ ctx.fillRect(0, 0, ngx * (g + 1), ngy * (g + 1));
+
+ /* fill the grid with empty state */
+ gx = ngx;
+ while (gx--) {
+ grid[gx] = [];
+ gy = ngy;
+ while (gy--) {
+ grid[gx][gy] = true;
+ }
+ }
+ }
+
+ i = 0;
+ var loopingFunction, stoppingFunction;
+
+ loopingFunction = setTimeout;
+ stoppingFunction = clearTimeout;
+
+ var timer = loopingFunction(function loop() {
+ if (i >= settings.list.length) {
+ stoppingFunction(timer);
+ return;
+ }
+ escapeTime = (new Date()).getTime();
+ putWord(settings.list[i]).then(res => {
+ if (exceedTime()) {
+ stoppingFunction(timer);
+ settings.abort();
+ return;
+ }
+ i++;
+ timer = loopingFunction(loop, settings.wait);
+ }).catch(error => console.log(error))
+ }, settings.wait);
+ };
+
+ // All set, start the drawing
+ start();
+};
+
+exports.WordCloud = WordCloud
\ No newline at end of file
diff --git a/components/word-cloud/index.js b/components/word-cloud/index.js
new file mode 100644
index 0000000..56ccb88
--- /dev/null
+++ b/components/word-cloud/index.js
@@ -0,0 +1,50 @@
+// word-cloud/index.js
+const {
+ WordCloud
+} = require("./WordCloud.js")
+Component({
+ /**
+ * 组件的属性列表
+ */
+ properties: {
+ list: {
+ type: Array,
+ value: [],
+ },
+ height: {
+ type: String,
+ value: "200"
+ },
+ width: {
+ type: String,
+ value: ""
+ },
+ color: {
+ type: String,
+ value: "random-light"
+ },
+ },
+
+ data: {
+ spans: []
+ },
+
+ ready() {
+ let that = this;
+ this.ctx = wx.createCanvasContext('canvas', this);
+ let query = this.createSelectorQuery();
+ query.select("#canvas").boundingClientRect(function (res) {
+ WordCloud(that.ctx, res, {
+ minSize: 8,
+ list: that.data.list,
+ color: that.data.color
+ }, that, function (val) {
+ that.data.spans.push(val)
+ // w.to_file("../../images/carSide.png")
+ that.setData({
+ spans: that.data.spans
+ })
+ })
+ }).exec();
+ }
+})
diff --git a/components/word-cloud/index.json b/components/word-cloud/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/components/word-cloud/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/components/word-cloud/index.wxml b/components/word-cloud/index.wxml
new file mode 100644
index 0000000..c66c247
--- /dev/null
+++ b/components/word-cloud/index.wxml
@@ -0,0 +1,8 @@
+
+
+
+
+
+ {{item.word}}
+
+
\ No newline at end of file
diff --git a/components/word-cloud/index.wxss b/components/word-cloud/index.wxss
new file mode 100644
index 0000000..9ed5446
--- /dev/null
+++ b/components/word-cloud/index.wxss
@@ -0,0 +1 @@
+/* word-cloud/index.wxss */
\ No newline at end of file
diff --git a/images/carSide.png b/images/carSide.png
new file mode 100644
index 0000000..d642155
Binary files /dev/null and b/images/carSide.png differ
diff --git a/pages/insight/index.js b/pages/insight/index.js
index 6cc3c52..41e0e8c 100644
--- a/pages/insight/index.js
+++ b/pages/insight/index.js
@@ -1,7 +1,39 @@
// index.js
-
+const words = [
+ ["江南", 1],
+ ["乌镇", 2],
+ ["儿时", 20],
+ ["入园", 8],
+ ["长大", 9],
+ ["happy", 10],
+ ["音乐喷泉", 1],
+ ["门票", 33],
+ ["江南", 1],
+ ["乌镇", 2],
+ ["玩耍", 12],
+ ["风景", 4],
+ ["六月", 5],
+ ["江南", 1],
+ ["乌镇", 2],
+ ["儿时", 20],
+ ["入园", 8],
+ ["长大", 9],
+ ["happy", 10],
+ ["音乐喷泉", 1],
+ ["门票", 33],
+ ["江南", 1],
+ ["乌镇", 2],
+ ["玩耍", 12],
+ ["风景", 4],
+ ["六月", 5]
+ ]
Page({
data: {
+ canvasId: 'w1',
+ words: words.map(item => {
+ item[1] = item[1] + 12
+ return item;
+ })
},
onShow() {
this.getTabBar().init();
diff --git a/pages/insight/index.json b/pages/insight/index.json
index 6cdce25..0ccfa0d 100644
--- a/pages/insight/index.json
+++ b/pages/insight/index.json
@@ -1,5 +1,5 @@
{
"usingComponents": {
-
+ "word-cloud": "../../components/word-cloud/index"
}
}
\ No newline at end of file
diff --git a/pages/insight/index.wxml b/pages/insight/index.wxml
index c1a4fe5..9fccf07 100644
--- a/pages/insight/index.wxml
+++ b/pages/insight/index.wxml
@@ -1,3 +1,6 @@
- 洞察
+
+
+
+