SeregPie / VueWordCloud

Generates a cloud out of the words.
https://seregpie.github.io/VueWordCloud/
MIT License
387 stars 60 forks source link

Progress event creating infinite loop #36

Closed davemg3 closed 6 years ago

davemg3 commented 6 years ago

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) {
   ....
SeregPie commented 6 years ago

This is the minimal code you need, to show the progress. No event hubs or methods are needed.

<div v-if="progress">
  {{ Math.round(progress.completedWords / progress.totalWords * 100) }}%
</div>
<vue-word-cloud
  :progress.sync="progress"
  :words="words"
  style="width: 100%; height: 200px;"
>
export default {
  data() {
    return {
      words: [],
      progress: undefined,
    };
  },
  /*...*/
};
SeregPie commented 6 years ago

The wording (totalWords, completedWords) can change in the future. I'm not satisfied with it right now.

davemg3 commented 6 years ago

Thanks for your feeback . I tried unsuccessfully during few hours with

  <div id="">
        <v-app
                v-cloak
                id="app-cloud"
        >
                <div
                        style="
                            height: 100%;
                            position: relative;
                            width: 100%;
                        "
                >
                    <div
                            :style="(progressVisible && progress)
                                ? {
                                    filter: 'blur(8px)',
                                    opacity: 0.3,
                                    pointerEvents: 'none',
                                    transform: 'scale(0.7,0.7)',
                                }
                                : {}
                            "
                            style="
                                bottom: 0;
                                left: 0;
                                position: relative;
                                right: 0;
                                top: 0;

                            "
                    >
                            <vue-word-cloud
                                    :words="words"
                                    v-on:update:progress="updateProgress"
                                    :color="([, weight]) => weight > 10 ? 'DeepPink' : weight > 5 ? 'RoyalBlue' : 'Indigo'"
                                    font-family="Roboto"
                                    style="width: 100%; height: 200px;" class="cloud_tag"
                            > </vue-word-cloud>
                    </div>
                    <v-scale-transition>
                        <v-progress-circular
                                v-if="progressVisible && progress"
                                :rotate="-90"
                                :size="100"
                                :value="pvalue"
                                :width="10"
                                color="primary"
                                style="
                                    bottom: 0;
                                    left: 0;
                                    margin: auto;
                                    position: absolute;
                                    right: 0;
                                    top: 0;
                                "
                        >{{ completedWords }} of {{ totalWords }}</v-progress-circular>
                    </v-scale-transition>
                </div>
        </v-app>
    </div>

and

    watch: {
            progress: function(currentProgress, previousProgress) {
 )
                if (previousProgress ) {
                    this.progressVisible = false;
                }
            },
        },
  methods: {

            updateProgress:function(progress) {
                this.progress = progress
...

But the circular spinner disappear at first word completed before other ones are completed, caused by this.progressVisible = false when 1st word is completed. but trying to remove this condition creates a infinite loop crashing my browser.

davemg3 commented 6 years ago

Your solution with :

and


  data() {
            return {
                isLoading: false,
                failed: false,
                words: [],
                progress: undefined,

            }

        },

This causes also an infinite loop without any display. Tag cloud is working is i remove the progress code. There must be something i didnt get well in the way the lib need to be used i guess. But definitely after different tests, this is

:progress.sync="progress"

which causes above my looping

SeregPie commented 6 years ago

can you upload your code to codepen or to something similar?

davemg3 commented 6 years ago

I never tried codepen before. I will try to achieve a reduced case...

davemg3 commented 6 years ago

Hello Sereg,

Please see https://codepen.io/DaveMG3/pen/LJaarZ (corrected) For testing add just :progress.sync="progress" , (i removed it from the test code as it crashes)

Another one with update:progress https://codepen.io/DaveMG3/pen/MqRYEa

SeregPie commented 6 years ago

Ok. I found the problem. ^^

This is a bug with Vue. I through they fixed it already. The problem is with inline functions. Every time the a property is changed, the inline functions are also recreated. This causes the cloud to recompute. So every time the progress changes, cloud starts the recomputing from the beginning.

Just move the inline functions into the methods.

https://codepen.io/SeregPie/pen/mGYeME

davemg3 commented 6 years ago

Yes i confirm it is working.

VladAnn9 commented 4 years ago

There is no code example on code open. Please update it!

davemg3 commented 4 years ago

@VladAnn9 , your comment feels rude...it seems to be a lack of respect to some coder who gives away free hours of his life for helping others people coding...and Hi!

VladAnn9 commented 4 years ago

@davemg3 sorry, didn't want to be rude or something. Just trying to figure it out. I'm apologize if my comment was rude! Can you explain or provide some code what exactly is working? Will be very thankful!

davemg3 commented 4 years ago

ok sorry...misunderstanding is easy when not using native language....snippets of code were uploaded on Codeopen to simulate the case but after 2 years it has been deleted by the platform. The issue was about using a Progress view while waiting for the computed words to be displayed. It was causing an infinite loop withtou displaying the words but it has been since fixed. I dont know what is your issue but it might not be related to my former one... I cant tell your more as this is a 2 year old bug already forgotten See you

VladAnn9 commented 4 years ago

@davemg3 Yeah, I got your bug, and I have the same right now. Here is how my code looks like: template:

 <vue-word-cloud
      :words="cloudWords"
      @ update:progress="progressHandler"
    >
    </vue-word-cloud>
   <v-progress-circular
        v-if="progress || progress.completedWords !== progress.totalWords"
        :size="100"
        :width="15"
        :value="progress.completedWords"
      >
        {{ progress.completedWords }}
      </v-progress-circular>

script:

 data: function() {
    return {
      progress: undefined
    }
  },
  props: {
    cloudWords: {
      type: Array
    }
  },
  methods: {
    progressHandler(e) {
      this.progress = e
    }
}

something like that. And when I'm using in progress tag progress variable it causes infinite looping.

ABusyProgrammer commented 3 years ago

@SeregPie The progress tracker still returns an infinite loop, for some reason. I followed the instructions above, and when I console.log the progress value, it shows that all words have been loaded; yet, it still remains in an infinite loop. Here is how I've tried to tackled it:

        <vue-word-cloud
          :style="{
            width: wordCloudWidth,
            height: '400px',
          }"
          style="margin: 0 auto;"
          :spacing="0.2"
          :font-size-ratio="5"
          :words="wordCloudData"
          :progress.sync="prog"
          :color="
            ([, , sent]) =>
              sent === 'blu'
                ? '#72CCD7'
                : sent === 'red'
                ? '#EB2D7C'
                : '#273248'
          "
          font-family="Helvetica"
          font-weight="Bold"
        >
          <template slot-scope="{ text, weight, word }">
            <div
              :title="weight"
              :style="
                'cursor: pointer; opacity: ' +
                (selectedWordData === null
                  ? '1'
                  : selectedWordData.word === text
                  ? '1'
                  : '0.15')
              "
              @click="onWordClick(text)"
            >
              {{ text }}
            </div>
          </template>
        </vue-word-cloud>
        <div v-if="prog">
           It is still loading...
        </div>

Data:

  data() {
    return {
      ...
      prog: undefined,
    };
  },

Is there anything I've don't wrong, based on the code above? I tried accessing the codepen.io, but it leads to a 404. Any help would be greatly appreciated,

Thanks in advance 😃