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: