improved legend for line chart, added thousands separator option for y labels
Showing
2 changed files
with
37 additions
and
14 deletions
| @@ -47,6 +47,7 @@ | @@ -47,6 +47,7 @@ | ||
| 47 | @property (nonatomic) CGFloat chartCavanWidth; | 47 | @property (nonatomic) CGFloat chartCavanWidth; |
| 48 | @property (nonatomic) CGFloat chartMargin; | 48 | @property (nonatomic) CGFloat chartMargin; |
| 49 | @property (nonatomic) BOOL showLabel; | 49 | @property (nonatomic) BOOL showLabel; |
| 50 | +@property (nonatomic) BOOL thousandsSeparator; | ||
| 50 | 51 | ||
| 51 | /** | 52 | /** |
| 52 | * Controls whether to show the coordinate axis. Default is NO. | 53 | * Controls whether to show the coordinate axis. Default is NO. |
| @@ -56,7 +56,6 @@ | @@ -56,7 +56,6 @@ | ||
| 56 | { | 56 | { |
| 57 | CGFloat yStep = (_yValueMax - _yValueMin) / _yLabelNum; | 57 | CGFloat yStep = (_yValueMax - _yValueMin) / _yLabelNum; |
| 58 | CGFloat yStepHeight = _chartCavanHeight / _yLabelNum; | 58 | CGFloat yStepHeight = _chartCavanHeight / _yLabelNum; |
| 59 | - NSString *yLabelFormat = self.yLabelFormat ? : @"%1.f"; | ||
| 60 | 59 | ||
| 61 | if (_yChartLabels) { | 60 | if (_yChartLabels) { |
| 62 | for (PNChartLabel * label in _yChartLabels) { | 61 | for (PNChartLabel * label in _yChartLabels) { |
| @@ -68,19 +67,19 @@ | @@ -68,19 +67,19 @@ | ||
| 68 | 67 | ||
| 69 | if (yStep == 0.0) { | 68 | if (yStep == 0.0) { |
| 70 | PNChartLabel *minLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)_chartCavanHeight, (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; | 69 | PNChartLabel *minLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)_chartCavanHeight, (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; |
| 71 | - minLabel.text = [NSString stringWithFormat:yLabelFormat, 0.0]; | 70 | + minLabel.text = [self formatYLabel:0.0]; |
| 72 | [self setCustomStyleForYLabel:minLabel]; | 71 | [self setCustomStyleForYLabel:minLabel]; |
| 73 | [self addSubview:minLabel]; | 72 | [self addSubview:minLabel]; |
| 74 | [_yChartLabels addObject:minLabel]; | 73 | [_yChartLabels addObject:minLabel]; |
| 75 | 74 | ||
| 76 | PNChartLabel *midLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight / 2), (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; | 75 | PNChartLabel *midLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight / 2), (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; |
| 77 | - midLabel.text = [NSString stringWithFormat:yLabelFormat, _yValueMax]; | 76 | + midLabel.text = [self formatYLabel:_yValueMax]; |
| 78 | [self setCustomStyleForYLabel:midLabel]; | 77 | [self setCustomStyleForYLabel:midLabel]; |
| 79 | [self addSubview:midLabel]; | 78 | [self addSubview:midLabel]; |
| 80 | [_yChartLabels addObject:midLabel]; | 79 | [_yChartLabels addObject:midLabel]; |
| 81 | 80 | ||
| 82 | PNChartLabel *maxLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, 0.0, (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; | 81 | PNChartLabel *maxLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, 0.0, (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; |
| 83 | - maxLabel.text = [NSString stringWithFormat:yLabelFormat, _yValueMax * 2]; | 82 | + maxLabel.text = [self formatYLabel:_yValueMax * 2]; |
| 84 | [self setCustomStyleForYLabel:maxLabel]; | 83 | [self setCustomStyleForYLabel:maxLabel]; |
| 85 | [self addSubview:maxLabel]; | 84 | [self addSubview:maxLabel]; |
| 86 | [_yChartLabels addObject:maxLabel]; | 85 | [_yChartLabels addObject:maxLabel]; |
| @@ -93,7 +92,7 @@ | @@ -93,7 +92,7 @@ | ||
| 93 | { | 92 | { |
| 94 | PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight - index * yStepHeight), (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; | 93 | PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight - index * yStepHeight), (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; |
| 95 | [label setTextAlignment:NSTextAlignmentRight]; | 94 | [label setTextAlignment:NSTextAlignmentRight]; |
| 96 | - label.text = [NSString stringWithFormat:yLabelFormat, _yValueMin + (yStep * index)]; | 95 | + label.text = [self formatYLabel:_yValueMin + (yStep * index)]; |
| 97 | [self setCustomStyleForYLabel:label]; | 96 | [self setCustomStyleForYLabel:label]; |
| 98 | [self addSubview:label]; | 97 | [self addSubview:label]; |
| 99 | [_yChartLabels addObject:label]; | 98 | [_yChartLabels addObject:label]; |
| @@ -542,8 +541,8 @@ | @@ -542,8 +541,8 @@ | ||
| 542 | yMin = 0.0f; | 541 | yMin = 0.0f; |
| 543 | } | 542 | } |
| 544 | 543 | ||
| 545 | - _yValueMin = _yFixedValueMin ? _yFixedValueMin : yMin ; | 544 | + _yValueMin = (_yFixedValueMin > -FLT_MAX) ? _yFixedValueMin : yMin ; |
| 546 | - _yValueMax = _yFixedValueMax ? _yFixedValueMax : yMax + yMax / 10.0; | 545 | + _yValueMax = (_yFixedValueMax > -FLT_MAX) ? _yFixedValueMax : yMax + yMax / 10.0; |
| 547 | 546 | ||
| 548 | if (_showLabel) { | 547 | if (_showLabel) { |
| 549 | [self setYLabels:yLabelsArray]; | 548 | [self setYLabels:yLabelsArray]; |
| @@ -684,6 +683,8 @@ | @@ -684,6 +683,8 @@ | ||
| 684 | _endPointsOfPath = [[NSMutableArray alloc] init]; | 683 | _endPointsOfPath = [[NSMutableArray alloc] init]; |
| 685 | self.userInteractionEnabled = YES; | 684 | self.userInteractionEnabled = YES; |
| 686 | 685 | ||
| 686 | + _yFixedValueMin = -FLT_MAX; | ||
| 687 | + _yFixedValueMax = -FLT_MAX; | ||
| 687 | _yLabelNum = 5.0; | 688 | _yLabelNum = 5.0; |
| 688 | _yLabelHeight = [[[[PNChartLabel alloc] init] font] pointSize]; | 689 | _yLabelHeight = [[[[PNChartLabel alloc] init] font] pointSize]; |
| 689 | 690 | ||
| @@ -743,6 +744,19 @@ | @@ -743,6 +744,19 @@ | ||
| 743 | } | 744 | } |
| 744 | 745 | ||
| 745 | 746 | ||
| 747 | +- (NSString*) formatYLabel:(double)value{ | ||
| 748 | + if (!self.thousandsSeparator) { | ||
| 749 | + NSString *format = self.yLabelFormat ? : @"%1.f"; | ||
| 750 | + return [NSString stringWithFormat:format,value]; | ||
| 751 | + } | ||
| 752 | + | ||
| 753 | + NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init]; | ||
| 754 | + [numberFormatter setFormatterBehavior: NSNumberFormatterBehavior10_4]; | ||
| 755 | + [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; | ||
| 756 | + return [numberFormatter stringFromNumber: [NSNumber numberWithDouble:value]]; | ||
| 757 | +} | ||
| 758 | + | ||
| 759 | + | ||
| 746 | - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{ | 760 | - (UIView*) getLegendWithMaxWidth:(CGFloat)mWidth{ |
| 747 | if ([self.chartData count] < 1) { | 761 | if ([self.chartData count] < 1) { |
| 748 | return nil; | 762 | return nil; |
| @@ -757,13 +771,17 @@ | @@ -757,13 +771,17 @@ | ||
| 757 | 771 | ||
| 758 | /* accumulated height */ | 772 | /* accumulated height */ |
| 759 | CGFloat totalHeight = 0; | 773 | CGFloat totalHeight = 0; |
| 774 | + CGFloat totalWidth = 0; | ||
| 760 | 775 | ||
| 761 | NSMutableArray *legendViews = [[NSMutableArray alloc] init]; | 776 | NSMutableArray *legendViews = [[NSMutableArray alloc] init]; |
| 762 | 777 | ||
| 763 | - NSUInteger numLabelsPerRow = ceil((float)[self.chartData count] / self.labelRowsInSerialMode); | ||
| 764 | - | ||
| 765 | /* Determine the max width of each legend item */ | 778 | /* Determine the max width of each legend item */ |
| 766 | - CGFloat maxLabelWidth = self.legendStyle == PNLegendItemStyleStacked ? (mWidth - legendLineWidth) : (mWidth / numLabelsPerRow - legendLineWidth); | 779 | + CGFloat maxLabelWidth; |
| 780 | + if (self.legendStyle == PNLegendItemStyleStacked) { | ||
| 781 | + maxLabelWidth = mWidth - legendLineWidth; | ||
| 782 | + }else{ | ||
| 783 | + maxLabelWidth = MAXFLOAT; | ||
| 784 | + } | ||
| 767 | 785 | ||
| 768 | /* this is used when labels wrap text and the line | 786 | /* this is used when labels wrap text and the line |
| 769 | * should be in the middle of the first row */ | 787 | * should be in the middle of the first row */ |
| @@ -772,6 +790,7 @@ | @@ -772,6 +790,7 @@ | ||
| 772 | font:[UIFont systemFontOfSize:self.legendFontSize]].height; | 790 | font:[UIFont systemFontOfSize:self.legendFontSize]].height; |
| 773 | 791 | ||
| 774 | NSUInteger counter = 0; | 792 | NSUInteger counter = 0; |
| 793 | + NSUInteger rowWidth = 0; | ||
| 775 | NSUInteger rowMaxHeight = 0; | 794 | NSUInteger rowMaxHeight = 0; |
| 776 | 795 | ||
| 777 | for (PNLineChartData *pdata in self.chartData) { | 796 | for (PNLineChartData *pdata in self.chartData) { |
| @@ -781,12 +800,14 @@ | @@ -781,12 +800,14 @@ | ||
| 781 | font:[UIFont systemFontOfSize:self.legendFontSize]]; | 800 | font:[UIFont systemFontOfSize:self.legendFontSize]]; |
| 782 | 801 | ||
| 783 | /* draw lines */ | 802 | /* draw lines */ |
| 784 | - | 803 | + if ((rowWidth + labelsize.width + legendLineWidth > mWidth)&&(self.legendStyle == PNLegendItemStyleSerial)) { |
| 785 | - if (counter != 0 && counter % numLabelsPerRow == 0) { | 804 | + rowWidth = 0; |
| 786 | x = 0; | 805 | x = 0; |
| 787 | y += rowMaxHeight; | 806 | y += rowMaxHeight; |
| 788 | rowMaxHeight = 0; | 807 | rowMaxHeight = 0; |
| 789 | } | 808 | } |
| 809 | + rowWidth += labelsize.width + legendLineWidth; | ||
| 810 | + totalWidth = self.legendStyle == PNLegendItemStyleSerial ? fmaxf(rowWidth, totalWidth) : fmaxf(totalWidth, labelsize.width + legendLineWidth); | ||
| 790 | 811 | ||
| 791 | /* If there is inflection decorator, the line is composed of two lines | 812 | /* If there is inflection decorator, the line is composed of two lines |
| 792 | * and this is the space that separates two lines in order to put inflection | 813 | * and this is the space that separates two lines in order to put inflection |
| @@ -823,7 +844,7 @@ | @@ -823,7 +844,7 @@ | ||
| 823 | andColor:pdata.color | 844 | andColor:pdata.color |
| 824 | andAlpha:pdata.alpha]]; | 845 | andAlpha:pdata.alpha]]; |
| 825 | 846 | ||
| 826 | - UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x + legendLineWidth, y, maxLabelWidth, labelsize.height)]; | 847 | + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x + legendLineWidth, y, labelsize.width, labelsize.height)]; |
| 827 | label.text = pdata.dataTitle; | 848 | label.text = pdata.dataTitle; |
| 828 | label.font = [UIFont systemFontOfSize:self.legendFontSize]; | 849 | label.font = [UIFont systemFontOfSize:self.legendFontSize]; |
| 829 | label.lineBreakMode = NSLineBreakByWordWrapping; | 850 | label.lineBreakMode = NSLineBreakByWordWrapping; |
| @@ -834,7 +855,8 @@ | @@ -834,7 +855,8 @@ | ||
| 834 | y += self.legendStyle == PNLegendItemStyleStacked ? labelsize.height : 0; | 855 | y += self.legendStyle == PNLegendItemStyleStacked ? labelsize.height : 0; |
| 835 | 856 | ||
| 836 | 857 | ||
| 837 | - totalHeight = self.legendStyle == PNLegendItemStyleStacked ? fmaxf(totalHeight, rowMaxHeight + y) : totalHeight + labelsize.height; | 858 | + totalHeight = self.legendStyle == PNLegendItemStyleSerial ? fmaxf(totalHeight, rowMaxHeight + y) : totalHeight + labelsize.height; |
| 859 | + | ||
| 838 | [legendViews addObject:label]; | 860 | [legendViews addObject:label]; |
| 839 | counter++; | 861 | counter++; |
| 840 | } | 862 | } |
-
Please register or login to post a comment