Vuejs-VueWordCloud: vue-word-cloud - A word cloud generator.

VueWordCloud

Generates a cloud out of the words.

demo

Try it out!

setup

npm

npm i vuewordcloud

ES module

Register the component globally.

import Vue from 'vue';
import VueWordCloud from 'vuewordcloud';

Vue.component(VueWordCloud.name, VueWordCloud);

or

Register the component in the scope of another component.

import VueWordCloud from 'vuewordcloud';

export default {
  components: {
    [VueWordCloud.name]: VueWordCloud,
  },
};

browser

<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuewordcloud"></script>

The component is globally available as VueWordCloud. If Vue is detected, the component will be registered automatically.

usage

<vue-word-cloud
  style="
    height: 480px;
    width: 640px;
  "
  :words="[['romance', 19], ['horror', 3], ['fantasy', 7], ['adventure', 3]]"
  :color="([, weight]) => weight > 10 ? 'DeepPink' : weight > 5 ? 'RoyalBlue' : 'Indigo'"
  font-family="Roboto"
/>

Pass custom renderer for the words.

<vue-word-cloud :words="words">
  <template slot-scope="{text, weight, word}">
    <div :title="weight" style="cursor: pointer;" @click="onWordClick(word)">
      {{ text }}
    </div>
  </template>
</vue-word-cloud>

properties

property type default description
animation-duration Number 1000 The duration of the animation.
animation-easing String 'ease' The easing of the animation.
animation-overlap Number 1 The overlap of the animation. Set the value to 1 to animate words all at once. Set the value to 0 to animate words one by one. The value 5 has the same effect as the value 1/5.
color [String, Function] 'Black' The default color for each word.
create-canvas Function * Creates a new Canvas instance.
create-worker Function * Creates a new Worker instance.
enter-animation [Object, String] * The enter animation.
font-family [String, Function] 'serif' The default font family for each word.
font-size-ratio Number 0 The font size ratio between the words. For example, if the value is 5, then the largest word will be 5 times larger than the smallest one. The value 5 has the same effect as the value 1/5.
font-style [String, Function] 'normal' The default font style for each word.
font-variant [String, Function] 'normal' The default font variant for each word.
font-weight [String, Function] 'normal' The default font weight for each word.
leave-animation [Object, String] * The leave animation.
load-font Function * Loads the font.
rotation-unit [String, Function] 'turn' The default rotation unit for each word. Possible values are 'turn', 'deg' and 'rad'.
rotation [Number, Function] 0 The default rotation for each word.
spacing Number 0 The spacing between the words. The value is relative to the font size.
text [String, Function] '' The default text for each word.
weight [Number, Function] 1 The default weight for each word.
words Array [] The words to place into the cloud. A value of the array could be either an object, an array or a string.
If the value is an object, it will be resolved to {text, weight, rotation, rotationUnit, fontFamily, fontStyle, fontVariant, fontWeight, color}.
If the value is an array, it will be resolved to [text, weight].
If the value is a string, it will be resolved to text.

let enterAnimation = {opacity: 0};
let leaveAnimation = {opacity: 0};

Make more complex animations.

let enterAnimation = {
  opacity: 0,
  transform: 'scale3d(0.3,0.3,0.3)'
};

Use classes for CSS animations.

let enterAnimation = 'animated bounceIn';
let leaveAnimation = 'animated hinge';

let createCanvas = function() {
  return document.createElement('canvas');
};

let loadFont = function(fontFamily, fontStyle, fontWeight, text) {
  return document.fonts.load([fontStyle, fontWeight, '1px', fontFamily].join(' '), text);
};

Provide custom loadFont function to support older browsers.

import FontFaceObserver from 'fontfaceobserver';

let loadFont = function(family, style, weight, text) {
  return (new FontFaceObserver(family, {style, weight})).load(text);
};

let createWorker = function(code) {
  return new Worker(URL.createObjectURL(new Blob([code])));
};

events

event description
update:progress The current progress of the cloud words computation.

