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

Grouping and Aggregating multiple fields from a JSON datasource within the chart

3 Answers 1596 Views
Charts
This is a migrated thread and some comments may be shown as answers.
Stephen
Top achievements
Rank 1
Stephen asked on 18 Oct 2013, 09:34 PM
I've been able to accomplish such grouping in certain charts and not others.
For example, assume that I have a datasource that looks something like this:

var pictures = [
{ type: "JPG", len: 20, wid: 15, appr: 17.5, count: 2 },
{ type: "JPG", len: 22, wid: 17, appr: 12.5, count: 3 },
{ type: "JPG", len: 24, wid: 15, appr: 10.5, count: 1 },
{ type: "JPG", len: 22, wid: 4, appr: 17.5, count: 6 },
{ type: "PNG", len: 20, wid: 15, appr: 17.5, count: 4 },
{ type: "PNG", len: 25, wid: 7, appr: 9.5, count: 4 },
{ type: "PNG", len: 21, wid: 11, appr: 21.5, count: 1 }
];


I want to group by my category which in this case is "type", I want to sum all other fields.

I am able to do this quite simply with column charts, simply by setting:

series: [{aggregate: "sum",categoryField: "type"}]

However, this does not work with bullet or pie charts, so in search
of a more universal method. I "massage" the data first by adding this
at the beginning:

var dataSource = new kendo.data.DataSource({
data: pictures,
group: {
field: "type",
aggregates: [
{ field: "len", aggregate: "sum" },
{ field: "wid", aggregate: "sum" }
]
}
});
 
dataSource.read();


I don't know why just grouping the datasource isn't enough.. I
have to throw it into arrays and assign each array to a series like so:

var seriesA = [],
seriesB = [],
categories = [],
items = dataSource.view(),
length = items.length,
item;
 
for (var i = 0; i < length; i++) {
item = items[i];
 
seriesA.push(item.aggregates.wid.sum);
seriesB.push(item.aggregates.len.sum);
}

This works as long as having only one valueField per series works.
In the case of a bullet chart, or if I want to assign a field to a
plotband to a bar/column chart: it does not.

I believe I must be doing something completely wrong, as converting
my ungrouped JSON object to a grouped kendo datasource should be enough.
Below is my JSFiddle..

http://jsfiddle.net/DxMb8/4/

Any help would be greatly appreciated! thanks!

3 Answers, 1 is accepted

Sort by
0
Iliana Dyankova
Telerik team
answered on 22 Oct 2013, 11:07 AM
Hello Stephen,

I am not quite sure if I understand correctly your scenario - could you please elaborate a bit more on the exact outcome you would like to achieve? This way I would be able to advice you further and provide concrete recommendations. Thank you in advance for your time and cooperation.

On a side note, pay attention to the following points:

  • By design series.aggregates is due to date series;
  • Basically the categorical charts (line, bar, column etc.) require a matching set of data points (note that the value can be null but the record needs to be presented in the data). If there is a different number of values you should use series.categoryField instead.

Regards,
Iliana Nikolova
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!

0
Stephen
Top achievements
Rank 1
answered on 22 Oct 2013, 04:53 PM
You allude to categorical charts, for which I am able to use series.categoryField to aggregate values.  I assume that pie chart and bullet chart are not considered categorical reports since this does not work for these.

I did read that series.aggregates are intended specifically for date categories, that being the case, I was looking at datasource aggregates, e.g. group.aggregates.

What I am specifically trying to do:  I have several charts based off of the same JSON query result array.   I want to group the result in the JS right before drawing each chart.  

Assume my JSON data object is an array named "myData".
var myDataSource = new kendo.data.DataSource({
   data: myData,
   group: {
      field: "type",
      aggregates: [
         { field: "len", aggregate: "sum" },
         //{ field: "wid", aggregate: "sum" }
      ]
   }
});
console.log(myDataSource.view());
The console displays an object with a field named "type" and two aggregates, exactly as it should with none of the extraneous data.
Now, how can I use that object as the datasource for my pie graph?


$("#chart").kendoChart({
        dataSource: myDataSource,
        seriesDefaults: {
            type: "pie",
        },
           series: {
                 field: "len"
           },
        categoryAxis: {
            field: "type"
        }
});
This does not work.
0
Accepted
Stephen
Top achievements
Rank 1
answered on 23 Oct 2013, 12:02 AM
We'll, it still seems a little bit redundant, but I believe I've solved my problem.
Using this, I believe I'll be able to flexibly group and aggregate any chart type from an ungrouped dataset.

Define the grouping and aggregation for the dataset:
var salesPersonData = new kendo.data.DataSource({
        data: data,
        schema: {
            model: {
                fields: {
                    Person  : { type: "string" },
                    Price   : { type: "number" }
                }
            }
        },
        group: {
            field: "Person",
            aggregates: [ {
                field: "Price",
                aggregate: "sum"
            } ]
        },
        sort: {
            field: "Person",
            dir: "asc"
        },
        change: createChart
    });

I chose to drop the data into the series.data, though it can also be tailored for use in the dataSource.data.
function createChart() {
         //gather into arrays (named)
       var dataObjs = salesPersonData.view(),
            recCount = dataObjs.length,
            dataObj,
            myData = [];
             
 
         for (var i = 0; i < recCount; i++) {
            dataObj = dataObjs[i];
            myData.push({
                value: dataObj.aggregates.Price.sum,
                category: dataObj.value
             });
         };
 
        $("#salesPersonChart").kendoChart({
            title: { text: ctitle },
           seriesDefaults: {
               labels: {
                   template: "#= category # - #= kendo.format('{0:P}', percentage)#"
               }
           },
            series: [{
                type: "pie",
                data: myData
            }],
 
            tooltip: {
                visible: true,
                template: "#= category # <br> #= kendo.format('{0:P}', percentage)# <br> #= kendo.format('{0:C}', value)#"
            },
        });
        var chart = $( "#salesPersonChart" ).data( "kendoChart" );
    }
    $(function() {
        salesPersonData.fetch();
    });
The biggest problem I had with the method I described originally was that  I could not access the category for tooltips/labels etc.   This solution is similar to my original attempt, however, this method makes a more complete data object with named subobjects which can be accessed just like any field in a local dataset.  
Tags
Charts
Asked by
Stephen
Top achievements
Rank 1
Answers by
Iliana Dyankova
Telerik team
Stephen
Top achievements
Rank 1
Share this question
or