wordcloud2.js icon indicating copy to clipboard operation
wordcloud2.js copied to clipboard

How to make sure all words are displayed in canvas

Open ia3andy opened this issue 11 years ago • 4 comments

Thanks for your very good plugin!

In my case, the weight of each words is a number of occurrences. I use the weightFactor function in order to normalize it. The problem is depending on the rotation random some big weighted words are shown or not. I can change de size of my canvas but by doing so I have sometimes big empty places.

  • Having some normalize functions choices would be a good enhancement (linear, exp, ..., custom).
  • Being able to have the size (height or width) of the canvas calculated automatically would be good as well.. Maybe having a function for rotation would be a solution since you can choose if you want to rotate depending on the weight...
  • I spent quite some time on your wordcloud code looking for a way to have the hover word highlighted. I found your fixed issue but no explanation on how to do so. At the end I found that you use a absolute div (no pointer-event) that you place using dimensions provided by the hover callback. You should say it in your doc :)

Thanks again

ia3andy avatar Dec 14 '13 12:12 ia3andy

Hi!

In my case, the weight of each words is a number of occurrences. I use the weightFactor function in order to normalize it. The problem is depending on the rotation random some big weighted words are shown or not. I can change de size of my canvas but by doing so I have sometimes big empty places.

Having some normalize functions choices would be a good enhancement (linear, exp, ..., custom). Being able to have the size (height or width) of the canvas calculated automatically would be good as well.. Maybe having a function for rotation would be a solution since you can choose if you want to rotate depending on the weight...

Indeed. While there is a custom function to specify the color or weight of a specific word, there isn't a function for rotateRatio. It's possible to patch the code and have it doing so.

I spent quite some time on your wordcloud code looking for a way to have the hover word highlighted. I found your fixed issue but no explanation on how to do so. At the end I found that you use a absolute div (no pointer-event) that you place using dimensions provided by the hover callback. You should say it in your doc :)

The demo page is part of the documentation. This can be made obvious on the doc. Doc sometimes leave important detail because of my inability as non-native English speaker to write great doc, compare to code -- patch to fix either or both is very welcome :)

timdream avatar Dec 16 '13 02:12 timdream

BTW you could listen to wordclouddrawn event and access it's drawn property to tell the word have been drawn or not.

timdream avatar Dec 16 '13 02:12 timdream

I went into a similar issue today. I found out, that the ordering of the entries is pretty relevant. It seems the the cloud is built inside out. So it might make sense to place the longest words first.

bwl21 avatar Mar 04 '19 14:03 bwl21

@timdream thank you so much for making this man!

Feedback: I thought "woudclouddrawn" was triggered when the whole cloud was finished drawing, however after reading this thread, it is indeed every time a word is drawn.

Using typescript, one can subscribe to the event like this:

document.getElementById('wordcloud-canvas-container').addEventListener('wordclouddrawn', (data : any) => this.onWordCloudDrawn(data));

wordcloud-canvas-container being a div around a canvas:

<div id="wordcloud-canvas-container">
    <canvas id="wordcloud-canvas" width="{{getCanvasWidth()}}" height="{{getCanvasHeight()}}"></canvas>
</div>

Then do something with it in onWordCloudDrawn(), eg print it in the console:

onWordCloudDrawn(eventData : any){
    console.log("Word cloud drawn", eventData);
}

The data has a "detail" property with important information, so my onWordCloudDrawn is actually:

onWordCloudDrawn(eventData : eventData){
    //console.log("Word cloud drawn", eventData);
    console.log(eventData.detail.item[0], eventData.detail.item[1], eventData.detail.drawn);
}

And then eventData is an interface, where I'm able to get the information I'm interested in:

export interface eventData {
    detail : { 
        drawn: boolean, 
        item: string | number [] 
    }
}

For my own project, I'm going to check if all words has been drawn, and then re-scale using the weightFactor property, or let users adjust it and re-draw.

This comment is only to provide a bit of feedback to you, as well as tell others what I was looking for reading this thread 😄

PeterOeClausen avatar Oct 24 '19 13:10 PeterOeClausen