3
votes

I am generating some dynamic vizframe column charts by looping at the response I get from my Odata service. One of my requirement for the chart is to show columns in different color depending on the value of a field I have in data. Let's call it validation status.

I have a fairly good idea on how to achieve this in normal situations by using the setVizProperties method and setting up rules for the dataPointStyle properties. It would still have been possible if I had the same criteria for all the charts and all the values. But that isn't the case since I need to check each record individually to determine it's status. So I thought of using the callback functionality of the dataPointStyle. But the problem here is that although it gives me the context but it doesn't tell me from which chart this callback has been triggered. My idea is that if I get the chart name or it's reference then I can access it's model and determine the color.

So if I can somehow get a reference of the vizframe from where the call back is being triggered, it will solve my problem.

callback Description: function (data, extData) {...} => true|false A function to determine whether a given data matches the rule. Parameters: data is an object with all bound field ids as keys, and corresponding values as values. It helps to consider it as the object containing everything you see in datapoint mouseover tooltip. If unbound dimensions or measures are set in FlatTableDataset context field, the related key/value pairs will be included in this parameter as well. extData is an object with all other measure fields that in the same line with current data point. Measure Ids as keys, and corresponding values as values. It helps to compare value between different measures.

Link to the vizFrame documentation

JSFiddle

My Data looks something like this:

[{
    "RunLogId": "0000000040",
    "RuleId": "00016",
    "CreatedOn": "2020-07-21",
    "CreatedAt": "09:44:35",
    "NAV_SUBSCRIBED_LOGS": {
      "results": [
        {
          "RunLogId": "0000000040",
          "Sequence": "00001",
          "RuleId": "00016",
          "Variation": "-3.94",
          "ValidationStatus": "F",
          "Dimension": "ABC"
        },
        {
          "RunLogId": "0000000040",
          "Sequence": "00002",
          "RuleId": "00016",
          "Variation": "1.04",
          "ValidationStatus": "S",
          "Dimension": "DEF"
        }
      ]
    }
  },
  {
    "RunLogId": "0000000033",
    "RuleId": "00014",
    "CreatedOn": "2020-07-15",
    "CreatedAt": "11:10:09",
    "NAV_SUBSCRIBED_LOGS": {
      "results": [
        {
          "RunLogId": "0000000033",
          "Sequence": "00001",
          "RuleId": "00014",
          "Variation": "-2.36",
          "ValidationStatus": "F",
          "Dimension": "ABC"
        },
        {
          "RunLogId": "0000000033",
          "Sequence": "00002",
          "RuleId": "00014",
          "Variation": "-5.05",
          "ValidationStatus": "F",
          "Dimension": "DEF"
        }
      ]
    }
  }]

My code looks some like this :

for (var i = 0; i < chartsCount; i++) {
            var oModel = new JSONModel();
            var chartData = aSubscriptions[i].NAV_SUBSCRIBED_LOGS.results;
            var aDimensions = [];
            var aDimFeeds = [];
            aDimensions.push({
                    name: "Dimension",
                    value: "{Dimension}"
                });
            aDimFeeds.push("Dimension");
            oModel.setData(chartData);
            oModel.refresh();
            
            var oDataset = new FlattenedDataset({
                dimensions: aDimensions,
                measures: [{
                    name: "Variation",
                    value: "{Variation}"
                }],
                data: {
                    path: "/"
                }
            });
            
            var oVizFrame = new VizFrame();
            oVizFrame.setVizType("column");
            oVizFrame.setHeight("450px");
            oVizFrame.setDataset(oDataset);
            oVizFrame.setModel(oModel);
            var feedValueAxisActual = new sap.viz.ui5.controls.common.feeds.FeedItem({
                    "uid": "valueAxis",
                    "type": "Measure",
                    "values": ["Variation"]
                }),
                feedCategoryAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
                    "uid": "categoryAxis",
                    "type": "Dimension",
                    "values": aDimFeeds
                });
                
            oVizFrame.addFeed(feedValueAxisActual);
            oVizFrame.addFeed(feedCategoryAxis);
            oVizFrame.setVizProperties({
                
                plotArea: {
                    
                    dataPointStyle: {
                        "rules": [
                            {
                                    callback: function (oContext, extData) {
                                        that.checkValue(oContext, "S");
                                    },
                                    "properties": {
                                        "color": "sapUiChartPaletteSemanticGoodLight1"
                                    },
                                    "displayName": "Successful"
                                }
                            , {
                                    callback: function (oContext, extData) {
                                        that.checkValue(oContext, "F");
                                    },
                                    properties: {
                                        color: "sapUiChartPaletteSemanticBadLight1"
                                    },
                                    "displayName": "Failed"
                            }
                        ],
                            others: {
                                properties: {
                                    color: "sapUiChartPaletteSemanticNeutral"
                                },
                                "displayName": "Undefined"
                            }
                    }
                }
            });
            //Chart Container
            var oChartContainer = new ChartContainer();
            var oChartContainerContent = new ChartContainerContent();
            oChartContainerContent.setContent(oVizFrame);
            oChartContainer.addContent(oChartContainerContent);
}
1

1 Answers

2
votes

Not sure if I understand you correctly but I'll give it a shot anyway. If I was wrong let me know.

You create charts in a loop. You want to access the specific chart in a callback.

Why don't you access oVizFrame in your callback?

First I would replace the for loop with a forEach. forEach calls a given function for every element in your array:

aSubscriptions.forEach(function(oSubscription) {
    const oModel = new JSONModel();
    const chartData = oSubscription.NAV_SUBSCRIBED_LOGS.results;

    ...
}

In a for loop your variables are reused. In a forEach function a new scope is created for every item. So when you access oVizFrame in your callback it is the same oVizFrame that you declared earlier.

Then you should be able to access oVizFrame in your callback.

oVizFrame.setVizProperties({
    plotArea: {
        dataPointStyle: {
            "rules": [{
                callback: function(oContext, extData) {
                    // >>>>>>>> Do something with oVizFrame <<<<<<<<
                    that.checkValue(oContext, "S");
                },
                ...
            }, {
                callback: function(oContext, extData) {
                    // >>>>>>>> Do something with oVizFrame <<<<<<<<
                    that.checkValue(oContext, "F");
                },
                ...
            }],
            ...
        }
    }
});