Линейная диаграмма

Описание: создание линейной диаграммы, использующей куб в качестве источника данных.

Файл «ViewController.h»

#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;
}
// Выполняет пользовательский пример, размещённый в теле данного метода
- (void) executeExample;
- (ChartLabel *)createDefaultLabel;
@end

Файл «ViewController.mm»

#import "ViewController.h"
#include "NArray.h"
#include "NNotificationCenterExt.h"
#include "PPLAccessRightsManager.h"
#include "PPLCalendarDimension.h"
#include "PPLCalendarDimensionDataLevel.h"
#include "PPLCalendarDimensionDataLevels.h"
#include "PPLCalendarPeriodDimension.h"
#include "PPLCubeDataSource.h"
#include "PPLCubeTableField.h"
#include "PPLDashboardReport.h"
#include "PPLMetabase.h"
#include "PPLMetabasePool.h"
#include "PPLMetabaseRepositoryWarehousePool.h"
#include "PPLOlapReport.h"
#include "PPLPivotTableCalculatedHeaderElement.h"
#include "PPLPivotTableCalculator.h"
#include "PPLPivotTableCalculatorMutableSetting.h"
#include "PPLPivotTableConditionFilter.h"
#include "PPLPivotTableFilterElements.h"
#include "PPLPivotTableHeaderElement.h"
#include "PPLPivotTableHeaderElements.h"
@interface ViewController()
    @property (retain) UIAlertView* waiterView;
    @property (assign) int signingAttempsCount;
@end
@implementation ViewController
const int static delay = 3;
const int maxSigningAttempsCount = 3; // Количество попыток подключения к репозиторию
NSString *host = @"nrspo-121.prognozcloud.ru";
NSString *webAppName = @"r7.2";
NSString *mobileAppName  = @"mobile";
NSString *login = @"sa";
NSString *password = @"sa";
-(id)init {
    self = [super init];
    if (self) {
        [self setSigningAttempsCount: 0];
        // Устанавливаем обработчик события успешного скачивания отчёта
        NNotificationCenterExt::addObserver(self, @selector(repositoryDownloadingFinished:), didDownloadRepositoryDescriptorNotificationName, NULL);
        // Устанавливаем обработчик события неуспешного скачивания отчёта
        NNotificationCenterExt::addObserver(self, @selector(repositoryDownloadingFailed:), didFailDownloadingRepositoryDescriptorNotificationName, NULL);
        // Устанавливаем обработчик события завершения аутентификации
        NNotificationCenterExt::addObserver(self, @selector(authenticationCompleted:), didAuthenticationCompletedDescriptorNotificationName, NULL);
        [self showWaiterWithText: NSLocalizedString(@"Signing in...", nil)];
        // Подключаемся к репозиторию
        [self connect];
    }
    return self;
}
-(void) connect {
    // Создаём репозиторий, содержащую информацию об отчетах
    m_metabase = PPLMetabase::sharedMetabase(NString::stringWithNSString(host), NString::stringWithNSString(webAppName), NString::stringWithNSString(mobileAppName));
    if (m_metabase->getHost() == nil) {
        m_metabase->setHost(NString::stringWithNSString(host));
    }
    if (m_metabase->isHttpsEnabled()) {
        m_metabase->setHttpsEnabled(false);
    }
    [self updateRepository];
    // Аутентифицируем пользователя
    [self authenticateUser];
}
// Аутентифицирует пользователя
-(void)authenticateUser {
    /* Устанавливаем логин и пароль для проверки,
    может ли указанный пользователь получить доступ к отчётам */
    PPLAccessRightsManager::accessRightsManager()->setAuthenticatedUser(m_metabase->getLogin(), m_metabase->getPassword());
}
// Обновляет состояние репозитория на основе данных на удалённом сервере
-(void)updateRepository {
    m_metabase->updateRemoteRepositoryContent(NString::stringWithNSString(login),
    NString::stringWithNSString(password));
}
- (void)authenticationCompleted:(NNotification *)notification {
    SNNumber errorType = notification->userInfo()->objectForKey<NNumber>(errorNotificationTypeKey);
    if (errorType->intValue() != PPLMetabase::errSuccess) {
        _signingAttempsCount++;
        NSLog(@"Ошибка авторизации (попытка %d)", _signingAttempsCount);
        if (_signingAttempsCount < maxSigningAttempsCount) {
            [self connect];
            } else {
            [self hideWaiter];
        }
    }
}
- (void)repositoryDownloadingFinished:(NNotification *)notification {
    NSLog(@"Данные репозитория успешно получены");
    [self hideWaiter];
    [self initObjectDescriptor];
}
- (void)repositoryDownloadingFailed:(NNotification *)notification {
    NSLog(@"Ошибка загрузки данных репозитория");
}
// Инициализирует объект репозитория
-(void)initObjectDescriptor {
    N_FOREACH(SPPLMetabaseRepositoryDescriptor, repositoryDescriptor, [self getRepositories]) {
        // Устанавливаем репозиторий в качестве текущего
        [self setCurrentRepository: repositoryDescriptor];
        // Получаем экспресс-отчет
        SPPLMetabaseRepositoryObjectDescriptor olapObjectDescriptor =
        [self getObjectDescriptorWithType: PPLMetabaseRepositoryObjectDescriptor::kExpressAnalysisReport];
        // Удаляем данный отчёт
        if ([self removeRepositoryObject: olapObjectDescriptor]) {
            return;
        };
        // Загружаем описание объекта репозитория
        bool isDownloading = [self downloadRepositoryObject: olapObjectDescriptor];
        if (isDownloading) {
            return;
        }
    }
}
// Устанавливает текущий репозиторий
-(void)setCurrentRepository: (SPPLMetabaseRepositoryDescriptor) repositoryDescriptor {
    m_metabase = PPLMetabase::sharedMetabase(repositoryDescriptor);
}
// Возвращает массив репозиториев
-(SNArray) getRepositories {
    SPPLMetabaseRepositoryWarehouse defaultWarehouse = PPLMetabaseRepositoryWarehousePool::sharedWarehousePool()->defaultWarehouse();
    return defaultWarehouse->repositoriesList();
}
// Возвращает описание объекта репозитория указанного типа
-(SPPLMetabaseRepositoryObjectDescriptor) getObjectDescriptorWithType: (PPLMetabaseRepositoryObjectDescriptor::Type) type {
    SPPLMetabaseRepositoryObjectDescriptor result = NULL;
    N_FOREACH(SPPLMetabaseRepositoryObjectDescriptor, objectDescriptor, m_metabase->allReportDescriptors()) {
        if(objectDescriptor->isReport()) {
            if(objectDescriptor->type() == type) {
                result = objectDescriptor;
                break;
            }
        }
        
    }
    return result;
}
// Удаляет указанный объект репозитория
-(bool)removeRepositoryObject: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    if (objectDescriptor && objectDescriptor->isLocal()) {
        [self removeReport: objectDescriptor];
        NSLog(@"Объект репозитория удалён");
        return true;
        } else {
        return false;
    }
}
// Загружает указанный объект репозитория
-(bool)downloadRepositoryObject: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    if (objectDescriptor && objectDescriptor->isRemote()) {
        [self downloadReport: objectDescriptor];
        return true;
        } else {
        return false;
    }
}
-(void) downloadReport: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    [self addObjectDownloadObservers];
    m_reportDescriptor = objectDescriptor;
    // Создаём пул репозитория
    SPPLMetabasePool metabasePool = PPLMetabasePool::sharedMetabasePool();
    SPPLMetabase metabase = metabasePool->sharedMetabase(NString::stringWithNSString(host), NString::stringWithNSString(webAppName), NString::stringWithNSString(mobileAppName));
    metabase->downloadReport(m_reportDescriptor);
    [self showWaiterWithText:NSLocalizedString(@"Downloading", nil)];
}
- (void)reportDownloadingFinished:(NNotification *)notification {
    SNDictionary userInfo = notification->userInfo();
    SNNumber isLastInQueue = userInfo->objectForKey<NNumber>(PPLNetDownloadManager::IS_LAST_IN_QUEUE_KEY);
    
    if (isLastInQueue && isLastInQueue->boolValue()) {
        [self initReport];
    }
}
- (void)reportDownloadingFailed:(NNotification *)notification {
    [self removeObjectDownloadObservers];
}
- (void)downloadProgressNotification:(NNotification *)notification {
    NSLog(@"%@",notification->userInfo()->description()->nsString());
}
- (void)initReport {
    if (m_reportDescriptor->isLocal()) {
        NSLog(@"Отчёт успешно загружен");
        [self hideWaiter];
        [self showWaiterWithText: NSLocalizedString(@"Opening...", nil)];
        [self removeObjectDownloadObservers];
        // Открываем отчёт
        [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);
}
// Отображает индикатор занятости
- (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];
}
// Удаляем индикатор занятости
- (void)hideWaiter {
    [[self waiterView] dismissWithClickedButtonIndex:0 animated:NO];
    [self setWaiterView: nil];
}
// Удаляет указанный объект репозитория
-(void)removeReport: (SPPLMetabaseRepositoryObjectDescriptor) objectDescriptor {
    NSString *slash = @"/";
    NSMutableString *repositoryPath = (m_metabase->isHttpsEnabled())?[NSMutableString stringWithString:@"https://"]:
    [NSMutableString stringWithString:@"http://"];
    [repositoryPath appendString: host];
    [repositoryPath appendString: slash];
    [repositoryPath appendString: webAppName];
    [repositoryPath appendString: slash];
    [repositoryPath appendString: mobileAppName];
    SPPLMetabase metabase = PPLMetabase::sharedMetabase(NString::stringWithNSString(repositoryPath));
    metabase->removeObject(objectDescriptor);
    // Обновляем состояние репозитория
    [self updateRepository];
}
-(void) openReport {
    SPPLMetabase metabase = PPLMetabase::sharedMetabase(m_reportDescriptor->repositoryDescriptor());
    m_olapReport = metabase->getReportByObjectKey(m_reportDescriptor->key())->qClass<PPLOlapReport>();
    SNDictionary gridOlapPlist = m_olapReport->storageDictionary()->objectForKey<NDictionary>(GRID_OLAP_KEY);
    SPPLOlapReport gridOlapReport = NULL;
    if (gridOlapPlist != NULL) {
        gridOlapReport = PPLOlapReport::olapReport(m_olapReport->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->fixedDimensions()) {
        for (int i = 0, nCount = fixed->count(); i < nCount; ++i) {
            SPPLDimension dim = fixed->objectAtIndex<PPLDimension>(i);
            key = dim->key();
            m_gridPivot->selectionSet()->getSelectionByDimensionKey(key)->selectAll();
        }
    }
    
    SNDictionary gridPivotTablePlist = m_olapReport->storageDictionary()->objectForKey<NDictionary>(GRID_PIVOT_TABLE_KEY);
    if (gridPivotTablePlist != NULL) {
        m_gridPivotTable->setupFromPlist(gridPivotTablePlist);
    }
    else {
        [self applyGridSettings];
    }
    m_gridPivot->refresh();
    NNotificationCenterExt::addObserver(self, @selector(pivotDidUpdateNotificatonHandler:), didUpdatePivotDataNotificationName, m_gridPivot);
    [self hideWaiter];
    // Выполняем пользовательский пример
    [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], @"asInSource",
    [NSNumber numberWithInt:2], @"decNumbers",
    [NSNumber numberWithBool:YES], @"separator",
    @"", @"prefix",
    @"", @"prefix",
    [NSNumber numberWithBool:NO], @"negativeRed",
    nil] retain];
    // Создаем диаграмму и определяем её размеры
    chart = [[Chart alloc] initWithName:@"chart"];
    chart.frame = CGRectMake(0, 0, 450, 450);
    // Устанавливаем рамку серого цвета
    [[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;
    // Создаем источник данных
    // Создаем 1-й ряд
    LineSeries *series = [LineSeries new];
    series.dataIndex = 0; // Индекс ряда, нумерация начинается с нуля
    series.defaultLabel = [self createDefaultLabel];
    [series setColor:[UIColor blueColor]]; // Цвет линии ряда
    series.isLegendVisible = YES; // Отображаем в легенде
    [series setShadowColor:[UIColor blueColor]]; // Цвет тени
    series.shadowOpacity = 0.2;// Прозрачность тени
    series.shadowRadius = 0.01;// Радиус тени
    series.showShadow = YES; // Отображаем тень
    // Создаем 2-й ряд
    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;
    // Создаем 3-й ряд
    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;
    // Создаем 4-й ряд
    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;
    // Устанавливаем источник данных
    [chart setDataSource:dataSource];
    [chart setDelegate:self];
    // Получаем максимальное и минимальное значения шкалы для оси Y
    [dataSource prepare];
    // Добавляем созданные ряды на диаграмму
    [chart addSeries:series];
    [chart addSeries:series1];
    [chart addSeries:series2];
    [chart addSeries:series3];
    // Скрываем временную ось
    [[chart timeAxis] setVisible:NO];
    // Обновляем данные
    [chart forceDataUpdate];
    // Отображаем диаграмму
    [self.view addSubview:chart];
    // Рассчитываем размеры для прорисовки диаграммы
    min = dataSource.yMin;
    max = dataSource.yMax;
    
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Определяем ссылку на выбранный ряд
    currSeries = nil;
}
// Возвращает все измерения данных
- (SNArray)allDimensions {
    SNMutableArray allDimensions = NMutableArray::mutableArrayWithArray(m_gridPivot->topHeader()->dimensions());
    allDimensions->addObjectsFromArray(m_gridPivot->leftHeader()->dimensions());
    allDimensions->addObjectsFromArray(m_gridPivot->fixedHeader()->dimensions());
    return allDimensions;
}
// Обрабатываем событие касания области диаграммы
- (void)chartTouchesTapInView:(UIView *)v withPoint:(CGPoint)point {
}
// Создаем подписи точек
- (ChartLabel *)createDefaultLabel {
    ChartLabel *result = [[[ChartLabel alloc] initWithFrame:CGRectZero] autorelease];
    result.background = [[SolidColorBrush new] autorelease]; // Фон
    result.borderColor = [UIColor blackColor]; // Цвет границ
    result.borderThickness = 1; // Толщина границ
    result.borderRadius = 10; // Радиус скругления углов
    result.font = [UIFont fontWithName:@"Arial" size:18]; // Шрифт
    result.formatter = [NSNumberFormatter new];
    result.textAlignment = AlignmentCenter; // Выравнивание текста
    result.textColor = [UIColor blackColor]; // Цвет текста
    // Определяем маску форматирования текста
    result.mask = [NSString stringWithFormat:@"%@#FVAL%@",
    (NSString *)[m_numberFormat objectForKey:@"prefix"],
    (NSString *)[m_numberFormat objectForKey:@"suffix"]];
    result.countOfDecimalNumbers = 3; // Число отображаемых десятичных знаков
    result.displayNegativesInRed = NO; // Формат отображения отрицательных значений
    // Скрываем дополнительные линии
    result.hasHorizontalNoteLine = result.hasVerticalNoteLine = result.hasFootNoteLine = NO;
    // Устанавливаем минимальную ширину
    result.minWidth = 0;
    return result;
}
// Применяет настройки таблицы
- (void)applyGridSettings {
    NSDictionary *settings = [self gridSettings];
    if (settings != nil) {
        NSDictionary *dataSettings = [settings objectForKey:@"data"];
        if (dataSettings != nil) {
            int aggregateData = [(NSNumber *)[dataSettings objectForKey:@"aggregateFixed"] intValue];
            // Получаем источник данных
            SPPLDataSource gridDS = m_metabase->getDataSourceByObjectId(m_reportDescriptor->dataSourceRefId());
            gridDS->setIsAggregate(aggregateData);
        }
        
        NSDictionary *totalsSettings = [settings objectForKey:@"totals"];
        if (totalsSettings != nil) {
            BOOL emptyAsZero = [(NSString *)[totalsSettings objectForKey:@"emptyValuesAsZero"] isEqualToString:@"true"];
            BOOL includeOwner = [(NSString *)[totalsSettings objectForKey:@"includeOwner"] isEqualToString:@"true"];
            BOOL useHierarchy = [(NSString *)[totalsSettings objectForKey:@"hierarchyTotals"] isEqualToString:@"true"];
            BOOL useLevels = [(NSString *)[totalsSettings objectForKey:@"levelTotals"] isEqualToString:@"true"];
            
            SPPLPivotTableTotalsSettings settings = m_gridPivotTable->totalsSettings();
            settings->setTreatEmptyAsZero(emptyAsZero);
            settings->setIncludeParents(includeOwner);
            settings->setUseHierarchy(useHierarchy);
            settings->setUseLevels(useLevels);
            
            if (NSArray *rows = [totalsSettings objectForKey:@"rows"])
            ReadPPLPivotTableTotalsTypes(settings->rowTypes(), rows);
            if (NSArray *columns = [totalsSettings objectForKey:@"columns"])
            ReadPPLPivotTableTotalsTypes(settings->columnTypes(), columns);
        }
        
        NSDictionary *filterSettings = [settings objectForKey:@"gridFilter"];
        if (filterSettings != nil && [[filterSettings objectForKey:@"enabled"] isEqual:@"true"]) {
            NSString *filterZero = [filterSettings objectForKey:@"filterZero"];
            NSString *filterEmpty = [filterSettings objectForKey:@"filterEmpty"];
            NSString *filterNonNumeric = [filterSettings objectForKey:@"filterNonNumeric"];
            
            if (filterZero) {
                m_gridPivotTable->filterSettings()->globalSettings()->setSuppressZero([filterZero boolValue]);
            }
            
            if (filterEmpty) {
                m_gridPivotTable->filterSettings()->globalSettings()->setSuppressEmpty([filterEmpty boolValue]);
            }
            
            if (filterNonNumeric) {
                m_gridPivotTable->filterSettings()->globalSettings()->setSuppressNonNumeric([filterNonNumeric boolValue]);
            }
            
            int elements = [[filterSettings objectForKey:@"filterElements"] intValue];
            switch (elements) {
                case 0:
                m_gridPivotTable->filterSettings()->globalSettings()->setElements(PPLPivotTableFilterElements::kRowsAndColumns);
                break;
                
                case 1:
                m_gridPivotTable->filterSettings()->globalSettings()->setElements(PPLPivotTableFilterElements::kRows);
                break;
                
                case 2:
                m_gridPivotTable->filterSettings()->globalSettings()->setElements(PPLPivotTableFilterElements::kColumns);
                break;
            }
            
            BOOL useConditions = [[filterSettings objectForKey:@"filterUseCondition"] isEqual:@"true"];
            m_gridPivotTable->filterSettings()->setUseConditionFilters(useConditions);
            
            int conditionType = [[filterSettings objectForKey:@"filterCondition"] intValue];
            SPPLPivotTableConditionFilterFactory filterFactory = new PPLPivotTableConditionFilterFactory();
            switch (conditionType) {
                case 0:
                m_gridPivotTable->filterSettings()->setUseConditionFilters(false);
                break;
                
                case 1:
                filterFactory->setFilterType(PPLPivotTableFilterType::kEquals);
                break;
                
                case 2:
                filterFactory->setFilterType(PPLPivotTableFilterType::kNotEquals);
                break;
                
                case 3:
                filterFactory->setFilterType(PPLPivotTableFilterType::kGreater);
                break;
                
                case 4:
                filterFactory->setFilterType(PPLPivotTableFilterType::kLess);
                break;
                
                case 5:
                filterFactory->setFilterType(PPLPivotTableFilterType::kGreaterOrEquals);
                break;
                
                case 6:
                filterFactory->setFilterType(PPLPivotTableFilterType::kLessOrEquals);
                break;
                
                case 7:
                filterFactory->setFilterType(PPLPivotTableFilterType::kBetween);
                break;
                
                case 8:
                filterFactory->setFilterType(PPLPivotTableFilterType::kLessOrGreater);
                break;
            }
            
            filterFactory->setValueA(NNumber::numberWithDouble([(NSNumber *)[filterSettings objectForKey:@"filterConditionA"] doubleValue]));
            filterFactory->setValueB(NNumber::numberWithDouble([(NSNumber *)[filterSettings objectForKey:@"filterConditionB"] doubleValue]));
            filterFactory->setKeepParent(false);
            filterFactory->setPercentMode(false);
            filterFactory->setRelatedTableElement(NULL);
            
            SPPLPivotTableConditionFilterSettings settings = filterFactory->create();
            m_gridPivotTable->filterSettings()->globalSettings()->setGlobalConditionalFilterSettings(settings);
        }
        
        NSDictionary *sortSettings = [settings objectForKey:@"gridSort"];
        if (sortSettings != nil) {
            NSArray *columnsSortSettings = [sortSettings objectForKey:@"columns"];
            if (columnsSortSettings != nil && columnsSortSettings.count > 0) {
                NSDictionary *columnSortSettings = [columnsSortSettings lastObject];
                NSInteger columnIndex = [[columnSortSettings objectForKey:@"index"] integerValue];
                NSInteger direction = [[columnSortSettings objectForKey:@"direction"] integerValue];
                
                if (direction > 0 && m_gridPivotTable->topHeader()->elements()->elementsCount() > columnIndex) {
                    SPPLPivotTableHeaderElement element = m_gridPivotTable->topHeader()->elements()->getElementByIndex(columnIndex);
                    
                    m_gridPivotTable->sorterSettings()->setRelatedTableElement(element);
                    if (direction == 1) {
                        m_gridPivotTable->sorterSettings()->setDirection(PPLPivotTableSortDirection::kAsc);
                    }
                    else if (direction == 2) {
                        m_gridPivotTable->sorterSettings()->setDirection(PPLPivotTableSortDirection::kDesc);
                    }
                }
            }
            
            NSArray *rowsSortSettings = [sortSettings objectForKey:@"rows"];
            if (rowsSortSettings != nil && rowsSortSettings.count > 0) {
                NSDictionary *rowSortSettings = [rowsSortSettings lastObject];
                NSInteger rowIndex = [[rowSortSettings objectForKey:@"index"] integerValue];
                NSInteger direction = [[rowSortSettings objectForKey:@"direction"] integerValue];
                
                if (direction > 0 && m_gridPivotTable->leftHeader()->elements()->elementsCount() > rowIndex) {
                    SPPLPivotTableHeaderElement element = m_gridPivotTable->leftHeader()->elements()->getElementByIndex(rowIndex);
                    m_gridPivotTable->sorterSettings()->setRelatedTableElement(element);
                    if (direction == 1) {
                        m_gridPivotTable->sorterSettings()->setDirection(PPLPivotTableSortDirection::kAsc);
                    }
                    else if (direction == 2) {
                        m_gridPivotTable->sorterSettings()->setDirection(PPLPivotTableSortDirection::kDesc);
                    }
                }
            }
        }
    }
}
// Возвращает настройки таблицы экспресс-отчёта
- (NSDictionary *)gridSettings {
    // Создаём объект репозитория
    SPPLMetabaseObject metabaseObject = new PPLMetabaseObject(m_reportDescriptor);
    // Создаём объект экспресс-отчёта
    SPPLOlapReport olapObject = PPLOlapReport::olapReport(metabaseObject->descriptor());
    if (olapObject->gridSettings() != NULL) {
        // Возвращаем настройки таблицы экспресс-отчёта
        return (NSDictionary *)olapObject->gridSettings()->nsObject();
    }
    else {
        return nil;
    }
}
// Выполняет пользовательский пример, размещённый в теле данного метода
-(void)executeExample { 
}
@end

См. также:

Анализ данных