This is a migrated thread and some comments may be shown as answers.

Sort Category Axis based on # of Items

16 Answers 381 Views
Chart
This is a migrated thread and some comments may be shown as answers.
DC
Top achievements
Rank 1
DC asked on 23 Dec 2019, 03:13 PM

I am trying to get the category axis values to be sorted in descending order based on the number of items they have. Also, I am using a Bar Chart not a Grid. I have tried this group compare:

group: { field: "category", dir: "desc",

compare: function(a, b) {if (a.items.length === b.items.length) {return 0;} else if (a.items.length > b.items.length) {return 1;} else {return -1;}}}

as stated in this documentation and advised by Admin Alex https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/configuration/group#groupcompare

I'll attach an image of what it looks like with that function in use. As you can see on the image, although one of my categoriy values has an item count of 24 which is the second highest, it is still near the bottom because it does not contain any items from the first Environment which is in the legend as "QA FT".

The only function that has managed to overwite this is one that sorts them but based on alphabetical order and it is a databound event. Here is the function:

function sortLabels(e) {
             var axis = e.sender.options.categoryAxis;
            axis.categories = axis.categories.sort();

        }

 

Another thing I have tried has been:

function sortLabels(e) {
             var axis = e.sender.options.categoryAxis;
            axis.categories = axis.categories.sort(function (a, b) {
        if (a.items.length === b.items.length) {
           return 0;
        } else if (a.items.length > b.items.length) {
           return 1;
        } else {
            return -1;
               }
            });

        }

Thank you,

DC

 

 

 

16 Answers, 1 is accepted

Sort by
0
Alex Hajigeorgieva
Telerik team
answered on 26 Dec 2019, 12:28 PM

Hello, Denys,

I have prepared a runnable sample using the provided chart configuration from this post and the group compare function seems to be working well:

https://dojo.telerik.com/@bubblemaster/OmipEPUC/4

However, from the look of the chart in the screenshot, it appears that the data may not be suitable for grouping. For data to be suitable for grouping, each category should have one group value - for each Environment, there should be a one group UserStory value, otherwise the chart creates zero bars for that category and the visible bars become very thin making space for the zero value bars.

Nonetheless, the question at hand - the group sort does work well and to set it initially for ASP.NET Core, use the Add() overload which allows for the compare function to be added:

 .Group(group=>group.Add("Environment", typeof(String),System.ComponentModel.ListSortDirection.Ascending, "myGroupCompare"))
                     

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
DC
Top achievements
Rank 1
answered on 26 Dec 2019, 02:54 PM

Hi Alex,

Thanks for the response and sorry I misstyped when I wrote by number of items. I meant by the count not the number of items in the group, UserStory with highest count should be at the top and so forth. Essentially, there is no way to achieve such desired result of having the category descending by count because some of those category items are grouped in multiple environments while others are not thus resulting in a 0? Also I get an argument issue in the Html Helper, I copied your code verbatum.

0
DC
Top achievements
Rank 1
answered on 26 Dec 2019, 03:02 PM
For example in this dojo https://dojo.telerik.com/eqIBUMaw there is no way to have it sorted with the B first because it has a count of 24 then followed up by C with count of 18 and then A with the lowest of all environments with 18 because the other stories that don't have all the environments are automatically assigned a 0 for that environment?
0
DC
Top achievements
Rank 1
answered on 26 Dec 2019, 03:10 PM
Sorry UserStory B with the 24 at top with the 15 because that story has 2 environments but still is at the top due to having a largest count out of all in the chart then followed by the 18. Something similar to the screenshot attached. This chart just happens to have the first envrionment appearing in all of the category items. 
0
Alex Hajigeorgieva
Telerik team
answered on 27 Dec 2019, 01:20 PM

Hello, Denys,

You can change the order as desired - i.e. B, C, A but you need to change the group compare function to loop through the group items and return the one with the highest Count property and use it to compare the groups:

https://dojo.telerik.com/@bubblemaster/ILisaMAJ

          group: {
            "field": "Environment",
            "dir": "asc",
            compare: function(a, b) {
              var maxCountInItemsA = Math.max(...a.items.map(o => o.Count));
              var maxCountInItemsB = Math.max(...b.items.map(o => o.Count));
              if (maxCountInItemsA === maxCountInItemsB) {
                return 0;
              } else if (maxCountInItemsA > maxCountInItemsB) {
                return 1;
              } else {
                return -1;
              }
            }
          },

As for the syntax, it looks as though there is a slight difference in the syntax for ASP.NET MVC and Core. You can check the available overloads of methods by positioning the cursor inside the method name (in this case Add) and pressing F12, this will take you in the Kendo.Mvc.dll and so you need to use the following syntax - differences are highlighted below:

 .DataSource(dataSource => dataSource
            .Read(read => read.Action("Read", "Chart"))
            .Group(group => group.Add<string>("Environment", Kendo.Mvc.ListSortDirection.Ascending, "myGroupCompare"))
        )

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
DC
Top achievements
Rank 1
answered on 27 Dec 2019, 07:54 PM

Hi Alex thanks for the help,

