Line Chart

Description: creating a line chart that uses cube as a data source.

The ViewController.h File

#import "Charting.h"
#import "DataSource.h"
#import <UIKit/UIKit.h>
#include "GridTotalsSettingsHelper.h"
#include "PPLMetabase.h"
#include "PPLOlapReportPlistKeys.h"
#include "PPLPivotTableConditionFilterFactory.h"
@interface ViewController : UIViewController<ChartTouchesDelegate> {
    Chart *chart;
    float max;
    float min;
    LineSeries *currSeries;
    NSMutableDictionary *m_numberFormat;
    SPPLMetabase m_metabase;
    SPPLMetabaseRepositoryObjectDescriptor m_reportDescriptor;
    DataSource *dataSource;
    SPPLPivotTable m_gridPivotTable;
    SPPLPivot m_gridPivot;
    SPPLOlapReport m_olapReport;
}
// Executes custom example placed in the body of this method
- (void) executeExample;
- (ChartLabel *)createDefaultLabel;
@end

The ViewController.mm File

#import &quot;ViewController.h&quot;
#include &quot;NArray.h&quot;
#include &quot;NNotificationCenterExt.h&quot;
#include &quot;PPLAccessRightsManager.h&quot;
#include &quot;PPLCalendarDimension.h&quot;
#include &quot;PPLCalendarDimensionDataLevel.h&quot;
#include &quot;PPLCalendarDimensionDataLevels.h&quot;
#include &quot;PPLCalendarPeriodDimension.h&quot;
#include &quot;PPLCubeDataSource.h&quot;
#include &quot;PPLCubeTableField.h&quot;
#include &quot;PPLDashboardReport.h&quot;
#include &quot;PPLMetabase.h&quot;
#include &quot;PPLMetabasePool.h&quot;
#include &quot;PPLMetabaseRepositoryWarehousePool.h&quot;
#include &quot;PPLOlapReport.h&quot;
#include &quot;PPLPivotTableCalculatedHeaderElement.h&quot;
#include &quot;PPLPivotTableCalculator.h&quot;
#include &quot;PPLPivotTableCalculatorMutableSetting.h&quot;
#include &quot;PPLPivotTableConditionFilter.h&quot;
#include &quot;PPLPivotTableFilterElements.h&quot;
#include &quot;PPLPivotTableHeaderElement.h&quot;
#include &quot;PPLPivotTableHeaderElements.h&quot;
@interface ViewController()
    @property (retain) UIAlertView* waiterView;
    @property (assign) int signingAttempsCount;