Comments

  • Usage of create-canvas prop
    Usage of create-canvas prop

    Aug 11, 2020

    I want to render the component as canvas. How should I work with create-canvas prop ?

    Reply
  • Property
    Property "$scopedSlots" was accessed during render but is not defined on instance

    May 7, 2021

    Does this component work with VUE 3?

    Reply
  • The circular progress never reaches 100%
    The circular progress never reaches 100%

    Jun 21, 2021

    In your demo, the circular progress never reaches 100% (1 full round). When the process finished, the circular progress always stops at a random place.

    I tried to fix it, but no success. Do you have any idea?

    Reply
  •   How to use in vue3
    How to use in vue3

    Aug 14, 2021

    null

                                                                                                                                                                                                           
    Reply
  • Add seed option
    Add seed option

    Jan 17, 2022

    I want to have the same word cloud every time, adding a seed option to get consistent results would be very appreciated

    Reply
  • Performance when rendering a lot of words
    Performance when rendering a lot of words

    Dec 29, 2017

    Hi,

    Great work so far with this library, I really like it.

    However I have noticed some performance issues when trying to load +/- 200 words, the initial render feels a lot slower then something like: wordcloud2.js. I assume this is because of the rendering using <div> instead of <canvas>? From what I can tell there is also no callback function that tells me when the rendering is complete so it's difficult to display some sort of preloader in the meantime.

    Any thoughts?

    Reply
  • Words not change when words input change
    Words not change when words input change

    Mar 1, 2018

     <vue-word-cloud 
                                            style="width: 400px; height: 400px;"
                                              :words="dataTagWords" 
                                              :color="([, weight]) => weight > 10 ? 'DeepPink' : weight > 5 ? 'RoyalBlue' : 'Indigo'"
                                          font-family="Roboto"
                                        ></vue-word-cloud>
    
    Reply
  • VueWordCloud do not show on firefox.
    VueWordCloud do not show on firefox.

    Jun 4, 2019

    I try to see VueWordCloud on firefox browser, but it's doesn't show. On chrome I can see VueWordCloud. My firefox version is 67.0.

    Reply
  • Use interpolation to limit word font sizes based on weight
    Use interpolation to limit word font sizes based on weight

    Sep 26, 2017

    Hi, first of all great work on this lib !

    With the current version, if we have 100 words with a weight of 1 and a word with a weight of 500, we can only read the big word, the 100 other ones are so small that we aren't able to read them. This may be not be a problem in some cases, but it is in mine.

    So I've made a change with this PR so that you can specify min and max font sizes for words. It uses a method based on React Native animation interpolation (https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/Libraries/Animated/src/nodes/AnimatedInterpolation.js#L103-L168).

    We give an inputRange [1, maxWeight] and an outputRange [minFontSize, maxFontSize]. So that the word(s) with a weight equal to maxWight have a font size equal to maxFontSize and all other words have a size between the given output range.

    I force the font size output range to [20, 100] pixels now, but it should be an optional property only for people who want to use it, with specifit min & max font sizes.

    Do you have any feedback or do I start implementing props ?

    Reply
  • [Bug Report] Chinese words are sticking together
    [Bug Report] Chinese words are sticking together

    Jul 5, 2018

    Check out this jsfiddle: https://jsfiddle.net/eywraw8t/140773/ .

    These words are sticking together, making themselves barely recognizable.

    I think it will be great to provide an option with which each word takes up its own space without overlapping each other.

    Reply
  • How can I set the font size?
    How can I set the font size?

    Aug 20, 2019

    Weird question, I know. I'm trying to use vue-bootstrap badges:

          <vue-word-cloud
            v-if="topics"
            :words="topics.map((topic) => [topic.text, parseInt(topic.weight * 10)])"
            style="width: 100%; height: 200px;"
            :font-size-ratio="2"
            font-family="Roboto"
          >
            <template slot-scope="{text, weight}">
              <div>
                <b-badge variant="primary">{{ text }}</b-badge>
              </div>
            </template>
          </vue-word-cloud>
    

    and it kind of works: image

    But I'd like to make it all smaller. If I specify a font-style, then all of the items have the same size.

    Reply
  • (solved) word cloud did not show
    (solved) word cloud did not show

    Jan 16, 2018

    I had trouble showing the word cloud graph. Then I figured out if I just added style="position:absolute" to the component then it would work. for example: <vue-word-cloud style="position:absolute" :words="[['romance', 19], ['horror', 3], ['fantasy', 7], ['adventure', 3]]" :color="([, weight]) => weight > 10 ? 'DeepPink' : weight > 5 ? 'RoyalBlue' : 'Indigo'" font-family="Roboto"

    hope this will help some lost souls btw thank you @SeregPie for this project

    Reply
  • Transpile to ES5
    Transpile to ES5

    Sep 26, 2017

    VueWordCloud.js uses ES2015+.

    There should be a transpiled version of the file in ES6 using something like babel. (or it breaks most apps)

    I can make a PR if you want.

    EDIT: Actually, I can't get it working with rollup and babel as I don't have much exeperience with these tools and the file uses Worker.

    Reply
  • Demo doesn't load on mobile Safari (iOS 10.3.3)...
    Demo doesn't load on mobile Safari (iOS 10.3.3)...

    Jul 11, 2018

    Awesome project, Sergej. Thanks for building this and MIT-licensing it.

    I just checked the demo on an older iPad (4th generation), which runs the previous official iOS (10.3.3), but the word cloud didn't show up. There are a lot of these devices in use, still.

    Do you have any idea are there any versions (and which ones) of iOS (mobile Safari) that are able to run the component?

    help wanted 
    Reply
  • Progress event creating infinite loop
    Progress event creating infinite loop

    Sep 21, 2018

    Hi, nice library. I tested it with one project , it working fine except when trying to implement progress.

    :progress.sync="progress"

    cause an infinite looping of my page. What are the proper instructions to use this event?

    <vue-word-cloud
           :progress.sync="progress"
           :words="words"
                :color="([, weight]) => weight > 10 ? 'DeepPink' : weight > 5 ? 'RoyalBlue' : 'Indigo'" font-family="Roboto"
               style="width: 100%; height: 200px;" class="cloud_tag"
    >
    

    .....

    export default {
        props: [],
        created () {
            console.log('created ')
            eventHub.$on('update:progress', this.updateProgress)
            this.isLoading = true
            this.loadTags('/cloud')
        },
        beforeDestroy() {
            eventHub.$off('update:progress');
        },
        watch: {
            progress: function(currentProgress, previousProgress) {
                if (previousProgress) {
                    this.progressVisible = false;
                }
            },
        },
        data() {
            return {
                isLoading: false,
                failed: false,
                words: [],
                progressVisible: true,
                progress: undefined,
                timestamp:null,
            }
    
        },
        methods: {
    
            updateProgress:function(progress){
                this.progress = progress
            },
       loadTags: function (url) {
       ....
    
    Reply