I tried your dojo with some hard coded data  from my project. With the function as is with the Spread Syntax I get a result as shown in the image1. Without the Spread Syntax it looks like I get a better result as shown in image2. I see the data sorted correctly in my browsers developer mode but when it comes to graphing it spills out the same as in the dojo example. I see what you have stated before about the zeros but and that appears to be the issue of why I am still unable to achieve the desired end result. The closest result to it has been the image2 with the function without the Spread Syntax and image 3 with this function

 function (a, b) {
                                if (a.items[0].Rank == b.items[0].Rank) {
                                    return 0;
                                } else if (a.items[0].Rank > b.items[0].Rank) {
                                    return 1;
                                } else {
                                    return -1;
                                }
                            }

 

https://dojo.telerik.com/IXAJUdUH

0
Preslav
Telerik team
answered on 01 Jan 2020, 02:02 PM

Hi Denys,

I checked the information in this thread and based on your last post I am not sure if you require any further help.

If you do need assistance, could you please elaborate on the exact question?

 

Regards,
Preslav
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
DC
Top achievements
Rank 1
answered on 02 Jan 2020, 02:29 PM

Hello Preslav,

I was just posting what got me closest to my desired goal incase anyone else were to look for a similar outcome. None of the suggested solutions got me my desired result though but they were close.

0
Alex Hajigeorgieva
Telerik team
answered on 07 Jan 2020, 09:02 AM

Hi, Denys,

I believe that the reason for not achieving the desired result might be that the items[0].Rank of each group might not always be the ones with the highest Rank.

To get the correct result in your case which seems to be looking for a specific property within the group items, you should:

  • Loop all of the items in each group using any syntax you prefer
  • Find the value by which you will conduct the custom sorting in each group
  • Return 1, 0 or -1 accordingly

Currently, the comparison only takes the 1st item from the group.

Can you clarify what you mean by:

"when it comes to graphing it spills out the same as in the dojo example"

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
DC
Top achievements
Rank 1
answered on 08 Jan 2020, 01:57 AM

Hello Alex,

Thanks for your help. I was able to get things working by doing some tweaking in my datasource end. 

 

0
DC
Top achievements
Rank 1
answered on 24 Jan 2020, 07:43 PM
Still working on this, turns out everything just worked for a specific data set, when using another the order of the categories is still out of sort. Using this function almost gets the result im looking for function(a, b) { var maxCountInItemsA = Math.max(...a.items.map(o => o.Count)); var maxCountInItemsB = Math.max(...b.items.map(o => o.Count)); if (maxCountInItemsA === maxCountInItemsB) { return 0; } else if (maxCountInItemsA > maxCountInItemsB) { return 1; } else { return -1; } }
0
Alex Hajigeorgieva
Telerik team
answered on 29 Jan 2020, 01:04 PM

Hi, Denys,

It would be most helpful if you share sample data and show us the expected outcome vs the current behaviour as you did before. A case like this should be easy to mock in a Dojo and have it resolved quickly as long as we have the complete picture.

Will you be able to share a runnable Dojo with some data that is not behaving quite as it should so we can debug it locally?

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
DC
Top achievements
Rank 1
answered on 03 Feb 2020, 06:14 PM

Hello Alex,

This Dojo: https://dojo.telerik.com/iHUwiQiY has the expected outcome. I also attached an image with the expected outcome as well. The category with the highest count is first on the axis.

 

This Dojo: https://dojo.telerik.com/UZIcURuF is what I am currently getting. My data is passed from my datasource already sorted the way I would like it to be displayed and I am also using the function you provided before which sorts it the way I would like to see it but am still getting this result.

Warm Regards,

DC

0
Accepted
Alex Hajigeorgieva
Telerik team
answered on 06 Feb 2020, 04:36 PM

Hello, Denys,

I had a look through the thread from the beginning and I am afraid that we have become so fixated on using the group compare function since one of the examples you shared worked as expected due to the data fitting the condition by accident that we have missed the actual requirement written clearly in the title of this thread.

I would like to apologize for following the wrong course of action and offer you the solution which we have in a how to article:

https://docs.telerik.com/kendo-ui/controls/charts/how-to/sorting/sort-category-groups

In your scenario, we have the added condition of wanting to sort the categories by the values of another field so we can use the sort compare function of array:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

To get the desired behaviour, you can remove the group compare and add this in the dataBound handler:

       dataBound: function(e) {
              var data = e.sender.dataSource.data();
              var axis = e.sender.options.categoryAxis;
              axis.categories = axis.categories.sort(function compare(a, b) {
                var itemsWithCategoryA = Math.max(...data.map(x=> x.UserStory == a ? x.Count: null));
                 var itemsWithCategoryB = Math.max(...data.map(x=> x.UserStory == b ? x.Count: null));
                if (itemsWithCategoryA > itemsWithCategoryB) {
                  return -1;
                }
                if (itemsWithCategoryA < itemsWithCategoryB ) {
                  return 1;
                }
                return 0;
              });
            }

Result: https://dojo.telerik.com/@bubblemaster/ItiPaDEr/2

I apologize once again for the delay.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
DC
Top achievements
Rank 1
answered on 06 Feb 2020, 07:41 PM

Hi Alex,

I tested it out and everything looks good. Thank you so much for your help.

 

Best Regards,

DC

0
Alex Hajigeorgieva
Telerik team
answered on 07 Feb 2020, 02:47 PM

Hello, DC,

Thank you for being such a sport and being so kind.

I hope the delay did not hinder you too much.

Regards,
Alex Hajigeorgieva
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
Tags
Chart
Asked by
DC
Top achievements
Rank 1
Answers by
Alex Hajigeorgieva
Telerik team
DC
Top achievements
Rank 1
Preslav
Telerik team
Share this question
or