Search code examples
javascripthtml3dword-cloud

d3 Word Cloud in Javascript - Can't use update function


I'm using the d3 word cloud (https://github.com/jasondavies/d3-cloud). It works pretty well, but I need to update the words every time I click a button. In the code that I found there is an "update" function declared in the return of another function as in the end of the code below:

function wordCloud(selector) {
    //lookForWords();
    var fill = d3.scale.category20();

    //Construct the word cloud's SVG element
    $(selector).html("");
    var svg = d3.select(selector).append("svg")
        .attr("width", 1000)
        .attr("height", 800)
        .append("g")
        .attr("transform", "translate(250,250)");

    $("svg").css('position','absolute');
    $("svg").css('top','250px');
    $("svg").css('left','500px');
    $("svg").css('overflow','visible');
    //Draw the word cloud
    function draw(words) {

        var cloud = svg.selectAll("g text")
                        .data(words, function(d) { return d.text; })

        //Entering words
        cloud.enter()
            .append("text")
            .style("font-family", "Impact")
            .style("fill", function(d, i) { return fill(i); })
            .attr("text-anchor", "middle")
            .attr('font-size', 1)
            .text(function(d) { return d.text; });

        //Entering and existing words
        cloud
            .transition()
                .duration(3500)
                .style("font-size", function(d) { return d.size + "px"; })
                .attr("transform", function(d) {
                    return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
                })
                .style("fill-opacity", 1);

        //Exiting words
        cloud.exit()
            .transition()
                .duration(3500)
                .style('fill-opacity', 1e-6)
                .attr('font-size', 1)
                .remove();
    }


    //Use the module pattern to encapsulate the visualisation code. We'll
    // expose only the parts that need to be public.
    return {

        //Recompute the word cloud for a new set of words. This method will
        // asycnhronously call draw when the layout has been computed.
        //The outside world will need to call this function, so make it part
        // of the wordCloud return value.
        update: function(words) {
            d3.layout.cloud().size([1000, 1000])
                .words(words)
                .padding(1)
                .rotate(function() { return ~~(Math.random() * 2) * 90; })
                .font("Impact")
                .fontSize(function(d) { return d.size; })
                .on("end", draw)
                .start();
        }
    }

}

I couldn't find a info about it online. How can I call this function from the "outside world"?


Solution

  • wordCloud(selector) returns an object that contains the update method.

    So, this should work:

    var wordCloud = wordCloud("#myDiv");
    
    wordCloud.update(myWords);