@end
@implementation ViewController
const int static delay = 3;
const int maxSigningAttempsCount = 3; // Number of repository connection attempts
NSString *host = @&quot;nrspo-121.prognozcloud.ru&quot;;
NSString *webAppName = @&quot;r7.2&quot;;
NSString *mobileAppName  = @&quot;mobile&quot;;
NSString *login = @&quot;sa&quot;;
NSString *password = @&quot;sa&quot;;
-(id)init {
    self = [super init];
    if (self) {
        [self setSigningAttempsCount: 0];
        // Set successful report download event handler
        NNotificationCenterExt::addObserver(self, @selector(repositoryDownloadingFinished:), didDownloadRepositoryDescriptorNotificationName, NULL);
        // Set  unsuccessful report download event handler
        NNotificationCenterExt::addObserver(self, @selector(repositoryDownloadingFailed:), didFailDownloadingRepositoryDescriptorNotificationName, NULL);
        // Set authentication complete event handler
        NNotificationCenterExt::addObserver(self, @selector(authenticationCompleted:), didAuthenticationCompletedDescriptorNotificationName, NULL);
        [self showWaiterWithText: NSLocalizedString(@&quot;Signing in...&quot;, nil)];
        // Connect repository
        [self connect];
    }
    return self;
}
-(void) connect {
    // Create a metabase containing information on reports
    m_metabase = PPLMetabase::sharedMetabase(NString::stringWithNSString(host), NString::stringWithNSString(webAppName), NString::stringWithNSString(mobileAppName));
    if (m_metabase-&gt;getHost() == nil) {
        m_metabase-&gt;setHost(NString::stringWithNSString(host));
    }
    if (m_metabase-&gt;isHttpsEnabled()) {
        m_metabase-&gt;setHttpsEnabled(false);
    }
    [self updateRepository];
    // Authenticate user
    [self authenticateUser];
}
// Authenticates user
-(void)authenticateUser {
    /* Set login and password for checking
    if specified user can access reports */
    PPLAccessRightsManager::accessRightsManager()-&gt;setAuthenticatedUser(m_metabase-&gt;getLogin(), m_metabase-&gt;getPassword());
}
// Refreshes repository state based on remote server data
-(void)updateRepository {
    m_metabase-&gt;updateRemoteRepositoryContent(NString::stringWithNSString(login),
    NString::stringWithNSString(password));
}
- (void)authenticationCompleted:(NNotification *)notification {
    SNNumber errorType = notification-&gt;userInfo()-&gt;objectForKey&lt;NNumber&gt;(errorNotificationTypeKey);
    if (errorType-&gt;intValue() != PPLMetabase::errSuccess) {
        _signingAttempsCount++;
        NSLog(@&quot;Authorization error (attempt %d)&quot;, _signingAttempsCount);
        if (_signingAttempsCount &lt; maxSigningAttempsCount) {
            [self connect];
            } else {
            [self hideWaiter];
        }
    }
}
- (void)repositoryDownloadingFinished:(NNotification *)notification {
    NSLog(@&quot;Repository data is successfully obtained&quot;);
    [self hideWaiter];
    [self initObjectDescriptor];
}
- (void)repositoryDownloadingFailed:(NNotification *)notification {
    NSLog(@&quot;Error loading repository data&quot;);
}
// Initializes repository object
-(void)initObjectDescriptor {
    N_FOREACH(SPPLMetabaseRepositoryDescriptor, repositoryDescriptor, [self getRepositories]) {
        // Set repository as the current one
        [self setCurrentRepository: repositoryDescriptor];
        // Get express report
        SPPLMetabaseRepositoryObjectDescriptor olapObjectDescriptor =
        [self getObjectDescriptorWithType: PPLMetabaseRepositoryObjectDescriptor::kExpressAnalysisReport];
        // Delete this report
        if ([self removeRepositoryObject: olapObjectDescriptor]) {
            return;
        };
        // Load repository object description
        bool isDownloading = [self downloadRepositoryObject: olapObjectDescriptor];
        if (isDownloading) {
            return;
        }
    }
}
// Sets current repository
-(void)setCurrentRepository: (SPPLMetabaseRepositoryDescriptor) repositoryDescriptor {
    m_metabase = PPLMetabase::sharedMetabase(repositoryDescriptor);
}
// Returns array of repositories
-(SNArray) getRepositories {
    SPPLMetabaseRepositoryWarehouse defaultWarehouse = PPLMetabaseRepositoryWarehousePool::sharedWarehousePool()-&gt;defaultWarehouse();
    return defaultWarehouse-&gt;repositoriesList();
}
// Returns description of specified type of repository object
-(SPPLMetabaseRepositoryObjectDescriptor) getObjectDescriptorWithType: (PPLMetabaseRepositoryObjectDescriptor::Type) type {
    SPPLMetabaseRepositoryObjectDescriptor result = NULL;
    N_FOREACH(SPPLMetabaseRepositoryObjectDescriptor, objectDescriptor, m_metabase-&gt;allReportDescriptors()) {
        if(objectDescriptor-&gt;isReport()) {
            if(objectDescriptor-&gt;type() == type) {
                result = objectDescriptor;
                break;
            }
        }
        
    }
    return result;
}
// Removes specified repository object
-(bool)removeRepositoryObject: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    if (objectDescriptor &amp;&amp; objectDescriptor-&gt;isLocal()) {
        [self removeReport: objectDescriptor];
        NSLog(@&quot;Repository object is removed&quot;);
        return true;
        } else {
        return false;
    }
}
// Loads specified repository object
-(bool)downloadRepositoryObject: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    if (objectDescriptor &amp;&amp; objectDescriptor-&gt;isRemote()) {
        [self downloadReport: objectDescriptor];
        return true;
        } else {
        return false;
    }
}
-(void) downloadReport: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    [self addObjectDownloadObservers];
    m_reportDescriptor = objectDescriptor;
    // Create a repository pool
    SPPLMetabasePool metabasePool = PPLMetabasePool::sharedMetabasePool();
    SPPLMetabase metabase = metabasePool-&gt;sharedMetabase(NString::stringWithNSString(host), NString::stringWithNSString(webAppName), NString::stringWithNSString(mobileAppName));
    metabase-&gt;downloadReport(m_reportDescriptor);
    [self showWaiterWithText:NSLocalizedString(@&quot;Downloading&quot;, nil)];
}
- (void)reportDownloadingFinished:(NNotification *)notification {
    SNDictionary userInfo = notification-&gt;userInfo();
    SNNumber isLastInQueue = userInfo-&gt;objectForKey&lt;NNumber&gt;(PPLNetDownloadManager::IS_LAST_IN_QUEUE_KEY);
    
    if (isLastInQueue &amp;&amp; isLastInQueue-&gt;boolValue()) {
        [self initReport];
    }
}
- (void)reportDownloadingFailed:(NNotification *)notification {
    [self removeObjectDownloadObservers];
}
- (void)downloadProgressNotification:(NNotification *)notification {
    NSLog(@&quot;%@&quot;,notification-&gt;userInfo()-&gt;description()-&gt;nsString());
}
- (void)initReport {
    if (m_reportDescriptor-&gt;isLocal()) {
        NSLog(@&quot;Report is successfully loaded&quot;);
        [self hideWaiter];
        [self showWaiterWithText: NSLocalizedString(@&quot;Opening...&quot;, nil)];
        [self removeObjectDownloadObservers];
        // Open report
        [self openReport];
    }
}
-(void)addObjectDownloadObservers {
    NNotificationCenterExt::addObserver(self, @selector(downloadProgressNotification:),
    downloadProgressNotificationName, NULL);
    NNotificationCenterExt::addObserver(self, @selector(reportDownloadingFinished:),
    downloadFinishedNotificationName, NULL);
    NNotificationCenterExt::addObserver(self, @selector(reportDownloadingFailed:),
    downloadFailedNotificationName, NULL);
}
-(void)removeObjectDownloadObservers {
    NNotificationCenterExt::removeObserver(self, downloadProgressNotificationName, NULL);
    NNotificationCenterExt::removeObserver(self, downloadFailedNotificationName, NULL);
    NNotificationCenterExt::removeObserver(self, downloadFinishedNotificationName, NULL);
}
// Displays Displays busy indicator
- (void)showWaiterWithText: (NSString *) text {
    self.waiterView = [[[UIAlertView alloc] initWithTitle:text
    message:nil
    delegate:self
    cancelButtonTitle:nil
    otherButtonTitles:nil] autorelease];
    
    UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    activityView.frame = CGRectMake(139.0f - 18.0f, 50.0f, 37.0f, 37.0f);
    [activityView startAnimating];
    [[self waiterView] addSubview:activityView];
    [[self waiterView] show];
    
    [activityView release];
}
// Remove busy indicator
- (void)hideWaiter {
    [[self waiterView] dismissWithClickedButtonIndex:0 animated:NO];
    [self setWaiterView: nil];
}
// Removes specified repository object
-(void)removeReport: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    NSString *slash = @&quot;/&quot;;
    NSMutableString *repositoryPath = (m_metabase-&gt;isHttpsEnabled())?[NSMutableString stringWithString:@&quot;https://&quot;]:
    [NSMutableString stringWithString:@&quot;http://&quot;];
    [repositoryPath appendString: host];
    [repositoryPath appendString: slash];
    [repositoryPath appendString: webAppName];
    [repositoryPath appendString: slash];
    [repositoryPath appendString: mobileAppName];
    SPPLMetabase metabase = PPLMetabase::sharedMetabase(NString::stringWithNSString(repositoryPath));
    metabase-&gt;removeObject(objectDescriptor);
    // Update repository state
    [self updateRepository];
}
-(void) openReport {
    SPPLMetabase metabase = PPLMetabase::sharedMetabase(m_reportDescriptor-&gt;repositoryDescriptor());
    m_olapReport = metabase-&gt;getReportByObjectKey(m_reportDescriptor-&gt;key())-&gt;qClass&lt;PPLOlapReport&gt;();
    SNDictionary gridOlapPlist = m_olapReport-&gt;storageDictionary()-&gt;objectForKey&lt;NDictionary&gt;(GRID_OLAP_KEY);
    SPPLOlapReport gridOlapReport = NULL;
    if (gridOlapPlist != NULL) {
        gridOlapReport = PPLOlapReport::olapReport(m_olapReport-&gt;descriptor(), gridOlapPlist);
    }
    
    m_gridPivot = (gridOlapReport != NULL) ? PPLPivot::pivot(gridOlapReport) : PPLPivot::pivot(m_olapReport);
    m_gridPivotTable = PPLPivotTable::pivotTable(m_gridPivot);
    
    int64 key;
    if (SNArray fixed = m_olapReport-&gt;fixedDimensions()) {
        for (int i = 0, nCount = fixed-&gt;count(); i &lt; nCount; ++i) {
            SPPLDimension dim = fixed-&gt;objectAtIndex&lt;PPLDimension&gt;(i);
            key = dim-&gt;key();
            m_gridPivot-&gt;selectionSet()-&gt;getSelectionByDimensionKey(key)-&gt;selectAll();
        }
    }
    
    SNDictionary gridPivotTablePlist = m_olapReport-&gt;storageDictionary()-&gt;objectForKey&lt;NDictionary&gt;(GRID_PIVOT_TABLE_KEY);
    if (gridPivotTablePlist != NULL) {
        m_gridPivotTable-&gt;setupFromPlist(gridPivotTablePlist);
    }
    else {
        [self applyGridSettings];
    }
    m_gridPivot-&gt;refresh();
    NNotificationCenterExt::addObserver(self, @selector(pivotDidUpdateNotificatonHandler:), didUpdatePivotDataNotificationName, m_gridPivot);
    [self hideWaiter];
    // Execute custom example
    [self performSelector:@selector(executeExample) withObject:NULL afterDelay:delay];
}
-(void) pivotDidUpdateNotificatonHandler: (NNotification *) notification {
    dataSource = [[DataSource alloc] initWithPivotTable:m_gridPivotTable];
    [self createChart];
}
-(void) createChart {
    m_numberFormat = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:NO], @&quot;asInSource&quot;,
    [NSNumber numberWithInt:2], @&quot;decNumbers&quot;,
    [NSNumber numberWithBool:YES], @&quot;separator&quot;,
    @&quot;&quot;, @&quot;prefix&quot;,
    @&quot;&quot;, @&quot;prefix&quot;,
    [NSNumber numberWithBool:NO], @&quot;negativeRed&quot;,
    nil] retain];
    // Create a chart and determine its size
    chart = [[Chart alloc] initWithName:@&quot;chart&quot;];
    chart.frame = CGRectMake(0, 0, 450, 450);
    // Set grey color border
    [[chart layer] setBorderColor: [[UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1] CGColor]];
    [[chart layer] setBorderWidth: 1.0f];
    
    chart.backgroundColor = [UIColor whiteColor];
    ValueAxis *ax = [chart.axes objectForKey:[NSNumber numberWithInt:AxisLineX]];
    ax.axisLabelsVertical = NO;
    // Create a  data source
    // Create the first series
    LineSeries *series = [LineSeries new];
    series.dataIndex = 0; // Series index, numbering starts with zero
    series.defaultLabel = [self createDefaultLabel];
    [series setColor:[UIColor blueColor]]; // Series line color
    series.isLegendVisible = YES; // Display in legend
    [series setShadowColor:[UIColor blueColor]]; // Shadow color
    series.shadowOpacity = 0.2;// Shadow transparency
    series.shadowRadius = 0.01;// Shadow radius
    series.showShadow = YES; // Display shadow
    // Create the second series
    LineSeries *series1 = [LineSeries new];
    series1.dataIndex = 1;
    series1.defaultLabel = [self createDefaultLabel];
    [series1 setColor:[UIColor redColor]];
    series1.isLegendVisible = YES;
    [series1 setShadowColor:[UIColor redColor]];
    series1.shadowOpacity = 0.2;
    series1.shadowRadius = 0.01;
    series1.showShadow = YES;
    // Create the third series
    LineSeries *series2 = [LineSeries new];
    series2.dataIndex = 2;
    series2.defaultLabel = [self createDefaultLabel];
    [series2 setColor:[UIColor greenColor]];
    series2.isLegendVisible = YES;
    [series2 setShadowColor:[UIColor greenColor]];
    series2.shadowOpacity = 0.2;
    series2.shadowRadius = 0.01;
    series2.showShadow = YES;
    // Create the fourth series
    LineSeries *series3 = [LineSeries new];
    series3.dataIndex = 3;
    series3.defaultLabel = [self createDefaultLabel];
    [series3 setColor:[UIColor darkGrayColor]];
    series3.isLegendVisible = YES;
    [series3 setShadowColor:[UIColor darkGrayColor]];
    series3.shadowOpacity = 0.2;
    series3.shadowRadius = 0.01;
    series3.showShadow = YES;
    // Set data source
    [chart setDataSource:dataSource];
    [chart setDelegate:self];
    // Get maximum and minimum values of Y axis scale
    [dataSource prepare];
    // Add created series to chart
    [chart addSeries:series];
    [chart addSeries:series1];
    [chart addSeries:series2];
    [chart addSeries:series3];
    // Hide timeline
    [[chart timeAxis] setVisible:NO];
    // Update data
    [chart forceDataUpdate];
    // Display chart
    [self.view addSubview:chart];
    // Calculate size for chart drawing
    min = dataSource.yMin;
    max = dataSource.yMax;
    
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Determine link to selected series
    currSeries = nil;
}
// Returns all data dimensions
- (SNArray)allDimensions {
    SNMutableArray allDimensions = NMutableArray::mutableArrayWithArray(m_gridPivot-&gt;topHeader()-&gt;dimensions());
    allDimensions-&gt;addObjectsFromArray(m_gridPivot-&gt;leftHeader()-&gt;dimensions());
    allDimensions-&gt;addObjectsFromArray(m_gridPivot-&gt;fixedHeader()-&gt;dimensions());
    return allDimensions;
}
// Handle chart area touch event
- (void)chartTouchesTapInView:(UIView *)v withPoint:(CGPoint)point {
}
// Create point labels
- (ChartLabel *)createDefaultLabel {
    ChartLabel *result = [[[ChartLabel alloc] initWithFrame:CGRectZero] autorelease];
    result.background = [[SolidColorBrush new] autorelease]; // Background
    result.borderColor = [UIColor blackColor]; // Border color
    result.borderThickness = 1; // Border width
    result.borderRadius = 10; // Corner rounding radius
    result.font = [UIFont fontWithName:@&quot;Arial&quot; size:18]; // Font
    result.formatter = [NSNumberFormatter new];
    result.textAlignment = AlignmentCenter; // Text alignment
    result.textColor = [UIColor blackColor]; // Text color
    // Determine text formatting mask
    result.mask = [NSString stringWithFormat:@&quot;%@#FVAL%@&quot;,
    (NSString *)[m_numberFormat objectForKey:@&quot;prefix&quot;],
    (NSString *)[m_numberFormat objectForKey:@&quot;suffix&quot;]];
    result.countOfDecimalNumbers = 3; // Number of displayed decimal places
    result.displayNegativesInRed = NO; // Format of displaying negative values
    // Hide additional lines
    result.hasHorizontalNoteLine = result.hasVerticalNoteLine = result.hasFootNoteLine = NO;
    // Set minimum width
    result.minWidth = 0;
    return result;
}
// Applies table settings
- (void)applyGridSettings {
    NSDictionary *settings = [self gridSettings];
    if (settings != nil) {
        NSDictionary *dataSettings = [settings objectForKey:@&quot;data&quot;];
        if (dataSettings != nil) {
            int aggregateData = [(NSNumber *)[dataSettings objectForKey:@&quot;aggregateFixed&quot;] intValue];
            // Get data source
            SPPLDataSource gridDS = m_metabase-&gt;getDataSourceByObjectId(m_reportDescriptor-&gt;dataSourceRefId());
            gridDS-&gt;setIsAggregate(aggregateData);
        }
        
        NSDictionary *totalsSettings = [settings objectForKey:@&quot;totals&quot;];
        if (totalsSettings != nil) {
            BOOL emptyAsZero = [(NSString *)[totalsSettings objectForKey:@&quot;emptyValuesAsZero&quot;] isEqualToString:@&quot;true&quot;];
            BOOL includeOwner = [(NSString *)[totalsSettings objectForKey:@&quot;includeOwner&quot;] isEqualToString:@&quot;true&quot;];
            BOOL useHierarchy = [(NSString *)[totalsSettings objectForKey:@&quot;hierarchyTotals&quot;] isEqualToString:@&quot;true&quot;];
            BOOL useLevels = [(NSString *)[totalsSettings objectForKey:@&quot;levelTotals&quot;] isEqualToString:@&quot;true&quot;];
            
            SPPLPivotTableTotalsSettings settings = m_gridPivotTable-&gt;totalsSettings();
            settings-&gt;setTreatEmptyAsZero(emptyAsZero);
            settings-&gt;setIncludeParents(includeOwner);
            settings-&gt;setUseHierarchy(useHierarchy);
            settings-&gt;setUseLevels(useLevels);
            
            if (NSArray *rows = [totalsSettings objectForKey:@&quot;rows&quot;])
            ReadPPLPivotTableTotalsTypes(settings-&gt;rowTypes(), rows);
            if (NSArray *columns = [totalsSettings objectForKey:@&quot;columns&quot;])
            ReadPPLPivotTableTotalsTypes(settings-&gt;columnTypes(), columns);
        }
        
        NSDictionary *filterSettings = [settings objectForKey:@&quot;gridFilter&quot;];
        if (filterSettings != nil &amp;&amp; [[filterSettings objectForKey:@&quot;enabled&quot;] isEqual:@&quot;true&quot;]) {
            NSString *filterZero = [filterSettings objectForKey:@&quot;filterZero&quot;];
            NSString *filterEmpty = [filterSettings objectForKey:@&quot;filterEmpty&quot;];
            NSString *filterNonNumeric = [filterSettings objectForKey:@&quot;filterNonNumeric&quot;];
            
            if (filterZero) {
                m_gridPivotTable-&gt;filterSettings()-&gt;globalSettings()-&gt;setSuppressZero([filterZero boolValue]);
            }
            
            if (filterEmpty) {
                m_gridPivotTable-&gt;filterSettings()-&gt;globalSettings()-&gt;setSuppressEmpty([filterEmpty boolValue]);
            }
            
            if (filterNonNumeric) {
                m_gridPivotTable-&gt;filterSettings()-&gt;globalSettings()-&gt;setSuppressNonNumeric([filterNonNumeric boolValue]);
            }
            
            int elements = [[filterSettings objectForKey:@&quot;filterElements&quot;] intValue];
            switch (elements) {
                case 0:
                m_gridPivotTable-&gt;filterSettings()-&gt;globalSettings()-&gt;setElements(PPLPivotTableFilterElements::kRowsAndColumns);
                break;
                
                case 1:
                m_gridPivotTable-&gt;filterSettings()-&gt;globalSettings()-&gt;setElements(PPLPivotTableFilterElements::kRows);
                break;
                
                case 2:
                m_gridPivotTable-&gt;filterSettings()-&gt;globalSettings()-&gt;setElements(PPLPivotTableFilterElements::kColumns);
                break;
            }
            
            BOOL useConditions = [[filterSettings objectForKey:@&quot;filterUseCondition&quot;] isEqual:@&quot;true&quot;];
            m_gridPivotTable-&gt;filterSettings()-&gt;setUseConditionFilters(useConditions);
            
            int conditionType = [[filterSettings objectForKey:@&quot;filterCondition&quot;] intValue];
            SPPLPivotTableConditionFilterFactory filterFactory = new PPLPivotTableConditionFilterFactory();
            switch (conditionType) {
                case 0:
                m_gridPivotTable-&gt;filterSettings()-&gt;setUseConditionFilters(false);
                break;
                
                case 1:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kEquals);
                break;
                
                case 2:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kNotEquals);
                break;
                
                case 3:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kGreater);
                break;
                
                case 4:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kLess);
                break;
                
                case 5:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kGreaterOrEquals);
                break;
                
                case 6:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kLessOrEquals);
                break;
                
                case 7:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kBetween);
                break;
                
                case 8:
                filterFactory-&gt;setFilterType(PPLPivotTableFilterType::kLessOrGreater);
                break;
            }
            
            filterFactory-&gt;setValueA(NNumber::numberWithDouble([(NSNumber *)[filterSettings objectForKey:@&quot;filterConditionA&quot;] doubleValue]));
            filterFactory-&gt;setValueB(NNumber::numberWithDouble([(NSNumber *)[filterSettings objectForKey:@&quot;filterConditionB&quot;] doubleValue]));
            filterFactory-&gt;setKeepParent(false);
            filterFactory-&gt;setPercentMode(false);
            filterFactory-&gt;setRelatedTableElement(NULL);
            
            SPPLPivotTableConditionFilterSettings settings = filterFactory-&gt;create();
            m_gridPivotTable-&gt;filterSettings()-&gt;globalSettings()-&gt;setGlobalConditionalFilterSettings(settings);
        }
        
        NSDictionary *sortSettings = [settings objectForKey:@&quot;gridSort&quot;];
        if (sortSettings != nil) {
            NSArray *columnsSortSettings = [sortSettings objectForKey:@&quot;columns&quot;];
            if (columnsSortSettings != nil &amp;&amp; columnsSortSettings.count &gt; 0) {
                NSDictionary *columnSortSettings = [columnsSortSettings lastObject];
                NSInteger columnIndex = [[columnSortSettings objectForKey:@&quot;index&quot;] integerValue];
                NSInteger direction = [[columnSortSettings objectForKey:@&quot;direction&quot;] integerValue];
                
                if (direction &gt; 0 &amp;&amp; m_gridPivotTable-&gt;topHeader()-&gt;elements()-&gt;elementsCount() &gt; columnIndex) {
                    SPPLPivotTableHeaderElement element = m_gridPivotTable-&gt;topHeader()-&gt;elements()-&gt;getElementByIndex(columnIndex);
                    
                    m_gridPivotTable-&gt;sorterSettings()-&gt;setRelatedTableElement(element);
                    if (direction == 1) {
                        m_gridPivotTable-&gt;sorterSettings()-&gt;setDirection(PPLPivotTableSortDirection::kAsc);
                    }
                    else if (direction == 2) {
                        m_gridPivotTable-&gt;sorterSettings()-&gt;setDirection(PPLPivotTableSortDirection::kDesc);
                    }
                }
            }
            
            NSArray *rowsSortSettings = [sortSettings objectForKey:@&quot;rows&quot;];
            if (rowsSortSettings != nil &amp;&amp; rowsSortSettings.count &gt; 0) {
                NSDictionary *rowSortSettings = [rowsSortSettings lastObject];
                NSInteger rowIndex = [[rowSortSettings objectForKey:@&quot;index&quot;] integerValue];
                NSInteger direction = [[rowSortSettings objectForKey:@&quot;direction&quot;] integerValue];
                
                if (direction &gt; 0 &amp;&amp; m_gridPivotTable-&gt;leftHeader()-&gt;elements()-&gt;elementsCount() &gt; rowIndex) {
                    SPPLPivotTableHeaderElement element = m_gridPivotTable-&gt;leftHeader()-&gt;elements()-&gt;getElementByIndex(rowIndex);
                    m_gridPivotTable-&gt;sorterSettings()-&gt;setRelatedTableElement(element);
                    if (direction == 1) {
                        m_gridPivotTable-&gt;sorterSettings()-&gt;setDirection(PPLPivotTableSortDirection::kAsc);
                    }
                    else if (direction == 2) {
                        m_gridPivotTable-&gt;sorterSettings()-&gt;setDirection(PPLPivotTableSortDirection::kDesc);
                    }
                }
            }
        }
    }
}
// Returns express report table settings
- (NSDictionary *)gridSettings {
    // Create a repository object
    SPPLMetabaseObject metabaseObject = new PPLMetabaseObject(m_reportDescriptor);
    // Create an express report object
    SPPLOlapReport olapObject = PPLOlapReport::olapReport(metabaseObject-&gt;descriptor());
    if (olapObject-&gt;gridSettings() != NULL) {
        // Returns expres report table settings
        return (NSDictionary *)olapObject-&gt;gridSettings()-&gt;nsObject();
    }
    else {
        return nil;
    }
}
// Executes custom example placed in the body of this method
-(void)executeExample { 
}
@end

See also:

Data Analysis