Loading ...
Sorry, an error occurred while loading the content.

Re: Help getting tree working!

Expand Messages
  • Felix Rabinovich
    I ve been grokking this example and have come to a somewhat philosophical dilemma (or, rather, trilemma :) As Eric s article correctly notes, the number of
    Message 1 of 10 , Jan 1, 2007
    • 0 Attachment
      I've been grokking this example and have come to a somewhat
      philosophical dilemma (or, rather, trilemma :)

      As Eric's article correctly notes, the number of nodes in a treeview
      can become very big very quickly. There is additional problem that
      when these trees are coming from server, it could also be
      unpredictable. In the article
      (http://yuiblog.com/sandbox/yui/v0113/examples/treeview/dyn_ld.php)
      the code assumes that the model nodes (eg., "3 series" or "V50")
      *don't* have children - so it's safe to make them leaves. In dynamic
      application you can't make such assumption.

      Anyway, I can think of three ways of designing the treeView:

      1. Get all nodes from the server and build the tree before displaying
      it for the first time. Of course, the complexity of the tree may be
      overwhelming. Coding-wise, though, it's the simplest.

      2. Get all nodes from the server; build the top level values and keep
      everything in an Array. When the user clicks to expand one branch,
      rebuild the appropriate branch from this array. The advantage: it's
      easy to determine whether the node has children (and should be
      depicted as such). Also, it's quite fast to build a branch in response
      to user's click. Con: Building such array is an overhead, and,
      needless to say, this array may be too big to handle, anyway. So, the
      question is - does building an array give significant enough
      advantages vs. building DOM tree to warrant such approach?

      3. Do everything completely dynamically. That is, build the top-level
      nodes from the server (including determining whether particular nodes
      have children or not); and then in response to a click go to the
      server and build the appropriate branch (again, checking the presence
      of children nodes).

      I hope my little dissertation makes sense. Maybe even somebody already
      discussed it (but I couldn't find it). Obviously, a lot depends on the
      size of the tree and latency of the server. With 100-node tree first
      approach is just fine; with million node product database on a fast
      Intranet server the third approach looks most appealing.

      But what about the middle? Was any testing done to guide when it is
      time to switch away from building whole tree in the client?

      Does second approach give any advantages?

      Thank you

      --- In ydn-javascript@yahoogroups.com, Eric Miraglia <miraglia@...> wrote:
      >
      > jmpow99,
      >
      > I've revised the posted example to address the issue of capturing the
      > node the user has clicked. Note that in the custom data object
      > passed into the TextNode constructor you can specify not just a label
      > member, as the example now shows, but an href member as well. That
      > href member can have the full URL, including querystring parameters,
      > to which you want the user to navigate when the label is clicked — a
      > common operation for a leaf node. If you want to do more
      > sophisticated markup for your Node label, you may want to consider
      > using an HTMLNode instead of a TextNode. The first argument for an
      > HTML node is the full markup for the Node's label, and that can be as
      > customized as you'd like.
      >
      > http://yuiblog.com/sandbox/yui/v0113/examples/treeview/dyn_ld.php
      >
      > Regards,
      > Eric
      >
      > ______________________________________________
      > Eric Miraglia
      > Yahoo! Presentation Platform Engineering
      >
      >
      > On Sep 26, 2006, at 6:56 AM, jmpow99 wrote:
      >
      > > Thank you Eric, much appreciated. I have things up and running now.
      > >
      > > A couple additional things I don't understand how to do with my
      > > example:
      > >
      > > How do I capture the node that the user clicks? I will need to grab
      > > that information to make my database call.
      > >
      > > Also, for each item in the tree, I want to build a hyperlink with
      > > parameters. What is the best way to go about this?
      > >
      > > I have looked everywhere for examples of a tree like this. Since I'm
      > > not used to javascript (out of my J2EE comfort zone), I rely on a good
      > > example, but havent' had any luck finding one)
      > >
      > > Thanks again!
      > >
      > > --- In ydn-javascript@yahoogroups.com, Eric Miraglia <miraglia@>
      > > wrote:
      > > >
      > > > jmpow99,
      > > >
      > > > I've taken your code below and reworked it a bit to make it
      > > > functional; take a look here:
      > > >
      > > > http://yuiblog.com/sandbox/yui/v0113/examples/treeview/dyn_ld.php
      > > >
      > > > There were a few issues in the code you pasted in here. Your
      > > > singleton was not formed correctly and it wasn't clear that all of
      > > > the functions were well-formed. However, without too many changes
      > > > your code appears to work as desired, so you were definitely on the
      > > > right track.
      > > >
      > > > Take a look at the functional example and let us know how things go
      > > > from there.
      > > >
      > > > Regards,
      > > > Eric
      > > >
      > > >
      > > >
      > > > Eric Miraglia
      > > > Yahoo! Presentation Platform Engineering
      > > >
      > > >
      > > >
      > > > On Sep 25, 2006, at 2:13 PM, jmpow99 wrote:
      > > >
      > > > > I took Yahoo's dynamic tree example and started making changes to
      > > > > statically simulate what calling the database. All data is in
      > > Arrays.
      > > > > The buildTree method gets the first Array loaded up as the
      > > root. All
      > > > > good.
      > > > >
      > > > > Now, I want to take the node the user clicks (call db with that
      > > id)
      > > > > then load up that parent node with an array of it's children.
      > > > >
      > > > > I can't seem to figure out the next steps:
      > > > >
      > > > > 1.) How do I get a handle on the node the user clicked?
      > > > > 2.)When I have the array of children, I'm looping through, how
      > > do I
      > > > > assign them to their parent? This loop will only be for one
      > > parent at
      > > > > a time.
      > > > >
      > > > > Thanks everyone, couldn't do it without these groups sharing
      > > > > knowledge!
      > > > >
      > > > > Here is my current code:
      > > > >
      > > > > /*create namespace for examples:*/
      > > > > YAHOO.namespace("example");
      > > > >
      > > > > /* Using Crockford's "Module Pattern": */
      > > > > YAHOO.example.treeExample = function() {
      > > > >
      > > > > function buildTree() {
      > > > >
      > > > >
      > > > > //create a new tree:
      > > > > tree = new YAHOO.widget.TreeView("treeContainer");
      > > > >
      > > > > //turn dynamic loading on for entire tree:
      > > > > tree.setDynamicLoad(loadNodeData, currentIconMode);
      > > > >
      > > > > //get root node for tree:
      > > > > var root = tree.getRoot();
      > > > >
      > > > > //create dummy data for root
      > > > > var mycars = new Array()
      > > > > mycars[0] = "Saab"
      > > > > mycars[1] = "Volvo"
      > > > > mycars[2] = "BMW"
      > > > > mycars[3] = "Ferrari"
      > > > > mycars[4] = "Yugo"
      > > > > mycars[5] = "Bentley"
      > > > >
      > > > > for (i=0;i<mycars.length;i++)
      > > > > {
      > > > >
      > > > > new YAHOO.widget.TextNode(mycars[i], root, false);
      > > > >
      > > > > }
      > > > >
      > > > > tree.draw();
      > > > > }
      > > > >
      > > > >
      > > > >
      > > > > function loadNodeData(node, fnLoadComplete) {
      > > > >
      > > > >
      > > > >
      > > > > //dummy data for bmw parent
      > > > > var bmws = ["3 series","m series","5 series","7 series","6
      > > series"];
      > > > >
      > > > > var children = bmws;
      > > > >
      > > > >
      > > > > //loop through children array and need to load up the bmw parent.
      > > > > How to do this???
      > > > > for (var i=0; i<children.length; i++) {
      > > > > thisModel = children[i];
      > > > > var newNode = new YAHOO.widget.TextNode(thisModel, node, false);
      > > > > }
      > > > >
      > > > > fnLoadComplete();
      > > > > }
      > > > >
      > > > >
      > > > > YAHOO.util.Event.addListener(window, "load",
      > > > > YAHOO.example.treeExample.init, YAHOO.example.treeExample,true)
      > > > >
      > > > >
      > > > >
      > > >
      > >
      > >
      > >
      >
    • smeep2k4
      I went with Option 3 for two reasons. First, it took the least amount of processing time overall (users can be so impatient!). Second, in the app that I
      Message 2 of 10 , Jan 2, 2007
      • 0 Attachment
        I went with Option 3 for two reasons. First, it took the least amount
        of processing time overall (users can be so impatient!). Second, in
        the app that I built (a call tree app), you usually have an idea of
        where you might want to go, so showing everything would be a waste of
        time. And when you consider that a subroutine could call many
        subroutines that call many more subroutines, I found that the tree
        would get huge if I were to use method 1 (taking a very long time to
        come back unless I imposed an artificial limit). This app creates a
        root node. Then, when the user clicks the node, it hits the server to
        bring back subroutines that this particular subroutine calls. Then,
        when the user clicks one of those nodes, it hits the server again, ad
        nauseum.

        The only problem I found overall is that I had to learn alot about how
        the YUI components work because there is absolutely no documentation
        anywhere that shows a TreeView/Connection Manager combination. Sure,
        there are articles that talk about it and how cool it is to have both
        in the same application, but try actually finding example code. Nada!


        --- In ydn-javascript@yahoogroups.com, "Felix Rabinovich" <felix@...>
        wrote:
        >
        > I've been grokking this example and have come to a somewhat
        > philosophical dilemma (or, rather, trilemma :)
        >
        > As Eric's article correctly notes, the number of nodes in a treeview
        > can become very big very quickly. There is additional problem that
        > when these trees are coming from server, it could also be
        > unpredictable. In the article
        > (http://yuiblog.com/sandbox/yui/v0113/examples/treeview/dyn_ld.php)
        > the code assumes that the model nodes (eg., "3 series" or "V50")
        > *don't* have children - so it's safe to make them leaves. In dynamic
        > application you can't make such assumption.
        >
        > Anyway, I can think of three ways of designing the treeView:
        >
        > 1. Get all nodes from the server and build the tree before displaying
        > it for the first time. Of course, the complexity of the tree may be
        > overwhelming. Coding-wise, though, it's the simplest.
        >
        > 2. Get all nodes from the server; build the top level values and keep
        > everything in an Array. When the user clicks to expand one branch,
        > rebuild the appropriate branch from this array. The advantage: it's
        > easy to determine whether the node has children (and should be
        > depicted as such). Also, it's quite fast to build a branch in response
        > to user's click. Con: Building such array is an overhead, and,
        > needless to say, this array may be too big to handle, anyway. So, the
        > question is - does building an array give significant enough
        > advantages vs. building DOM tree to warrant such approach?
        >
        > 3. Do everything completely dynamically. That is, build the top-level
        > nodes from the server (including determining whether particular nodes
        > have children or not); and then in response to a click go to the
        > server and build the appropriate branch (again, checking the presence
        > of children nodes).
        >
        > I hope my little dissertation makes sense. Maybe even somebody already
        > discussed it (but I couldn't find it). Obviously, a lot depends on the
        > size of the tree and latency of the server. With 100-node tree first
        > approach is just fine; with million node product database on a fast
        > Intranet server the third approach looks most appealing.
        >
        > But what about the middle? Was any testing done to guide when it is
        > time to switch away from building whole tree in the client?
        >
        > Does second approach give any advantages?
        >
        > Thank you
        >
        > --- In ydn-javascript@yahoogroups.com, Eric Miraglia <miraglia@> wrote:
        > >
        > > jmpow99,
        > >
        > > I've revised the posted example to address the issue of capturing
        the
        > > node the user has clicked. Note that in the custom data object
        > > passed into the TextNode constructor you can specify not just a
        label
        > > member, as the example now shows, but an href member as well. That
        > > href member can have the full URL, including querystring parameters,
        > > to which you want the user to navigate when the label is clicked — a
        > > common operation for a leaf node. If you want to do more
        > > sophisticated markup for your Node label, you may want to consider
        > > using an HTMLNode instead of a TextNode. The first argument for an
        > > HTML node is the full markup for the Node's label, and that can be
        as
        > > customized as you'd like.
        > >
        > > http://yuiblog.com/sandbox/yui/v0113/examples/treeview/dyn_ld.php
        > >
        > > Regards,
        > > Eric
        > >
        > > ______________________________________________
        > > Eric Miraglia
        > > Yahoo! Presentation Platform Engineering
        > >
        > >
        > > On Sep 26, 2006, at 6:56 AM, jmpow99 wrote:
        > >
        > > > Thank you Eric, much appreciated. I have things up and running now.
        > > >
        > > > A couple additional things I don't understand how to do with my
        > > > example:
        > > >
        > > > How do I capture the node that the user clicks? I will need to grab
        > > > that information to make my database call.
        > > >
        > > > Also, for each item in the tree, I want to build a hyperlink with
        > > > parameters. What is the best way to go about this?
        > > >
        > > > I have looked everywhere for examples of a tree like this. Since I'm
        > > > not used to javascript (out of my J2EE comfort zone), I rely on
        a good
        > > > example, but havent' had any luck finding one)
        > > >
        > > > Thanks again!
        > > >
        > > > --- In ydn-javascript@yahoogroups.com, Eric Miraglia <miraglia@>
        > > > wrote:
        > > > >
        > > > > jmpow99,
        > > > >
        > > > > I've taken your code below and reworked it a bit to make it
        > > > > functional; take a look here:
        > > > >
        > > > > http://yuiblog.com/sandbox/yui/v0113/examples/treeview/dyn_ld.php
        > > > >
        > > > > There were a few issues in the code you pasted in here. Your
        > > > > singleton was not formed correctly and it wasn't clear that all of
        > > > > the functions were well-formed. However, without too many changes
        > > > > your code appears to work as desired, so you were definitely
        on the
        > > > > right track.
        > > > >
        > > > > Take a look at the functional example and let us know how
        things go
        > > > > from there.
        > > > >
        > > > > Regards,
        > > > > Eric
        > > > >
        > > > >
        > > > >
        > > > > Eric Miraglia
        > > > > Yahoo! Presentation Platform Engineering
        > > > >
        > > > >
        > > > >
        > > > > On Sep 25, 2006, at 2:13 PM, jmpow99 wrote:
        > > > >
        > > > > > I took Yahoo's dynamic tree example and started making
        changes to
        > > > > > statically simulate what calling the database. All data is in
        > > > Arrays.
        > > > > > The buildTree method gets the first Array loaded up as the
        > > > root. All
        > > > > > good.
        > > > > >
        > > > > > Now, I want to take the node the user clicks (call db with
        that
        > > > id)
        > > > > > then load up that parent node with an array of it's children.
        > > > > >
        > > > > > I can't seem to figure out the next steps:
        > > > > >
        > > > > > 1.) How do I get a handle on the node the user clicked?
        > > > > > 2.)When I have the array of children, I'm looping through, how
        > > > do I
        > > > > > assign them to their parent? This loop will only be for one
        > > > parent at
        > > > > > a time.
        > > > > >
        > > > > > Thanks everyone, couldn't do it without these groups sharing
        > > > > > knowledge!
        > > > > >
        > > > > > Here is my current code:
        > > > > >
        > > > > > /*create namespace for examples:*/
        > > > > > YAHOO.namespace("example");
        > > > > >
        > > > > > /* Using Crockford's "Module Pattern": */
        > > > > > YAHOO.example.treeExample = function() {
        > > > > >
        > > > > > function buildTree() {
        > > > > >
        > > > > >
        > > > > > //create a new tree:
        > > > > > tree = new YAHOO.widget.TreeView("treeContainer");
        > > > > >
        > > > > > //turn dynamic loading on for entire tree:
        > > > > > tree.setDynamicLoad(loadNodeData, currentIconMode);
        > > > > >
        > > > > > //get root node for tree:
        > > > > > var root = tree.getRoot();
        > > > > >
        > > > > > //create dummy data for root
        > > > > > var mycars = new Array()
        > > > > > mycars[0] = "Saab"
        > > > > > mycars[1] = "Volvo"
        > > > > > mycars[2] = "BMW"
        > > > > > mycars[3] = "Ferrari"
        > > > > > mycars[4] = "Yugo"
        > > > > > mycars[5] = "Bentley"
        > > > > >
        > > > > > for (i=0;i<mycars.length;i++)
        > > > > > {
        > > > > >
        > > > > > new YAHOO.widget.TextNode(mycars[i], root, false);
        > > > > >
        > > > > > }
        > > > > >
        > > > > > tree.draw();
        > > > > > }
        > > > > >
        > > > > >
        > > > > >
        > > > > > function loadNodeData(node, fnLoadComplete) {
        > > > > >
        > > > > >
        > > > > >
        > > > > > //dummy data for bmw parent
        > > > > > var bmws = ["3 series","m series","5 series","7 series","6
        > > > series"];
        > > > > >
        > > > > > var children = bmws;
        > > > > >
        > > > > >
        > > > > > //loop through children array and need to load up the bmw
        parent.
        > > > > > How to do this???
        > > > > > for (var i=0; i<children.length; i++) {
        > > > > > thisModel = children[i];
        > > > > > var newNode = new YAHOO.widget.TextNode(thisModel, node, false);
        > > > > > }
        > > > > >
        > > > > > fnLoadComplete();
        > > > > > }
        > > > > >
        > > > > >
        > > > > > YAHOO.util.Event.addListener(window, "load",
        > > > > > YAHOO.example.treeExample.init, YAHOO.example.treeExample,true)
        > > > > >
        > > > > >
        > > > > >
        > > > >
        > > >
        > > >
        > > >
        > >
        >
      • Eric Miraglia
        ... Felix, Your dissertation makes good sense, yes. And I think the paragraph above highlights the key factors you need to account for in making your
        Message 3 of 10 , Jan 2, 2007
        • 0 Attachment
          On Jan 1, 2007, at 12:57 PM, Felix Rabinovich wrote:

          I hope my little dissertation makes sense. Maybe even somebody already
          discussed it (but I couldn't find it). Obviously, a lot depends on the
          size of the tree and latency of the server. With 100-node tree first
          approach is just fine; with million node product database on a fast
          Intranet server the third approach looks most appealing.

          Felix,

          Your dissertation makes good sense, yes.  And I think the paragraph above highlights the key factors you need to account for in making your decision.  

          I would just add one item, though, to the mix: In a fully dynamic tree where all data lives on the server side, when you expand a node you will go to the server to get a list of children for that node.  This is the "classic" usage pattern.  However, you can ask the server, when returning child nodes for an expanding node, to also return a child count for each new child.  New children who themselves have no children can be created as leaf nodes, dynamic loading can be turned off for those nodes, etc.

          Beyond that, I think your analysis is quite thorough.  There won't be a single answer that works for everyone.  However, an array even of several thousand nodes, depending on usage and data, should perform well in most browsers; full rendering of a TreeView at page load when there are more than 100 nodes is probably a bad idea in most cases.   And doing some user testing to determine how often a user will interact with the tree and how many clicks per interaction will help guide your decisions as well.

          Regards,
          Eric

          ______________________________________________
          Eric Miraglia
          Yahoo! User Interface Library



        • Felix Rabinovich
          I can second that! It seems to me that creating TextNode in handleSuccess() doesn t do anything on the screen. I haven t done a stand-alone snippet (my code is
          Message 4 of 10 , Jan 2, 2007
          • 0 Attachment
            I can second that! It seems to me that creating TextNode in
            handleSuccess() doesn't do anything on the screen.

            I haven't done a stand-alone snippet (my code is in tpl files talking
            to PHP on the server), but FireBug shows that the values in the new
            YAHOO.widget.TextNode() call are all good. In fact, I just call

            var tmpNode = new YAHOO.widget.TextNode(
            { label: "Success", href: "main.php"}, tree.getRoot(), false);

            I see that the code gets executed - but there is nothing on the screen :(

            Is there any example that has TreeView/Connection Manager combination?

            --- In ydn-javascript@yahoogroups.com, "smeep2k4" <wilsondr@...> wrote:
            > The only problem I found overall is that I had to learn alot about how
            > the YUI components work because there is absolutely no documentation
            > anywhere that shows a TreeView/Connection Manager combination. Sure,
            > there are articles that talk about it and how cool it is to have both
            > in the same application, but try actually finding example code. Nada!
          • Alan Pinstein
            Thanks for this idea... I just figured out how to do this part in practice. I ve posted a live example if others are interested:
            Message 5 of 10 , Feb 9, 2007
            • 0 Attachment
              Thanks for this idea... I just figured out how to do this part in practice. I've posted a live example if others are interested:


              The key is setting:

              node.dynamicLoadComplete = true;

              On nodes that you're certain have no kids.

              This *greatly* improves the interface! Thanks for pointing me in the right direction.

              Thanks,
              Alan

              On Jan 2, 2007, at 11:03 AM, Eric Miraglia wrote:

              I would just add one item, though, to the mix: In a fully dynamic tree where all data lives on the server side, when you expand a node you will go to the server to get a list of children for that node.  This is the "classic" usage pattern.  However, you can ask the server, when returning child nodes for an expanding node, to also return a child count for each new child.  New children who themselves have no children can be created as leaf nodes, dynamic loading can be turned off for those nodes, etc.


            Your message has been successfully submitted and would be delivered to recipients shortly.