Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -(void)autoGenerateMajorTickLocations:(CPTNumberSet __autoreleasing *)newMajorLocations minorTickLocations:(CPTNumberSet __autoreleasing *)newMinorLocations
- {
- // Create sets for locations
- CPTMutableNumberSet majorLocations = [NSMutableSet set];
- CPTMutableNumberSet minorLocations = [NSMutableSet set];
- // Get plot range
- CPTMutablePlotRange *range = [[self.plotSpace plotRangeForCoordinate:self.coordinate] mutableCopy];
- CPTPlotRange *theVisibleRange = self.visibleRange;
- if ( theVisibleRange ) {
- [range intersectionPlotRange:theVisibleRange];
- }
- // Validate scale type
- BOOL valid = YES;
- CPTScaleType scaleType = [self.plotSpace scaleTypeForCoordinate:self.coordinate];
- switch ( scaleType ) {
- case CPTScaleTypeLinear:
- // supported scale type
- break;
- case CPTScaleTypeLog:
- // supported scale type--check range
- if ( (range.minLimitDouble <= 0.0) || (range.maxLimitDouble <= 0.0) ) {
- valid = NO;
- }
- break;
- case CPTScaleTypeLogModulus:
- // supported scale type
- break;
- default:
- // unsupported scale type--bail out
- valid = NO;
- break;
- }
- if ( !valid ) {
- *newMajorLocations = majorLocations;
- *newMinorLocations = minorLocations;
- return;
- }
- // Cache some values
- NSUInteger numTicks = self.preferredNumberOfMajorTicks;
- NSUInteger minorTicks = self.minorTicksPerInterval + 1;
- double length = fabs(range.lengthDouble);
- // Filter troublesome values and return empty sets
- if ( length != 0.0 ) {
- switch ( scaleType ) {
- case CPTScaleTypeLinear:
- {
- // Determine interval value
- switch ( numTicks ) {
- case 0:
- numTicks = 5;
- break;
- case 1:
- numTicks = 2;
- break;
- default:
- // ok
- break;
- }
- NSDecimal zero = CPTDecimalFromInteger(0);
- NSDecimal one = CPTDecimalFromInteger(1);
- NSDecimal majorInterval;
- if ( numTicks == 2 ) {
- majorInterval = CPTNiceLength(range.lengthDecimal);
- }
- else {
- majorInterval = CPTDecimalDivide( range.lengthDecimal, CPTDecimalFromUnsignedInteger(numTicks - 1) );
- majorInterval = CPTNiceNum(majorInterval);
- }
- if ( CPTDecimalLessThan(majorInterval, zero) ) {
- majorInterval = CPTDecimalMultiply( majorInterval, CPTDecimalFromInteger(-1) );
- }
- NSDecimal minorInterval;
- if ( minorTicks > 1 ) {
- minorInterval = CPTDecimalDivide( majorInterval, CPTDecimalFromUnsignedInteger(minorTicks) );
- }
- else {
- minorInterval = zero;
- }
- // Calculate actual range limits
- NSDecimal minLimit = range.minLimitDecimal;
- NSDecimal maxLimit = range.maxLimitDecimal;
- // Determine the initial and final major indexes for the actual visible range
- NSDecimal initialIndex = CPTDecimalDivide(minLimit, majorInterval);
- NSDecimalRound(&initialIndex, &initialIndex, 0, NSRoundDown);
- NSDecimal finalIndex = CPTDecimalDivide(maxLimit, majorInterval);
- NSDecimalRound(&finalIndex, &finalIndex, 0, NSRoundUp);
- // Iterate through the indexes with visible ticks and build the locations sets
- for ( NSDecimal i = initialIndex; CPTDecimalLessThanOrEqualTo(i, finalIndex); i = CPTDecimalAdd(i, one) ) {
- NSDecimal pointLocation = CPTDecimalMultiply(majorInterval, i);
- NSDecimal minorPointLocation = pointLocation;
- for ( NSUInteger j = 1; j < minorTicks; j++ ) {
- minorPointLocation = CPTDecimalAdd(minorPointLocation, minorInterval);
- if ( CPTDecimalLessThan(minorPointLocation, minLimit) ) {
- continue;
- }
- if ( CPTDecimalGreaterThan(minorPointLocation, maxLimit) ) {
- continue;
- }
- [minorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:minorPointLocation]];
- }
- if ( CPTDecimalLessThan(pointLocation, minLimit) ) {
- continue;
- }
- if ( CPTDecimalGreaterThan(pointLocation, maxLimit) ) {
- continue;
- }
- [majorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:pointLocation]];
- }
- }
- break;
- case CPTScaleTypeLog:
- {
- double minLimit = range.minLimitDouble;
- double maxLimit = range.maxLimitDouble;
- if ( (minLimit > 0.0) && (maxLimit > 0.0) ) {
- // Determine interval value
- length = log10(maxLimit / minLimit);
- double interval = signbit(length) ? -1.0 : 1.0;
- double intervalStep = pow( 10.0, fabs(interval) );
- // Determine minor interval
- double minorInterval = intervalStep * 0.9 * pow( 10.0, floor( log10(minLimit) ) ) / minorTicks;
- // Determine the initial and final major indexes for the actual visible range
- NSInteger initialIndex = (NSInteger)lrint( floor( log10( minLimit / fabs(interval) ) ) ); // can be negative
- NSInteger finalIndex = (NSInteger)lrint( ceil( log10( maxLimit / fabs(interval) ) ) ); // can be negative
- // Iterate through the indexes with visible ticks and build the locations sets
- for ( NSInteger i = initialIndex; i <= finalIndex; i++ ) {
- double pointLocation = pow(10.0, i * interval);
- for ( NSUInteger j = 1; j < minorTicks; j++ ) {
- double minorPointLocation = pointLocation + minorInterval * j;
- if ( minorPointLocation < minLimit ) {
- continue;
- }
- if ( minorPointLocation > maxLimit ) {
- continue;
- }
- [minorLocations addObject:@(minorPointLocation)];
- }
- minorInterval *= intervalStep;
- if ( pointLocation < minLimit ) {
- continue;
- }
- if ( pointLocation > maxLimit ) {
- continue;
- }
- [majorLocations addObject:@(pointLocation)];
- }
- }
- }
- break;
- case CPTScaleTypeLogModulus:
- {
- double minLimit = range.minLimitDouble;
- double maxLimit = range.maxLimitDouble;
- // Determine interval value
- double modMinLimit = CPTLogModulus(minLimit);
- double modMaxLimit = CPTLogModulus(maxLimit);
- double multiplier = pow( 10.0, floor( log10(length) ) );
- multiplier = (multiplier < 1.0) ? multiplier : 1.0;
- double intervalStep = 10.0;
- // Determine the initial and final major indexes for the actual visible range
- NSInteger initialIndex = (NSInteger)lrint( floor(modMinLimit / multiplier) ); // can be negative
- NSInteger finalIndex = (NSInteger)lrint( ceil(modMaxLimit / multiplier) ); // can be negative
- if ( initialIndex < 0 ) {
- // Determine minor interval
- double minorInterval = intervalStep * 0.9 * multiplier / minorTicks;
- for ( NSInteger i = MIN(0, finalIndex); i >= initialIndex; i-- ) {
- double pointLocation;
- double sign = -multiplier;
- if ( multiplier < 1.0 ) {
- pointLocation = sign * pow(10.0, fabs( (double)i ) - 1.0);
- }
- else {
- pointLocation = sign * pow( 10.0, fabs( (double)i ) );
- }
- for ( NSUInteger j = 1; j < minorTicks; j++ ) {
- double minorPointLocation = pointLocation + sign * minorInterval * j;
- if ( minorPointLocation < minLimit ) {
- continue;
- }
- if ( minorPointLocation > maxLimit ) {
- continue;
- }
- [minorLocations addObject:@(minorPointLocation)];
- }
- minorInterval *= intervalStep;
- if ( i == 0 ) {
- pointLocation = 0.0;
- }
- if ( pointLocation < minLimit ) {
- continue;
- }
- if ( pointLocation > maxLimit ) {
- continue;
- }
- [majorLocations addObject:@(pointLocation)];
- }
- }
- if ( finalIndex >= 0 ) {
- // Determine minor interval
- double minorInterval = intervalStep * 0.9 * multiplier / minorTicks;
- for ( NSInteger i = MAX(0, initialIndex); i <= finalIndex; i++ ) {
- double pointLocation;
- double sign = multiplier;
- if ( multiplier < 1.0 ) {
- pointLocation = sign * pow(10.0, fabs( (double)i ) - 1.0);
- }
- else {
- pointLocation = sign * pow( 10.0, fabs( (double)i ) );
- }
- for ( NSUInteger j = 1; j < minorTicks; j++ ) {
- double minorPointLocation = pointLocation + sign * minorInterval * j;
- if ( minorPointLocation < minLimit ) {
- continue;
- }
- if ( minorPointLocation > maxLimit ) {
- continue;
- }
- [minorLocations addObject:@(minorPointLocation)];
- }
- minorInterval *= intervalStep;
- if ( i == 0 ) {
- pointLocation = 0.0;
- }
- if ( pointLocation < minLimit ) {
- continue;
- }
- if ( pointLocation > maxLimit ) {
- continue;
- }
- [majorLocations addObject:@(pointLocation)];
- }
- }
- }
- break;
- default:
- break;
- }
- }
- // Return tick locations sets
- *newMajorLocations = majorLocations;
- *newMinorLocations = minorLocations;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement