Recently, I needed to draw k-line and line Charts for my project, and introduced the Charts of the third-party icon library.
The charting library is basically enough for everyone’s needs for charting, but the API explanation is not very detailed. The library has powerful functions, but developers are still confused for a long time. And there are not many related resources on the Internet, so I wrote this article in the hope of helping you.
Let’s take a look at the official Demo:The line chartA histogramK line graph
After looking at the effect drawing, let’s introduce how to draw various charts one by one.
The first step
Introduction of third-party charting library Charts
I use the Carthage method to introduce, directly add Github “Danielgindi /Charts” ~>3.0.4 in the Cartfile and then enter in the terminal command line: Carthage update –platform iOS.
Once imported, your project will contain this file:Since the framework is written in Swift, OC developers need to add bridge files to their projects,Charts-Swift
“Bridge” is a bridge file, you don’t need to customize, which class you want to call “Charts” in,import "Charts-Swift.h"
Documents will do.
The second step
Define charts and set various properties of ICONS
There are many types of Charts. Here I will give some representative examples :BarChartView(bar chart), LineChartView(broken line chart), CandleStickChartView(candle chart, K-chart) and so on.
ChartsView attributes:
1. Scale property
As the name implies, the icon supports drag and drop. ScaleYEnabled = YES indicates that drag and drop is supported on the vertical coordinate, and scaleXEnabled = YES indicates that drag and drop is supported on the horizontal coordinate.
2. The chartDescription attribute
Turn on this property and your diagram will have a description of your icon. Such as:chartView.chartDescription.enabled = YES
ChartView. ChartDescription. Text = @ "wang nima chartsView"
The fine print belowWang Nima's chartsView
That’s the description of my ChartsView.
3, pinchZoomEnabled
Whether to support X – and Y-axis scaling at the same time. If YES, scaling is supported at the same time.
4, maxVisibleCount
The maxVisibleCount property controls the maximum number of numbers displayed on the icon. If your icon does not want to display the number, you can set the maxVisibleCount property to 0.
5, legend
This Bool indicates whether to display legends. See the “– DataSet 1” field at the bottom of the graph. If you don’t want this field to be displayed, set legend.
6, noDataText
What text should be displayed on the ChartsView when there is no data. There are three important properties in chartsView that developers need to set, leftAxis, rightAxis, and xAxis.
7, doubleTapToZoomEnabled
Whether double click scaling is allowed.
8 the delegate.
Agent, you know that. There are 4 corresponding Protocal, all optional
// The number in the chart is selected
- (void)chartValueSelected:(ChartViewBase * _Nonnull)chartView entry:(ChartDataEntry * _Nonnull)entry highlight:(ChartHighlight * _Nonnull)highlight;// The blank area in the chart is clicked
- (void)chartValueNothingSelected:(ChartViewBase * _Nonnull)chartView;
// Chart zoom
- (void)chartScaled:(ChartViewBase * _Nonnull)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY;
// The icon is moved
- (void)chartTranslated:(ChartViewBase * _Nonnull)chartView dX:(CGFloat)dX dY:(CGFloat)dY;
Copy the code
The Axis attribute
1, enabled
If set to NO, the corresponding axes are not displayed.
2, labelPosition
Said the left axis coordinate position, there are two options: YAxisLabelPositionOutsideChart = 0, YAxisLabelPositionInsideChart = 1, the coordinate display outside the shaft or the shaft.
3, labelCount
That is, the maximum number of coordinate points displayed on the coordinate axis
4, drawGridBackgroundEnabled
Whether to draw grid lines
5, gridLineDashLengths
GridLineDashLengths = @[@2.f, @5.f] = 2.0f line width and 5.0f spacing
The third step
Fill in the data
Now that we have defined the basic properties of the table, we are ready to populate the data. I’ll just use the broken line chart here as an example.
Let’s first introduce two concepts :set and data. LineChartData is the data class of line graph. It can be composed of many sets, one of which is a line. So we can define the properties of a set to draw all kinds of polylines. The following is an example:
// Whether to draw ICONS
set1.drawIconsEnabled = NO;
// Fold color
[set1 setColor:UIColor.blackColor];
// The color of the broken point
[set1 setCircleColor:UIColor.blackColor];
// The width of the polyline
set1.lineWidth = 1.0;
// The width of the broken point
set1.circleRadius = 3.0;
// Whether to draw hollow circles
set1.drawCircleHoleEnabled = NO;
// The size of the broken point value
set1.valueFont = [UIFont systemFontOfSize:9.f];
// The line width of the legend
set1.formLineWidth = 1.0;
// The font size of the legend
set1.formSize = 15.0;
Copy the code
Here’s how to populate the data:
// Define an array to hold data
// Corresponds to the data to be displayed on the Y-axis
NSMutableArray *yVals = [[NSMutableArray alloc] init];
for (int i = 0; i < self.financeLineDotDataList.count; i++) {
BTCTrenddata *dotData = (BTCTrenddata *)[self.financeLineDotDataList objectAtIndex:i];
// Save the horizontal and vertical coordinates as ChartDataEntry. Note that the horizontal value is usually the value of I, not the specific value in your data. How to display the specific data on the X-axis will be discussed below.
ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:i y:dotData.price];
[yVals addObject:entry];
}
LineChartDataSet *set1 = nil;
// If your chart has been drawn before, you can simply reassign data.
// If not, define the attributes of set first.
if (self.financeLineChartsView.data.dataSetCount > 0) {
LineChartData *data = (LineChartData *)self.financeLineChartsView.data;
set1 = (LineChartDataSet *)data.dataSets[0];
// set1.yVals = yVals;
set1 = (LineChartDataSet *)self.financeLineChartsView.data.dataSets[0];
set1.values = yVals;
// Notify data to update
[self.financeLineChartsView.data notifyDataChanged];
// Tell the chart to update
[self.financeLineChartsView notifyDataSetChanged];
}else{
// Create LineChartDataSet object
set1 = [[LineChartDataSet alloc] initWithValues:yVals];
// Customize the attributes of a set
// Set the style of the line
set1.drawIconsEnabled = NO;
set1.formLineWidth = 1.1;// Fold width
set1.formSize = 15.0;
set1.drawValuesEnabled = YES;// Whether to display data at inflection points
set1.valueColors = @[[UIColor whiteColor]];// The color of the data displayed at the inflection point of the broken line
[set1 setColor:RGBCOLOR(248.144.28)];// Fold color
// Fold inflection style
set1.drawCirclesEnabled = NO;// Whether to draw inflection points
// Second fill style: gradient fill
set1.drawFilledEnabled = YES;// Whether to fill the color
NSArray *gradientColors = @[(id)RGBACOLOR(218.168.42.0).CGColor,
(id)RGBACOLOR(248.223.91.1).CGColor];
CGGradientRef gradientRef = CGGradientCreateWithColors(nil, (CFArrayRef)gradientColors, nil);
set1.fillAlpha = 1.0f;/ / transparency
set1.fill = [ChartFill fillWithLinearGradient:gradientRef angle:90.0f];// Assign to fill the color object
CGGradientRelease(gradientRef);/ / release gradientRef
// Click to select the inflection point interaction style
set1.highlightEnabled = YES;// Select the inflection point, whether to turn on the highlight effect (show crosshair)
set1.highlightColor = RGBCOLOR(125.125.125);// Select the color of the crosshair at the inflection point
set1.highlightLineWidth = 1.1/ [UIScreen mainScreen].scale;// Crosshair width
set1.highlightLineDashLengths = @[@5The @5];// The dotted line style of the crosshair
// Put the LineChartDataSet object into the array
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
// Create a LineChartData object. This object is the final data object needed by lineChartView
LineChartData *data = [[LineChartData alloc] initWithDataSets:dataSets];
[data setValueFont:[UIFont systemFontOfSize:8.f]];// Text font
[data setValueTextColor:[UIColor whiteColor]];// Text color
self.financeLineChartsView.data = data;
// Here we can call a loading animation i.e. 1s out of a draw point
[self.financeLineChartsView animateWithXAxisDuration:1.0f];
}
Copy the code
That’s the basic way to populate the data. At this point, you have mastered the basic method of charting using charts. Let’s take a look at some of the more difficult ones.
Key and Difficult points
-
Requirement 1: Two tables are linked, that is, drag or drop one table, and the other table needs to be moved.
This requirement can be addressed by protocol:
- (void)chartScaled:(ChartViewBase *)chartView scaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY { CGAffineTransform srcMatrix = chartView.viewPortHandler.touchMatrix; [self.combinedChartView.viewPortHandler refreshWithNewMatrix:srcMatrix chart:self.combinedChartView invalidate:YES]; [self.barChartView.viewPortHandler refreshWithNewMatrix:srcMatrix chart:self.barChartView invalidate:YES]; } Copy the code
- (void)chartTranslated:(ChartViewBase *)chartView dX:(CGFloat)dX dY:(CGFloat)dY { CGAffineTransform srcMatrix = chartView.viewPortHandler.touchMatrix; [self.combinedChartView.viewPortHandler refreshWithNewMatrix:srcMatrix chart:self.combinedChartView invalidate:YES]; [self.barChartView.viewPortHandler refreshWithNewMatrix:srcMatrix chart:self.barChartView invalidate:YES]; } Copy the code
-
Requirement 2: Draw multiple types of line tables on one chart, such as k-chart + bar chart
This requirement uses another ChartView type :CombinedChartView
CombinedChartData *combinedData = [[CombinedChartData alloc] init]; combinedData.lineData = [self generateLineData]; combinedData.candleData = [self generateCandleData]; Copy the code
Without further ado, I will post a Demo later
-
Requirement 3: You want to display specific values on the X-axis
Now, as I said, when we’re drawing the table, the X value is the value of I, from 0 to I, so how do we display the X value that the server gave us? Here need to introduce a deal: IChartAxisValueFormatter, declare an NSObject class, such as BTCDepthXAxisFormatter follow IChartAxisValueFormatter protocol, Override -(NSString *)stringForValue:(double)value axis:(ChartAxisBase *)axis method, then assign, ValueFormatter = [[BTCDepthXAxisFormatter alloc] init].
-
Requirement 4: Add the arrow indicating the highest and lowest values on the K-chart, and the effect is shown as follows:
Rewrite the 'CandleStickChartRenderer' class in the third-party library, which is responsible for drawing and rendering k-chart data. `@objc open func drawDataSet(context: CGContext, dataSet: The ICandleChartDataSet () 'method iterates and draws all the points that need to be displayed. Therefore, we can retrieve the maximum and minimum point coordinates in this method, with the following code: Objc if minValue > low {minValue = low minPositionX = xPos} if maxValue < high { MaxValue = high maxPositionX = xPos} ' ' Objc let lowestVisbleEntry = dataSet. EntryForIndex (_XBounds.min) as? CandleChartDataEntry else { return } var lowestVisblePoint: CGPoint = CGPoint.init(x: lowestVisbleEntry.x, y: LowestVisbleEntry. Low) // This is mainly to get the X coordinates, LowestVisbleEntry. Low can be high, open, close trans.pointValuetopixel (&lowestVisblePoint) // Arrow data guard let in the right-most visible area highestVisbleEntry = dataSet.entryForIndex( _xBounds.range + _xBounds.min) as? CandleChartDataEntry else { return } var highestVisblePoint: CGPoint = CGPoint.init(x: highestVisbleEntry.x, y: HighestVisbleEntry. High) trans.pointValuetopixel (&highestVisblePoint) // Let minValueStr = string.init (format: "%.4f", minValue) var minPoint: CGPoint = CGPoint.init(x: CGFloat(minPositionX), y: CGFloat(minValue * animator.phasey)) // Point converted to pixel trans.pointValuetOpixel (&minPoint) calculateTextPosition(minValueStr, originPoint: &minPoint, lowestVisibleX: lowestVisblePoint.x, highestVisibleX: highestVisblePoint.x, isMaxValue: Let maxValueStr = string.init (format: "%.4f", maxValue) var maxPoint: CGPoint = cgPoint.init (x: CGFloat(maxPositionX), y: CGFloat(maxValue * animator.phaseY)) trans.pointValueToPixel(&maxPoint) calculateTextPosition(maxValueStr, originPoint: &maxPoint, lowestVisibleX: lowestVisblePoint.x, highestVisibleX: highestVisblePoint.x, isMaxValue: True) thanks @<font color=#0099ff size=3 face=" black ">Leo is my </font> solution to the arrow drawing problem perfectly. Interested students can download the source code] [CandleStickChartRenderer. Swift (https://github.com/wangnima123/ArrowInCandleStickChartRenderer.git) to replace the Char The CandleStickChartRenderer file in the TS library is used to display the maximum and minimum arrows in the visible area.Copy the code
So far, the basic usage of ios-Charts has been introduced. If there are any questions you don’t understand, you can add my wechat (justlikeitRobert) or click on my Demo on Github for research. Welcome Star as encouragement and reward for my code words. 😄