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 chartsViewThat’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. 😄