1. #1
    Sencha User
    Join Date
    Jan 2010
    Posts
    125
    Vote Rating
    1
    Answers
    2
    darkling235 is on a distinguished road

      0  

    Default Answered: Tree Panel new appearance

    Answered: Tree Panel new appearance


    I'm trying to create a new Organization Tree structure. GWT in general doesn't seem to have a ton of options for this (if anyone does know a good one please let me know because that could save me a ton of work) and I'm trying to make a new appearance for the TreeGrid to do the job.

    Our current OrgChart looks like this (the one in the middle)

    tree.jpg




    We're currently using a javascript library called InfoVis JIT. It's not bad certainly but having native javascript embedded in our GWT is a maintenance issue and we'd like to improve the look and feel of the chart anyway.

    Can anyone make some recommendations about how to go about creating this new TreeAppearance? I've made appearances before but this is more complicated than anything I've done to date. Basically the idea is a hierarchical tree with all siblings appearing side by side and opening on click to show their children below them.
    Has anyone done anything like this or can give me some guidance about where to start? Or even for a first step: Which would be easier? To rework TreeGrid or to rework Tree to show siblings side by side and hierarchical data?

    If I managed to pull off the "horizontal tree" phase two might be to do some logic to manage keeping specific nodes in focus as the thing expands although that's just a Nice-To-Have. Any help would be much appreciated.
    Thanks.

  2. Couple of thoughts:

    The drawing you have going is more of a graph visualization than a tree - I'm making this distinction to suggest that HTML is probably not sufficient to draw this. The angle of the lines between nodes alone is going to make this difficult - while some browsers support CSS that could make this happen, its not something that can be implemented for all browsers that GXT supports.

    That said, I've seen this done for GXT 2, though with lines at right angles to each other. The basic idea is to build a table for each parent node, with the following structure:

    Code:
    +-----+-----+
    |parent node|
    +-----+-----+
    |     |     |
    +-----+-----+
    | children  |
    +-----------+
    The table has three rows - the first is just to draw the current node, which spans the full width of the row. The second then exists just to draw the center line to go down to the next level - no content in the cells, just a border between the two cells. The third row then holds all children, so that as it grows, it expands the first two rows to make them fit better. I think you may need several cells in that last row, one for each child, and then to set colspans on the second row to keep it even. Wait-- forgot one - you need one more row above the whole thing as a line *in* to the parent node - you may omit this for the root node.

    The child cells then need three styles - first-child, last-child, and child. The regular child has a line above it, the first-child has a line above the right half of it, and the last child has a line above the right half of it:
    Code:
    +------+-------+------+
    |      |   |   |      |
    |--+---|---+---|---+--|
    |  |   |   |   |   |  |
    |child | child | child|
    +---------------------+
    Table lines that should be drawn in bold - note that the line above the word 'child' is actually part of the child.

    This whole process then assumes that each set of children dom elements will be nested into a parent dom element - that recursive dom structure is what gives the existing Tree its shape as well.

    TreeAppearance will need a complete re-implementation to do this. The guts will be in renderNode, which will draw each element (something like the first table I mentioned). Then, the various finder methods will need a custom setup to find the nodes that they describe - checking out existing implementations and usages for what these each are specifically for:
    Code:
        XElement findIconElement(XElement target);
    
        XElement findJointElement(XElement target);
    
        XElement getCheckElement(XElement container);
    
        XElement getContainerElement(XElement node);
    
        XElement getIconElement(XElement container);
    
        XElement getJointElement(XElement container);
    
        XElement getTextElement(XElement container);
    The Tree needs to be able to modify specific nodes as things expand/collapse, etc. These methods are responsible for that work:
    Code:
        XElement onCheckChange(XElement node, XElement checkElement, boolean checkable, CheckState state);
    
        XElement onJointChange(XElement node, XElement jointElement, Joint joint, TreeStyle ts);
    
        void onSelect(XElement node, boolean select);
    
       /*If supporting DnD*/
        void onDropOver(XElement node, boolean over);
    
        void onHover(XElement node, boolean over);
    And last (from my quick glance, you may find more methods that are important, but these are the landmark ones), the Tree needs to be able to ask questions about what the user is clicking on - these methods let the tree find out what the user is doing:
    Code:
        boolean isCheckElement(XElement target);
    
        boolean isJointElement(XElement target);
    Instead, a visualization package just draws elements on the page and positions them, whether it is done in a browser, or elsewhere. In this case, you do the bookkeeping of relative positioning in memory, not in any dom structure. This is how the various charts on the right half of your screen are implemented in GXT 3.

    The DrawComponent class allows any sprites to be added to it anywhere - LineSprites could make up the dashes between nodes (or a single PathSprite, using LineTo commands to draw, and MoveTo to get to the next position). ImageSprite or TextSprite or both then could be used to actually build each node. Depending on the size/distribution of the tree, you might want to start at the top and center the first node, then work your way down (easier approach, good for a smaller number of nodes) or walk depth-first and render nodes starting at the bottom-left corner, making children and parents fit where they can. If there are not enough nodes to reach to the top, just adjust all nodes to fit - if there are too many, then some kind of scrolling or expand/collapse mechanism will be required. Consider the use of TextMetrics to measure how large a string will be when deciding how much room you need.

    This isn't an easy problem, and there is no canned answer for all cases, so we haven't built the One True Horizontal Tree and shipped it in GXT. Teams that need this typically have very specific requirements - DnD, icons drawn around/in nodes, specific scrolling or expanding features

  3. #2
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Posts
    2,023
    Vote Rating
    57
    Answers
    79
    Colin Alworth is a jewel in the rough Colin Alworth is a jewel in the rough Colin Alworth is a jewel in the rough Colin Alworth is a jewel in the rough

      0  

    Default


    Couple of thoughts:

    The drawing you have going is more of a graph visualization than a tree - I'm making this distinction to suggest that HTML is probably not sufficient to draw this. The angle of the lines between nodes alone is going to make this difficult - while some browsers support CSS that could make this happen, its not something that can be implemented for all browsers that GXT supports.

    That said, I've seen this done for GXT 2, though with lines at right angles to each other. The basic idea is to build a table for each parent node, with the following structure:

    Code:
    +-----+-----+
    |parent node|
    +-----+-----+
    |     |     |
    +-----+-----+
    | children  |
    +-----------+
    The table has three rows - the first is just to draw the current node, which spans the full width of the row. The second then exists just to draw the center line to go down to the next level - no content in the cells, just a border between the two cells. The third row then holds all children, so that as it grows, it expands the first two rows to make them fit better. I think you may need several cells in that last row, one for each child, and then to set colspans on the second row to keep it even. Wait-- forgot one - you need one more row above the whole thing as a line *in* to the parent node - you may omit this for the root node.

    The child cells then need three styles - first-child, last-child, and child. The regular child has a line above it, the first-child has a line above the right half of it, and the last child has a line above the right half of it:
    Code:
    +------+-------+------+
    |      |   |   |      |
    |--+---|---+---|---+--|
    |  |   |   |   |   |  |
    |child | child | child|
    +---------------------+
    Table lines that should be drawn in bold - note that the line above the word 'child' is actually part of the child.

    This whole process then assumes that each set of children dom elements will be nested into a parent dom element - that recursive dom structure is what gives the existing Tree its shape as well.

    TreeAppearance will need a complete re-implementation to do this. The guts will be in renderNode, which will draw each element (something like the first table I mentioned). Then, the various finder methods will need a custom setup to find the nodes that they describe - checking out existing implementations and usages for what these each are specifically for:
    Code:
        XElement findIconElement(XElement target);
    
        XElement findJointElement(XElement target);
    
        XElement getCheckElement(XElement container);
    
        XElement getContainerElement(XElement node);
    
        XElement getIconElement(XElement container);
    
        XElement getJointElement(XElement container);
    
        XElement getTextElement(XElement container);
    The Tree needs to be able to modify specific nodes as things expand/collapse, etc. These methods are responsible for that work:
    Code:
        XElement onCheckChange(XElement node, XElement checkElement, boolean checkable, CheckState state);
    
        XElement onJointChange(XElement node, XElement jointElement, Joint joint, TreeStyle ts);
    
        void onSelect(XElement node, boolean select);
    
       /*If supporting DnD*/
        void onDropOver(XElement node, boolean over);
    
        void onHover(XElement node, boolean over);
    And last (from my quick glance, you may find more methods that are important, but these are the landmark ones), the Tree needs to be able to ask questions about what the user is clicking on - these methods let the tree find out what the user is doing:
    Code:
        boolean isCheckElement(XElement target);
    
        boolean isJointElement(XElement target);
    Instead, a visualization package just draws elements on the page and positions them, whether it is done in a browser, or elsewhere. In this case, you do the bookkeeping of relative positioning in memory, not in any dom structure. This is how the various charts on the right half of your screen are implemented in GXT 3.

    The DrawComponent class allows any sprites to be added to it anywhere - LineSprites could make up the dashes between nodes (or a single PathSprite, using LineTo commands to draw, and MoveTo to get to the next position). ImageSprite or TextSprite or both then could be used to actually build each node. Depending on the size/distribution of the tree, you might want to start at the top and center the first node, then work your way down (easier approach, good for a smaller number of nodes) or walk depth-first and render nodes starting at the bottom-left corner, making children and parents fit where they can. If there are not enough nodes to reach to the top, just adjust all nodes to fit - if there are too many, then some kind of scrolling or expand/collapse mechanism will be required. Consider the use of TextMetrics to measure how large a string will be when deciding how much room you need.

    This isn't an easy problem, and there is no canned answer for all cases, so we haven't built the One True Horizontal Tree and shipped it in GXT. Teams that need this typically have very specific requirements - DnD, icons drawn around/in nodes, specific scrolling or expanding features

  4. #3
    Sencha User
    Join Date
    Jan 2010
    Posts
    125
    Vote Rating
    1
    Answers
    2
    darkling235 is on a distinguished road

      0  

    Default


    Thank you for the insight. I see this is every bit as messy as I expected. I'll have to talk to management and see if this is something they still wish to pursue.

Tags for this Thread