Grid as a tree: any idea when?

So,
Vaadin 7.6 now focuses on the developer experience
. Anyone knows of this includes bringing a Tree to the Grid? :slight_smile:

I am also eager to get a component better than the TreeTable. We are having lots of performance issues and jumping with TreeTable. (BTW I am displaying a construction project WBS in a treetable with calculations… )

I am thinking of using the Grid as is for the display, and to emulate the tree I will put an icon that changes when open closed, and I will change my data dictionary putting the right elements in the list… Do you vaadineers think it’s a good idea? did someone try it? do you see problems already doing so?.. Would the refresh after opening a node be very long?

Thanks.

I have developed an addon EverproTreeGrid that wrapes the normal great component ‘Grid’ and allows to send a Hierarchical Data source.

Here’s the link to the addon:

https://vaadin.com/directory#!addon/everprotreegrid

I have developed an addon EverproTreeGrid that wrapes the normal great component ‘Grid’ and allows to send a Hierarchical Data source.

Here’s the link to the addon:

https://vaadin.com/directory#!addon/everprotreegrid

Ah, I didn’t notice your add-on, so I did a very rough and hacky implementation with similar ideas. The
example code is here
. Your code is probably better for the purpose, as my implemention is not very finished. In any case, I hope there’s some use for that. For example, you seem to use image for the node icon, but I’m using a FontIcon for that, as is done in Tree.

Note that you shouldn’t use style names beginning with “v-” to your components, as they are reserved for Vaadin components.

I’ve also try to implement it. Try it out if you are interested https://vaadin.com/directory#!addon/gridtree

