2014-06-27 28 views
2

我在JSON符號例如一個OData的列表:如何在綁定到客戶端控件之前將SAPUI5 OData分組?

var data = [ 
{"category" : "A", "value" : 1, "group" : "x"}, 
{"category" : "B", "value" : 2, "group" : "y"}, 
{"category" : "C", "value" : 3, "group" : "x"}, 
{"category" : "A", "value" : 4, "group" : "y"}, 
{"category" : "A", "value" : 5, "group" : "x"} 
]; 

首先我篩選反對離開group == x;價值觀是:

var data = [ 
{"category" : "A", "value" : 1, "group" : "x"}, 
{"category" : "C", "value" : 3, "group" : "x"}, 
{"category" : "A", "value" : 5, "group" : "x"} 
]; 

現在我想集團(客戶端)按類別和總結值,所以結果應該是:

var data = [ 
{"category" : "A", "value" : 6, }, 
{"category" : "C", "value" : 3, }, 
]; 

之後,我會將模型綁定到某個SAPUI5控件。

但是分組部分似乎不可能。

有人知道該問題的通用解決方案嗎?

潛在用途案例:

var oDataset = new sap.viz.ui5.data.FlattenedDataset({ 
    dimensions : [ {axis : 1, value : "{category}", name : "Category" } ], 
    measures : [ {value : "{value}", name : "Value" } ], 
    data : { 
     path : "/Data" 
    } 
}); 

var oGraph = new sap.viz.ui5.Donut({ 
    dataset : oDataset, // sap.viz.ui5.data.Dataset 
}); 

回答

6

以下代碼適用於我。通過泛型綁定查詢多個產品的Northwind Order_Details服務,映射減少返回的綁定並將每個訂單的數量聚合到已售出的總質量,並在柱狀圖中顯示結果。

see jsBin Example

注sap.viz介紹Array.prototype.map和Array.prototype.reduce功能

var sURI = 'http://services.odata.org/Northwind/Northwind.svc/'; 
var oDataModel = new sap.ui.model.odata.ODataModel(sURI, true); 
oDataModel.setSizeLimit(10000); 
var oJSONModel = new sap.ui.model.json.JSONModel({}, 'jmodel'); 

// handle list of contexts 
var handler = function(oEvent) { 
    var mapCallback = function(oContext) { 
     var obj = {}; 
     obj.ProductID = oContext.getObject().ProductID, 
     obj.Quantity = oContext.getObject().Quantity 
     return obj; 
    }; 

    var reduceCallback = function(aPrev, oCurr) { 
     var aNext = aPrev; 
     var bFound = false; 

     aNext.forEach(function(item) { 
      if (item.ProductID === oCurr.ProductID) { 
       bFound = true; 
       item.Quantity += oCurr.Quantity; 
      } 
     }) 

     if (bFound === false) { 
      aNext.push(oCurr); 
     } 

     return aNext; 
    }; 
    //release handler 
    oBindings.detachChange(handler); 

    var aTotals = oEvent.oSource.getContexts().map(mapCallback).reduce(reduceCallback, []); 
    oJSONModel.setData({ 
     'Order_Totals': aTotals 
    }); 
}; 

// Filter all orders by 3 products 
var oFilter1 = new sap.ui.model.Filter("ProductID", sap.ui.model.FilterOperator.EQ, '1'); 
var oFilter2 = new sap.ui.model.Filter("ProductID", sap.ui.model.FilterOperator.EQ, '68'); 
var oFilter3 = new sap.ui.model.Filter("ProductID", sap.ui.model.FilterOperator.EQ, '11'); 
var aFilter = [oFilter1, oFilter2, oFilter3]; 

// Sort by ProductID 
var oSorter = new sap.ui.model.Sorter("ProductID", false, true); 

// Reduce the returned payload by nominating need fields 
var oSelect = { 
    select: 'ProductID,Quantity' 
} 

var oBindings = oDataModel.bindList("/Order_Details", null, oSorter, aFilter, oSelect); 

// call OData service and handle results 
oBindings.attachChange(handler); 
oBindings.getContexts(); 

var oDataset = new sap.viz.ui5.data.FlattenedDataset({ 
    dimensions: [{ 
     axis: 1, 
     name: 'ProductID', 
     value: "{ProductID}" 
    }], 
    measures: [{ 
     name: 'Quantity Sold', 
     value: '{Quantity}' 
    }], 
    data: { 
     path: "/Order_Totals" 
    } 
}); 

var oColumnChart = new sap.viz.ui5.Column({ 
    width: "80%", 
    height: "400px", 
    plotArea: { 
     'colorPalette': d3.scale.category20().range() 
    }, 
    title: { 
     visible: true, 
     text: 'Qutantity Sold by Product' 
    }, 
    dataset: oDataset 
}); 

oColumnChart.setModel(oJSONModel); 
1

對於你最終的結果我已經寫了代碼。雖然它沒有完全優化,但它工作正常。

這是您的完整的代碼

var data = [ 
{"category" : "A", "value" : 1, "group" : "x"}, 
{"category" : "B", "value" : 2, "group" : "y"}, 
{"category" : "C", "value" : 3, "group" : "x"}, 
{"category" : "A", "value" : 4, "group" : "y"}, 
{"category" : "A", "value" : 5, "group" : "x"} 
]; 

function groupBy(array , f) 
{ 
    var groups = {}; 
    array.forEach(function(o) 
    { 
    if(o.group=="x") 
    { 
     var group = JSON.stringify(f(o)); 
     groups[group] = groups[group] || []; 
     groups[group].push(o); 
    } 

    }); 
    return Object.keys(groups).map(function(group) 
    { 
    return groups[group]; 
    }) 
} 
var groupByGroup = groupBy(data, function(item) 
{ 
    return [item.group]; 
}); 
var groupByCategory = groupBy(groupByGroup[0], function(item) 
{ 
    return [item.category]; 
}); 
getData(groupByCategory); 

function getData(groupByCategory) 
{ 
    var finalData=[]; 
    for(var i=0;i< groupByCategory.length;i++) 
    { 
    var temp=0; 
     for(var j=0;j<groupByCategory[i].length;j++) 
     { 
      temp+=parseInt(groupByCategory[i][j].value); 
     } 
     finalData.push({"category":groupByCategory[i][0].category, "value":temp}) 
    } 
    console.log(finalData);//final data is your required results 
} 

如果你想用兩個參數.Suppose你想按類別以及組再到比較groupByGroup功能,您必須編寫如下

groupByCategory = groupBy(groupByGroup[0], function(item) 
    { 
    return [item.category,item.group]; 
    }) 
比較

並從groupBy函數中刪除if(o.group ==「x」)。 這個問題可以很容易地使用underscore.js.For幫忙看看這個問題

Underscore.js: Sum of items in a collection

希望這將幫助你來解決。