diff --git a/README.md b/README.md index 7de086b..1296ddd 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,10 @@ chart.setOption({ // NOTE disable it will lead to UI blocking when there is lots of words. layoutAnimation: true, + // Set to any string to set the seed for the random word placement + // and get consistent results + randomSeed: null, + // Global text style textStyle: { fontFamily: 'sans-serif', diff --git a/package-lock.json b/package-lock.json index bb7c020..044b99b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "echarts-wordcloud", "version": "2.1.0", "license": "ISC", + "dependencies": { + "seedrandom": "^3.0.5" + }, "devDependencies": { "echarts": "^5.4.0", "prettier": "^2.5.1", @@ -1014,6 +1017,11 @@ "node": ">= 10.13.0" } }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, "node_modules/serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -2175,6 +2183,11 @@ "ajv-keywords": "^3.5.2" } }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", diff --git a/package.json b/package.json index b0b9480..24f1f6d 100644 --- a/package.json +++ b/package.json @@ -22,5 +22,8 @@ "prettier": "^2.5.1", "webpack": "^5.11.1", "webpack-cli": "^4.3.1" + }, + "dependencies": { + "seedrandom": "^3.0.5" } } diff --git a/src/layout.js b/src/layout.js index e4ee4cf..6d63367 100644 --- a/src/layout.js +++ b/src/layout.js @@ -8,6 +8,8 @@ 'use strict'; +import seedrandom from 'seedrandom' + // setImmediate if (!window.setImmediate) { window.setImmediate = (function setupSetImmediate() { @@ -169,9 +171,9 @@ var getItemExtraData = function (item) { }; // Based on http://jsfromhell.com/array/shuffle -var shuffleArray = function shuffleArray(arr) { +var shuffleArray = function shuffleArray(arr, random) { for (var j, x, i = arr.length; i; ) { - j = Math.floor(Math.random() * i); + j = Math.floor(random() * i); x = arr[--i]; arr[i] = arr[j]; arr[j] = x; @@ -245,7 +247,9 @@ var WordCloud = function WordCloud(elements, options) { classes: null, hover: null, - click: null + click: null, + + randomSeed: null }; if (options) { @@ -371,6 +375,8 @@ var WordCloud = function WordCloud(elements, options) { var minRotation = Math.min(settings.maxRotation, settings.minRotation); var rotationStep = settings.rotationStep; + var random = settings.randomSeed == null ? Math.random : seedrandom(settings.randomSeed.toString()); + /* information/object available to all functions, set when start() */ var grid, // 2d array containing filling information ngx, @@ -386,11 +392,11 @@ var WordCloud = function WordCloud(elements, options) { function randomHslColor(min, max) { return ( 'hsl(' + - (Math.random() * 360).toFixed() + + (random() * 360).toFixed() + ',' + - (Math.random() * 30 + 70).toFixed() + + (random() * 30 + 70).toFixed() + '%,' + - (Math.random() * (max - min) + min).toFixed() + + (random() * (max - min) + min).toFixed() + '%)' ); } @@ -538,7 +544,7 @@ var WordCloud = function WordCloud(elements, options) { return 0; } - if (Math.random() > settings.rotateRatio) { + if (random() > settings.rotateRatio) { return 0; } @@ -546,7 +552,7 @@ var WordCloud = function WordCloud(elements, options) { return minRotation; } - return minRotation + Math.round(Math.random() * rotationRange / rotationStep) * rotationStep; + return minRotation + Math.round(random() * rotationRange / rotationStep) * rotationStep; }; var getTextInfo = function getTextInfo( @@ -1068,7 +1074,7 @@ var WordCloud = function WordCloud(elements, options) { if (settings.shuffle) { points = [].concat(points); - shuffleArray(points); + shuffleArray(points, random); } // Try to fit the words by looking at each point. diff --git a/src/wordCloud.js b/src/wordCloud.js index fbdf574..4839afa 100644 --- a/src/wordCloud.js +++ b/src/wordCloud.js @@ -134,7 +134,9 @@ echarts.registerLayout(function (ecModel, api) { shuffle: false, - shape: seriesModel.get('shape') + shape: seriesModel.get('shape'), + + randomSeed: seriesModel.get('randomSeed') }); function onWordCloudDrawn(e) {