Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: "Row Group" Column #419

Closed
ataft opened this issue Aug 26, 2019 · 17 comments
Closed

Feature: "Row Group" Column #419

ataft opened this issue Aug 26, 2019 · 17 comments

Comments

@ataft
Copy link
Contributor

ataft commented Aug 26, 2019

Allow for a dedicated "Row Group" column, hiding the original columns for any grouped fields.

In the example below, there is a column called "Group" with groups for Country and Year, both of which are not displayed as stand-alone columns:

image

@6pac
Copy link
Owner

6pac commented Sep 2, 2019

Good feature, happy to accept a PR

@ghiscoding
Copy link
Collaborator

ghiscoding commented Jan 29, 2020

@ataft
That might be doable by doing these steps

  1. keep a temp array of your column definitions with by running grid.getColumns() after loading the grid. Also you should do a deep clone so that it won't affect any changes that you do to the temp array later.
  2. add the "Group" column at the beginning of your column defs temp array by doing an unshift (e.g. we do that with the checkbox row selection)
  3. before grouping, get to know which columns you want to remove
    • remove these columns by doing a slice on the temp array
  4. set the temp array as the new column definitions with grid.setColumns(temp)
  5. finally do the grouping

Using the setColumns will add new columns or hide existing ones (not remove), for example we do that with the column picker when we want to hide a column.

So it might visibly do what you're looking into achieving... if that doesn't work try inverting step 4 and 5.

That could go into a new plugin as 6pac suggested

@ataft
Copy link
Contributor Author

ataft commented Mar 14, 2020

Would it be too forward of me to ask if either @6pac or @ghiscoding would be interested in implementing this as a consulting gig?

@6pac
Copy link
Owner

6pac commented Mar 14, 2020

Possibly, but I'm flat out right now. Perhaps in a couple of months? Having a closer look, what you want is, I think, quite close to http://6pac.github.io/SlickGrid/examples/example-grouping.html and http://6pac.github.io/SlickGrid/examples/example5-collapsing.html
Might not be too hard to synthesize the two?

@ataft
Copy link
Contributor Author

ataft commented Mar 16, 2020

The first grouping example highlights the problem. Grouped columns are showing twice as the group and as a regular column, as shown here:
image

The second example is what it should look like, in that the grouped column isn't duplicated as a regular column. However, looking at the code-base, this approach looks like it doesn't use the Grouping plugin with aggregators, but rather relies on parent-child relationships. While similar, I'm afraid this approach could lead to more problems down the line.

I just tried the steps @ghiscoding laid out, and the setColumns() approach seems to work. It's a bit tricky when it comes to groups and grand total footer rows, but I've been able to work around that. I still have work to do on it, but will think through how this might be done in a plugin, hopefully I can report back soon.

@ghiscoding
Copy link
Collaborator

@ataft
I'm currently working on a new feature that is similar to that, Tree Data View which is the same as Ag-Grid Tree-Data. I'll eventually add this demo in SlickGrid itself in a couple of weeks I guess. Tree Data is not exactly the same as Row Grouping but it's very similar. See animated gif below, I got Filtering working by asking on Stack Overflow question and I have single sorting almost working (multi-column sorting is not yet working). I would also like to have Aggregation as well, but that might come later. Our current project requires this to create Customer Quote grid (and maybe Bill of Materials).

You can try out the Example in my repo, the file to test with is examples/example-tree-data.html which is what is shown below. I'd be happy to get help if you want to help out. Technically that would work with 2 form of dataset (1.hierarchical which is a tree view and/or 2.parent/child references). It's very complex to implement, I have to switch back and forth from hierarchical to flat and then flat to hierarchical, because I need hierarchical to sort but SlickGrid needs flat data so I need to convert it back and forth. The filtering was also very complex but luckily I got a really nice guy to help out and answered my SO question and he even contributed directly to my branch.

Also note that I created yet another lib (3rd one now) called Slickgrid-Universal which is framework agnostic, it's again a wrapper on top of SlickGrid but outputs vanilly JS code (written in TypeScript), I'm moving/copying all common code found in Angular-Slickgrid. I'm starting to use it in SalesForce which only accept ES6 vanillaJS hence why I created the lib. I also plan to later rewrite Angular-Slickgrid and Aurelia-Slickgrid to use that as the core/common code to have 1 common place to work with (instead of having duplicate code in both framework, 80% is common the 20% left is framework specific and so both lib will still exist but common code will move to the universal lib).

SlickGrid is AWESOME and my team is finally starting to realize that with all my work around it 😃
The beauty of the Open Source world...

6iD2ly0AKA

and this is the Ag-Grid demo, they have Aggregation on the File Size, I intend to add that as well eventually... guess where I got my inspiration lol 😉

image

@ataft
Copy link
Contributor Author

ataft commented Apr 9, 2020

Cool, this looks right. However, I don't see the difference between "Tree" and "Row Group" other than the way the underlying data is structured. Also, doesn't SlickGrid already have "Tree"? My issue when I tried to use SlickGrid tree was that I would have to massage the underlying data in a way that didn't make sense and also required a whole new aggregation methodology.

When I followed your instructions on hiding columns via setColumns(), I'm able to use the existing Row Grouping AND aggregation, changing nothing in my code base. Here's an example of what my "hack" looks like (with a pivot hack too):

image

@ghiscoding
Copy link
Collaborator

indeed the "Tree" and "Row Group" seems very similar, I don't see much of a difference except on how the data is displayed. I'm glad you got something working with what I wrote earlier, if it works I would stick with that since Tree Data can be slower in performance because it deals with a lot of recursion and the complexity is much higher.