Any news on this? The two addons I could find don’t support filtering. (https://vaadin.com/directory#!addon/everprotreegrid and https://vaadin.com/directory#!addon/gridtree).
I don’t know how difficult it would be to take one of those as base and implement Container.Filterable myself…

Hi, I am the developer of https://vaadin.com/directory#!addon/everprotreegrid. I have just uploaded a new version that supports the Container.Filterable. Please try it and don’t hesitate to let me know if you face any problems or need help.

Wow, that was fast!
Thanks for your help Antoine, I’ll try it :slight_smile:

Hi, I am testing the addon but I don’t know how to add items to the container. addItem is not supported
Thanks for the help

Adding items to the container depends on your implemetation of the Container no? It does not realy depend on the Grid component unless I didn’t quite understand your question. But anyway what is the class you are using as DataSrource? Do you want to post your code or somothing?

Sorry, I wasn’t understanding the concept. In truth I don’t know if I understand it completely. To set a TreeGrid, is it necessary to add the properties to both the container and the grid? Ex:

[code]
EverproTreeGrid treeGrid = new EverproTreeGrid(“passportNum”, “passportNum”);
HierarchicalContainer container = new HierarchicalContainer();

container.addContainerProperty(“passportNum”, String.class, “”);
container.addContainerProperty(“name”, String.class, “”);
container.addContainerProperty(“surname”, String.class, “”);

treeGrid.addColumn(“name”, String.class);
treeGrid.addColumn(“surname”, String.class);

// Fill container
{

}

treeGrid.setContainerDataSource((Container.Hierarchical) container); // It clashes with Grid’s method if no casting
[/code]I haven’t found a way to do it without defining the properties twice, is it possible?

Also I found a small error to your instructions on the addon page. The mixin to import to the stylesheet is called “addons”, so it should be:
@include addons;
instead of
@include everprotreegridaddons;
:slight_smile:

I haven’t tested yet the filtering functionality, it’s the next thing I’ll do. Thanks!

The filtering functionality works perfectly.

What I am having trouble with now is the button renderer.
I have seen that there is a EverProTreeButtonRenderer, but I don’t know how to use it.
As far as I know, to be able to add a generated property you need to wrap the container with a GeneratedPropertyContainer. But this kind of container is not Hierarchical. Could you give me a short example of how to use the EverProTreeButtonRenderer?

Ok, these are my latest findings:
I don’t have to use EverProTreeButtonRenderer, I can use a normal one doing something like this:

[code]
ButtonRenderer buttonRenderer = new ButtonRenderer(listener);
treeGrid.getColum(“edit”).setRenderer(buttonRenderer, new Converter<String, String>(){

public String convertToModel(String value, Class<? extends String> targetType, Locale locale) throws com.vaadin.data.util.converter.Converter.ConversionException {
return “Not Implemented”;
}

public String convertToPresentation(String value, Class<? extends String> targetType, Locale locale) throws com.vaadin.data.util.converter.Converter.ConversionException {

return “Edit”;
}

public Class getModelType() {
return String.class;
}

public Class getPresentationType() {
return String.class;
}
});
[/code]To solve my problem with others components, I am using ComponentRenderer addon. For this I have had to wrap the class GeneratedPropertyContainer in order to implement Hierarchical. I havençt tested a lot, but I think that something like this should just be fine:

 public class HierarchicalGeneratedPropertyContainer extends GeneratedPropertyContainer implements Container.Hierarchical
{
/**
* Constructor for GeneratedPropertyContainer.
*
* @param container underlying indexed container
*/
public HierarchicalGeneratedPropertyContainer (Indexed container)
{
super(container);
}

@Override
public Collection<?> getChildren (Object itemId)
{
return ((Container.Hierarchical) getWrappedContainer()).getChildren(itemId);
}

@Override
public Object getParent (Object itemId)
{
return ((Container.Hierarchical) getWrappedContainer()).getParent(itemId);
}

@Override
public Collection<?> rootItemIds ()
{
return ((Container.Hierarchical) getWrappedContainer()).rootItemIds();
}

// Same with all other methods that need implementation for Hierarchical
}

I am still setting the properties twice though, properties for the hierarchical container and colums for the tree grid.


A- Redering of the expand collaps column and icons.
You obviously get a default one being the blue arrows, but you can change these icons or even add other icons that desccribe the type of node you are on…

a- if you just want to change the icons them you can simply overwrite the style in the scss:
.v-foc-gridtree-node-expanded
.v-foc-gridtree-node-collapsed
.v-foc-gridtree-node-leaf

NB: In a future version I should remove the v- as this is reserved to native vaadin components

b- If you want to have a rederer by node type, then you need to set your NodeStyleGenerator that allows you to get your node object and decide on the style you want to apply. In the following example I do so for an object of my own where Bkdn can represent a material, service or role…

            getTreeGrid().setNodeStyleGenerator(new IEverproTreeGridNodeStyleGenerator(){
                public String getStyleName(Object itemId, String defaultStyleName) {
                    String style = defaultStyleName;
                    MyItem item = getTreeGrid().getDataSource().getItem(itemId);
                    if(item != null){
                        //Depending on the type of the node we add a string to the style
                        //which would become something like:
                        //foc-gridtree-node-expanded-material,...
                        if(item.isMaterial()){
                            style += "-material";
                        }else if(item.isService()){
                            style += "-service";
                        }else if(item.isRole()){
                            style += "-role";
                        }
                    }
                    return style;
                }
            });

In my case these are the styles that I used

  .v-foc-gridtree-node-expanded-material {
    border: 0px;
    
    background-image: url("icons/16x16/tree-node-expanded.png"), url("icons/16x16/material.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;

    height: 20px;
    padding-left: 40px;
  }

  .v-foc-gridtree-node-collapsed-material  {
    border: 0px;
    
    background-image: url("icons/16x16/tree-node-collapsed.png"), url("icons/16x16/material.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;
    height: 20px;
    padding-left: 40px;
  }
  
  .v-foc-gridtree-node-leaf-material  {
    border: 0px;
    
    background-image: url("icons/tree-node-leaf.png"), url("icons/16x16/material.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;
    height: 20px;
    padding-left: 25px;
  
  }


  .v-foc-gridtree-node-expanded-service {
    border: 0px;
    
    background-image: url("icons/16x16/tree-node-expanded.png"), url("icons/16x16/service.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;

    height: 20px;
    padding-left: 40px;
  }

  .v-foc-gridtree-node-collapsed-service {
    border: 0px;
    
    background-image: url("icons/16x16/tree-node-collapsed.png"), url("icons/16x16/service.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;
    height: 20px;
    padding-left: 40px;
  }
  
  .v-foc-gridtree-node-leaf-service {
    border: 0px;
    
    background-image: url("icons/tree-node-leaf.png"), url("icons/16x16/service.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;
    height: 20px;
    padding-left: 25px;
  
  }

  .v-foc-gridtree-node-expanded-role {
    border: 0px;
    
    background-image: url("icons/16x16/tree-node-expanded.png"), url("icons/16x16/resourcerole.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;

    height: 20px;
    padding-left: 40px;
  }

  .v-foc-gridtree-node-collapsed-role {
    border: 0px;
    
    background-image: url("icons/16x16/tree-node-collapsed.png"), url("icons/16x16/resourcerole.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;
    height: 20px;
    padding-left: 40px;
  }
  
  .v-foc-gridtree-node-leaf-role {
    border: 0px;
    
    background-image: url("icons/tree-node-leaf.png"), url("icons/16x16/resourcerole.png");
    background-position: 0px 0px, 16px 0px;
    background-repeat:  no-repeat;
    background-color: transparent;
    height: 20px;
    padding-left: 25px;
  
  }


B- Setting the properties twice:

I don’t see the harm in that. Actually in my case it is very rare that one would need to display in the table, or tree all the properties that exist in the datasource, becase the data source would reflec the database content which prctically ends up not matching exactly what I want to show to the user…


C- Sharing the example:
I don’t have an example in my plugin because when I built it I used it in my particular case of DataSource implementation… so if you are doing a simple example I would be grateful if you cn share it on the post, I will include it then in the AddOn :slight_smile:

Hi, thank you for the clarification on the styles, some of it can be helpful, but what I meant is that the instructions in the addon page are a little wrong :stuck_out_tongue:

As example for the page addon you could use what I posted in this same thread: https://vaadin.com/forum#!/thread/9075352/14496241

I’m going to use the addon extensively, thanks. I have been able to make it work with filtering and components in cells, wich is what I needed :slight_smile:

I am glad this could help Enkara. I will update the instruction and use your example but could you please help me on that: how did you fill the container
// Fill container
{ … }
Because as I said allthough I have built a full ERP on
FOC framework
which uses Vaadin, I use my own implementitons of Container/Item/Property so no experience in this native part.
Thanks

My case is a little bit special also, but I’ll try to give an example, which completes the example above:

List<Person> listPeople = getListPeople();

List<Person> children = new ArrayList<>();
listPeople.forEach(person -> {
   if (isParent(person))
   {
      String parentRowId = person.getPassportNum();
      addItem(person, parentRowId);
      container.setChildrenAllowed(parentRowId, false);
   }
   else
      children.add(person);
});

children.forEach(child -> {
   String parentRowId = child.getParentPassportNum();
   container.setChildrenAllowed(parentRowId, true);
   String childRowId = child.getPassportNum();
   addItem(child, childRowId);
   container.setParent(childRowId, parentRowId);
   container.setChildrenAllowed(childRowId, false);
});

private void addItem (Person person, Object id)
{
   Item item = container.addItem(id);
   item.getItemProperty("passportNum").setValue(person.getPassportNum());
   item.getItemProperty("name").setValue(person.getName());
   item.getItemProperty("surname").setValue(person.getSurname());
}

Hi Antoine,

I met a new problem with the everprotreetable. When creating the table it is necessary to enter the propertyIdForItemIdValue, but my table doesn’t have any column that can be an id, only a combination of properties would get a unique id for the row.
Is there a way to solve that?

The only way I can think of to solve it is to have an extra column with a (generated) unique value and hide that column, but I don’t know if I’m missing something and it’s simpler than that.

Thanks again

Hi all,

Glad to announce that we just published initial release of hierarchy support for Grid as an addon:

https://vaadin.com/addon/vaadin-treegrid

This is add-on for Vaadin 7 now, but we will have this work migrated to Vaadin 8 later.