I suggest you ...

Add a word cloud graph

219 votes
Sign in
or sign in with
  • facebook
  • google
    Password icon
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Yuval Lubowich shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →


    Sign in
    or sign in with
    • facebook
    • google
      Password icon
      Signed in as (Sign out)
      • Prithvi Maddi commented  ·   ·  Flag as inappropriate

        I am trying to make a word clickable and trying to change its style mark it as clicked. Is there a way to do that?

      • Harry commented  ·   ·  Flag as inappropriate

        Unstable efficiency. Sometimes take less than a second, sometimes take more than 20 second for the same set of data.

      • Monte Shaffer commented  ·   ·  Flag as inappropriate


        This is the jquery plugin I was working on... It could output to canvas and/or div...

        The place word correctly isn't fully functioning, and so I started working on


        to troubleshoot why.

        I have used highcharts before, and it seems like the best place to develop the final working script. Hence the posts here.

        I don't know your highchart-plugin logic, but I am certain you do. I believe most of the algorithm is outlined, with some minor bugs.

        I am hoping the algorithm logic is outlined well in my two example pages.

        Can your team take over the highchart-plugin? This would benefit me, since I am working on a project that could use this tool, but I am on a 30-day deadline to get a beta-launched, and for now, I can use your 3-d bubble charts.

      • Monte Shaffer commented  ·   ·  Flag as inappropriate


        I believe I have got most of the algorithm finished ...


        It uses the SAT-js algorithm to account for rotation of words, and fit the next words...

        The idea would be ... an input would have the following:

        word: "Big Font", font: "Times, san-serif", size: "14px"

        The system would have a fill region ... width by height, and

        (1) loop over words to compute BBoxes for each, do some calculation to determine that they will fit into the fill region, if not, reduce the "fontFactor" internal number so we know they will fit.

        (2) loop over the words again, based on rotation settings, and place each word... "top" "left" should be the anchor for each word, and rotation should happen from top/left... now rotated, loop through previous bboxes to make certain there isn't a rectangle collision (I also create outside border bboxes). If it doesn't collide, we place the word. If it collides, we loop over the next archimedean spiral location.

        (3) The algorithm basically works here: https://assets.mypatentideas.com/images/fiddle/jquery-words/div.html ... I was trying to write as a jquery plugin, but ignore that (you can look at it, it does have some "stemming" and other functions to allow a text-string input to build the array of words and freq. The core algorithm is the div.html page itself... very linear logic.

        (4) The algorithm would return an array that I could see would easily fit within your highcharts options framework.

      • AdminTorstein Hønsi (CPO, Founder, Highcharts JS) commented  ·   ·  Flag as inappropriate

        A Highcharts plugin would be appreciated! Following the series-point concept, I would expect each word to be a point with a name and a value. The points would be laid out inside the plot area.

        Use the renderer object for text, including its .getBBox function.

        I've set up a boilerplate for you, where I demonstrate rotation, text sizing and tooltip support. Now what's missing is the algorithm itself: http://jsfiddle.net/highcharts/espnodxm/

      • Monte Shaffer commented  ·   ·  Flag as inappropriate

        The placement / collision computations should probably happen as a thread "worker" ... and then you can create as much data as you want.

        If I proceed, I will write as a highcarts plugin, but would prefer if you did so.

        Nice work on highcharts...

      • Monte Shaffer commented  ·   ·  Flag as inappropriate

        You want to allow words to rotate, and not collide, I was using a hidden div approach to identify a particular bbox for a given word, and then sat-js to see if the new word collides with previous words on the screen...

        // Version 0.6.0 - Copyright 2012 - 2016 - Jim Riecken <jimr@jimr.ca>
        // Released under the MIT License - https://github.com/jriecken/sat-js
        // A simple library for determining intersections of circles and
        // polygons using the Separating Axis Theorem.
        /** @preserve SAT.js - Version 0.6.0 - Copyright 2012 - 2016 - Jim Riecken <jimr@jimr.ca> - released under the MIT License. https://github.com/jriecken/sat-js */

        ... with canvas you could do a more expensive, tighter lookup to account for whitespace within a bbox...

        ... also, because these calculations get expensive, you may want to setup as a "worker" in a threaded environment ...

        The basic logic:

        self.options = $.extend(true, {}, $.fn.cloudMe.options, options ); // load options
        self.prepareStopWords(); // snowball, unbc, tennessess, glasgow ... and custom ... [with basic stemming]
        // self.data is generated here

        where drawMe

        first-word is centered, with a given font-size (currently hacked based on freq)
        initialBBOXES (get out-of-frame bboxes)
        first-word added to BBOXES

        NEXT WORD
        .. randomly determine if rotation will occur.
        .. if so, select stepped rotation (we want some order, so rotations align) ... the rotation will alter the corner of the bbox, I rotate around a bbox center...
        .. pick a random element on the screen so the rotated bbox will fit within the frame
        .. see if this bbox doesn't collide with array of BBOXES previously placed (first-word, top-border, bottom-border, left-border, right-border, ... previous NEXT elements)
        .. if it does collide, move the box along an archimedian spiral, and check again ... repeat until placed,
        .. add current word to BBOXES stack, and proceed to next word. I place largest words first... the fontsize and color are related to the frequency of times the word appeared...

        After a few days working on this, I realized it is better within highcharts, if you can make that happen...

        The source (not finished) of the logic is here:


      • Monte Shaffer commented  ·   ·  Flag as inappropriate

        The logic for the word cloud is rather straight forward, and I have been working on a jquery plugin to do the logic.


        I was using canvas to build, but highcharts seems the better solution.

        $.fn.cloudMe.options = {
        data: {
        method: "val", // val for INPUT/TEXTAREA, html for DIV, direct for attachment to obj
        identifier: "#my-text", // for val or html
        object: {}, // you can directly attach
        methods: {
        pluginInitiated: function() {}, // custom function ... object has been initiated ...

        preparePre: function(){}, // called before generic prepare function ... raw data is processing
        preparePost: function(){}, // called after generic prepare function ... raw data is processing

        customWeight: function(){}, // perform a custom weighting on object ... based on n... log(n), sqrt(n), quantile(n)
        prepare: {
        stopwords: {
        enabled: true,
        language: "en",
        lists: ["snowball","tennessee","glasgow","unbc"],
        custom: ["patent","claimed","claim","claims","fig"]
        prepareDefault: true, // call preparePre, then this default function, then preparePost
        removeTabsUnlessFirst: true,
        cleanse72:true, // put in format of 72 characters per line, with line break, and double breaks between paragraphs
        removeNonAlphaNumeric: true,
        stemmer: true, // in the default function, create stem objects as well
        draw: {
        width: 400, // this will override inline style
        height: 600, // this is the DOM size
        dpi: 300, // the canvas will scale for hi-res output ... e.g. 96 dpi (screen) -> 300 dpi (print)
        which: "nonstop", // "original" or "non" (no stop words) or "nonstem" (no stop words, stemmed)
        display: "original", // display the original word (lower cased)
        scale: "n", // "n" is freq, "log(n)", "sqrt(n)"
        weight: "freq", // obj element that is used to determine size
        minFreq: 3, // n >= 3 to be included
        maxWords: 250, // sort on frequency, stop when this many words are displayed ... Inf for Infinite, or 9999999,
        rotateRatio: 0.7, // percent of elements that will be rotated
        rotatePositions: 6, // number of rotated elements "6" means 7 with unrotated rectangle ... should be even here ... or not?
        rotateMin: -30, // degrees to rotate back
        rotateMax: 30, // degrees to rotate forward
        fitSpiral: "Archimedean", // spiral approach to fit the current rectangle
        fitFirst: "center center", // maybe other approaches?
        fitNext: "random", // pic a random place on a screen, maybe a random grid if "workers"
        fontFamily: 'Times, serif',
        fontSizeMin: "12px", // or "8 pt" ... seems like pt is better than px ... or not
        fontSizeMax: "67px", // or "18pt"
        colorMin: '#ff0000',
        colorMax: '#000000',
        fontColorSteps: 11, // how many color/font combos (linked) ... numeric font-sizes (8,18px = 11 steps)
        method: "canvas", // DOM as backup
        title: "{word} appeared <BR /> {freq} times" // if DOM, append to title as "tooltip" with details for each span, {elements} must be object identifiers within a single element

      Feedback and Knowledge Base