Also, doesn't SlickGrid already have "Tree"?

Yes this Collapsing Example but there's a few flaw, the filters are not working correctly, it doesn't check for the entire node tree. For example in my print earlier, if I search (filter) for the word "map" it should show the entire tree "Documents > pdf > map.pdf" while current collapsing example expect that word to be in each of the node.

For example in current collapsing demo, you can see Task 7 is under Task 6
image

If I search for 7, I expect the grid to show that full tree path "Task 6 > Task 7" but instead here's what it currently shows
image

You can see it's not the behavior we are expecting, there are other edge cases not working as well. It's complex to work with a tree, you technically have to go through the full tree path to filter and sort. I thought it was easy but it's much more complex than it seems, there's a lot of recursion in play and performance can be bad too.

@ataft
Copy link
Contributor Author

ataft commented Apr 9, 2020

Then why put effort into improving the SlickGrid Tree? Your comments make the argument that tree has no real purpose, as it's just a Row Group with a dedicated grouping column, but row grouping is more flexible, performant, and logical.

I think that the concept of Tree existed before Row Grouping, but once Ag-Grid and SlickGrid implemented a meaningful Row Group component, it rendered Tree useless. Looking back, isn't Tree more of a temporary hack to do Row Grouping?

I think it's important that SlickGrid takes a standard data structure and features such as Grouping, Pivoting (future), Aggregation, Filtering, etc. work on that same data structure. The Tree component forces a totally different data structure, but adds no value.

As an aside, I like the idea of the SlickGrid Universal wrapper. The Aurelia and Angular ones look cool, but I use neither framework and stay away from framework-specific open source projects. SlickGrid is awesome and I'm thankful that you guys have put so much work into it.

@ghiscoding
Copy link
Collaborator

ghiscoding commented Apr 9, 2020

Multi-Column Grouping is very different and is not the same as a Tree Data. Parent/Child references, like a Bill of Materials, can't work with Grouping it's fundamentally different.

I don't know much about Row Group, it's not my use case, my use case really is all about Tree Data View.

The Tree component forces a totally different data structure, but adds no value.

I find that you are wrong on that part but that is your point of view. I myself didn't really care about Tree Data, neither understood it, until my company came up with this use case (Customer Quote). Having a 1 column with parent/child with unlimited tree depth is fundamentally different from multi-column grouping. I don't use much Excel so I can't really provide example against Excel, Tree Data might be pivot-table, I'm not sure

As an aside, I like the idea of the SlickGrid Universal wrapper. The Aurelia and Angular ones look cool, but I use neither framework and stay away from framework-specific open source projects.

That's exactly the concept, trying to make it framework agnostic and have 1 common place to troubleshoot. I also made a demo with vanilla JS code here

@ataft
Copy link
Contributor Author

ataft commented Apr 9, 2020

Good point, I see the use case for unlimited tree depth with regards to uneven/ragged trees and how this differs from multi-column grouping.

@6pac
Copy link
Owner

6pac commented Apr 10, 2020

The universal build sounds really interesting. I've been ridiculously busy for about 2 1/2 years now, but finally all the projects are coming to an end, and there's nothing new coming in (and with COVID, may not be for a while!). Looking forward to having a bit of time to investigate what you're doing.
I'm definitely in the plain JS/jQuery camp (not at all keen on moving to TypeScript or any of the other new languages), but as I understand it you've developed a lot of additional things like filters and other add-ons for your TypeScript repos. It would be great to port some of this back to Slickgrid (and I think that's what you're proposing), but first I really need to sit down, load all this up and check it out just so I understand the scope of what you've done.

@ghiscoding
Copy link
Collaborator

Just so you understand better, what I'm doing with this new Slickgrid-Universal repo is moving all the common code I have in Angular-Slickgrid and Aurelia-Slickgrid (2 different frameworks). The common code is about 80% while 20% is framework specific. Ok but why is that a problem? Well because when I push something that is common code, I have to push it 2 lib (for both framework) and I have to keep both in sync but I would rather just push into 1 common place, that is where the lib comes in. It requires lot of time investment and I didn't think it was going to be possible until a new project came from work which requires a grid but written in plain ES6 JS, so with that in mind, I started doing the common lib...

What is TypeScript and why use it? It simply adds Type, which JS doesn't have by definition. Adding the Types removes lot of potential bugs at coding time instead of running time. But what you really have to know is that TypeScript is just a superset of JS, it will at the end of it compile into plain JS code (that is what my new lib does and that is what I can use in our new SalesForce project). It's not very hard to learn, you just add the Types after the variable declaration (example, var1: number for a number, then var1: number[] or var1: Array<number> for an array of numbers), they did it this way because that is the only way that it can compile in JS, because if they add the type on the left it would be invalid JS code, while on the right side it's like an object and it's valid code. The TypeScript code is very similar to C# or other languages when you start playing with it for a while, very easy to learn. BTW, there are some training site like Pluralsight which now offer free month because of Covid, there are few TypeScript courses there.

@ghiscoding
Copy link
Collaborator

@ataft
That print screen you showed the print screen earlier in this post, would you mind creating a PR to add this demo as a new example? I'd be interested to see the final code.

@ataft
Copy link
Contributor Author

ataft commented May 15, 2020

I'd much rather this be an option on GroupItemMetadataProvider, but don't have the time to make that production-worthy right now. I created PR #492 as an example.

@ghiscoding
Copy link
Collaborator

Thanks, appreciated 👍

@ghiscoding
Copy link
Collaborator

@ataft we now have a new version, so I added your new Example to the Examples list in the Grouping Section. The list is editable, so if you wish to change the name then go ahead.

Thanks again for the new demo.
Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants