Operating system requirements: iOS 5.0 or later.
Mobile device: iPad.
This example describes conditional formatting setup for table cells based on the rule "Value between A and B". The conditional formatting setting pool is used to apply rule settings.
Executing the example requires to place the following code instead of the executeExample method of the ViewController class (see the Displaying of Express Report section):
-(void)executeExample {
MAExpressAnalysisReportViewController *contr = (MAExpressAnalysisReportViewController *)m_controller;
// Get array of data view controllers
NSArray *controllers =[contr dataViewControllers];
// Determine values of A and B
double valueA = 7000;
double valueB = 8000;
// Parse data view controllers in cycle
for(NSObject *controller in controllers)
{
// Check if the current controller is a table data view controller
if([controller isMemberOfClass:[MAGridDataViewController class]])
{
// Get table data view controller object
MAGridDataViewController *gridController = (MAGridDataViewController *)controller;
// Get controller view
UIView *view = [gridController view];
// Get array of subviews
NSArray *subviews = [view subviews];
// Parse subviews in cycle
for(NSObject *subview in subviews)
{
// Check if the current view is a table view
if([subview isMemberOfClass:[NuGridView class]])
{
// Get table view object
NuGridView *gridView = (NuGridView *)subview;
// Get table delegate
MAGridDelegate *delegate = (MAGridDelegate*)[gridView gridDelegate];
// Get proxy data source
MAGridProxyDataSource *proxyDatasource = (MAGridProxyDataSource*)[delegate proxyDataSource];
// Determine rule-based conditional formatting settings
MAConditionalFormattingRules *rules = [[MAConditionalFormattingRules new] autorelease];
// Apply rules to the whole table
[rules setArea: kCFAEntireTable];
// Get conditional formatting rule
MAConditionalFormattingRule *formattingRule = [rules ruleByType: kCFRTBetween];
// Mark created rule as active
[formattingRule setActive: YES];
// Set fill color for cells that satisfy the rule
[formattingRule setColor: [UIColor colorWithRed:1 green:0.77 blue:0.27 alpha:1]];
// Use absolute numeric values
[formattingRule setValueFormat: kCFRVFNumber];
// Enable data sorting
[formattingRule setApplyOrder: YES];
// Create a conditional formatting setting pool
MAConditionalFormattingPool *formattingPool = [[MAConditionalFormattingPool new] autorelease];
// Set conditional formatting setting pool
[formattingRule setConditionalFormattingPool: formattingPool];
// Initialize object with predefined data
MAConditionalFormattingRulePreparedData *preparedData = [[MAConditionalFormattingRulePreparedData new] autorelease];
NSMutableArray *dataArray = nil; // Data array
double total = 0.0; // Total sum of data values
// Check if it is required to prepare settings for conditional formatting rule
bool isNeedPrepareData = [formattingRule needPrepareDataForCellInRow:nil andColumn:nil withArea:[rules area]];
if (isNeedPrepareData) {
// Prepare data
[preparedData setPreparedValueA: [NSNumber numberWithDouble: valueA]];
[preparedData setPreparedValueB: [NSNumber numberWithDouble: valueB]];
// Write prepared data into conditional formatting setting pool
[formattingPool putPreparedData: preparedData forRuleInRow:nil andColumn:nil withType: [formattingRule type] withArea:kCFAEntireTable];
// Create a sorted data array for the whole table
dataArray = [self dataArrayForEntireTableForDataSource: proxyDatasource];
[dataArray removeObjectIdenticalTo:[NSNull null]];
[dataArray sortUsingSelector:@selector(compare:)];
// Calculate total sum of array data
total = [self calculateDataTotal:dataArray];
if ([formattingRule applyOrder]) {
// Prepare data for conditional formatting rule
[formattingRule prepareWithSortedDataArray:dataArray
andDataTotal:total
inRow:nil
andColumn:nil
withArea: [rules area]];
}
}
// Create a helper for working with conditional formatting settings
MAConditionalFormattingHelper *formattingHelper = [[MAConditionalFormattingHelper alloc] initWithProxyDataSource: proxyDatasource];
// Apply conditional formatting settings to the whole table
[formattingHelper applyGlobalConditionalFormat: rules];
// Get average value in the range (A; B)
double valueA = [[preparedData preparedValueA] doubleValue];
double valueB = [[preparedData preparedValueB] doubleValue];
double averageValue = (valueA + valueB) / 2;
// Determine whether obtained value belongs to this range
bool conformsToValue = [formattingRule conformsToValue: [NSNumber numberWithDouble: averageValue]];
NSLog(@"Value %f %@belongs to interval (%f; %f)", averageValue, (conformsToValue? @"": @"not "),
valueA, valueB);
// Determine color corresponding to this range
UIColor *color = [rules colorForValue: [NSNumber numberWithDouble: averageValue]];
const CGFloat *components = CGColorGetComponents([color CGColor]);
if (components != NULL) {
CGFloat r = components[0];
CGFloat g = components[1];
CGFloat b = components[2];
NSString *hexString=[NSString stringWithFormat:@"%02X%02X%02X", (int)(r * 255), (int)(g * 255), (int)(b * 255)];
NSLog(@"Color corresponding to value %f: #%@", averageValue, hexString);
}
}
}
}
}
}
// Creates a data array for the whole table
- (NSMutableArray *)dataArrayForEntireTableForDataSource:(MAGridProxyDataSource *)dataSource {
// Get object used to work with table
SPPLPivotTable pivotTable = dataSource.dataSource.pivotTable;
// Get number of rows
int rowCount = pivotTable->leftHeader()->elements()->elementsCount();
// Get number of columns
int columnCount = pivotTable->topHeader()->elements()->elementsCount();
// Create a data array
NSMutableArray *result = [NSMutableArray arrayWithCapacity:rowCount * columnCount];
for (int r = 0; r < rowCount; ++r) {
SPPLPivotTableHeaderElement leftElement = pivotTable->leftHeader()->elements()->getElementByIndex(r);
BOOL isRowInTotal = pivotTable->leftHeader()->elements()->isElementInTotals(leftElement);
if (isRowInTotal) {
continue;
}
for (int c = 0; c < columnCount; ++c) {
SPPLPivotTableHeaderElement topElement = pivotTable->topHeader()->elements()->getElementByIndex(c);
BOOL isColumnInTotal = pivotTable->topHeader()->elements()->isElementInTotals(topElement);
if (isColumnInTotal) {
continue;
}
// Get table cell data
SNID data = pivotTable->getData(r, c);
NSObject *value = (data != NULL) ? (NSObject *)data->nsObject() : nil;
if ([value isKindOfClass:NSNumber.class]) {
// Add cell value to array
[result addObject:value];
}
}
}
return result;
}
// Calculates sum of data values from specified array
- (double)calculateDataTotal:(NSArray *)dataArray {
double total = 0.0; // Sum of all data
for (NSNumber *number in dataArray) {
if (![number isEqual:nil]) {
double doubleValue = [number doubleValue];
total += doubleValue;
}
}
return total;
}
After executing the example the conditional formatting with the use of the rule "Cells between A and B" is applied to the express report whole table. All the cells containing values from 7000 to 8000 are filled with yellow color:

The development environment console displays notifications whether the 7500 value belongs to the range (7000; 8000), also fill color of the cell corresponding to this value:
Value 7500.000000 belongs to range (7000.000000; 8000.000000)
Color corresponding to value 7500.000000: #FFC444
Identical result is obtained if the code fragment
[formattingRule prepareWithSortedDataArray:dataArray andDataTotal:total inRow:nil andColumn:nil withArea: [rules area]];
is replaced with the following script:
MAConditionalFormattingRulePreparedData *data = [formattingPool preparedDataForRuleInRow:nil andColumn:nil withType:[formattingRule type] withArea: [rules area]]; [formattingRule setValue:data forKey:@"preparedData"]; [formattingRule setValue:[NSNumber numberWithBool: NO] forKey:@"empty"];
After executing the example conditional formatting is applied with the same settings:
See also: