andi

improved legend for line chart, added thousands separator option for y labels

@@ -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 -  
763 - NSUInteger numLabelsPerRow = ceil((float)[self.chartData count] / self.labelRowsInSerialMode);  
764 777
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,18 +844,19 @@ @@ -823,18 +844,19 @@
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;
830 label.numberOfLines = 0; 851 label.numberOfLines = 0;
831 - 852 +
832 rowMaxHeight = fmaxf(rowMaxHeight, labelsize.height); 853 rowMaxHeight = fmaxf(rowMaxHeight, labelsize.height);
833 x += self.legendStyle == PNLegendItemStyleStacked ? 0 : labelsize.width + legendLineWidth; 854 x += self.legendStyle == PNLegendItemStyleStacked ? 0 : labelsize.width + legendLineWidth;
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 }