Parsing a taxonomy tree in Flash Actionscript 3

I often need to integrate Flash AS3 elements into Drupal projects. Something made very easy by the great AS3 Drupal Proxy and Drupal AMFServer module from the guys at DPDK. Of the structures that are returned by the default Services module, the taxonomy tree needs a little more processing than most.

In order to parse the taxonomy tree in my AS3 frontend code I use the recursive function shown below (here on its own, stripped a bit - by default part of a DrupalUtils helper class & returning a as3ds tree).

As an aside: because Actionscript 3.0 primitive types like ints are immutable (in effect passing-by-value), I wrap the variable that keeps track of the callee level in a separate Reference class (enabling passing-by-reference) to forgo global variables, a no-no in recursive functions.

package org.drupal.amfserver
{
    ...

    public class DrupalNewsServer extends MovieClip
    {

        ...

        public function DrupalNewsServer()
        {
            ...
            proxy = new DrupalProxy(endpoint,DrupalProxy.VERSION_7);
            proxy.setHandler("taxonomy_vocabulary", "getTree", onTreeResult, onStatus);
            sequence.add(new CallBackTask(proxy.setRemoteCallId, "taxonomy_vocabulary.getTree(2)"));
            sequence.add(new DrupalInvokeTask(proxy, "taxonomy_vocabulary", "getTree", 2));

            sequence.execute();
        }       
       
        private function onTreeResult(data : DrupalData):void
        {
            parseDrupalTree(data.getData());
        }       

        /********************/
        /* recursive parser */
        /********************/

        public function parseDrupalTree( obj : *, level : int = 0, parentTid: int = 0,
                                         main_level:Reference=null):void
        {
            if (!main_level)
            {
                main_level = new Reference();
                main_level.value = 0;
            }
           
            // tabs for testing by trace
            var tabs:String = "";
            for (var i : int = 0; i < level; i++)
            {
                tabs += "\t\t";
            }

            var level_array = new Array();
            for (var prop:String in obj)
            {
                if (obj[prop].depth == level
                    && obj[prop].parents.indexOf(String(parentTid)) != -1
                    && level_array.indexOf(obj[prop].tid) == -1)
                {
                    if (level>main_level.value)
                    {
                        // do things on down tree
                        level_array.splice(0);
                    }
                    if (level<main_level.value)
                    {   
                        // do things on up tree
                        level_array.splice(0);
                    }
                    level_array.push(obj[prop].tid);
                    // trace
                    trace( tabs + "[" + obj[prop].tid + "] " + obj[prop].name + " level " + level);
                    main_level.value = level;
                    parseDrupalTree( obj, level + 1, obj[prop].tid, main_level);
                }
            }
        }
    }
}

class Reference {
    public var value:*;
}

The result is a nicely indented taxonomy tree:

[1] Milieu level 0
                [7] Subthema 3 level 1
                [8] Subthema 4 level 1
[3] Scholen level 0
                [7] Subthema 3 level 1
                [9] Subthema 5 level 1
[4] Educatie level 0
                [5] Subthema 1 level 1
                                [7] Subthema 3 level 2
                [6] Subthema 2 level 1
[2] Vrouwen level 0
                [10] Subthema 6 level 1

When used with as3ds tree structure this translates for example into the following (AS3 application screenshot):

Comments

rolf's picture

Hi Robin, nice read and

Hi Robin,
nice read and thanks for the props. any reason why you do not use the tree structure from the dpdk package also? I actually made those datastructures to provide a more comprehensive api than the polygonal one (which is an
excellent and fast implementation by the way).
greetz!

admin's picture

Hi Rolf, I didn't use the

Hi Rolf,
I didn't use the tree structure from the dpdk package because I didn't know one existed. Great that it provides a more comprehensive API! I will look it up and update my post to reflect my findings.
Thanks!

Post new comment

14 + 1 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.