├── .gitignore ├── CCTrendCharts.podspec ├── CCTrendCharts └── CCTrendCharts │ ├── 1daykline.json │ ├── CCTrendCharts.h │ ├── Core │ ├── Animator │ │ └── CCProtocolAnimatorBase.h │ ├── Common │ │ ├── CALayer+CCUtility.h │ │ ├── CALayer+CCUtility.m │ │ ├── CCBaseUtility.h │ │ ├── CCBaseUtility.m │ │ ├── CCCoordinateUtility.h │ │ ├── CCCoordinateUtility.m │ │ ├── CCMacro.h │ │ ├── CCSingleEventManager.h │ │ ├── CCSingleEventManager.m │ │ ├── CCTAIConfig.h │ │ ├── CCTAIConfig.m │ │ ├── NSString+CCUtility.h │ │ ├── NSString+CCUtility.m │ │ ├── Protocol │ │ │ └── CCProtocolBase.h │ │ ├── UIColor+CCUtility.h │ │ └── UIColor+CCUtility.m │ ├── DataProvider │ │ ├── Axis │ │ │ ├── CCDefaultXAxis.h │ │ │ ├── CCDefaultXAxis.m │ │ │ ├── CCDefaultYAxis.h │ │ │ └── CCDefaultYAxis.m │ │ ├── CCBarChartDataSet.h │ │ ├── CCBarChartDataSet.m │ │ ├── CCChartData.h │ │ ├── CCChartData.m │ │ ├── CCChartDataSetBase.h │ │ ├── CCChartDataSetBase.m │ │ ├── CCKLineChartData.h │ │ ├── CCKLineChartData.m │ │ ├── CCKLineChartDataSet.h │ │ ├── CCKLineChartDataSet.m │ │ ├── CCLineChartDataSet.h │ │ ├── CCLineChartDataSet.m │ │ ├── CCVolumeChartDataSet.h │ │ ├── CCVolumeChartDataSet.m │ │ ├── Cursor │ │ │ ├── CCDefaultCursor.h │ │ │ └── CCDefaultCursor.m │ │ ├── Entity │ │ │ ├── CCChartDataEntity.h │ │ │ ├── CCChartDataEntity.m │ │ │ ├── CCKLineDataEntity.h │ │ │ ├── CCKLineDataEntity.m │ │ │ ├── CCVolumeDataEntity.h │ │ │ └── CCVolumeDataEntity.m │ │ ├── Protocol │ │ │ ├── CCProtocolAxisBase.h │ │ │ ├── CCProtocolChartDataProvider.h │ │ │ ├── CCProtocolChartDataSet.h │ │ │ ├── CCProtocolCursorBase.h │ │ │ ├── CCProtocolKLineChartDataProvider.h │ │ │ ├── CCProtocolTAIDataSet.h │ │ │ └── Entity │ │ │ │ └── CCProtocolChartDataEntityBase.h │ │ └── TAIDataSet │ │ │ ├── CCLineMADataSet.h │ │ │ └── CCLineMADataSet.m │ ├── Formatter │ │ ├── CCXAxisDefaultFormatter.h │ │ ├── CCXAxisDefaultFormatter.m │ │ ├── CCXAxisFixedFormatter.h │ │ ├── CCXAxisFixedFormatter.m │ │ └── Protocol │ │ │ └── CCProtocolXAxisFormatterBase.h │ ├── Gesture │ │ ├── CCChartTransformer.h │ │ ├── CCChartTransformer.m │ │ ├── CCChartViewPixelHandler.h │ │ ├── CCChartViewPixelHandler.m │ │ ├── CCGestureDefaultHandler.h │ │ ├── CCGestureDefaultHandler.m │ │ └── Protocol │ │ │ └── CCGestureHandlerProtocol.h │ ├── Renderer │ │ ├── CCBarDataChartRenderer.h │ │ ├── CCBarDataChartRenderer.m │ │ ├── CCDataChartRenderer.h │ │ ├── CCDataChartRenderer.m │ │ ├── CCDefaultCursorRenderer.h │ │ ├── CCDefaultCursorRenderer.m │ │ ├── CCDefaultMarkerRenderer.h │ │ ├── CCDefaultMarkerRenderer.m │ │ ├── CCDefaultXAxisRenderer.h │ │ ├── CCDefaultXAxisRenderer.m │ │ ├── CCDefaultYAxisRenderer.h │ │ ├── CCDefaultYAxisRenderer.m │ │ ├── CCKLineDataChartRenderer.h │ │ ├── CCKLineDataChartRenderer.m │ │ ├── CCLineDataChartRenderer.h │ │ ├── CCLineDataChartRenderer.m │ │ ├── CCRendererBase+LayerCache.h │ │ ├── CCRendererBase+LayerCache.m │ │ ├── CCRendererBase.h │ │ ├── CCRendererBase.m │ │ ├── CCTAILegendRenderer.h │ │ ├── CCTAILegendRenderer.m │ │ ├── CCVolumeDataChartRenderer.h │ │ ├── CCVolumeDataChartRenderer.m │ │ └── Protocol │ │ │ ├── CCProtocolAxisRenderer.h │ │ │ ├── CCProtocolChartRendererBase.h │ │ │ ├── CCProtocolCursorRenderer.h │ │ │ ├── CCProtocolDataChartRenderer.h │ │ │ ├── CCProtocolKLineDataChartRenderer.h │ │ │ ├── CCProtocolLegendRenderer.h │ │ │ └── CCProtocolMarkerRenderer.h │ └── View │ │ ├── CCAssembledChartView.h │ │ ├── CCAssembledChartView.m │ │ ├── CCBarChartView.h │ │ ├── CCBarChartView.m │ │ ├── CCChartViewBase.h │ │ ├── CCChartViewBase.m │ │ ├── CCKLineChartView.h │ │ ├── CCKLineChartView.m │ │ ├── CCLineChartView.h │ │ ├── CCLineChartView.m │ │ ├── CCVolumeChartView.h │ │ ├── CCVolumeChartView.m │ │ ├── Protocol │ │ └── CCProtocolChartViewBase.h │ │ └── ViewSync │ │ └── CCProtocolChartViewSync.h │ └── PrefixHeader.pch ├── CCTrendChartsDemo ├── CCTrendChartsDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── CCTrendChartsDemo.xcscheme ├── CCTrendChartsDemo.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── CCTrendChartsDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── MainTableViewController.h │ ├── MainTableViewController.m │ ├── NetworkHelper.h │ ├── NetworkHelper.m │ ├── PrefixHeader.pch │ ├── ViewDemo │ │ ├── DafaultStyle │ │ │ ├── AssembledViewController.h │ │ │ ├── AssembledViewController.m │ │ │ ├── AssembledViewController.xib │ │ │ ├── BarViewController.h │ │ │ ├── BarViewController.m │ │ │ ├── BarViewController.xib │ │ │ ├── BaseViewController.h │ │ │ ├── BaseViewController.m │ │ │ ├── KLineViewController.h │ │ │ ├── KLineViewController.m │ │ │ ├── KLineViewController.xib │ │ │ ├── RealTimeLineViewController.h │ │ │ ├── RealTimeLineViewController.m │ │ │ ├── RealTimeLineViewController.xib │ │ │ ├── VolumeViewController.h │ │ │ ├── VolumeViewController.m │ │ │ └── VolumeViewController.xib │ │ └── YunexStyle │ │ │ ├── YunexCursorRenderer.h │ │ │ ├── YunexCursorRenderer.m │ │ │ ├── YunexViewController.h │ │ │ ├── YunexViewController.m │ │ │ └── YunexViewController.xib │ └── main.m ├── Podfile ├── Podfile.lock └── Pods │ ├── CCEasyKVO │ ├── CCEasyKVO │ │ └── Classes │ │ │ ├── NSObject+CCEasyKVO.h │ │ │ └── NSObject+CCEasyKVO.m │ ├── LICENSE │ └── README.md │ ├── Local Podspecs │ └── CCTrendCharts.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ └── project.pbxproj │ └── Target Support Files │ ├── CCEasyKVO │ ├── CCEasyKVO-Info.plist │ ├── CCEasyKVO-dummy.m │ ├── CCEasyKVO-prefix.pch │ ├── CCEasyKVO-umbrella.h │ ├── CCEasyKVO.debug.xcconfig │ ├── CCEasyKVO.modulemap │ └── CCEasyKVO.release.xcconfig │ ├── CCTrendCharts │ ├── CCTrendCharts-Info.plist │ ├── CCTrendCharts-dummy.m │ ├── CCTrendCharts-prefix.pch │ ├── CCTrendCharts-umbrella.h │ ├── CCTrendCharts.debug.xcconfig │ ├── CCTrendCharts.modulemap │ └── CCTrendCharts.release.xcconfig │ └── Pods-CCTrendChartsDemo │ ├── Pods-CCTrendChartsDemo-Info.plist │ ├── Pods-CCTrendChartsDemo-acknowledgements.markdown │ ├── Pods-CCTrendChartsDemo-acknowledgements.plist │ ├── Pods-CCTrendChartsDemo-dummy.m │ ├── Pods-CCTrendChartsDemo-frameworks-Debug-input-files.xcfilelist │ ├── Pods-CCTrendChartsDemo-frameworks-Debug-output-files.xcfilelist │ ├── Pods-CCTrendChartsDemo-frameworks-Release-input-files.xcfilelist │ ├── Pods-CCTrendChartsDemo-frameworks-Release-output-files.xcfilelist │ ├── Pods-CCTrendChartsDemo-frameworks.sh │ ├── Pods-CCTrendChartsDemo-umbrella.h │ ├── Pods-CCTrendChartsDemo.debug.xcconfig │ ├── Pods-CCTrendChartsDemo.modulemap │ └── Pods-CCTrendChartsDemo.release.xcconfig ├── Doc.md ├── LICENSE ├── README.md └── Screenshot ├── 1575542732977187.mp4 ├── gpu_state.jpg ├── screenshot002.jpg ├── screenshot003.jpg ├── screenshot004.jpg ├── screenshot005.jpg ├── screenshot006.jpg └── screenshot007.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots/**/*.png 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /CCTrendCharts.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint CCTrendCharts.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'CCTrendCharts' 11 | s.version = '0.9.2' 12 | s.summary = '趋势图表库' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | 趋势图表库, 支持股票K线图, 折线图, 柱型图; 22 | 支持分页加载数据, 支持定制指标信息(MD等); 23 | 支持长按指示器, 双指平滑缩放; 24 | 另外提供了基础绘制框架, 方便用户自行添加各种风格的渲染器; 25 | 26 | Trend chart library, support stock K-line chart (candle chart), line chart, bar chart; 27 |   Support pagination loading data, support custom indicator information (MD, etc.); 28 |   Support long press indicator, smooth zoom with two fingers; 29 |   In addition, a basic drawing framework is provided to facilitate users to add various styles of renderers by themselves; 30 | DESC 31 | 32 | s.homepage = 'https://github.com/cocos543/CCTrendCharts' 33 | s.screenshots = 'https://raw.githubusercontent.com/cocos543/CCTrendCharts/dev/Screenshot/screenshot002.jpg', 'https://raw.githubusercontent.com/cocos543/CCTrendCharts/dev/Screenshot/screenshot006.jpg', 'https://raw.githubusercontent.com/cocos543/CCTrendCharts/dev/Screenshot/screenshot007.jpg' 34 | s.license = { :type => 'MIT', :file => 'LICENSE' } 35 | s.author = { 'Cocos543' => '543314602@qq.com' } 36 | s.source = { :git => 'https://github.com/cocos543/CCTrendCharts.git', :tag => s.version.to_s } 37 | # s.social_media_url = 'https://twitter.com/' 38 | 39 | s.ios.deployment_target = '9.0' 40 | 41 | s.source_files = 'CCTrendCharts/CCTrendCharts/**/*' 42 | 43 | s.prefix_header_file = 'CCTrendCharts/CCTrendCharts/PrefixHeader.pch' 44 | 45 | # s.resource_bundles = { 46 | # 'CCTrendCharts' => ['CCTrendCharts/Assets/*.png'] 47 | # } 48 | 49 | # s.public_header_files = 'Pod/Classes/**/*.h' 50 | # s.frameworks = 'UIKit', 'MapKit' 51 | # s.dependency 'AFNetworking', '~> 2.3' 52 | s.dependency 'CCEasyKVO' 53 | end 54 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/CCTrendCharts.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCTrendCharts.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/5. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for CCTrendCharts. 12 | FOUNDATION_EXPORT double CCTrendChartsVersionNumber; 13 | 14 | //! Project version string for CCTrendCharts. 15 | FOUNDATION_EXPORT const unsigned char CCTrendChartsVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | 26 | 27 | // 全部内置视图 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | #import 34 | 35 | 36 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Animator/CCProtocolAnimatorBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolAnimatorBase.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCProtocolBase.h" 10 | 11 | @protocol CCProtocolAnimatorBase 12 | 13 | @property (nonatomic, assign) CGFloat *phaseX; 14 | 15 | @property (nonatomic, assign) CGFloat *phaseY; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CALayer+CCUtility.h: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+CCUtility.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/12. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CALayer (CCUtility) 14 | 15 | + (void)quickUpdateLayer:(dispatch_block_t)block; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CALayer+CCUtility.m: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+CCUtility.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/12. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CALayer+CCUtility.h" 10 | 11 | @implementation CALayer (CCUtility) 12 | 13 | + (void)quickUpdateLayer:(nonnull dispatch_block_t)block { 14 | [CATransaction begin]; 15 | [CATransaction setDisableActions:YES]; 16 | block(); 17 | [CATransaction commit]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCBaseUtility.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCBaseUtility.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/27. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CCBaseUtility : NSObject 14 | 15 | + (CGFloat)floatRandomBetween:(CGFloat)a and:(CGFloat)b; 16 | 17 | + (NSInteger)intRandomBetween:(NSInteger)a and:(NSInteger)b; 18 | 19 | + (CGFloat)currentScale; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCBaseUtility.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCBaseUtility.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/27. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCBaseUtility.h" 10 | 11 | @implementation CCBaseUtility 12 | 13 | + (CGFloat)floatRandomBetween:(CGFloat)a and:(CGFloat)b { 14 | // 精度默认8位数 15 | const CGFloat precision = 100000000.0; 16 | 17 | int startVal = a * precision; 18 | // 确保随机数包含b 19 | int endVal = b * precision + 1; 20 | 21 | int randomValue = startVal + (arc4random() % (endVal - startVal)); 22 | 23 | return (randomValue / precision); 24 | } 25 | 26 | + (NSInteger)intRandomBetween:(NSInteger)a and:(NSInteger)b { 27 | // 确保随机数包含b 28 | b++; 29 | return a + (arc4random() % (b - a)); 30 | } 31 | 32 | + (CGFloat)currentScale { 33 | return UIScreen.mainScreen.scale; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCCoordinateUtility.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCCoordinateUtility.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/23. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | /** 13 | 根据传入的Edge结构体, 剪切rect, 返回剪切后的rect 14 | 15 | @param rect 要剪切的rect 16 | @param insets 剪切掉的边缘值 17 | @return 剪切之后的rect 18 | */ 19 | CG_EXTERN CGRect CGRectClipRectUsingEdge(CGRect rect, UIEdgeInsets insets); 20 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCCoordinateUtility.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCCoordinateUtility.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/23. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCCoordinateUtility.h" 10 | 11 | CGRect CGRectClipRectUsingEdge(CGRect rect, UIEdgeInsets insets) { 12 | return CGRectMake(rect.origin.x + insets.left, 13 | rect.origin.y + insets.top, 14 | rect.size.width - insets.left - insets.right, 15 | rect.size.height - insets.top - insets.bottom); 16 | } 17 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCMacro.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCMacro.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define CGContextIndependent(ctx, code) \ 12 | CGContextSaveGState(ctx); \ 13 | code \ 14 | CGContextRestoreGState(ctx); \ 15 | 16 | #ifdef DEBUG 17 | #define NSLog(format, ...) printf("\n[%s] %s [%d] %s\n", __TIME__, __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ## __VA_ARGS__] UTF8String]); 18 | #else 19 | #define NSLog(format, ...) 20 | #endif 21 | 22 | //#define CC_X_INIT_TRANSLATION 1 23 | 24 | // K线图实体绘制部分 占 轴距离的百分比 25 | #define CC_KLINE_ENTITY_DISTANCE_PERCENT 0.7 26 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCSingleEventManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCSingleEventManager.h 3 | // CCTrendCharts 4 | // 5 | // 单事件管理器 6 | // 7 | // Created by Cocos on 2019/11/19. 8 | // Copyright © 2019 Cocos. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface CCSingleEventManager : NSObject 16 | 17 | 18 | /// 标记事件已完成 19 | - (void)done; 20 | 21 | 22 | /// 延迟标记事件完成 23 | /// @param interval 延迟时长(秒) 24 | - (void)doneDelay:(NSTimeInterval)interval; 25 | 26 | 27 | /// 新事件产生时, 调用该方法传入事件Block, 调用该方法之后必须调用done, 才能响应下一个事件 28 | /// @param eventBlock void(^)(void) 29 | - (void)newEventWithBlock:(nonnull dispatch_block_t)eventBlock; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCSingleEventManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCSingleEventManager.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/19. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCSingleEventManager.h" 10 | 11 | @interface CCSingleEventManager() { 12 | BOOL _token; 13 | 14 | // 顺序队列, 保证_token变量的修改是线程安全的. 15 | dispatch_queue_t _serialQ; 16 | } 17 | 18 | @end 19 | 20 | @implementation CCSingleEventManager 21 | 22 | - (instancetype)init { 23 | self = [super init]; 24 | if (self) { 25 | _token = YES; 26 | _serialQ = dispatch_queue_create("com.cctrandcharts.serail", DISPATCH_QUEUE_SERIAL); 27 | } 28 | return self; 29 | } 30 | 31 | - (void)done { 32 | dispatch_async(_serialQ, ^{ 33 | self->_token = YES; 34 | }); 35 | } 36 | 37 | - (void)doneDelay:(NSTimeInterval)interval { 38 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 39 | [self done]; 40 | }); 41 | } 42 | 43 | - (void)newEventWithBlock:(dispatch_block_t)eventBlock { 44 | // 确保所有事件都是顺序执行的 45 | dispatch_async(_serialQ, ^{ 46 | if (self->_token) { 47 | dispatch_async(dispatch_get_main_queue(), ^{ 48 | eventBlock(); 49 | }); 50 | self->_token = NO; 51 | } 52 | }); 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCTAIConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCTAIConfig.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/29. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | //#import 10 | #import "CCProtocolTAIDataSet.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | 15 | @interface CCTAIConfigItem : NSObject 16 | 17 | @property (nonatomic, strong) id N; 18 | 19 | /// 指标文案 20 | @property (nonatomic, strong) NSString *label; 21 | 22 | /// 字体 23 | @property (nonatomic, strong) UIFont *font; 24 | 25 | /// 指标的颜色 26 | @property (nonatomic, strong) UIColor *color; 27 | 28 | /// 指标右间距 29 | @property (nonatomic, assign) CGFloat rightInterval; 30 | 31 | /// 数值格式化 32 | @property (nonatomic, strong) NSNumberFormatter *formatter; 33 | 34 | 35 | /// 数据集的类名, 用于动态创建对应的数据集 36 | @property (nonatomic, strong) Class dataSetClass; 37 | 38 | @end 39 | 40 | 41 | 42 | /// 指标配置 43 | /// 44 | /// 根据配置的指标信息, 绘制和计算对应的指标 45 | @interface CCTAIConfig : NSObject 46 | 47 | - (instancetype)initWithConfig:(NSArray *)config; 48 | 49 | 50 | /// 配置指标信息 51 | /// 52 | /// 格式: 配置对应数据集类名为key, value的内容表示对应的具体指标. 53 | /// 比如配置 @{@"CCLineMADataSet", @[5, 10, 20, 60]} 54 | /// 表示遇到CCLineMADataSet数据集时, 分别绘制N为5, 10, 20, 60的线形图 55 | @property (nonatomic, strong) NSArray *conf; 56 | 57 | @end 58 | 59 | NS_ASSUME_NONNULL_END 60 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/CCTAIConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCTAIConfig.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/29. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCTAIConfig.h" 10 | 11 | @implementation CCTAIConfigItem 12 | @end 13 | 14 | 15 | @implementation CCTAIConfig 16 | 17 | - (instancetype)initWithConfig:(NSArray *)config { 18 | self = [super init]; 19 | if (self) { 20 | _conf = config; 21 | } 22 | 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/NSString+CCUtility.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+CCUtility.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/10/8. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSString (CCUtility) 14 | 15 | 16 | /** 17 | 绘制字符串 18 | 19 | @param ctx 上下文对象 20 | @param x x方向位置 21 | @param y y方向位置 22 | @param anchor 文本锚点, 取值范围:0~1 (锚点总是和提供的x,y重合. 如果提供的x,y是文本的中心, 则锚点传入(0.5,0.5) ) 23 | @param attr 字符串属性 24 | */ 25 | - (void)drawTextIn:(CGContextRef)ctx x:(CGFloat)x y:(CGFloat)y anchor:(CGPoint)anchor attributes:(nullable NSDictionary *)attr; 26 | 27 | 28 | 29 | /// 将字符设置到指定的CATextLayer上, 并这是Layer的位置到指定位置 30 | /// @param layer 目标图层 31 | /// @param point 位置 32 | /// @param anchor 文本锚点, 取值范围:0~1 (锚点总是和提供的x,y重合. 如果提供的x,y是文本的中心, 则锚点传入(0.5,0.5) ) 33 | /// @param attr 字符串属性 34 | - (void)drawTextInLayer:(CATextLayer *)layer point:(CGPoint)point anchor:(CGPoint)anchor attributes:(NSDictionary *)attr; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/NSString+CCUtility.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+CCUtility.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/10/8. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "NSString+CCUtility.h" 10 | 11 | @implementation NSString (CCUtility) 12 | 13 | - (void)drawTextIn:(CGContextRef)ctx x:(CGFloat)x y:(CGFloat)y anchor:(CGPoint)anchor attributes:(NSDictionary *)attr { 14 | 15 | UIGraphicsPushContext(ctx); 16 | 17 | CGPoint drawPoint = CGPointMake(x, y); 18 | // 获取文本尺寸 19 | CGSize labelSize = [self sizeWithAttributes:attr]; 20 | 21 | drawPoint.x = x - labelSize.width * anchor.x; 22 | drawPoint.y = y - labelSize.height * anchor.y; 23 | 24 | CGContextSaveGState(ctx); 25 | [self drawAtPoint:drawPoint withAttributes:attr]; 26 | CGContextRestoreGState(ctx); 27 | 28 | UIGraphicsPopContext(); 29 | } 30 | 31 | - (void)drawTextInLayer:(CATextLayer *)layer point:(CGPoint)point anchor:(CGPoint)anchor attributes:(NSDictionary *)attr { 32 | 33 | // 获取文本尺寸 34 | CGSize labelSize = [self sizeWithAttributes:attr]; 35 | 36 | point.x = point.x - labelSize.width * anchor.x; 37 | point.y = point.y - labelSize.height * anchor.y; 38 | 39 | layer.frame = CGRectMake(point.x, point.y, labelSize.width, labelSize.height); 40 | layer.string = self; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/Protocol/CCProtocolBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolBase.h 3 | // CCTrendCharts 4 | // 5 | // 通用的基础协议 6 | // 7 | // Created by Cocos on 2019/9/6. 8 | // Copyright © 2019 Cocos. All rights reserved. 9 | // 10 | 11 | #import 12 | #import "CCMacro.h" 13 | #import "CCBaseUtility.h" 14 | #import "CCCoordinateUtility.h" 15 | #import "NSString+CCUtility.h" 16 | #import "UIColor+CCUtility.h" 17 | 18 | @protocol CCProtocolBase 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/UIColor+CCUtility.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+CCUtility.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/5. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIColor (CCUtility) 14 | 15 | + (UIColor *)stringToColor:(NSString *)str opacity:(CGFloat)opacity; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Common/UIColor+CCUtility.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+CCUtility.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/5. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "UIColor+CCUtility.h" 10 | 11 | @implementation UIColor (CCUtility) 12 | 13 | + (UIColor *)stringToColor:(NSString *)str opacity:(CGFloat)opacity { 14 | if (!str || [str isEqualToString:@""]) { 15 | return nil; 16 | } 17 | 18 | if (![str hasPrefix:@"#"]) { 19 | NSLog(@"%@ is not beging with #",str); 20 | } 21 | 22 | unsigned red,green,blue; 23 | NSRange range; 24 | range.length = 2; 25 | range.location = 1; 26 | [[NSScanner scannerWithString:[str substringWithRange:range]] scanHexInt:&red]; 27 | range.location = 3; 28 | [[NSScanner scannerWithString:[str substringWithRange:range]] scanHexInt:&green]; 29 | range.location = 5; 30 | [[NSScanner scannerWithString:[str substringWithRange:range]] scanHexInt:&blue]; 31 | UIColor *color= [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:opacity]; 32 | return color; 33 | } 34 | 35 | 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Axis/CCDefaultXAxis.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultXAxis.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/6. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolAxisBase.h" 11 | #import "CCProtocolXAxisFormatterBase.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface CCDefaultXAxis : NSObject 16 | 17 | @property (nonatomic, strong) id formatter; 18 | 19 | @property (nonatomic, assign) CCXAxisLabelPosition labelPosition; 20 | 21 | 22 | /** 23 | 用于显示在轴上的字符串, 也称原始字符串, 下标就是对应X轴索引 24 | */ 25 | @property (nonatomic, copy) NSArray *entities; 26 | 27 | 28 | /// 起点实体轴, 和Y轴的距离. 29 | /// 30 | /// 默认值 0.5 31 | @property (nonatomic, assign) CGFloat startMargin; 32 | 33 | /// 终点实体轴, 和Y轴的距离. 34 | /// 35 | /// 默认值 0.5 36 | @property (nonatomic, assign) CGFloat endMargin; 37 | 38 | /// x方向实体的间距 39 | /// 40 | /// 当autoXSapce为YES时, 该参数无效 41 | /// 42 | /// 默认值 8个点 43 | @property (nonatomic, assign) CGFloat xSpace; 44 | 45 | /// 自动计算xSpace的值 46 | /// 47 | /// 如果totalCount不为0时, 则按照totalCount指定的数量计算xSpace的值. 48 | /// 49 | /// 如果totalCount为0, 则自动根据绘制区域宽度设置xSpace, 以满足数据全屏显示 50 | /// 51 | /// 默认值 NO 52 | @property (nonatomic, assign) BOOL autoXSapce; 53 | 54 | /// 设置总数据个数 55 | /// 56 | /// 正常情况下不需要设置, 如果设置了数据个数, 则autoXSapce会被设置为YES 57 | /// 58 | /// 默认值 0 59 | @property (nonatomic, assign) NSInteger totalCount; 60 | 61 | @end 62 | 63 | NS_ASSUME_NONNULL_END 64 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Axis/CCDefaultXAxis.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultXAxis.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/6. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCDefaultXAxis.h" 10 | #import "CCXAxisDefaultFormatter.h" 11 | 12 | @interface CCDefaultXAxis () { 13 | BOOL _customRequireSize; 14 | } 15 | @end 16 | 17 | @implementation CCDefaultXAxis 18 | @synthesize labelDisable = _labelDisable; 19 | 20 | @synthesize axisColor = _axisColor; 21 | @synthesize axisLineWidth = _axisLineWidth; 22 | @synthesize axisLineDisabled = _axisLineDisabled; 23 | @synthesize font = _font; 24 | @synthesize labelColor = _labelColor; 25 | 26 | @synthesize xLabelOffset = _xLabelOffset; 27 | @synthesize yLabelOffset = _yLabelOffset; 28 | @synthesize requireSize = _requireSize; 29 | 30 | @synthesize gridColor = _gridColor; 31 | @synthesize gridLineWidth = _gridLineWidth; 32 | @synthesize gridLineEnabled = _gridLineEnabled; 33 | 34 | - (instancetype)init { 35 | self = [super init]; 36 | if (self) { 37 | _axisColor = UIColor.grayColor; 38 | _axisLineWidth = 1.f; 39 | 40 | _gridLineWidth = 1.f; 41 | _gridColor = [UIColor.lightGrayColor colorWithAlphaComponent:0.2]; 42 | _gridLineEnabled = YES; 43 | 44 | _font = [UIFont systemFontOfSize:10]; 45 | _labelColor = UIColor.grayColor; 46 | 47 | _xLabelOffset = 0; 48 | _yLabelOffset = 5; 49 | 50 | _startMargin = 0.5; 51 | _endMargin = 0.5; 52 | _xSpace = 8.f; 53 | _autoXSapce = NO; 54 | _totalCount = 0; 55 | 56 | // 设置默认的formatter对象 57 | _formatter = [[CCXAxisDefaultFormatter alloc] init]; 58 | } 59 | return self; 60 | } 61 | 62 | /// 这里取第一个元素的文案信息 63 | - (CGSize)requireSize { 64 | if (_customRequireSize) { 65 | return _requireSize; 66 | } 67 | 68 | if (self.entities.count <= 0) { 69 | return CGSizeZero; 70 | } 71 | 72 | NSString *maxLabel = [self.formatter stringForIndex:0 origin:self.entities[0]]; 73 | 74 | CGSize size = [maxLabel sizeWithAttributes:@{ NSFontAttributeName: self.font }]; 75 | size.width += self.xLabelOffset; 76 | size.height += self.yLabelOffset; 77 | 78 | return size; 79 | } 80 | 81 | - (void)setRequireSize:(CGSize)requireSize { 82 | _customRequireSize = YES; 83 | _requireSize = requireSize; 84 | } 85 | 86 | - (void)setTotalCount:(NSInteger)totalCount { 87 | self.autoXSapce = YES; 88 | _totalCount = totalCount; 89 | } 90 | 91 | #pragma mark - NSCopying 92 | - (nonnull id)copyWithZone:(nullable NSZone *)zone { 93 | typeof(self) axis = [[self.class allocWithZone:zone] init]; 94 | 95 | axis.axisLineDisabled = self.axisLineDisabled; 96 | axis.axisColor = [self.axisColor copy]; 97 | axis.axisLineWidth = self.axisLineWidth; 98 | axis.font = [self.font copy]; 99 | axis.labelColor = [self.labelColor copy]; 100 | axis.labelDisable = self.labelDisable; 101 | axis.xLabelOffset = self.xLabelOffset; 102 | axis.yLabelOffset = self.yLabelOffset; 103 | 104 | if (_customRequireSize) { 105 | axis.requireSize = self.requireSize; 106 | } 107 | 108 | axis.gridColor = [self.gridColor copy]; 109 | axis.gridLineWidth = self.gridLineWidth; 110 | axis.gridLineEnabled = self.gridLineEnabled; 111 | 112 | axis.formatter = [(NSObject *)self.formatter copy]; 113 | axis.labelPosition = self.labelPosition; 114 | 115 | axis.startMargin = self.startMargin; 116 | axis.endMargin = self.endMargin; 117 | 118 | return axis; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Axis/CCDefaultYAxis.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultYAxis.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/6. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolAxisBase.h" 11 | #import "CCChartData.h" 12 | 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface CCDefaultYAxis : NSObject 17 | 18 | 19 | /// 根据当前 20 | /// @param charData 数据源 21 | - (void)calculateMinMax:(CCChartData *)charData; 22 | 23 | 24 | /// 根据轴最值, labelCount等参数, 生成y轴实体数据, 有需要可以重写 25 | - (void)generateEntities; 26 | 27 | - (instancetype)initWithDependency:(CCYAsixDependency)dependency NS_DESIGNATED_INITIALIZER; 28 | 29 | - (instancetype)init NS_UNAVAILABLE; 30 | 31 | // 确定y轴数据格式 32 | @property (nonatomic, strong) NSNumberFormatter *formatter; 33 | 34 | 35 | /** 36 | 如果用户自行设置过minValue或者maxValue, customValue会被设置为true, 否则为false; 37 | 当customValue为false时, 库会自动结合具体的数值确定大小值 38 | */ 39 | @property (nonatomic, assign) BOOL customValue; 40 | 41 | 42 | /// 最少2个 43 | @property (nonatomic, assign) NSInteger labelCount; 44 | 45 | @property (nonatomic, assign) CGFloat axisMinValue; 46 | 47 | @property (nonatomic, assign) CGFloat axisMaxValue; 48 | 49 | 50 | /// 额外给最大最小值的范围值追加一个百分比, 避免实体贴近上下边缘绘制, 这样渲染出来的效果好看一些. 51 | /// 52 | /// 该值默认是0.05(5%) 53 | @property (nonatomic, assign) CGFloat minMaxRangeExtraPrecent; 54 | 55 | @property (nonatomic, assign) CCYAxisLabelPosition labelPosition; 56 | 57 | @property (nonatomic, assign) CCYAsixDependency dependency; 58 | 59 | 60 | /** 61 | 绘制到y轴上的信息 62 | 63 | 64 | 通常是有多少个元素就在y轴上绘制多少个文本 65 | */ 66 | @property (nonatomic, strong) NSArray *entities; 67 | 68 | 69 | /** 70 | return entities.count 71 | */ 72 | @property (nonatomic, assign, readonly) NSInteger entityCount; 73 | 74 | 75 | 76 | // 可以再设计子类, 描述网格信息 77 | @end 78 | 79 | NS_ASSUME_NONNULL_END 80 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCBarChartDataSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCBarChartDataSet.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/24. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartDataSetBase.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | extern CCDataSetName const _Nonnull kCCNameBarDataSet; 14 | 15 | /// 适用于柱型图 16 | @interface CCBarChartDataSet : CCChartDataSetBase 17 | 18 | 19 | /// 实体绘制的尺寸在两个轴的百分比 20 | /// 21 | /// 默认值 0.7 22 | @property (nonatomic, assign) CGFloat entityDistancePercent; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCBarChartDataSet.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCBarChartDataSet.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/24. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCBarChartDataSet.h" 10 | 11 | CCDataSetName const kCCNameBarDataSet = @"kCCNameBarDataSet"; 12 | 13 | @implementation CCBarChartDataSet 14 | 15 | - (instancetype)initWithEntities:(NSArray> *)entities withName:(CCDataSetName)name { 16 | if (name == nil) { 17 | name = kCCNameBarDataSet; 18 | } 19 | 20 | self = [super initWithEntities:entities withName:name]; 21 | if (self) { 22 | _entityDistancePercent = 0.7; 23 | } 24 | return self; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCChartData.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartData.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolChartDataSet.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | 15 | /** 16 | 数据整体: 17 | 18 | 为视图提供数据, 一个数据整体包含了一个或多个数据集, 以及一个x轴文案信息(多个数据集应该共用同样的x轴) 19 | 至于y轴的文案信息, 实际上是由数据集得到的, 所以这里数据整体不需要囊括y轴文案信息 20 | */ 21 | @interface CCChartData : NSObject 22 | 23 | 24 | - (instancetype)init NS_UNAVAILABLE; 25 | 26 | /** 27 | 默认初始化方法 28 | 29 | @param xVals X轴全部数据对应文案信息 30 | @param dataSets 数据集数组, 每个数据集都支持单独绘制, 包括不同颜色样式 31 | @return 数据整体 32 | */ 33 | - (instancetype)initWithXVals:(NSArray *)xVals dataSets:(NSArray> *)dataSets NS_DESIGNATED_INITIALIZER; 34 | 35 | 36 | /** 37 | 根据当前数据集重新计算最大最小值 38 | */ 39 | - (void)calcMinMaxStart:(NSInteger)start End:(NSInteger)end; 40 | 41 | 42 | /// 获取数据源中的全部匹配的index实体 43 | /// @param index 索引 44 | - (NSArray> *)entitiesForIndex:(NSInteger)index; 45 | 46 | 47 | /// 从名为dataSetName的数据集中, 获取指定索引的实体. 48 | /// @param index 索引 49 | /// @param dataSetName 数据集名字 50 | - (NSArray> *)entityForIndex:(NSInteger)index inDataSet:(CCDataSetName)dataSetName; 51 | 52 | 53 | /// 获取指定名字的dataSet, 这里可能有多个同名dataSet, 所以返回数组 (后期将可能支持数据组绘制) 54 | /// @param name dataSet名字 55 | - (NSMutableArray> *)dataSetWithName:(CCDataSetName)name; 56 | 57 | /** 58 | 集合数组 59 | */ 60 | @property (nonatomic, strong) NSMutableArray> *dataSets; 61 | 62 | 63 | /** 64 | X轴对应的数据(x轴上的文案) 65 | */ 66 | @property (nonatomic, strong) NSArray *xVals; 67 | 68 | @property (nonatomic, readonly, assign) CGFloat maxY; 69 | 70 | @property (nonatomic, readonly, assign) CGFloat minY; 71 | 72 | @property (nonatomic, readonly, assign) CGFloat minX; 73 | 74 | @property (nonatomic, readonly, assign) CGFloat maxX; 75 | 76 | 77 | @end 78 | 79 | NS_ASSUME_NONNULL_END 80 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCChartData.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartData.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartData.h" 10 | 11 | 12 | @implementation CCChartData 13 | 14 | - (instancetype)initWithXVals:(NSArray *)xVals dataSets:(NSArray> *)dataSets { 15 | self = [super init]; 16 | if (self) { 17 | _xVals = xVals; 18 | _dataSets = dataSets.mutableCopy; 19 | 20 | [self calcMinMaxStart:0 End:xVals.count]; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)resetValue { 26 | _maxY = -CGFLOAT_MAX; 27 | _minY = CGFLOAT_MAX; 28 | 29 | _maxX = NSIntegerMin; 30 | _minX = NSIntegerMax; 31 | } 32 | 33 | - (void)calcMinMaxStart:(NSInteger)start End:(NSInteger)end { 34 | // 重置最大最小值 35 | [self resetValue]; 36 | 37 | for (id dataSet in self.dataSets) { 38 | 39 | [dataSet calcMinMaxStart:start End:end]; 40 | // 计算 y 41 | if (_minY > dataSet.minY) { 42 | _minY = dataSet.minY; 43 | } 44 | if (_maxY < dataSet.maxY) { 45 | _maxY = dataSet.maxY; 46 | } 47 | 48 | // 计算 x 49 | if (_minX > dataSet.minX) { 50 | _minX = dataSet.minX; 51 | } 52 | if (_maxX < dataSet.maxX) { 53 | _maxX = dataSet.maxX; 54 | } 55 | } 56 | } 57 | 58 | - (NSArray> *)entitiesForIndex:(NSInteger)index { 59 | for (id dataSet in self.dataSets) { 60 | return [dataSet entityForIndex:index]; 61 | 62 | } 63 | return nil; 64 | } 65 | 66 | - (NSArray> *)entityForIndex:(NSInteger)index inDataSet:(NSString *)dataSetName { 67 | 68 | NSArray> *dataSets = [self dataSetWithName:dataSetName]; 69 | NSMutableArray *arr; 70 | for (id dataSet in dataSets) { 71 | if ([dataSet entityForIndex:index]) { 72 | if (!arr) { 73 | arr = @[].mutableCopy; 74 | } 75 | [arr addObject:[dataSet entityForIndex:index]]; 76 | } 77 | } 78 | return arr; 79 | } 80 | 81 | - (NSMutableArray> *)dataSetWithName:(CCDataSetName)name { 82 | NSMutableArray *arr; 83 | for (id set in self.dataSets) { 84 | if ([set.name isEqualToString:name]) { 85 | if (!arr) { 86 | arr = @[].mutableCopy; 87 | } 88 | [arr addObject:set]; 89 | } 90 | } 91 | return arr.mutableCopy; 92 | } 93 | 94 | #pragma mark - Getter & Setter 95 | - (void)setDataSets:(NSArray> *)dataSets { 96 | _dataSets = dataSets.mutableCopy; 97 | 98 | [self calcMinMaxStart:NSIntegerMin End:NSIntegerMax]; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCChartDataSetBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartDataSetBase.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/10/9. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolChartDataSet.h" 11 | 12 | extern CCDataSetName const _Nonnull kCCNameBaseDataSet; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface CCChartDataSetBase : NSObject 17 | 18 | - (instancetype)initWithEntities:(NSArray> *)entities withName:(nullable CCDataSetName)name NS_DESIGNATED_INITIALIZER; 19 | 20 | - (instancetype)init NS_UNAVAILABLE; 21 | 22 | - (void)resetValue; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCChartDataSetBase.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartDataSetBase.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/10/9. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartDataSetBase.h" 10 | 11 | CCDataSetName const kCCNameBaseDataSet = @"BaseDataSet"; 12 | 13 | @implementation CCChartDataSetBase 14 | @synthesize entities = _entities; 15 | 16 | @synthesize color = _color; 17 | @synthesize maxY = _maxY; 18 | @synthesize minY = _minY; 19 | @synthesize name = _name; 20 | @synthesize maxX = _maxX; 21 | @synthesize minX = _minX; 22 | 23 | 24 | - (instancetype)initWithEntities:(NSArray> *)entities withName:(CCDataSetName)name { 25 | self = [super init]; 26 | if (self) { 27 | _entities = entities; 28 | _name = name; 29 | _color = [UIColor whiteColor]; 30 | 31 | [self resetValue]; 32 | 33 | [self calcMinMaxStart:0 End:entities.count]; 34 | } 35 | 36 | return self; 37 | } 38 | 39 | - (void)resetValue { 40 | _maxY = -CGFLOAT_MAX; 41 | _minY = CGFLOAT_MAX; 42 | 43 | _maxX = NSIntegerMin; 44 | _minX = NSIntegerMax; 45 | } 46 | 47 | /** 48 | 重新计算数据集中的最值 49 | */ 50 | - (void)calcMinMaxStart:(NSInteger)start End:(NSInteger)end { 51 | [self resetValue]; 52 | 53 | for (id val in self.entities) { 54 | if (val.xIndex < start || val.xIndex > end) { 55 | continue; 56 | } 57 | 58 | if (_minY > val.value) { 59 | _minY = val.value; 60 | } 61 | if (_maxY < val.value) { 62 | _maxY = val.value; 63 | } 64 | 65 | if (_minX > val.xIndex) { 66 | _minX = val.xIndex; 67 | } 68 | if (_maxX < val.xIndex) { 69 | _maxX = val.xIndex; 70 | } 71 | } 72 | } 73 | 74 | - (NSArray> *)entityForIndex:(NSInteger)index { 75 | NSMutableArray *arr; 76 | for (id val in self.entities) { 77 | if (val.xIndex == index) { 78 | if (!arr) { 79 | arr = @[].mutableCopy; 80 | } 81 | [arr addObject:val]; 82 | } 83 | } 84 | return arr; 85 | } 86 | 87 | #pragma mark - Setter & Getter 88 | - (void)setEntities:(NSArray> *)entities { 89 | _entities = entities; 90 | 91 | [self calcMinMaxStart:NSIntegerMin End:NSIntegerMax]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCKLineChartData.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineChartData.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartData.h" 10 | #import "CCTAIConfig.h" 11 | 12 | //运行时的是数据集类应该是CCKLineChartDataSet或者CCVolumeChartDataSet 13 | #import "CCKLineChartDataSet.h" 14 | #import "CCVolumeChartDataSet.h" 15 | 16 | #import "CCLineMADataSet.h" 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface CCKLineChartData : CCChartData 21 | 22 | 23 | /// 调用该方法之后, ChartData会根据config计算并生成数据集 24 | /// @param config 配置 25 | - (void)notifyTAIConfigChange:(CCTAIConfig *)config; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCKLineChartData.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineChartData.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCKLineChartData.h" 10 | 11 | @implementation CCKLineChartData 12 | 13 | - (void)notifyTAIConfigChange:(CCTAIConfig *)config { 14 | id klineDataSet = [[self dataSetWithName:kCCNameKLineDataSet] lastObject]; 15 | if (!klineDataSet) { 16 | klineDataSet = [[self dataSetWithName:kCCVolumeChartDataSet] lastObject]; 17 | } 18 | 19 | if (!klineDataSet) { 20 | return; 21 | } 22 | 23 | for (CCTAIConfigItem *item in config.conf) { 24 | if ([item.dataSetClass conformsToProtocol:@protocol(CCProtocolTAIDataSet)]) { 25 | id dataSet = [[item.dataSetClass alloc] initWithRawEntities:klineDataSet.entities N:item.N]; 26 | if (!dataSet) { 27 | continue; 28 | } 29 | 30 | dataSet.label = item.label; 31 | dataSet.color = item.color; 32 | dataSet.font = item.font; 33 | 34 | [self.dataSets addObject:dataSet]; 35 | } 36 | } 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCKLineChartDataSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineChartDataSet.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCChartDataSetBase.h" 12 | #import "CCKLineDataEntity.h" 13 | 14 | extern CCDataSetName const _Nonnull kCCNameKLineDataSet; 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | @interface CCKLineChartDataSet : CCChartDataSetBase 19 | 20 | - (instancetype)initWithEntities:(NSArray *)entities withName:(nullable NSString *)name; 21 | 22 | @property (nonatomic, strong) NSArray *entities; 23 | 24 | /// 上升颜色 25 | @property (nonatomic, strong) UIColor *risingColor; 26 | 27 | /// 下降颜色 28 | @property (nonatomic, strong) UIColor *fallingColor; 29 | 30 | /// 需要留意一下k线十字星的颜色是什么...这里默认是灰色 31 | @property (nonatomic, strong) UIColor *flatColor; 32 | 33 | /// 是否填充上升蜡烛图 34 | @property (nonatomic, assign) BOOL isRisingFill; 35 | 36 | /// 是否填充下降蜡烛图 37 | @property (nonatomic, assign) BOOL isFallingFill; 38 | 39 | 40 | /** 41 | 高亮信息 42 | */ 43 | @property (nonatomic, strong) UIColor *highlightColor; 44 | 45 | @property (nonatomic, assign) CGFloat lineWidth; 46 | 47 | @end 48 | 49 | NS_ASSUME_NONNULL_END 50 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCKLineChartDataSet.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineChartDataSet.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCKLineChartDataSet.h" 10 | 11 | CCDataSetName const kCCNameKLineDataSet = @"KLineDataSet"; 12 | 13 | @implementation CCKLineChartDataSet 14 | // 由父类合成 15 | @dynamic entities; 16 | 17 | // 子类重新合成变量, 因为这个变量本身是不对外界开放修改的, 只能这么做了 18 | @synthesize maxY = _maxY; 19 | @synthesize minY = _minY; 20 | @synthesize maxX = _maxX; 21 | @synthesize minX = _minX; 22 | 23 | /// 指定的初始化方法 24 | /// @param entities 实体 25 | /// @param name 数据集名字, 默认是kCCNameKLineDataSet 26 | - (instancetype)initWithEntities:(NSArray *)entities withName:(CCDataSetName)name { 27 | if (name == nil) { 28 | name = kCCNameKLineDataSet; 29 | } 30 | 31 | self = [super initWithEntities:entities withName:name]; 32 | if (self) { 33 | _risingColor = [UIColor stringToColor:@"#de4e43" opacity:1]; 34 | _fallingColor = [UIColor stringToColor:@"#4ba74a" opacity:1]; 35 | _flatColor = UIColor.lightGrayColor; 36 | _isRisingFill = YES; 37 | _isFallingFill = YES; 38 | _lineWidth = 1.f; 39 | } 40 | [self resetValue]; 41 | 42 | [self calcMinMaxStart:NSIntegerMin End:NSIntegerMax]; 43 | 44 | return self; 45 | } 46 | 47 | // 这里需要重写, 因为父类修改的是父类的私有变量 48 | - (void)resetValue { 49 | _maxY = -CGFLOAT_MAX; 50 | _minY = CGFLOAT_MAX; 51 | 52 | _maxX = NSIntegerMin; 53 | _minX = NSIntegerMax; 54 | } 55 | 56 | /// K线数据集的最值计算方法, 是通过数据实体中的最高最低值字段计算出的, 所以需要重写父类方法 57 | /// @param start 起点 58 | /// @param end 终点 59 | - (void)calcMinMaxStart:(NSInteger)start End:(NSInteger)end { 60 | [self resetValue]; 61 | 62 | for (CCKLineDataEntity *val in self.entities) { 63 | if (val.xIndex < start || val.xIndex > end) { 64 | continue; 65 | } 66 | 67 | if (_minY > val.lowest) { 68 | _minY = val.lowest; 69 | } 70 | 71 | if (_maxY < val.highest) { 72 | _maxY = val.highest; 73 | } 74 | 75 | if (_minX > val.xIndex) { 76 | _minX = val.xIndex; 77 | } 78 | if (_maxX < val.xIndex) { 79 | _maxX = val.xIndex; 80 | } 81 | } 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCLineChartDataSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCLineChartDataSet.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/22. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartDataSetBase.h" 10 | 11 | extern CCDataSetName const _Nonnull kCCNameLineDataSet; 12 | 13 | typedef NS_ENUM (NSUInteger, CCLineChartDrawType) { 14 | CCLineChartDrawTypeLine = 0, // 折线图 15 | CCLineChartDrawTypeCurve // 曲线图 16 | }; 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | /// 线形图数据集 21 | /// 22 | /// 用于充当线形图渲染器的数据提供者 23 | @interface CCLineChartDataSet : CCChartDataSetBase 24 | 25 | /// 绘制类型 26 | @property (nonatomic, assign) CCLineChartDrawType drawType; 27 | 28 | /// 线宽 29 | @property (nonatomic, assign) CGFloat lineWidth; 30 | 31 | @property (nonatomic, assign) CAShapeLayerLineCap lineCap; 32 | 33 | @property (nonatomic, assign) CAShapeLayerLineJoin lineJoin; 34 | 35 | // 填充线条和两轴之间的颜色 36 | @property (nonatomic, strong) UIColor *fillColor; 37 | 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCLineChartDataSet.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCLineChartDataSet.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/22. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCLineChartDataSet.h" 10 | 11 | CCDataSetName const kCCNameLineDataSet = @"LineDataSet"; 12 | 13 | @implementation CCLineChartDataSet 14 | 15 | - (instancetype)initWithEntities:(NSArray> *)entities withName:(CCDataSetName)name { 16 | if (name == nil) { 17 | name = kCCNameLineDataSet; 18 | } 19 | 20 | self = [super initWithEntities:entities withName:name]; 21 | if (self) { 22 | _lineJoin = kCALineJoinRound; 23 | _lineWidth = 1.f; 24 | _fillColor = UIColor.clearColor; 25 | } 26 | return self; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCVolumeChartDataSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeChartDataSet.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/21. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCKLineChartDataSet.h" 10 | #import "CCVolumeDataEntity.h" 11 | 12 | extern CCDataSetName const _Nonnull kCCVolumeChartDataSet; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | 17 | /// 适用于交易量柱型图的数据集 18 | @interface CCVolumeChartDataSet : CCKLineChartDataSet 19 | 20 | - (instancetype)initWithKLineChartDataSet:(CCKLineChartDataSet *)dataSet; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/CCVolumeChartDataSet.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeChartDataSet.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/21. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCVolumeChartDataSet.h" 10 | 11 | CCDataSetName const kCCVolumeChartDataSet = @"VolumeChartDataSet"; 12 | 13 | @implementation CCVolumeChartDataSet 14 | // 子类重新合成变量, 因为这个变量本身是不对外界开放修改的, 只能这么做了 15 | @synthesize maxY = _maxY; 16 | @synthesize minY = _minY; 17 | @synthesize maxX = _maxX; 18 | @synthesize minX = _minX; 19 | 20 | - (instancetype)initWithEntities:(NSArray *)entities withName:(NSString *)name { 21 | if (name == nil) { 22 | name = kCCVolumeChartDataSet; 23 | } 24 | self = [super initWithEntities:entities withName:name]; 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithKLineChartDataSet:(CCKLineChartDataSet *)dataSet { 29 | // 把 kline dataset 中的实体转成交易量实体 30 | NSMutableArray *arr = @[].mutableCopy; 31 | for (id val in dataSet.entities) { 32 | [arr addObject:[[CCVolumeDataEntity alloc] initWithKLineDataEntity:val]]; 33 | } 34 | 35 | self = [self initWithEntities:arr withName:nil]; 36 | 37 | if (self) { 38 | 39 | self.risingColor = [dataSet.risingColor copy]; 40 | self.fallingColor = [dataSet.fallingColor copy]; 41 | self.flatColor = [dataSet.flatColor copy]; 42 | self.highlightColor = [dataSet.highlightColor copy]; 43 | 44 | self.isRisingFill = dataSet.isRisingFill; 45 | self.isFallingFill = dataSet.isFallingFill; 46 | 47 | } 48 | return self; 49 | } 50 | 51 | // 这里需要重写, 因为父类修改的是父类的私有变量 52 | - (void)resetValue { 53 | _maxY = -CGFLOAT_MAX; 54 | _minY = CGFLOAT_MAX; 55 | 56 | _maxX = NSIntegerMin; 57 | _minX = NSIntegerMax; 58 | } 59 | 60 | /// 交易量数据集的最值计算 61 | /// @param start 起点 62 | /// @param end 终点 63 | - (void)calcMinMaxStart:(NSInteger)start End:(NSInteger)end { 64 | [self resetValue]; 65 | 66 | for (CCVolumeDataEntity *val in self.entities) { 67 | if (val.xIndex < start || val.xIndex > end) { 68 | continue; 69 | } 70 | 71 | if (_minY > val.volume) { 72 | _minY = val.volume; 73 | } 74 | 75 | if (_maxY < val.volume) { 76 | _maxY = val.volume; 77 | } 78 | 79 | if (_minX > val.xIndex) { 80 | _minX = val.xIndex; 81 | } 82 | if (_maxX < val.xIndex) { 83 | _maxX = val.xIndex; 84 | } 85 | } 86 | } 87 | 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Cursor/CCDefaultCursor.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultCursor.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/5. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCProtocolCursorBase.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CCDefaultCursor : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Cursor/CCDefaultCursor.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultCursor.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/5. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCDefaultCursor.h" 10 | 11 | @implementation CCDefaultCursor 12 | @synthesize lineWidth = _lineWidth; 13 | @synthesize lineDashPhase = _lineDashPhase; 14 | @synthesize lineDashLengths = _lineDashLengths; 15 | @synthesize lineColor = _lineColor; 16 | @synthesize lineCap = _lineCap; 17 | @synthesize font = _font; 18 | @synthesize labelColor = _labelColor; 19 | @synthesize impactFeedback = _impactFeedback; 20 | @synthesize intensity = _intensity; 21 | @synthesize yAxisYLabelOffset = _yAxisYLabelOffset; 22 | @synthesize xAxisYLabelOffset = _xAxisYLabelOffset; 23 | 24 | - (instancetype)init { 25 | self = [super init]; 26 | if (self) { 27 | _lineWidth = 1.f; 28 | _lineColor = [UIColor.whiteColor colorWithAlphaComponent:0.5]; 29 | _font = [UIFont systemFontOfSize:10]; 30 | _lineCap = kCGLineCapRound; 31 | _labelColor = UIColor.whiteColor; 32 | _lineDashPhase = 0.f; 33 | _yAxisYLabelOffset = _xAxisYLabelOffset = 0.f; 34 | 35 | if (@available(iOS 13.0, *)) { 36 | _impactFeedback = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; 37 | } else { 38 | if (@available(iOS 10.0, *)) { 39 | _impactFeedback = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; 40 | } else { 41 | // Fallback on earlier versions 42 | } 43 | } 44 | _intensity = 0.5; 45 | } 46 | return self; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Entity/CCChartDataEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartDataEntity.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolChartDataEntityBase.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface CCChartDataEntity : NSObject 15 | 16 | - (instancetype)initWithValue:(CGFloat)value xIndex:(NSInteger)xIndex data:(nullable id)data; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Entity/CCChartDataEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartDataEntity.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartDataEntity.h" 10 | 11 | @implementation CCChartDataEntity 12 | @synthesize value = _value; 13 | @synthesize xIndex = _xIndex; 14 | @synthesize data = _data; 15 | @synthesize timeInt = _timeInt; 16 | 17 | - (instancetype)init { 18 | return [self initWithValue:0 xIndex:0 data:nil]; 19 | } 20 | 21 | - (instancetype)initWithValue:(CGFloat)value xIndex:(NSInteger)xIndex data:(id)data { 22 | self = [super init]; 23 | if (self) { 24 | _value = value; 25 | _xIndex = xIndex; 26 | _data = data; 27 | } 28 | return self; 29 | } 30 | 31 | - (NSString *)description { 32 | return [NSString stringWithFormat:@"[%p] xIndex: %@, value: %@, time: %@, data: %@", self, @(self.xIndex), @(self.value), @(self.timeInt), self.data]; 33 | } 34 | 35 | 36 | 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Entity/CCKLineDataEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineDataEntity.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartDataEntity.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | 14 | // 用于表示当前实体是上升还是下降还是无状态(开盘等于收盘, 价格和前一天收盘价一样) 15 | typedef NS_ENUM(NSUInteger, CCKLineDataEntityState) { 16 | CCKLineDataEntityStateRising, 17 | CCKLineDataEntityStateFalling, 18 | CCKLineDataEntityStateNone, 19 | }; 20 | 21 | @interface CCKLineDataEntity : CCChartDataEntity 22 | 23 | 24 | /// 实体状态(升降平) 25 | /// 26 | /// 已经支持股票趋势和24小时开盘的趋势图(虚拟币) 27 | @property (nonatomic, assign, readonly) CCKLineDataEntityState entityState; 28 | 29 | /// 最高价的 30 | @property (nonatomic, assign) CGFloat highest; 31 | 32 | /// 最低价的 33 | @property (nonatomic, assign) CGFloat lowest; 34 | 35 | /// 开盘价 36 | @property (nonatomic, assign) CGFloat opening; 37 | 38 | /// 收盘价 39 | @property (nonatomic, assign) CGFloat closing; 40 | 41 | /// 成交量(股) 42 | @property (nonatomic, assign) CGFloat volume; 43 | 44 | /// 成交额 45 | @property (nonatomic, assign) CGFloat amount; 46 | 47 | /// 换手率 48 | @property (nonatomic, assign) CGFloat turnoverrate; 49 | 50 | /// 涨跌幅度百分比 51 | @property (nonatomic, assign) CGFloat percent; 52 | 53 | /// 涨跌额 54 | /// 55 | /// 这里需要注意, 股票和虚拟币不同, 股票不是24小时交易, 而且有盘前盘后竞价, 第2天的开盘价不一定等于第1天的收盘价. 56 | /// 所以当天开盘价等于收盘价时, 需要配合changing属性来确定绘制的颜色. 57 | /// 如果不提供该值, 默认为0.0 58 | @property (nonatomic, assign) CGFloat changing; 59 | 60 | 61 | @end 62 | 63 | NS_ASSUME_NONNULL_END 64 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Entity/CCKLineDataEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineDataEntity.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCKLineDataEntity.h" 10 | 11 | @implementation CCKLineDataEntity 12 | - (instancetype)init { 13 | self = [super init]; 14 | if (self) { 15 | _changing = 0; 16 | _amount = 0; 17 | _volume = 0; 18 | } 19 | 20 | return self; 21 | } 22 | 23 | - (CCKLineDataEntityState)entityState { 24 | if (self.opening > self.closing) { 25 | return CCKLineDataEntityStateFalling; 26 | } else if (self.opening < self.closing) { 27 | return CCKLineDataEntityStateRising; 28 | } else { 29 | if (self.changing > 0) { 30 | return CCKLineDataEntityStateRising; 31 | } else if (self.changing < 0) { 32 | return CCKLineDataEntityStateFalling; 33 | } else { 34 | // 这里主要是考虑到股票交易有收盘, 所以开盘价等于收盘价并不代表changing就是0. 35 | return CCKLineDataEntityStateNone; 36 | } 37 | } 38 | } 39 | 40 | - (CGFloat)value { 41 | return self.closing; 42 | } 43 | 44 | - (NSString *)description { 45 | NSString *str = [super description]; 46 | return [NSString stringWithFormat:@"%@\nhighest = %f\nlowest = %f\nopening = %f\nclosing = %f\nvolume = %f\namount = %f\nturnoverrate = %f\nchanging = %f\npercent = %f", str, self.highest, self.lowest, self.opening, self.closing, self.volume, self.amount, self.turnoverrate, self.changing, self.percent]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Entity/CCVolumeDataEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeDataEntity.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/3. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCKLineDataEntity.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CCVolumeDataEntity : CCKLineDataEntity 14 | 15 | - (instancetype)initWithKLineDataEntity:(CCKLineDataEntity *)entity; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Entity/CCVolumeDataEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeDataEntity.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/3. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCVolumeDataEntity.h" 10 | 11 | @implementation CCVolumeDataEntity 12 | 13 | - (instancetype)initWithKLineDataEntity:(CCKLineDataEntity *)entity { 14 | self = [super init]; 15 | if (self) { 16 | self.highest = entity.highest; 17 | self.lowest = entity.lowest; 18 | self.opening = entity.opening; 19 | self.closing = entity.closing; 20 | self.volume = entity.volume; 21 | self.amount = entity.amount; 22 | self.turnoverrate = entity.turnoverrate; 23 | self.changing = entity.changing; 24 | 25 | // value用不到 26 | self.xIndex = entity.xIndex; 27 | self.timeInt = entity.timeInt; 28 | self.data = entity.data; 29 | } 30 | return self; 31 | } 32 | 33 | - (CGFloat)value { 34 | return self.volume; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Protocol/CCProtocolAxisBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolAxisBase.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolBase.h" 11 | 12 | typedef NS_ENUM (NSUInteger, CCXAxisLabelPosition) { 13 | CCXAxisLabelPositionBottom, // X轴上方 14 | CCXAxisLabelPositionTop, // x轴下方 15 | }; 16 | 17 | typedef NS_ENUM (NSUInteger, CCYAxisLabelPosition) { 18 | CCYAxisLabelPositionInside, // y轴里侧 19 | CCYAxisLabelPositionOutside, // y轴外侧 20 | }; 21 | 22 | typedef NS_ENUM (NSUInteger, CCYAsixDependency) { 23 | CCYAsixDependencyLeft = 0 << 0, // 左侧Y轴 24 | CCYAsixDependencyRight = 1 << 1, // 右侧Y轴 25 | }; 26 | 27 | 28 | @protocol CCProtocolAxisBase < 29 | CCProtocolBase, 30 | NSCopying // 所有的Axis数据提供者都需要支持NSCopying协议, 这是为了方便其他视图复制样式 31 | > 32 | @required 33 | 34 | /** 35 | 轴上文字字体 36 | */ 37 | @property (nonatomic, strong) UIFont *font; 38 | 39 | /** 40 | label颜色 41 | */ 42 | @property (nonatomic, strong) UIColor *labelColor; 43 | 44 | 45 | /// 禁止渲染Label 46 | /// 47 | /// 默认 NO 48 | @property (nonatomic, assign) BOOL labelDisable; 49 | 50 | /** 51 | label最大行数, 支持文本多行摆放 52 | */ 53 | //@property (nonatomic, assign) NSInteger labelMaxLine; 54 | 55 | /** 56 | 轴的颜色 57 | */ 58 | @property (nonatomic, strong) UIColor *axisColor; 59 | 60 | /** 61 | 轴线粗细程度 62 | */ 63 | @property (nonatomic, assign) CGFloat axisLineWidth; 64 | 65 | /** 66 | 轴上文案x方向偏移量. x轴默认是0, y轴默认是5. 67 | */ 68 | @property (nonatomic, assign) CGFloat xLabelOffset; 69 | 70 | /** 71 | 轴上文案y方向偏移量, 负值表示向上偏移. x轴默认是5, y轴默认是0. 72 | */ 73 | @property (nonatomic, assign) CGFloat yLabelOffset; 74 | 75 | 76 | /// 是否禁止绘制轴线 77 | /// 78 | /// 默认 NO 79 | @property (nonatomic, assign) BOOL axisLineDisabled; 80 | 81 | /// 返回轴上文案区域最大需要的尺寸 82 | @property (nonatomic, assign, readwrite) CGSize requireSize; 83 | 84 | #pragma mark - 网格属性 85 | 86 | /// 网格颜色 87 | @property (nonatomic, strong) UIColor *gridColor; 88 | 89 | /// 网格线宽 90 | @property (nonatomic, assign) CGFloat gridLineWidth; 91 | 92 | @property (nonatomic, assign) BOOL gridLineEnabled; 93 | 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Protocol/CCProtocolChartDataProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolChartDataProvider.h 3 | // CCTrendCharts 4 | // 5 | // 数据提供者, 提供必备数据, 例如当前数据集的最大值最小值, 6 | // 这里具体实现的类, 要提供图表可视范围内的最值, 还是全部数据的最值, 取决于具体的类, 视图渲染的时候, 7 | // 采集的数据来自DataProvider, 所以实现这个协议的类最终会影响绘制结果. 8 | // 9 | // Created by Cocos on 2019/9/9. 10 | // Copyright © 2019 Cocos. All rights reserved. 11 | // 12 | 13 | #import 14 | #import "CCChartData.h" 15 | 16 | @protocol CCProtocolChartDataProvider 17 | @required 18 | // getTransformer 19 | 20 | // 数据源 21 | @property (nonatomic, readonly) CCChartData *data; 22 | 23 | // Y轴最大值 24 | @property (nonatomic, assign, readonly) CGFloat chartMaxY; 25 | 26 | // Y轴最小值 27 | @property (nonatomic, assign, readonly) CGFloat chartMinY; 28 | 29 | // X轴最大值 30 | @property (nonatomic, assign, readonly) CGFloat chartMaxX; 31 | 32 | // X轴最小值 33 | @property (nonatomic, assign, readonly) CGFloat chartMinX; 34 | 35 | /// 最近优先, 趋势图默认为YES, 适合趋势交易图的显示习惯 36 | @property (nonatomic, readonly) BOOL recentFirst; 37 | 38 | 39 | 40 | /** 41 | 经过2D变换之后可见的最小索引 42 | */ 43 | @property (nonatomic, assign, readonly) NSInteger lowestVisibleXIndex; 44 | 45 | 46 | /** 47 | 经过2D变换之后可见的最大索引 48 | */ 49 | @property (nonatomic, assign, readonly) NSInteger highestVisibleXIndex; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Protocol/CCProtocolChartDataSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolChartDataSet.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCProtocolBase.h" 10 | #import "CCProtocolChartDataEntityBase.h" 11 | 12 | typedef NSString *CCDataSetName; 13 | 14 | @protocol CCProtocolChartDataSet 15 | @required 16 | - (instancetype)initWithEntities:(NSArray> *)entities withName:(CCDataSetName)name; 17 | 18 | 19 | /// 计算数据集在指定范围内的最值 20 | /// @param start 起点 21 | /// @param end 终点 22 | - (void)calcMinMaxStart:(NSInteger)start End:(NSInteger)end; 23 | 24 | 25 | /// 获取指定index的实体, 这里index就是对应的x-index 26 | /// @param index x轴上的索引 27 | - (NSArray> *)entityForIndex:(NSInteger)index; 28 | 29 | /** 30 | 具体的数据信息 31 | 32 | 注意: 为了简化运算, 线形图等实体之间有前后关系的, 要求xIndex和实体在数组中的索引一一匹配. 33 | */ 34 | @property (nonatomic, strong) NSArray> *entities; 35 | 36 | 37 | /** 38 | 数据集名字, 用户可以自定义, 方便通过名字获取集合, 名字必须唯一的. 39 | */ 40 | @property (nonatomic, copy) CCDataSetName name; 41 | 42 | 43 | /** 44 | 绘制的颜色信息, 默认白色 45 | */ 46 | @property (nonatomic, strong) UIColor *color; 47 | 48 | /** 49 | 数据集中最小的y值 50 | */ 51 | @property (nonatomic, readonly, assign) CGFloat minY; 52 | 53 | 54 | /** 55 | 数据集中最大的y值 56 | */ 57 | @property (nonatomic, readonly, assign) CGFloat maxY; 58 | 59 | 60 | @property (nonatomic, readonly, assign) NSInteger minX; 61 | 62 | 63 | @property (nonatomic, readonly, assign) NSInteger maxX; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Protocol/CCProtocolCursorBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolCursorBase.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/5. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolBase.h" 11 | 12 | @protocol CCProtocolCursorBase 13 | 14 | 15 | 16 | /// X轴上文案的y方向偏移量 17 | /// 18 | /// 默认值 0 19 | @property (nonatomic, assign) CGFloat xAxisYLabelOffset; 20 | 21 | /// Y轴上文案的y方向偏移量 22 | /// 23 | /// 默认值 0 24 | @property (nonatomic, assign) CGFloat yAxisYLabelOffset; 25 | 26 | /// 指示器颜色 27 | @property (nonatomic, strong) UIColor *lineColor; 28 | 29 | /// 文本颜色 30 | @property (nonatomic, strong) UIColor *labelColor; 31 | 32 | /// 字体 33 | @property (nonatomic, strong) UIFont *font; 34 | 35 | /// 线宽 36 | @property (nonatomic, assign) CGFloat lineWidth; 37 | 38 | /// CGContext - setLineDash 39 | @property (nonatomic, assign) CGFloat lineDashPhase; 40 | 41 | @property (nonatomic, strong) NSArray *lineDashLengths; 42 | 43 | @property (nonatomic, assign) CGLineCap lineCap; 44 | 45 | 46 | /// 提供震动反馈, 默认是UIImpactFeedbackStyleLight类型 47 | @property (nonatomic, strong) UIImpactFeedbackGenerator *impactFeedback API_AVAILABLE(ios(10.0)); 48 | 49 | 50 | /// 震动强度, 取值0.0 ~ 1.0 51 | @property (nonatomic, assign) CGFloat intensity API_AVAILABLE(ios(13.0)); 52 | 53 | 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Protocol/CCProtocolKLineChartDataProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolKLineChartDataProvider.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/19. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolChartDataProvider.h" 11 | #import "CCKLineChartData.h" 12 | #import "CCTAIConfig.h" 13 | 14 | @protocol CCProtocolKLineChartDataProvider 15 | @required 16 | 17 | @property (nonatomic, strong, readonly) CCKLineChartData *klineChartData; 18 | 19 | @property (nonatomic, strong, readonly) CCTAIConfig *TAIConfig; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Protocol/CCProtocolTAIDataSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolTAIDataSet.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/29. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCProtocolChartDataSet.h" 10 | 11 | /// 技术指标数据集 technical analysis indicators 12 | @protocol CCProtocolTAIDataSet 13 | 14 | /// 计算指标数值(该方法暂时无效) 15 | /// @param rawEntities 新追加的原生数据 16 | - (void)calcIndicatorUseAppending:(NSArray> *)rawEntities; 17 | 18 | - (instancetype)initWithRawEntities:(NSArray> *)rawEntities N:(id)N; 19 | 20 | /// 把原生数据转成对应的指标数据 21 | /// 22 | /// 在这里实现了具体的指标算法 23 | /// @param rawEntities 原生数据 24 | /// @param N 指标信息 (例如N日均线) 25 | + (NSArray> *)rawEntitiesToEntities:(NSArray> *)rawEntities N:(id)N; 26 | 27 | /// 指标用于展示的名字 28 | @property (nonatomic, strong) NSString *label; 29 | 30 | @property (nonatomic, strong) UIFont *font; 31 | 32 | /// 数值格式化 33 | @property (nonatomic, strong) NSNumberFormatter *formatter; 34 | 35 | /// 指标右间距 36 | @property (nonatomic, assign) CGFloat rightInterval; 37 | 38 | /// 具体指标 (如: MA5, MA10) 39 | @property (nonatomic, strong) id N; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/Protocol/Entity/CCProtocolChartDataEntityBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolChartDataEntityBase.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/24. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCProtocolBase.h" 10 | 11 | 12 | /** 13 | 所有实体都需要实现基础协议 14 | */ 15 | @protocol CCProtocolChartDataEntityBase 16 | 17 | /** 18 | 实体附加信息, 一般用于扩展信息 19 | */ 20 | @property (nonatomic, strong) id data; 21 | 22 | 23 | /** 24 | 实体的值, 一般就是对应到y轴上的值 25 | */ 26 | @property (nonatomic, assign) CGFloat value; 27 | 28 | 29 | /** 30 | 实体对应的x坐标 31 | */ 32 | @property (nonatomic, assign) NSInteger xIndex; 33 | 34 | 35 | /// 每一个实体都有各自的时间信息 36 | @property (nonatomic, assign) NSTimeInterval timeInt; 37 | 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/TAIDataSet/CCLineMADataSet.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCLineMADataSet.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/29. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCLineChartDataSet.h" 10 | #import "CCProtocolTAIDataSet.h" 11 | 12 | #import "CCKLineDataEntity.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /// MA指标 (Moving average) 17 | @interface CCLineMADataSet : CCLineChartDataSet 18 | 19 | - (instancetype)initWithRawEntities:(NSArray *)rawEntities N:(id)N NS_DESIGNATED_INITIALIZER; 20 | 21 | - (instancetype)initWithEntities:(NSArray *)entities withName:(nullable CCDataSetName)name NS_UNAVAILABLE; 22 | 23 | + (nullable NSArray> *)rawEntitiesToEntities:(NSArray *)rawEntities N:(id)N; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/DataProvider/TAIDataSet/CCLineMADataSet.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCLineMADataSet.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/29. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCLineMADataSet.h" 10 | 11 | @implementation CCLineMADataSet 12 | @synthesize label = _label; 13 | @synthesize N = _N; 14 | @synthesize font = _font; 15 | @synthesize rightInterval = _rightInterval; 16 | @synthesize formatter = _formatter; 17 | 18 | - (instancetype)initWithRawEntities:(NSArray *)rawEntities N:(id)N { 19 | id e = [CCLineMADataSet rawEntitiesToEntities:rawEntities N:N]; 20 | 21 | self = [super initWithEntities:e withName:kCCNameLineDataSet]; 22 | if (self) { 23 | _N = N; 24 | _font = [UIFont systemFontOfSize:10]; 25 | _rightInterval = 8; 26 | _formatter = [[NSNumberFormatter alloc] init]; 27 | _formatter.minimumFractionDigits = 2; 28 | _formatter.maximumFractionDigits = 2; 29 | } 30 | return self; 31 | } 32 | 33 | #pragma mark - CCProtocolTAIDataSet 34 | 35 | - (void)calcIndicatorUseAppending:(NSArray *)rawEntities { 36 | // 该方法暂时无效, 一旦数据更新了, 指标都是重新计算的, 暂时没有发现性能问题, 所以改方法暂时为空 37 | } 38 | 39 | + (NSArray > *)rawEntitiesToEntities:(NSArray *)rawEntities N:(id)N { 40 | // 根据当前的N值, 计算出均线信息 41 | NSInteger n = [N intValue]; 42 | if (n == 0) { 43 | return nil; 44 | } 45 | 46 | NSMutableArray *ret = @[].mutableCopy; 47 | // 当前计算的位置 48 | NSInteger loc = 0; 49 | for (NSInteger i = loc; i <= (NSInteger)rawEntities.count - n; i++) { 50 | CGFloat sum = 0; 51 | 52 | for (NSInteger j = i; j < i + n; j++) { 53 | // 这里直接取value字段, 具体的value字段返回值是什么由实体自行实现 54 | // 例如, k线实体, value返回的是对应的closing属性. 交易量实体返回的是volume属性 55 | sum += rawEntities[j].value; 56 | } 57 | 58 | CCChartDataEntity *e = [[CCChartDataEntity alloc] initWithValue:sum / n xIndex:rawEntities[loc].xIndex data:nil]; 59 | e.timeInt = rawEntities[loc].timeInt; 60 | [ret addObject:e]; 61 | loc++; 62 | } 63 | 64 | return ret; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Formatter/CCXAxisDefaultFormatter.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCXAxisDefaultFormatter.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolXAxisFormatterBase.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface CCXAxisDefaultFormatter : NSObject 15 | 16 | - (instancetype)init; 17 | 18 | 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Formatter/CCXAxisDefaultFormatter.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCXAxisDefaultFormatter.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCXAxisDefaultFormatter.h" 10 | 11 | @interface CCXAxisDefaultFormatter () 12 | 13 | @property (nonatomic, assign) NSUInteger modulus; 14 | 15 | @end 16 | 17 | @implementation CCXAxisDefaultFormatter 18 | @synthesize modulusStartIndex = _modulusStartIndex; 19 | @synthesize minModulus = _minModulus; 20 | 21 | - (instancetype)init { 22 | self = [super init]; 23 | if (self) { 24 | _modulusStartIndex = 0; 25 | _modulus = 6; 26 | } 27 | return self; 28 | } 29 | 30 | /** 31 | 默认的实现, 简单返回原来的字符串 32 | */ 33 | - (NSString *)stringForIndex:(NSInteger)index origin:(NSString *)origin { 34 | return origin; 35 | } 36 | 37 | - (BOOL)needToDrawLabelAt:(NSInteger)index { 38 | 39 | if (index >= self.modulusStartIndex && 40 | (index - self.modulusStartIndex) % self.modulus == 0) { 41 | return YES; 42 | } 43 | 44 | return NO; 45 | } 46 | 47 | /// 更新当前的modules, 防止x轴文案重叠 48 | - (void)calcModulusWith:(CGFloat)contentWidth xSpace:(CGFloat)space labelSize:(CGSize)size { 49 | // 计算出可见区域一共可以绘制多少个文案 50 | NSInteger count = ceil(contentWidth / fabs(space)); 51 | 52 | 53 | // 为了避免label太密集, 这里假设label的宽度更长一些 54 | CGSize hhh = [@"hhh" sizeWithAttributes:nil]; 55 | size.width += hhh.width; 56 | 57 | // 总宽度需要乘以放大系数 58 | self.modulus = MAX(ceil(count * size.width / contentWidth), self.minModulus); 59 | } 60 | 61 | #pragma mark NSCopying 62 | - (id)copyWithZone:(NSZone *)zone { 63 | typeof(self) fat = [[self.class allocWithZone:zone] init]; 64 | fat.modulus = self.modulus; 65 | fat.modulusStartIndex = self.modulusStartIndex; 66 | fat.minModulus = self.minModulus; 67 | 68 | return fat; 69 | } 70 | @end 71 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Formatter/CCXAxisFixedFormatter.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCXAxisFixedFormatter.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/4. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCXAxisDefaultFormatter.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CCXAxisFixedFormatter : CCXAxisDefaultFormatter 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Formatter/CCXAxisFixedFormatter.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCXAxisFixedFormatter.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/4. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCXAxisFixedFormatter.h" 10 | 11 | @implementation CCXAxisFixedFormatter 12 | 13 | - (void)calcModulusWith:(CGFloat)contentWidth xSpace:(CGFloat)space labelSize:(CGSize)size { 14 | // 用户设置了modulus之后, 固定不改变. 15 | } 16 | 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Formatter/Protocol/CCProtocolXAxisFormatterBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolFormatterBase.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolAxisBase.h" 11 | 12 | // X轴上的文案信息不像Y轴, 应该理解成是用户是否自行定义文案样式, 而不一定是数值 13 | @protocol CCProtocolXAxisFormatterBase 14 | 15 | 16 | /** 17 | 根据传入的x轴信息和原始字符串, 返回对应格式化后的字符串 18 | 19 | @param index x轴索引 20 | @param origin 原始字符串 21 | @return 格式化后的字符串 22 | */ 23 | - (NSString *)stringForIndex:(NSInteger)index origin:(NSString *)origin; 24 | 25 | 26 | /** 27 | 是否需要绘制指定index的文案 28 | 29 | @param index 数据实体的索引 30 | @return 是否需要绘制文案 31 | */ 32 | - (BOOL)needToDrawLabelAt:(NSInteger)index; 33 | 34 | 35 | /// 更新当前的modulus 36 | - (void)calcModulusWith:(CGFloat)contentWidth xSpace:(CGFloat)space labelSize:(CGSize)size; 37 | 38 | 39 | /** 40 | modulus参数生效的起始位置 41 | */ 42 | @property (nonatomic, assign) NSInteger modulusStartIndex; 43 | 44 | 45 | /** 46 | 模, 自动计算 47 | 48 | 索引 % modulus == 0 时, 对应的文案才会被绘制 49 | */ 50 | @property (nonatomic, assign, readonly) NSUInteger modulus; 51 | 52 | 53 | /// 用户可以设置最小间隔, 防止缩小时太过密集 54 | @property (nonatomic, assign) NSUInteger minModulus; 55 | 56 | @end 57 | 58 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Gesture/CCChartTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartTransformer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/19. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCChartViewPixelHandler.h" 11 | 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | /** 16 | 该类用于实现元素坐标变换 17 | */ 18 | @interface CCChartTransformer : NSObject 19 | 20 | - (instancetype)initWithViewPixelHandler:(CCChartViewPixelHandler *)viewPixelHandler; 21 | 22 | /** 23 | 更新标准矩阵, 用于确定数据实体和实体之间的规则; 24 | 实体的序号就是实体在x轴上的初始值, 例如最一个实体a序号是0, a应用标准矩阵之后x轴的位置还是0, 0*matrix.a = 0 25 | 第二个实体b,序号是1, 应用标准矩阵之后在x轴的位置就是1*matrix.a; 26 | 第三个实体c, 序号是2, 应用标准矩阵之后在x轴的位置就是2*matrix.a; 27 | 从这里可以看出来标准矩阵matrix中a位置的数值其实就是两个相邻实体的距离. 28 | 29 | 标准矩阵一般有如下用法: 30 | 31 | 1. 绘制x轴的label 32 | 33 | 绘制x轴文本信息时, 主要关心的是两个数据实体中心轴之间的距离.每一个数据实体的中心轴, 也是这个实体在x轴上的label的中心点, 34 | 也称为label的锚点. 35 | 只有提供中心轴距离信息, 才能确定绘制第n个实体时对应的label锚点在哪儿. 36 | 37 | 2. 绘制数据实体 38 | 39 | 这个是显而易见的, 绘制实体肯定是需要知道实体的中心轴. 40 | 如果实体的形状是点(如折线图), 那么这个点就坐落在中心轴上. 41 | 如果实体的形状是矩形(如K线图), 那么这个矩形的中心坐落在中心轴上. 42 | 43 | @param matrix 新矩阵 44 | */ 45 | - (void)refreshMatrix:(CGAffineTransform)matrix; 46 | 47 | 48 | /** 49 | 更新偏差矩阵 50 | 51 | 偏差矩阵一般有如下用法: 52 | 1. 纠正数据实体的位置 53 | 54 | 比如x轴上的第一个数据实体序号0, 初始点就是(x=0, y=0), 这个点其实是在视图的左上角. 为了让这个点 55 | 落到曲线图坐标系的原点(中学数学的笛卡尔坐标系, 不是iOS系统视图坐标系), 所以初始点应用上偏差矩阵之后就会坐落在笛卡尔坐标系原点了. 56 | 57 | 假设没有缩放操作. 则每一个点的真实位置就是应用 "标准矩阵*偏差矩阵" 的矩阵之后得到得值, 就是真实位置. 58 | 59 | 60 | @param offsetMatrix 新矩阵 61 | */ 62 | - (void)refreshOffsetMatrix:(CGAffineTransform)offsetMatrix; 63 | 64 | 65 | 66 | /** 67 | 传入一个点, 返回映射后的真实坐标位置 68 | 69 | @param point 原始的点 70 | @param phaseY 动画阶段, 取值范围 0 ~ 1 (当前版本暂不支持动画, 该参数无效) 71 | @return 映射之后的点 72 | */ 73 | - (CGPoint)pointToPixel:(CGPoint)point forAnimationPhaseY:(CGFloat)phaseY; 74 | 75 | 76 | /** 77 | 传入一个矩形, 返回映射后的真实坐标位置 78 | 79 | @param rect 原始的矩形 80 | @param phaseY 动画阶段, 取值范围 0 ~ 1 (当前版本暂不支持动画, 该参数无效) 81 | @return 映射之后的矩形 82 | */ 83 | - (CGRect)rectToPixel:(CGRect)rect forAnimationPhaseY:(CGFloat)phaseY; 84 | 85 | 86 | /// 作用和pointToPixel:forAnimationPhaseY:相反 87 | - (CGPoint)pixelToPoint:(CGPoint)pixel forAnimationPhaseY:(CGFloat)phaseY; 88 | 89 | /// 作用和rectToPixel:forAnimationPhaseY:相反 90 | - (CGRect)pixelToRect:(CGRect)pixel forAnimationPhaseY:(CGFloat)phaseY; 91 | 92 | 93 | /// 传入y方向最大最小值, 计算标准矩阵x,y两个方向的信息 94 | /// @param minY 最大y值 95 | /// @param maxY 最小y值 96 | /// @param startMargin 起点边缘 97 | /// @param xSpace 轴间距 98 | /// @param recentFirst 数据展示模式 99 | - (CGAffineTransform)calcMatrixWithMinValue:(CGFloat)minY maxValue:(CGFloat)maxY startMargin:(CGFloat)startMargin xSpace:(CGFloat)xSpace rentFirst:(BOOL)recentFirst; 100 | 101 | 102 | 103 | /// 单独计算y方向矩阵信息 104 | /// @param minY 最小y 105 | /// @param maxY 最大y 106 | - (CGAffineTransform)calcMatrixOrientationYWithMinValue:(CGFloat)minY maxValue:(CGFloat)maxY; 107 | 108 | /// 返回指定数量的实体之间的距离 109 | /// @param indexCount 实体数量 110 | - (CGFloat)distanceBetweenSpace:(CGFloat)indexCount; 111 | 112 | /** 113 | 输出最终的变换矩阵, 可以直接作用转换元素的像素位置, 如有需要请直接使用该变量 114 | */ 115 | @property (nonatomic, readonly) CGAffineTransform valueToPixelMatrix; 116 | 117 | 118 | /// 用于从指定的像素中取得实际对应的数据实体索引, 如有需要请直接使用该变量 119 | @property (nonatomic, readonly) CGAffineTransform pixelToValueMatrix; 120 | 121 | @end 122 | 123 | NS_ASSUME_NONNULL_END 124 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Gesture/CCChartViewPixelHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartViewPixelHandler.h 3 | // CCTrendCharts 4 | // 5 | // 所有放大缩小操作都会作用到Handler对象上 6 | // 7 | // Created by Cocos on 2019/9/9. 8 | // Copyright © 2019 Cocos. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface CCChartViewPixelHandler : NSObject 16 | 17 | - (void)resetGestureMatrix; 18 | 19 | - (BOOL)isInBounds:(CGPoint)point; 20 | 21 | - (BOOL)isInBoundsLeft:(CGFloat)y; 22 | 23 | - (BOOL)isInBoundsRight:(CGFloat)y; 24 | 25 | - (BOOL)isInBoundsTop:(CGFloat)y; 26 | 27 | - (BOOL)isInBoundsBottom:(CGFloat)y; 28 | 29 | /// 是否正处于平移或者缩放状态 30 | - (BOOL)isGestureProcessing; 31 | 32 | - (void)updateContentRectOffsetLeft:(CGFloat)offsetLeft offsetRight:(CGFloat)offsetRight offsetTop:(CGFloat)offsetTop offsetBottom:(CGFloat)offsetBottom; 33 | 34 | /** 35 | 直接缩放当前矩阵 36 | 37 | @param scaleX x轴 38 | @param scaleY y轴 39 | */ 40 | - (CGAffineTransform)zoomScaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY; 41 | 42 | 43 | /** 44 | 返回围绕指定中心点放大缩小的矩阵 (不影响原来矩阵) 45 | 46 | @param scaleX x轴 47 | @param scaleY y轴 48 | @param center 中心点 49 | */ 50 | - (CGAffineTransform)zoomScaleX:(CGFloat)scaleX scaleY:(CGFloat)scaleY aroundCenter:(CGPoint)center; 51 | 52 | 53 | /** 54 | 返回围绕center放大固定比例的矩阵 (不影响原来矩阵) 55 | 56 | @param center 中心点 57 | */ 58 | - (CGAffineTransform)zoomInAroundCenter:(CGPoint)center; 59 | 60 | /** 61 | 返回围绕center放大固定比例的矩阵 (不影响原来矩阵) 62 | 63 | @param center 中心点 64 | */ 65 | - (CGAffineTransform)zoomOutAroundCenter:(CGPoint)center; 66 | 67 | 68 | 69 | /** 70 | 手势矩阵, 主要用于存放缩放平移操作的信息 71 | */ 72 | @property (nonatomic, assign) CGAffineTransform gestureMatrix; 73 | 74 | 75 | /// 初始矩阵, 用于确定当前整体缩放平移效果是否为原始效果 76 | @property (nonatomic, assign) CGAffineTransform anInitMatrix; 77 | 78 | /** 79 | 视图的总大小(含两轴上的文字信息) 80 | */ 81 | @property (nonatomic, assign) CGRect viewFrame; 82 | 83 | @property (nonatomic, assign, readonly) CGFloat viewWidth; 84 | 85 | @property (nonatomic, assign, readonly) CGFloat viewHeight; 86 | 87 | /** 88 | 趋势图的可绘制部分, 也可以理解为画图的大小 89 | */ 90 | @property (nonatomic, assign) CGRect contentRect; 91 | 92 | @property (nonatomic, assign, readonly) CGFloat contentWidth; 93 | 94 | @property (nonatomic, assign, readonly) CGFloat contentHeight; 95 | 96 | 97 | // 定义其他放大缩小的方法, 用于改变CGAffineTransform结构体信息 98 | 99 | 100 | /** 101 | 当前Y轴缩放比例, 默认为1, 暂时不支持y轴缩放 102 | */ 103 | @property (nonatomic, assign, readonly) CGFloat scaleY; 104 | 105 | 106 | /** 107 | 当前X轴缩放比例, 默认为1 108 | */ 109 | @property (nonatomic, assign, readonly) CGFloat scaleX; 110 | 111 | 112 | /** 113 | 当前x轴的平移, 默认是0 114 | */ 115 | @property (nonatomic, assign, readonly) CGFloat transX; 116 | 117 | 118 | /** 119 | Y轴最大缩放比例, 默认为2 120 | */ 121 | @property (nonatomic, assign, readonly) CGFloat maxScaleY; 122 | 123 | 124 | /** 125 | X轴最大缩放比例, 默认为2 126 | */ 127 | @property (nonatomic, assign, readonly) CGFloat maxScaleX; 128 | 129 | /** 130 | Y轴最小缩放比例, 默认为0.3 131 | */ 132 | @property (nonatomic, assign, readonly) CGFloat minScaleY; 133 | 134 | 135 | /** 136 | X轴最小缩放比例, 默认为0.3 137 | */ 138 | @property (nonatomic, assign, readonly) CGFloat minScaleX; 139 | 140 | 141 | 142 | /** 143 | 第一象限区域左侧 144 | */ 145 | @property (nonatomic, assign, readonly) CGFloat contentLeft; 146 | 147 | /** 148 | 第一象限区域右侧 149 | */ 150 | @property (nonatomic, assign, readonly) CGFloat contentRight; 151 | 152 | /** 153 | 第一象限区域上侧 154 | */ 155 | @property (nonatomic, assign, readonly) CGFloat contentTop; 156 | 157 | /** 158 | 第一象限区域下侧 159 | */ 160 | @property (nonatomic, assign, readonly) CGFloat contentBottom; 161 | 162 | 163 | /** 164 | 左侧Y轴到视图左边的距离 165 | */ 166 | @property (nonatomic, assign, readonly) CGFloat offsetLeft; 167 | 168 | 169 | /** 170 | 右侧Y轴到视图右边的距离 171 | */ 172 | @property (nonatomic, assign, readonly) CGFloat offsetRight; 173 | 174 | 175 | /** 176 | 第一象限绘制区域顶部到视图顶部的距离 177 | */ 178 | @property (nonatomic, assign, readonly) CGFloat offsetTop; 179 | 180 | 181 | /** 182 | 第一象限绘制区域底部到视图底部的距离 183 | */ 184 | @property (nonatomic, assign, readonly) CGFloat offsetBottom; 185 | 186 | @end 187 | 188 | NS_ASSUME_NONNULL_END 189 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Gesture/CCGestureDefaultHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCGestureDefaultHandler.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/10/24. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCGestureHandlerProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface CCGestureDefaultHandler : NSObject 15 | 16 | /// 初始化方法 17 | - (instancetype)initWithTransformer:(CCChartViewPixelHandler *)viewPixelHandler; 18 | 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Gesture/Protocol/CCGestureHandlerProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCGestureDefaultHandlerProtocol.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/10/24. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCProtocolBase.h" 10 | #import "CCChartViewPixelHandler.h" 11 | 12 | @protocol CCGestureHandlerDelegate 13 | 14 | 15 | /// 进行缩放操作 16 | /// @param point 缩放的中心点 17 | /// @param matrix 缩放的内容 18 | - (void)gestureDidPinchInLocation:(CGPoint)point matrix:(CGAffineTransform)matrix; 19 | 20 | 21 | /// 缩放操作结束 22 | /// @param point 缩放的中心点 23 | /// @param matrix 缩放的内容 24 | - (void)gestureDidEndPinchInLocation:(CGPoint)point matrix:(CGAffineTransform)matrix; 25 | 26 | 27 | /// 进行滚动操作 28 | - (void)gestureDidPanIncrementOffset:(CGPoint)point matrix:(CGAffineTransform)matrix; 29 | 30 | 31 | /// 正在进行长按+滚动操作 32 | /// @param point 长按中心 33 | - (void)gestureDidLongPressInLocation:(CGPoint)point; 34 | 35 | /// 结束长按操作 36 | - (void)gestureDidEndLongPressInLocation:(CGPoint)point; 37 | 38 | @end 39 | 40 | 41 | @protocol CCGestureHandlerProtocol 42 | 43 | 44 | /// 平移手势触发 45 | - (void)panGestureChange:(UIPanGestureRecognizer *)gr; 46 | 47 | /// 长按手势触发 48 | - (void)longPressGestureStateChanging:(UILongPressGestureRecognizer *)gr; 49 | 50 | /// 双击手势触发 51 | - (void)doubleTapGestureStateChanging:(UITapGestureRecognizer *)gr; 52 | 53 | /// 单击手势触发 54 | - (void)tapGestureStateChanging:(UITapGestureRecognizer *)gr; 55 | 56 | /// 双指缩放触发 57 | - (void)pinchGestureStateChanging:(UIPinchGestureRecognizer *)gr; 58 | 59 | /// 滚动事件 60 | - (void)didScrollIncrementOffsetX:(CGFloat)incrementOffsetX; 61 | 62 | 63 | 64 | @property (nonatomic, weak) CCChartViewPixelHandler *viewPixelHandler; 65 | 66 | @property (nonatomic, weak) UIView *baseView; 67 | 68 | /// 提供一个用于缩放的手势 69 | @property (nonatomic, readonly) UIPinchGestureRecognizer *pinchGesture; 70 | 71 | /// 提供一个长按的手势 72 | @property (nonatomic, readonly) UILongPressGestureRecognizer *longPressGesture; 73 | 74 | @property (nonatomic, weak) iddelegate; 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCBarDataChartRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCBarDataChartRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCDataChartRenderer.h" 10 | #import "CCBarChartDataSet.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface CCBarDataChartRenderer : CCDataChartRenderer 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCBarDataChartRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCBarDataChartRenderer.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCBarDataChartRenderer.h" 10 | #import "CCRendererBase+LayerCache.h" 11 | 12 | @implementation CCBarDataChartRenderer 13 | - (instancetype)initWithViewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer DataProvider:(id)dataProvider { 14 | self = [super initWithViewHandler:viewPixelHandler transform:transformer DataProvider:dataProvider]; 15 | if (self) { 16 | [self cc_registerLayerMaker:^__kindof CALayer *_Nonnull { 17 | return CAShapeLayer.layer; 18 | } forKey:NSStringFromClass(CAShapeLayer.class)]; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)renderData:(CALayer *)contentLayer { 24 | [self cc_releaseAllLayerBackToBufferPool]; 25 | 26 | CCChartData *data = self.dataProvider.data; 27 | CCBarChartDataSet *dataSet = [[data dataSetWithName:kCCNameBarDataSet] lastObject]; 28 | if (dataSet == nil) { 29 | return; 30 | } 31 | 32 | CGFloat barWidth = fabs([self.transformer distanceBetweenSpace:dataSet.entityDistancePercent]); 33 | CGFloat halfBarWidth = barWidth / 2; 34 | 35 | CAShapeLayer *layer = [self cc_requestLayersCacheWithMakerKey:NSStringFromClass(CAShapeLayer.class)]; 36 | [CALayer quickUpdateLayer:^{ 37 | layer.frame = self.viewPixelHandler.contentRect; 38 | [contentLayer addSublayer:layer]; 39 | }]; 40 | 41 | UIBezierPath *path = UIBezierPath.bezierPath; 42 | 43 | for (NSInteger i = 0; i < dataSet.entities.count; i++) { 44 | id entity = dataSet.entities[i]; 45 | CGPoint pixel = [self.transformer pointToPixel:CGPointMake(i, entity.value) forAnimationPhaseY:1]; 46 | if ([self.viewPixelHandler isInBoundsLeft:pixel.x + halfBarWidth] && [self.viewPixelHandler isInBoundsRight: pixel.x - halfBarWidth]) { 47 | // 这里画一个圆角矩形 48 | [path appendPath:[UIBezierPath bezierPathWithRoundedRect:[contentLayer convertRect:CGRectMake(pixel.x - halfBarWidth, pixel.y,barWidth, self.viewPixelHandler.contentBottom - pixel.y) toLayer:layer] cornerRadius:halfBarWidth]]; 49 | } 50 | } 51 | 52 | [CALayer quickUpdateLayer:^{ 53 | layer.path = path.CGPath; 54 | layer.fillColor = dataSet.color.CGColor; 55 | layer.masksToBounds = YES; 56 | }]; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCDataChartRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDataRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/13. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCRendererBase.h" 10 | #import "CCProtocolDataChartRenderer.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface CCDataChartRenderer : CCRendererBase 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCDataChartRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCDataRenderer.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/13. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCDataChartRenderer.h" 10 | 11 | @implementation CCDataChartRenderer 12 | 13 | - (void)renderData:(CALayer *)contentLayer { 14 | // 什么都不做 15 | } 16 | 17 | - (void)renderDataSet:(CALayer *)contentLayer dataSet:(id)dataSet { 18 | // 什么都不做 19 | } 20 | 21 | - (void)renderHighlighted:(CAShapeLayer *)contentLayer { 22 | // 什么都不做 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCDefaultCursorRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultCursorRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/4. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCRendererBase.h" 12 | #import "CCProtocolCursorRenderer.h" 13 | #import "CCDefaultYAxis.h" 14 | #import "CCDefaultXAxis.h" 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | @interface CCDefaultCursorRenderer : CCRendererBase 19 | 20 | - (instancetype)init NS_UNAVAILABLE; 21 | 22 | - (instancetype)initWithCursor:(id)cursor viewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer DataProvider:(id)dataProvider; 23 | 24 | 25 | @property (nonatomic, weak) CCDefaultYAxis *leftAxis; 26 | 27 | @property (nonatomic, weak) CCDefaultYAxis *rightAxis; 28 | 29 | @property (nonatomic, weak) CCDefaultXAxis *xAxis; 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCDefaultMarkerRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultMarkerRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/7. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCRendererBase.h" 12 | #import "CCProtocolMarkerRenderer.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface CCDefaultMarkerRenderer : CCRendererBase 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCDefaultMarkerRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultMarkerRenderer.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/7. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCDefaultMarkerRenderer.h" 10 | #import "CCChartDataEntity.h" 11 | 12 | @interface CCDefaultMarkerRenderer () { 13 | // 0 左, 1 右 14 | BOOL _currentMarkerSied; 15 | } 16 | 17 | @end 18 | 19 | @implementation CCDefaultMarkerRenderer 20 | 21 | - (instancetype)initWithViewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer DataProvider:(id)dataProvider { 22 | self = [super initWithViewHandler:viewPixelHandler transform:transformer DataProvider:dataProvider]; 23 | if (self) { 24 | _currentMarkerSied = 1; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)beginRenderingInLayer:(CALayer *)contentLayer atIndex:(NSInteger)index { 31 | // 获取当前index下完整的实体 32 | CCChartData *charData = self.dataProvider.data; 33 | CCChartDataEntity *entity = [[charData entitiesForIndex:index] lastObject]; 34 | 35 | // 作为示例, 这里简单绘制一下标记 36 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 37 | CGContextSaveGState(ctx); 38 | { 39 | NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init]; 40 | fmt.maximumFractionDigits = 4; 41 | fmt.minimumFractionDigits = 4; 42 | 43 | NSDateFormatter *dateFmt = [[NSDateFormatter alloc] init]; 44 | dateFmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh-Hans"]; 45 | dateFmt.dateFormat = @"yyyy/MM/dd HH:mm:ss EEEE"; 46 | 47 | NSString *yText = [fmt stringFromNumber:@(entity.value)]; 48 | NSString *xTest = [NSString stringWithFormat:@"第:%@个", @(entity.xIndex)]; 49 | NSString *title = [dateFmt stringFromDate:[NSDate dateWithTimeIntervalSince1970:entity.timeInt]]; 50 | UIFont *titleFont = [UIFont systemFontOfSize:10]; 51 | CGSize titleSize = [title sizeWithAttributes:@{ NSFontAttributeName: titleFont }]; 52 | 53 | // 标记的矩形尺寸 54 | CGRect rect = CGRectMake(0, self.viewPixelHandler.contentTop, titleSize.width, (titleSize.height + 8) * 3); 55 | 56 | if ([self.transformer pointToPixel:CGPointMake(index, 0) forAnimationPhaseY:1].x > self.viewPixelHandler.contentRight - rect.size.width) { 57 | rect.origin.x = self.viewPixelHandler.contentLeft; 58 | _currentMarkerSied = 0; 59 | } else if ([self.transformer pointToPixel:CGPointMake(index, 0) forAnimationPhaseY:1].x < self.viewPixelHandler.contentLeft + rect.size.width) { 60 | rect.origin.x = self.viewPixelHandler.contentRight - rect.size.width; 61 | _currentMarkerSied = 1; 62 | } else { 63 | if (_currentMarkerSied) { 64 | rect.origin.x = self.viewPixelHandler.contentRight - rect.size.width; 65 | } else { 66 | rect.origin.x = self.viewPixelHandler.contentLeft; 67 | } 68 | } 69 | 70 | CGContextSetFillColorWithColor(ctx, UIColor.grayColor.CGColor); 71 | CGContextAddRect(ctx, rect); 72 | CGContextFillPath(ctx); 73 | 74 | [title drawTextIn:ctx x:rect.origin.x y:rect.origin.y anchor:CGPointMake(0, 0) attributes:@{ NSFontAttributeName: titleFont }]; 75 | [xTest drawTextIn:ctx x:rect.origin.x y:rect.origin.y + 15 anchor:CGPointZero attributes:@{ NSFontAttributeName: titleFont }]; 76 | [yText drawTextIn:ctx x:rect.origin.x y:rect.origin.y + 30 anchor:CGPointZero attributes:@{ NSFontAttributeName: titleFont }]; 77 | } 78 | CGContextRestoreGState(ctx); 79 | 80 | CGImageRef img = CGBitmapContextCreateImage(ctx); 81 | 82 | [CALayer quickUpdateLayer:^{ 83 | contentLayer.contents = (__bridge_transfer id)img; 84 | }]; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCDefaultXAxisRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultXAxisRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/12. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCRendererBase.h" 12 | #import "CCProtocolAxisRenderer.h" 13 | #import "CCDefaultXAxis.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface CCDefaultXAxisRenderer : CCRendererBase 18 | 19 | @property (nonatomic, weak) CCDefaultXAxis *axis; 20 | 21 | - (instancetype)initWithAxis:(CCDefaultXAxis *)axis viewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCDefaultYAxisRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCDefaultYAxisRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/12. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCRendererBase.h" 11 | #import "CCProtocolAxisRenderer.h" 12 | #import "CCDefaultYAxis.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface CCDefaultYAxisRenderer : CCRendererBase 17 | 18 | @property (nonatomic, weak) CCDefaultYAxis *axis; 19 | 20 | /** 21 | 传入最小, 最大值, 渲染层根据axis对象计算出y轴上的全部label 22 | 23 | @param min min 24 | @param max max 25 | */ 26 | - (void)processAxisEntities:(CGFloat)min :(CGFloat)max; 27 | 28 | 29 | - (instancetype)init NS_UNAVAILABLE; 30 | 31 | /** 32 | 指定初始化方法, 用于创建Axis渲染实例 33 | 34 | @param axis y轴数据提供者 35 | @param viewPixelHandler 视图像素处理对象 36 | @param transformer 反射对象 37 | @return instancetype 38 | */ 39 | - (instancetype)initWithAxis:(CCDefaultYAxis *)axis viewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer; 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCKLineDataChartRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineDataChartRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/13. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCDataChartRenderer.h" 11 | #import "CCProtocolKLineDataChartRenderer.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | 16 | /// K线渲染器, 用于渲染蜡烛图 17 | @interface CCKLineDataChartRenderer : CCDataChartRenderer 18 | 19 | 20 | /// 根据传入的路径渲染图层 21 | /// @param risingPath 上升路径 22 | /// @param fallingPath 下降路径 23 | /// @param flatPath 平价路径 24 | /// @param name 数据集名字 25 | /// @param contentLayer 内容图层 26 | - (void)renderDataWithRising:(UIBezierPath *)risingPath fallingPath:(UIBezierPath *)fallingPath flatPath:(UIBezierPath *)flatPath usingDataSetName:(CCDataSetName)name inContentLayer:(CALayer *)contentLayer; 27 | 28 | 29 | 30 | // 这里的访问权限本应该是"模块内"可见(internal), 不过OC并没有这种特性. 31 | @property (nonatomic, strong) CAShapeLayer *risingLayer; 32 | 33 | @property (nonatomic, strong) CAShapeLayer *fallingLayer; 34 | 35 | @property (nonatomic, strong) CAShapeLayer *flatLayer; 36 | 37 | /// 存放内容图层, 主要是为了实现遮罩效果(只显示渲染区域的内容) 38 | @property (nonatomic, strong) CALayer *subContentLayer; 39 | 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCLineDataChartRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCLineDataChartRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/22. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCDataChartRenderer.h" 10 | #import "CCLineChartDataSet.h" 11 | #import "CCLineMADataSet.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | /// 线形图渲染器 16 | @interface CCLineDataChartRenderer : CCDataChartRenderer 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCRendererBase+LayerCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCRendererBase+LayerCache.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/3. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCRendererBase.h" 11 | 12 | typedef __kindof CALayer *_Nonnull(^LayerMaker)(void); 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | 17 | /// 提供Layer缓存池, 用于快速获取layer 18 | @interface CCRendererBase (LayerCache) 19 | /// 注册图层生成器 20 | /// @param maker 图层生成器 21 | /// @param key 标记, 用于获取图层生成器 22 | - (void)cc_registerLayerMaker:(nonnull LayerMaker)maker forKey:(NSString *)key; 23 | 24 | /// 请求获取缓冲池中的图层 25 | /// @param key 指定 26 | - (__kindof CALayer *)cc_requestLayersCacheWithMakerKey:(NSString *)key; 27 | 28 | /// 释放所有图层, 将所有图层移出父图层, 但是不会从缓存池中删除 29 | - (void)cc_releaseAllLayerBackToBufferPool; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCRendererBase+LayerCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCRendererBase+LayerCache.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/3. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCRendererBase+LayerCache.h" 10 | #import 11 | 12 | static void *kLayersCache = &kLayersCache; 13 | 14 | #define kMaker @"maker" 15 | #define kLayers @"layers" 16 | #define kUsingCount @"usingCount" 17 | 18 | @implementation CCRendererBase (LayerCache) 19 | 20 | - (NSMutableDictionary *)layersCacheDic { 21 | id obj = objc_getAssociatedObject(self, kLayersCache); 22 | if (!obj) { 23 | obj = @{}.mutableCopy; 24 | objc_setAssociatedObject(self, kLayersCache, obj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 25 | } 26 | return obj; 27 | } 28 | 29 | - (CALayer *)cc_requestLayersCacheWithMakerKey:(NSString *)key { 30 | NSMutableDictionary *val = self.layersCacheDic[key]; 31 | CALayer *l = nil; 32 | 33 | if (val) { 34 | NSMutableArray *layers = val[kLayers]; 35 | NSInteger count = [val[kUsingCount] integerValue]; 36 | if (count >= layers.count) { 37 | [layers addObject:((LayerMaker)val[kMaker])()]; 38 | } 39 | l = layers[count]; 40 | val[kUsingCount] = @(count + 1); 41 | } 42 | 43 | return l; 44 | } 45 | 46 | - (void)cc_registerLayerMaker:(LayerMaker)maker forKey:(NSString *)key { 47 | if (!self.layersCacheDic[key]) { 48 | // 保存了生成器, 缓存池, 计数变量 49 | NSMutableDictionary *val = @{ kMaker: maker, kLayers: @[].mutableCopy, kUsingCount: @(0) }.mutableCopy; 50 | self.layersCacheDic[key] = val; 51 | } else { 52 | // 如果key已经存在, 则重置计数为0即可 53 | NSMutableDictionary *val = self.layersCacheDic[key]; 54 | val[kUsingCount] = @(0); 55 | } 56 | } 57 | 58 | - (void)cc_releaseAllLayerBackToBufferPool { 59 | NSEnumerator *enumerator = [self.layersCacheDic objectEnumerator]; 60 | NSMutableDictionary *val; 61 | 62 | while ((val = [enumerator nextObject])) { 63 | for (CALayer *l in val[kLayers]) { 64 | [l removeFromSuperlayer]; 65 | } 66 | val[kUsingCount] = @(0); 67 | } 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCRendererBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCRendererBase.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/13. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolChartRendererBase.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface CCRendererBase : NSObject 15 | 16 | - (instancetype)init NS_UNAVAILABLE; 17 | 18 | - (instancetype)initWithViewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer DataProvider:(nullable id)dataProvider NS_DESIGNATED_INITIALIZER; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCRendererBase.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCRendererBase.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/13. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCRendererBase.h" 10 | 11 | @implementation CCRendererBase 12 | @synthesize viewPixelHandler = _viewPixelHandler; 13 | @synthesize transformer = _transformer; 14 | @synthesize dataProvider = _dataProvider; 15 | 16 | - (instancetype)initWithViewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer DataProvider:(id)dataProvider { 17 | self = [super init]; 18 | if (self) { 19 | _viewPixelHandler = viewPixelHandler; 20 | _transformer = transformer; 21 | _dataProvider = dataProvider; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCTAILegendRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCTAILegendRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/2. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCRendererBase.h" 12 | #import "CCProtocolLegendRenderer.h" 13 | #import "CCProtocolTAIDataSet.h" 14 | 15 | #import "CCRendererBase+LayerCache.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | 20 | /// 技术指标渲染器 21 | @interface CCTAILegendRenderer : CCRendererBase 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCTAILegendRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCTAILegendRenderer.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/2. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCTAILegendRenderer.h" 10 | #import 11 | 12 | @interface CCTAILegendRenderer () { 13 | CGFloat xPos; 14 | } 15 | 16 | @end 17 | 18 | @implementation CCTAILegendRenderer 19 | - (instancetype)initWithViewHandler:(CCChartViewPixelHandler *)viewPixelHandler transform:(CCChartTransformer *)transformer DataProvider:(id)dataProvider { 20 | self = [super initWithViewHandler:viewPixelHandler transform:transformer DataProvider:dataProvider]; 21 | if (self) { 22 | [self cc_registerLayerMaker:^__kindof CALayer *_Nonnull { 23 | return CATextLayer.layer; 24 | } forKey:NSStringFromClass(CATextLayer.class)]; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)beginRenderingInLayer:(CALayer *)contentLayer atIndex:(NSInteger)index { 30 | [self cc_releaseAllLayerBackToBufferPool]; 31 | xPos = 24; 32 | int i = 0; 33 | CCChartData *data = self.dataProvider.data; 34 | for (id dataSet in data.dataSets) { 35 | if ([dataSet conformsToProtocol:@protocol(CCProtocolTAIDataSet)]) { 36 | id taiDataSet = (id)dataSet; 37 | id val; 38 | if (index < dataSet.entities.count) { 39 | val = taiDataSet.entities[index]; 40 | } 41 | 42 | CATextLayer *layer = [self cc_requestLayersCacheWithMakerKey:NSStringFromClass(CATextLayer.class)]; 43 | 44 | // 根据文案的长度设置layer的frame 45 | NSString *label; 46 | if (!val) { 47 | label = [NSString stringWithFormat:@"%@:-", taiDataSet.label]; 48 | } else { 49 | label = [NSString stringWithFormat:@"%@:%@", taiDataSet.label, [taiDataSet.formatter stringFromNumber:@(val.value)]]; 50 | } 51 | 52 | CGSize size = [label sizeWithAttributes:@{ NSFontAttributeName: taiDataSet.font }]; 53 | 54 | [CALayer quickUpdateLayer:^{ 55 | [contentLayer addSublayer:layer]; 56 | 57 | layer.frame = CGRectMake(self->xPos, 0, size.width, size.height); 58 | layer.font = (__bridge CTFontRef)taiDataSet.font; 59 | layer.fontSize = taiDataSet.font.pointSize; 60 | layer.string = label; 61 | 62 | layer.foregroundColor = taiDataSet.color.CGColor; 63 | layer.contentsScale = CCBaseUtility.currentScale; 64 | layer.alignmentMode = kCAAlignmentCenter; 65 | }]; 66 | 67 | xPos = xPos + taiDataSet.rightInterval + size.width; 68 | i++; 69 | } 70 | } 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCVolumeDataChartRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeDataChartRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCKLineDataChartRenderer.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | 14 | /// 交易量渲染器属于k线数据渲染器的一种, 直接继承k线渲染器. 15 | @interface CCVolumeDataChartRenderer : CCKLineDataChartRenderer 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/CCVolumeDataChartRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeDataChartRenderer.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCVolumeDataChartRenderer.h" 10 | 11 | @interface CCVolumeDataChartRenderer () 12 | 13 | @end 14 | 15 | @implementation CCVolumeDataChartRenderer 16 | 17 | - (void)renderData:(CALayer *)contentLayer { 18 | // 交易量柱型图的实体颜色是根据k线实体的涨跌决定的. 19 | // 所以这里和k线数据渲染器一样, 通过多个图层组合而成. 20 | CCKLineChartData *data = self.dataProvider.klineChartData; 21 | CCVolumeChartDataSet *dataSet = (CCVolumeChartDataSet *)[[data dataSetWithName:kCCVolumeChartDataSet] lastObject]; 22 | 23 | CALayer *subContentLayer = self.subContentLayer; 24 | subContentLayer.masksToBounds = YES; 25 | 26 | [CALayer quickUpdateLayer:^{ 27 | subContentLayer.frame = self.viewPixelHandler.contentRect; 28 | [contentLayer addSublayer:subContentLayer]; 29 | }]; 30 | 31 | // 一半宽的大小 32 | CGFloat halfWidth = fabs([self.transformer distanceBetweenSpace:CC_KLINE_ENTITY_DISTANCE_PERCENT / 2]); 33 | 34 | // 绘制上升路径 35 | UIBezierPath *risingPath = UIBezierPath.bezierPath; 36 | // 绘制下降路径 37 | UIBezierPath *fallingPath = UIBezierPath.bezierPath; 38 | // 用于绘制K线十字星, 这种情况比较少见, 出现了才需要绘制. 39 | UIBezierPath *flatPath = nil; 40 | 41 | // 临时路径 42 | UIBezierPath *path = UIBezierPath.bezierPath; 43 | for (CCKLineDataEntity *val in dataSet.entities) { 44 | // 先确定位置 45 | CGFloat xPos = [self.transformer pointToPixel:CGPointMake(val.xIndex, 0) forAnimationPhaseY:1].x; 46 | if (xPos + halfWidth < self.viewPixelHandler.contentLeft || xPos - halfWidth > self.viewPixelHandler.contentRight) { 47 | continue; 48 | } 49 | [path removeAllPoints]; 50 | 51 | // 柱高 52 | CGFloat yVal = val.volume; 53 | 54 | yVal = [self.transformer pointToPixel:CGPointMake(0, yVal) forAnimationPhaseY:1].y; 55 | 56 | [path moveToPoint:[subContentLayer convertPoint:CGPointMake(xPos - halfWidth, yVal) fromLayer:contentLayer]]; 57 | [path addLineToPoint:[subContentLayer convertPoint:CGPointMake(xPos + halfWidth, yVal) fromLayer:contentLayer]]; 58 | [path addLineToPoint:[subContentLayer convertPoint:CGPointMake(xPos + halfWidth, self.viewPixelHandler.contentBottom) fromLayer:contentLayer]]; 59 | [path addLineToPoint:[subContentLayer convertPoint:CGPointMake(xPos - halfWidth, self.viewPixelHandler.contentBottom) fromLayer:contentLayer]]; 60 | [path closePath]; 61 | 62 | if (val.entityState == CCKLineDataEntityStateFalling) { 63 | [fallingPath appendPath:path]; 64 | } else if (val.entityState == CCKLineDataEntityStateRising) { 65 | [risingPath appendPath:path]; 66 | } else if (val.entityState == CCKLineDataEntityStateNone) { 67 | [flatPath appendPath:path]; 68 | } 69 | } 70 | 71 | [self renderDataWithRising:risingPath fallingPath:fallingPath flatPath:flatPath usingDataSetName:kCCVolumeChartDataSet inContentLayer:subContentLayer]; 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/Protocol/CCProtocolAxisRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolAxisRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | #import 9 | 10 | #import "CCProtocolChartRendererBase.h" 11 | #import "CCProtocolAxisBase.h" 12 | 13 | @protocol CCProtocolAxisRenderer 14 | 15 | 16 | /** 17 | 渲染层直接根据axis对象进行渲染 18 | */ 19 | @property (nonatomic, weak) id axis; 20 | 21 | /** 22 | 绘制轴上的Label 23 | 24 | @param contentLayer 将数据渲染到contentLayer上 25 | */ 26 | - (void)renderLabels:(CALayer *)contentLayer; 27 | 28 | /** 29 | 绘制网格 30 | 31 | @param contentLayer 将数据渲染到contentLayer上 32 | */ 33 | - (void)renderGridLines:(CALayer *)contentLayer; 34 | 35 | 36 | /** 37 | 绘制轴线 38 | 39 | @param contentLayer 将数据渲染到contentLayer上 40 | */ 41 | - (void)renderAxisLine:(CALayer *)contentLayer; 42 | 43 | 44 | 45 | /// 便捷渲染方法 46 | /// @param contentLayer 目标层 47 | - (void)beginRenderingInLayer:(CALayer *)contentLayer; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/Protocol/CCProtocolChartRendererBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolChartRendererBase.h 3 | // CCTrendCharts 4 | // 5 | // 渲染层基础协议 6 | // 7 | // Created by Cocos on 2019/9/9. 8 | // Copyright © 2019 Cocos. All rights reserved. 9 | // 10 | 11 | #import "CCProtocolBase.h" 12 | 13 | #import "CCChartViewPixelHandler.h" 14 | #import "CCChartTransformer.h" 15 | #import "CCProtocolChartDataProvider.h" 16 | 17 | #import "CALayer+CCUtility.h" 18 | 19 | @protocol CCProtocolChartRendererBase 20 | @required 21 | // 持有一个视图操作者CCChartViewPixelHandler, 所有放大缩小平移等信息都存储在viewHandler里面的CGAffineTransform, 这样方便运算数据的最终座标 22 | @property (nonatomic, readonly) CCChartViewPixelHandler *viewPixelHandler; 23 | 24 | 25 | 26 | /** 27 | 记录和反射相关的信息, 结合CCChartViewPixelHandler对象可以运算出数据的真实坐标 28 | */ 29 | @property (nonatomic, readonly) CCChartTransformer *transformer; 30 | 31 | 32 | /// 提供给渲染层一些数据信息, 这里没有直接提供数据源是为了解偶 33 | @property (nonatomic, weak, readonly) id dataProvider; 34 | 35 | // 渲染层可以拆分成多个子类, x轴类, 左y轴类, 右y轴类, 数据渲染类, Marker渲染类(就是手指长按浮出来的标记块) 36 | // 其中每个子类由负责各种渲染, 比如x轴的负责画一条横线, 横线上的文字等 37 | 38 | // 还可以设置其它子协议, 比如最小可见x index, 最大可见x index, 这样就可以提供给渲染层, 渲染层才知道要渲染哪些数据 39 | @end 40 | 41 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/Protocol/CCProtocolCursorRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolCursorRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/4. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCProtocolChartRendererBase.h" 12 | #import "CCProtocolCursorBase.h" 13 | #import "CCProtocolAxisBase.h" 14 | 15 | @protocol CCProtocolCursorRenderer 16 | 17 | - (void)beginRenderingInLayer:(CALayer *)layer center:(CGPoint)center; 18 | 19 | - (void)renderCursor:(CALayer *)layer center:(CGPoint)center; 20 | 21 | - (void)renderXLabel:(CALayer *)layer center:(CGPoint)center; 22 | 23 | - (void)renderLeftLabel:(CALayer *)layer center:(CGPoint)center; 24 | 25 | - (void)renderRightLabel:(CALayer *)layer center:(CGPoint)center; 26 | 27 | 28 | /// 渲染层直接根据cursor对象进行渲染 29 | @property (nonatomic, weak) id cursor; 30 | 31 | 32 | /// 为指示器提供数据信息 33 | @property (nonatomic, weak) id leftAxis; 34 | 35 | /// 为指示器提供数据信息 36 | @property (nonatomic, weak) id rightAxis; 37 | 38 | /// 为指示器提供数据信息 39 | @property (nonatomic, weak) id xAxis; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/Protocol/CCProtocolDataChartRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolDataChartRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolChartRendererBase.h" 11 | #import "CCProtocolChartDataSet.h" 12 | #import "CCProtocolChartDataProvider.h" 13 | 14 | @protocol CCProtocolDataChartRenderer 15 | /** 16 | 绘制趋势图数据 17 | 18 | @param contentLayer 将数据渲染到contentLayer上 19 | */ 20 | - (void)renderData:(CALayer *)contentLayer; 21 | 22 | - (void)renderDataSet:(CALayer *)contentLayer dataSet:(id)dataSet; 23 | 24 | 25 | /** 26 | 绘制趋势图高亮部分信息 27 | 28 | @param contentLayer 将数据渲染到contentLayer上 29 | */ 30 | - (void)renderHighlighted:(CAShapeLayer *)contentLayer; 31 | 32 | 33 | /** 34 | 渲染的时候根据数据提供者(一般是视图本身而不是数据集, 这里其实是做了一个解偶) 35 | */ 36 | @property (nonatomic, weak) id dataProvider; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/Protocol/CCProtocolKLineDataChartRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolKLineDataRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/19. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CCProtocolDataChartRenderer.h" 11 | #import "CCProtocolKLineChartDataProvider.h" 12 | 13 | @protocol CCProtocolKLineDataChartRenderer 14 | 15 | @property (nonatomic, weak) id dataProvider; 16 | 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/Protocol/CCProtocolLegendRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolLegendRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/2. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCProtocolChartRendererBase.h" 10 | 11 | 12 | /// 图例渲染器 13 | @protocol CCProtocolLegendRenderer 14 | 15 | - (void)beginRenderingInLayer:(CALayer *)contentLayer atIndex:(NSInteger)index; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/Renderer/Protocol/CCProtocolMarkerRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolMarkerRenderer.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/4. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CCProtocolChartRendererBase.h" 12 | 13 | @protocol CCProtocolMarkerRenderer 14 | 15 | - (void)beginRenderingInLayer:(CALayer *)contentLayer atIndex:(NSInteger)index; 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCAssembledChartView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCAssembledChartView.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/22. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartViewBase.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | 14 | /// 组合图 15 | /// 16 | /// 可以按照一定顺序组合传入的各类ChartView, 并提供事件同步功能, 这样所有ChartView就可以响应相同的事件了 17 | /// 18 | @interface CCAssembledChartView : UIView 19 | 20 | - (void)setNeedsPrepareChart; 21 | 22 | - (void)resetViewGesture; 23 | 24 | 25 | /// 配置需要组合的视图 26 | /// @param views 视图组 27 | /// 28 | /// 该方法会执行下面几个动作 29 | /// 30 | /// 1. 把数组中的视图都关联在一起, 可以共同响应手势 31 | /// 32 | /// 2. 自动按照顺序向下调整视图, 视图的高度则等于视图本身的高度, 宽度等于父视图 33 | /// 34 | /// 3. 所有视图的y轴labelPosition都被设置为CCYAxisLabelPositionInside, 这是因为外侧的label会导致渲染区间大小不一致,从而无法很好地同步视图. 35 | /// 36 | /// 4. 所有视图xAxis的xSpace,startMargin,endMargin三个属性都被设置为第一个视图的值 37 | - (void)configChartViews:(NSArray *)views; 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCBarChartView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCBarChartView.h 3 | // CCTrendCharts 4 | // 5 | // 条状图, 可以用来绘制趋势图中的交易量图 6 | // 7 | // Created by Cocos on 2019/11/20. 8 | // Copyright © 2019 Cocos. All rights reserved. 9 | // 10 | 11 | #import "CCChartViewBase.h" 12 | 13 | #import "CCDefaultCursor.h" 14 | 15 | #import "CCDefaultYAxisRenderer.h" 16 | #import "CCDefaultXAxisRenderer.h" 17 | #import "CCDefaultCursorRenderer.h" 18 | #import "CCDefaultMarkerRenderer.h" 19 | #import "CCBarDataChartRenderer.h" 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | /// 条状图 24 | @interface CCBarChartView : CCChartViewBase 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCBarChartView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCBarChartView.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCBarChartView.h" 10 | 11 | @interface CCBarChartView () 12 | /** 13 | 高亮图层 14 | */ 15 | @property (nonatomic, strong) CAShapeLayer *highlightLayer; 16 | 17 | /** 18 | 数据图层 19 | */ 20 | @property (nonatomic, strong) CALayer *dataLayer; 21 | 22 | @end 23 | 24 | @implementation CCBarChartView 25 | @synthesize dataRenderer = _dataRenderer; 26 | @synthesize leftAxisRenderer = _leftAxisRenderer; 27 | @synthesize rightAxisRenderer = _rightAxisRenderer; 28 | @synthesize xAxisRenderer = _xAxisRenderer; 29 | @synthesize cursorRenderer = _cursorRenderer; 30 | @synthesize markerRenderer = _markerRenderer; 31 | @synthesize legendRenderer = _legendRenderer; 32 | 33 | - (instancetype)initWithFrame:(CGRect)frame { 34 | self = [super initWithFrame:frame]; 35 | if (self) { 36 | self.leftAxis = [[CCDefaultYAxis alloc] initWithDependency:CCYAsixDependencyLeft]; 37 | self.rightAxis = [[CCDefaultYAxis alloc] initWithDependency:CCYAsixDependencyRight]; 38 | 39 | self.xAxis = [[CCDefaultXAxis alloc] init]; 40 | self.cursor = [[CCDefaultCursor alloc] init]; 41 | 42 | _leftAxisRenderer = [[CCDefaultYAxisRenderer alloc] initWithAxis:self.leftAxis viewHandler:self.viewPixelHandler transform:self.transformer]; 43 | 44 | _rightAxisRenderer = [[CCDefaultYAxisRenderer alloc] initWithAxis:self.rightAxis viewHandler:self.viewPixelHandler transform:self.rightTransformer]; 45 | 46 | _xAxisRenderer = [[CCDefaultXAxisRenderer alloc] initWithAxis:self.xAxis viewHandler:self.viewPixelHandler transform:self.transformer]; 47 | 48 | _cursorRenderer = [[CCDefaultCursorRenderer alloc] initWithCursor:self.cursor viewHandler:self.viewPixelHandler transform:self.transformer DataProvider:self]; 49 | _cursorRenderer.leftAxis = self.leftAxis; 50 | _cursorRenderer.rightAxis = self.rightAxis; 51 | _cursorRenderer.xAxis = self.xAxis; 52 | 53 | _markerRenderer = nil; 54 | _legendRenderer = nil; 55 | 56 | // 组合条形图渲染器 57 | _dataRenderer = [[CCBarDataChartRenderer alloc] initWithViewHandler:self.viewPixelHandler transform:self.transformer DataProvider:self]; 58 | 59 | [self addDefualtGesture]; 60 | } 61 | return self; 62 | } 63 | 64 | - (void)layoutSubviews { 65 | [super layoutSubviews]; 66 | 67 | CGRect frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 68 | self.dataLayer.frame = frame; 69 | } 70 | 71 | /// 数据渲染 72 | - (void)dataRendering { 73 | [self.dataRenderer renderData:self.dataLayer]; 74 | } 75 | 76 | #pragma mark - Getter & Setter 77 | - (CALayer *)dataLayer { 78 | if (!_dataLayer) { 79 | _dataLayer = CALayer.layer; 80 | 81 | [self.layer addSublayer:_dataLayer]; 82 | } 83 | 84 | return _dataLayer; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCChartViewBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCChartViewBase.h 3 | // CCTrendCharts 4 | // 5 | // 基类视图, 所有不同的趋势图都将继承该类 6 | // 7 | // 框架部分设计灵感来自Charts, 感谢. 8 | // 9 | // Created by Cocos on 2019/9/6. 10 | // Copyright © 2019 Cocos. All rights reserved. 11 | // 12 | 13 | #import "CCProtocolChartViewBase.h" 14 | #import "CCProtocolChartDataProvider.h" 15 | 16 | #import "CCGestureDefaultHandler.h" 17 | 18 | #import "CCSingleEventManager.h" 19 | 20 | #import "CCProtocolChartViewSync.h" 21 | 22 | NS_ASSUME_NONNULL_BEGIN 23 | 24 | @class CCChartViewBase; 25 | 26 | @protocol CCChartViewDataSource 27 | 28 | /// 提供全部数据 29 | - (CCChartData *)chartDataInView:(CCChartViewBase *)chartView; 30 | 31 | /// 提供实时更新最后一个节点的数据(未完成) 32 | - (CCChartData *)chartDataForRealTimeInView:(CCChartViewBase *)chartView; 33 | 34 | @end 35 | 36 | @protocol CCChartViewDelegate 37 | 38 | /// 图库希望得到下一页的数据, 用于渲染 39 | /// 40 | /// 目前有两种情况触发这个方法 41 | /// 42 | /// 1. 普通趋势图(非recentFirst), 视图向左滚动到出现右边界之后会触发. 43 | /// 44 | /// 2. recentFirst趋势图, 视图向右滚动到出现左边界之后会触发. 45 | /// 46 | /// 注意, 该方法只是通知用户"期待获取下一页数据", 但实际有没有新数据要提供, 由用户自行决定. 47 | /// 如果有新数据提供, 请调用[charview setNeedsPrepareChart]通知图库, 之后提供相应数据源即可. 48 | - (void)chartViewExpectLoadNextPage:(CCChartViewBase *)view eventManager:(CCSingleEventManager *)eventManager; 49 | 50 | // 长按事件 51 | - (void)charViewDidLongPressAtIndex:(NSInteger)index; 52 | 53 | // 点击事件 54 | 55 | // 双击事件 56 | 57 | @end 58 | 59 | /** 60 | 请不要直接使用基类视图! 61 | */ 62 | @interface CCChartViewBase : UIView 63 | 64 | 65 | /// 重置视图状态, 该方法只是让手势矩阵重置为初始值, 并没有重新渲染视图. 66 | - (void)resetViewGesture; 67 | 68 | /// 添加默认手势 69 | - (void)addDefualtGesture; 70 | 71 | /** 72 | 标记视图需要重新准备信息. 调用该方法并不会立即重新计算信息, 而是等到当前runloop周期结束之后(同setNeedsDisplay) 73 | */ 74 | - (void)setNeedsPrepareChart; 75 | 76 | /** 77 | 子类需要实现该方法, 为整个视图做好数据准备. 78 | 请勿直接调用该方法, 需要更新Chart信息请调用setNeedsPrepareChart 79 | */ 80 | - (void)prepareChart; 81 | 82 | @property (nonatomic, weak) id dataSource; 83 | @property (nonatomic, weak) id delegate; 84 | 85 | /** 86 | 基类声明了数据源属性以及读写方法 87 | */ 88 | @property (nonatomic, strong) CCChartData *data; 89 | 90 | /// 用于确定xy轴距离整个视图边缘的大小. 两轴文案加上该属性的值即为最终距离 91 | @property (nonatomic, assign) UIEdgeInsets clipEdgeInsets; 92 | 93 | /// 最近优先显示, 默认为YES, 适合趋势交易图的显示习惯, 此时page(页码)向左递增 94 | /// 如果是按照早期到当前的顺序显示, 则将该参数设置为NO, 此时page(页码)向右递增 95 | @property (nonatomic, assign) BOOL recentFirst; 96 | 97 | /// 处理手势操作的具体功能 98 | @property (nonatomic, strong) id gestureHandler; 99 | 100 | 101 | /// 指示器风格 102 | /// 103 | /// 这是个可能会被删除的属性, 因为后期横向滚动可能从ScrollView实现改为PanGesture实现. 104 | @property (nonatomic, assign) UIScrollViewIndicatorStyle indicatorStyle; 105 | 106 | 107 | /// 显示横向滚动条 108 | /// 109 | /// 默认 YES 110 | @property (nonatomic, assign) BOOL showsHorizontalScrollIndicator; 111 | 112 | @end 113 | 114 | NS_ASSUME_NONNULL_END 115 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCKLineChartView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCKLineChartView.h 3 | // CCTrendCharts 4 | // 5 | // 用于绘制Candlestick, 交易趋势图, 以下名字统一称为K线图(K Line Diagram). 6 | // 7 | // Created by Cocos on 2019/9/6. 8 | // Copyright © 2019 Cocos. All rights reserved. 9 | // 10 | 11 | #import "CCChartViewBase.h" 12 | 13 | #import "CCDefaultCursor.h" 14 | 15 | #import "CCDefaultYAxisRenderer.h" 16 | #import "CCDefaultXAxisRenderer.h" 17 | #import "CCDefaultCursorRenderer.h" 18 | #import "CCDefaultMarkerRenderer.h" 19 | #import "CCKLineDataChartRenderer.h" 20 | #import "CCTAILegendRenderer.h" 21 | 22 | 23 | #import "CCProtocolKLineChartDataProvider.h" 24 | 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | /// K线趋势图 29 | /// 30 | /// 根据数据集中的类型, 提供蜡烛图(candlestick), 折线图(line) 31 | @interface CCKLineChartView : CCChartViewBase 32 | 33 | 34 | /// 技术指标配置 35 | @property (nonatomic, strong) CCTAIConfig *TAIConfig; 36 | /** 37 | 定义CCProtocolRectangularCoordinateChartDataProvider协议中的数据源, 这里可以换成其他合法子类 38 | */ 39 | 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCLineChartView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCLineChartView.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/22. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCChartViewBase.h" 10 | 11 | #import "CCDefaultCursor.h" 12 | 13 | #import "CCDefaultYAxisRenderer.h" 14 | #import "CCDefaultXAxisRenderer.h" 15 | #import "CCDefaultCursorRenderer.h" 16 | #import "CCDefaultMarkerRenderer.h" 17 | #import "CCLineDataChartRenderer.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | 22 | /// 线形图 23 | /// 24 | /// 可以绘制多条折线, 如果需要在同个区域绘制多条折线+条状图的话, 请使用CCAssembleChartView. 25 | @interface CCLineChartView : CCChartViewBase 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCLineChartView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCLineChartView.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/22. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCLineChartView.h" 10 | 11 | @interface CCLineChartView() 12 | /** 13 | 数据图层 14 | */ 15 | @property (nonatomic, strong) CALayer *dataLayer; 16 | 17 | @end 18 | 19 | @implementation CCLineChartView 20 | @synthesize dataRenderer = _dataRenderer; 21 | @synthesize leftAxisRenderer = _leftAxisRenderer; 22 | @synthesize rightAxisRenderer = _rightAxisRenderer; 23 | @synthesize xAxisRenderer = _xAxisRenderer; 24 | @synthesize cursorRenderer = _cursorRenderer; 25 | @synthesize markerRenderer = _markerRenderer; 26 | @synthesize legendRenderer = _legendRenderer; 27 | 28 | - (instancetype)initWithFrame:(CGRect)frame { 29 | self = [super initWithFrame:frame]; 30 | if (self) { 31 | self.leftAxis = [[CCDefaultYAxis alloc] initWithDependency:CCYAsixDependencyLeft]; 32 | self.rightAxis = [[CCDefaultYAxis alloc] initWithDependency:CCYAsixDependencyRight]; 33 | 34 | self.xAxis = [[CCDefaultXAxis alloc] init]; 35 | self.cursor = [[CCDefaultCursor alloc] init]; 36 | 37 | 38 | 39 | _leftAxisRenderer = [[CCDefaultYAxisRenderer alloc] initWithAxis:self.leftAxis viewHandler:self.viewPixelHandler transform:self.transformer]; 40 | 41 | _rightAxisRenderer = [[CCDefaultYAxisRenderer alloc] initWithAxis:self.rightAxis viewHandler:self.viewPixelHandler transform:self.rightTransformer]; 42 | 43 | _xAxisRenderer = [[CCDefaultXAxisRenderer alloc] initWithAxis:self.xAxis viewHandler:self.viewPixelHandler transform:self.transformer]; 44 | 45 | _cursorRenderer = [[CCDefaultCursorRenderer alloc] initWithCursor:self.cursor viewHandler:self.viewPixelHandler transform:self.transformer DataProvider:self]; 46 | _cursorRenderer.leftAxis = self.leftAxis; 47 | _cursorRenderer.rightAxis = self.rightAxis; 48 | _cursorRenderer.xAxis = self.xAxis; 49 | 50 | _markerRenderer = nil; 51 | 52 | _dataRenderer = [[CCLineDataChartRenderer alloc] initWithViewHandler:self.viewPixelHandler transform:self.transformer DataProvider:self]; 53 | 54 | 55 | [self addDefualtGesture]; 56 | } 57 | return self; 58 | } 59 | 60 | 61 | - (void)layoutSubviews { 62 | [super layoutSubviews]; 63 | 64 | CGRect frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 65 | self.dataLayer.frame = frame; 66 | } 67 | 68 | /// 数据渲染 69 | - (void)dataRendering { 70 | [self.dataRenderer renderData:self.dataLayer]; 71 | } 72 | 73 | #pragma mark - Getter & Setter 74 | - (CALayer *)dataLayer { 75 | if (!_dataLayer) { 76 | _dataLayer = CALayer.layer; 77 | 78 | [self.layer addSublayer:_dataLayer]; 79 | } 80 | 81 | return _dataLayer; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCVolumeChartView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeChartView.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCKLineChartView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /// 交易量图 14 | /// 15 | /// 根据数据集中的类型, 提供交易量图, 折线图(line) 16 | @interface CCVolumeChartView : CCKLineChartView 17 | 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/CCVolumeChartView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCVolumeChartView.m 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/11/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "CCVolumeChartView.h" 10 | #import "CCVolumeDataChartRenderer.h" 11 | 12 | @implementation CCVolumeChartView 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | // 交易量柱型图渲染器 18 | self.dataRenderer = [[CCVolumeDataChartRenderer alloc] initWithViewHandler:self.viewPixelHandler transform:self.transformer DataProvider:self]; 19 | self.markerRenderer = nil; 20 | } 21 | return self; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/Protocol/CCProtocolChartViewBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolChartViewBase.h 3 | // CCTrendCharts 4 | // 5 | // 规定了所有ChartView必须实现的协议 6 | // 7 | // Created by Cocos on 2019/9/6. 8 | // Copyright © 2019 Cocos. All rights reserved. 9 | // 10 | 11 | #import "CCProtocolBase.h" 12 | 13 | #import "CCProtocolDataChartRenderer.h" 14 | #import "CCProtocolAxisRenderer.h" 15 | #import "CCProtocolCursorRenderer.h" 16 | #import "CCProtocolMarkerRenderer.h" 17 | 18 | #import "CCDefaultYAxis.h" 19 | #import "CCDefaultXAxis.h" 20 | #import "CCProtocolCursorBase.h" 21 | #import "CCProtocolMarkerRenderer.h" 22 | #import "CCProtocolLegendRenderer.h" 23 | 24 | NS_ASSUME_NONNULL_BEGIN 25 | 26 | @protocol CCProtocolChartViewBase 27 | @required 28 | 29 | 30 | /// 用于支持数据渲染, 基类方法默认不做任何事情, 子类可自行实现. 31 | - (void)dataRendering; 32 | 33 | /** 34 | 所有2D变换信息都存储在viewHandler里, 以及视图当前画布信息, 可直接由用户手势改变其信息. 35 | */ 36 | @property (nonatomic, readonly) CCChartViewPixelHandler *viewPixelHandler; 37 | 38 | /** 39 | 记录和反射相关的信息, 结合CCChartViewPixelHandler对象可以运算出数据的真实坐标 40 | */ 41 | @property (nonatomic, readonly) CCChartTransformer *transformer; 42 | 43 | 44 | /// 专供右轴使用的变形器 45 | @property (nonatomic, readonly, nullable) CCChartTransformer *rightTransformer; 46 | 47 | /** 48 | 提供Y轴上文案的信息, 左轴不能为nil 49 | */ 50 | @property (nonatomic, strong) CCDefaultYAxis *leftAxis; 51 | 52 | 53 | /// 右轴功能同左轴, 右轴可以为nil 54 | @property (nonatomic, strong, nullable) CCDefaultYAxis *rightAxis; 55 | 56 | /** 57 | 提供X轴上文案信息 58 | */ 59 | @property (nonatomic, strong) CCDefaultXAxis *xAxis; 60 | 61 | @property (nonatomic, strong, nullable) id cursor; 62 | 63 | /** 64 | 渲染组件 65 | */ 66 | @property (nonatomic, strong) id dataRenderer; 67 | 68 | /** 69 | 这里视图类只需要关注渲染对象是否实现基础协议即可, 具体的渲染过程由渲染对象内部处理 70 | */ 71 | @property (nonatomic, strong) id xAxisRenderer; 72 | 73 | @property (nonatomic, strong) id leftAxisRenderer; 74 | 75 | @property (nonatomic, strong, nullable) id rightAxisRenderer; 76 | 77 | @property (nonatomic, strong, nullable) id markerRenderer; 78 | 79 | @property (nonatomic, strong, nullable) id cursorRenderer; 80 | 81 | @property (nonatomic, strong, nullable) id legendRenderer; 82 | 83 | @end 84 | 85 | NS_ASSUME_NONNULL_END 86 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/Core/View/ViewSync/CCProtocolChartViewSync.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCProtocolChartViewSync.h 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/12/4. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /// 描述视图同步需要的信息 12 | @protocol CCProtocolChartViewSync 13 | 14 | - (void)chartViewSyncForPan:(id)panEvent; 15 | 16 | - (void)chartViewSyncForPinch:(id)pinchEvent; 17 | 18 | - (void)chartViewSyncForLongPress:(id)longPressEvent; 19 | 20 | - (void)chartViewSyncEndForPan; 21 | 22 | - (void)chartViewSyncEndForPinch; 23 | 24 | - (void)chartViewSyncEndForLongPress; 25 | 26 | 27 | /// 拖动事件, 可以被观察 28 | @property (nonatomic, strong) id sync_panObservable; 29 | 30 | /// 缩放事件, 可以被观察 31 | @property (nonatomic, strong) id sync_pinchObservable; 32 | 33 | /// 长按事件, 可以被观察 34 | @property (nonatomic, strong) id sync_longPressObservable; 35 | 36 | /// 缩放手势, 默认YES 37 | @property (nonatomic, assign) BOOL sync_pinchGesutreEnable; 38 | 39 | /// 拖动手势, 默认YES 40 | /// 41 | /// 禁用时, 可以避免滚动事件重复传递给其他人 42 | @property (nonatomic, assign) BOOL sync_panGesutreEnable; 43 | 44 | /// 长按手势, 默认YES 45 | @property (nonatomic, assign) BOOL sync_longPressGesutreEnable; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /CCTrendCharts/CCTrendCharts/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // CCTrendCharts 4 | // 5 | // Created by Cocos on 2019/9/20. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | // Include any system framework and library headers here that should be included in all compilation units. 13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 14 | 15 | //#import "UIColor+CCUtility.h" 16 | //#import "CCCoordinateUtility.h" 17 | //#import "CCBaseUtility.h" 18 | //#import "NSString+CCUtility.h" 19 | //#import "CALayer+CCUtility.h" 20 | 21 | #endif /* PrefixHeader_pch */ 22 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo.xcodeproj/xcshareddata/xcschemes/CCTrendChartsDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/6. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow * window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/6. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationDidBecomeActive:(UIApplication *)application {} 24 | 25 | - (void)applicationWillResignActive:(UIApplication *)application {} 26 | 27 | - (void)applicationWillEnterForeground:(UIApplication *)application {} 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application {} 30 | 31 | - (void)applicationWillTerminate:(UIApplication *)application {} 32 | 33 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 34 | return true; 35 | } 36 | 37 | 38 | //#pragma mark - UISceneSession lifecycle 39 | // 40 | // 41 | //- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { 42 | // // Called when a new scene session is being created. 43 | // // Use this method to select a configuration to create the new scene with. 44 | // return [[UISceneConfiguration alloc] initWithName:@"Default" sessionRole:connectingSceneSession.role]; 45 | //} 46 | // 47 | // 48 | //- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { 49 | // // Called when the user discards a scene session. 50 | // // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 51 | // // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 52 | //} 53 | 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIUserInterfaceStyle 6 | Light 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/MainTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainTableViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/6. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MainTableViewController : UITableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/NetworkHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkHelper.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/10. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | 14 | /// 便捷请求网络 15 | @interface NetworkHelper : NSObject 16 | 17 | + (instancetype)share; 18 | 19 | @property (nonatomic, strong) NSURLSession *session; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/NetworkHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkHelper.m 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/10. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "NetworkHelper.h" 10 | 11 | @interface NetworkHelper () 12 | 13 | @end 14 | 15 | @implementation NetworkHelper 16 | - (instancetype)init { 17 | self = [super init]; 18 | if (self) { 19 | [self _configAPINetwork]; 20 | } 21 | return self; 22 | } 23 | 24 | + (instancetype)share { 25 | static NetworkHelper *obj; 26 | static dispatch_once_t onceToken; 27 | dispatch_once(&onceToken, ^{ 28 | obj = [[NetworkHelper alloc] init]; 29 | }); 30 | return obj; 31 | } 32 | 33 | 34 | - (void)_configAPINetwork { 35 | self.session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.defaultSessionConfiguration]; 36 | [[self.session dataTaskWithURL:[NSURL URLWithString:@"https://www.xueqiu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 37 | 38 | }] resume]; 39 | 40 | // 如果无法访问接口, 可以通过下面手动设置cookie, cookie的值可以用浏览器访问一下雪球官网得到~ 41 | // NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 42 | 43 | // [cookieJar setCookie:[NSHTTPCookie cookieWithProperties:@{ 44 | // NSHTTPCookieDomain: @".xueqiu.com", 45 | // NSHTTPCookiePath: @"/", 46 | // NSHTTPCookieName: @"xq_a_token", 47 | // NSHTTPCookieValue: @"5e0d8a38cd3acbc3002589f46fc1572c302aa8a2", 48 | // NSHTTPCookieExpires: [NSDate dateWithTimeIntervalSinceNow:60 * 60] 49 | // }]]; 50 | // 51 | // [cookieJar setCookie:[NSHTTPCookie cookieWithProperties:@{ 52 | // NSHTTPCookieDomain: @".xueqiu.com", 53 | // NSHTTPCookiePath: @"/", 54 | // NSHTTPCookieName: @"xqat", 55 | // NSHTTPCookieValue: @"5e0d8a38cd3acbc3002589f46fc1572c302aa8a2", 56 | // NSHTTPCookieExpires: [NSDate dateWithTimeIntervalSinceNow:60 * 60] 57 | // }]]; 58 | // 59 | // [cookieJar setCookie:[NSHTTPCookie cookieWithProperties:@{ 60 | // NSHTTPCookieDomain: @".xueqiu.com", 61 | // NSHTTPCookiePath: @"/", 62 | // NSHTTPCookieName: @"xq_r_token", 63 | // NSHTTPCookieValue: @"670668eda313118d7214487d800c21ad0202e141", 64 | // NSHTTPCookieExpires: [NSDate dateWithTimeIntervalSinceNow:60 * 60] 65 | // }]]; 66 | } 67 | 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/10. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | #import 13 | 14 | // Include any system framework and library headers here that should be included in all compilation units. 15 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 16 | 17 | // 比例适配主要是通过宏和内联函数实现 18 | // 定义常用屏幕宏 19 | #define IS_LANDSPACE UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation) 20 | #define SCREEN_WIDTH (IS_LANDSPACE ? [UIScreen mainScreen].bounds.size.height : [UIScreen mainScreen].bounds.size.width) 21 | #define SCREEN_HEIGHT (IS_LANDSPACE ? [UIScreen mainScreen].bounds.size.width : [UIScreen mainScreen].bounds.size.height) 22 | #define UI(x) UIAdapter(x) 23 | #define UIRect(x) UIRectAdapter(x) 24 | 25 | // 根据指定机型,返回对应适配比例 26 | static inline CGFloat UIAdapter(CGFloat x) { 27 | CGFloat scale = (414 / SCREEN_WIDTH); 28 | return (NSInteger)x / scale; 29 | } 30 | 31 | static inline CGRect UIRectAdapter(CGFloat x, CGFloat y, CGFloat w, CGFloat h) { 32 | return CGRectMake(UIAdapter(x), UIAdapter(y), UIAdapter(w), UIAdapter(h)); 33 | } 34 | 35 | #endif /* PrefixHeader_pch */ 36 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/AssembledViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AssembledViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/13. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | #import "NetworkHelper.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface AssembledViewController : BaseViewController 15 | 16 | - (NSString *)getXAxisLabelFormat; 17 | 18 | @property (nonatomic, strong) CCSingleEventManager *eventManager; 19 | 20 | @property (nonatomic, strong) NSArray *taiItems; 21 | 22 | // 简单记录股票数据已加载到的时间点 23 | @property (nonatomic, assign) NSTimeInterval minTime; 24 | 25 | @property (nonatomic, strong) CCKLineChartView *klineView; 26 | 27 | @property (nonatomic, strong) CCVolumeChartView *volumeView; 28 | 29 | @property (nonatomic, strong) CCLineChartView *lineView; 30 | 31 | @property (nonatomic, strong) CCAssembledChartView *assembleView; 32 | 33 | @property (nonatomic, strong) UIScrollView *scrollView; 34 | 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/BarViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BarViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/24. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @import CCTrendCharts; 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface BarViewController : UIViewController 16 | 17 | @property (weak, nonatomic) IBOutlet UIView *contentView; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/BarViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BarViewController.m 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/24. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "BarViewController.h" 10 | 11 | @interface BarViewController () 12 | 13 | @property (nonatomic, strong) CCBarChartView *chartView; 14 | 15 | @end 16 | 17 | @implementation BarViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view from its nib. 22 | 23 | CCBarChartView *view = [[CCBarChartView alloc] initWithFrame:CGRectMake(24, 0, SCREEN_WIDTH - 48, 250)]; 24 | view.delegate = self; 25 | view.dataSource = self; 26 | self.chartView = view; 27 | [self.contentView addSubview:self.chartView]; 28 | 29 | view.backgroundColor = [UIColor stringToColor:@"#F6F6F7" opacity:1]; 30 | view.layer.cornerRadius = 4.f; 31 | view.clipEdgeInsets = UIEdgeInsetsMake(24, 8, 12, 24); 32 | 33 | view.rightAxis.axisLineDisabled = YES; 34 | 35 | view.leftAxis.axisColor = [UIColor stringToColor:@"#D8D8D8" opacity:1]; 36 | view.leftAxis.labelColor = [UIColor stringToColor:@"#99999A" opacity:1]; 37 | view.leftAxis.labelCount = 7; 38 | view.leftAxis.formatter = [[NSNumberFormatter alloc] init]; 39 | view.leftAxis.formatter.minimumFractionDigits = 2; 40 | view.leftAxis.formatter.maximumFractionDigits = 2; 41 | view.leftAxis.gridLineEnabled = NO; 42 | view.leftAxis.labelPosition = CCYAxisLabelPositionOutside; 43 | 44 | // 不需要右轴 45 | view.rightAxis = nil; 46 | 47 | view.xAxis.axisColor = [UIColor stringToColor:@"#D8D8D8" opacity:1]; 48 | view.xAxis.labelColor = [UIColor stringToColor:@"#99999A" opacity:1]; 49 | view.xAxis.totalCount = 30; 50 | view.xAxis.formatter.modulusStartIndex = 0; 51 | view.xAxis.yLabelOffset = 5; 52 | view.xAxis.gridLineEnabled = NO; 53 | // 设置一下左右边缘距离 54 | view.xAxis.startMargin = 1; 55 | view.xAxis.endMargin = 1; 56 | 57 | view.cursor.labelColor = [UIColor stringToColor:@"#5543D7" opacity:1]; 58 | view.cursor.lineColor = [UIColor stringToColor:@"#5543D7" opacity:0.5]; 59 | view.cursor.xAxisYLabelOffset = 5; 60 | 61 | [view setNeedsPrepareChart]; 62 | } 63 | 64 | #pragma mark - CCChartViewDataSource 65 | 66 | - (CCChartData *)chartDataInView:(CCChartViewBase *)chartView { 67 | //固定30个实体 68 | NSMutableArray *entities = @[].mutableCopy; 69 | NSMutableArray *xVals = @[].mutableCopy; 70 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 71 | 72 | formatter.dateFormat = @"MM/dd"; 73 | 74 | CGFloat max = 0; 75 | for (NSInteger i = 0; i < 30; i++) { 76 | CCChartDataEntity *entity = [[CCChartDataEntity alloc] initWithValue:[CCBaseUtility floatRandomBetween:0 and:10] xIndex:i data:nil]; 77 | [entities addObject:entity]; 78 | [xVals addObject:[NSString stringWithFormat:@"%@", [formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:1577203200 - i * 3600 * 24]]]]; 79 | if (max < entity.value) { 80 | max = entity.value; 81 | } 82 | } 83 | 84 | CCBarChartDataSet *dataSet = [[CCBarChartDataSet alloc] initWithEntities:entities withName:nil]; 85 | dataSet.color = [UIColor stringToColor:@"#5543D7" opacity:1]; 86 | dataSet.entityDistancePercent = 0.65; 87 | 88 | CCChartData *data = [[CCChartData alloc] initWithXVals:xVals dataSets:@[dataSet]]; 89 | 90 | // 得到最大最小值之后, 手动设置给Y轴 91 | self.chartView.leftAxis.axisMinValue = 0; 92 | self.chartView.leftAxis.axisMaxValue = max * 1.2; 93 | 94 | return data; 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/BarViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/BaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | @import CCTrendCharts; 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface BaseViewController : UIViewController 18 | 19 | - (void)loadDataWithStokeCode:(NSString *)code time:(NSInteger)time; 20 | 21 | - (IBAction)clickBtnAction:(id)sender; 22 | 23 | @property (weak, nonatomic) IBOutlet UIView *contentView; 24 | @property (weak, nonatomic) IBOutlet UITextField *codeTextField; 25 | 26 | // 已获取的全部数据 27 | @property (nonatomic, strong, nullable) NSArray *chartDataArr; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/BaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.m 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | 11 | @interface BaseViewController () 12 | 13 | @end 14 | 15 | @implementation BaseViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)loadDataWithStokeCode:(NSString *)code time:(NSInteger)time { 23 | 24 | } 25 | 26 | - (IBAction)clickBtnAction:(id)sender { 27 | [self.view endEditing:YES]; 28 | if (self.codeTextField.text != nil) { 29 | self.chartDataArr = nil; 30 | [self loadDataWithStokeCode:self.codeTextField.text time:(NSInteger)[NSDate.date timeIntervalSince1970] * 1000]; 31 | } 32 | } 33 | 34 | - (IBAction)stockAction:(UISegmentedControl *)sender { 35 | NSArray *s = @[@"SH600519", @"SZ000001", @"01810", @"BABA"]; 36 | self.codeTextField.text = s[sender.selectedSegmentIndex]; 37 | } 38 | 39 | 40 | 41 | 42 | 43 | /* 44 | #pragma mark - Navigation 45 | 46 | // In a storyboard-based application, you will often want to do a little preparation before navigation 47 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 48 | // Get the new view controller using [segue destinationViewController]. 49 | // Pass the selected object to the new view controller. 50 | } 51 | */ 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/KLineViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // KLineViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/10. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | #import "NetworkHelper.h" 11 | 12 | 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface KLineViewController : BaseViewController 17 | 18 | // 下面几个函数是把部分变量值拆出来, 是为了方便子demo中的其他子类实现自己的对应类型的数据, 方便代码复用, 除此之外没有其他任何含义. 19 | - (id)getDataSetFrom:(NSArray *)entities; 20 | 21 | - (id)getEntityWith:(NSInteger)xIndex; 22 | 23 | - (NSString *)getXAxisLabelFormat; 24 | 25 | 26 | @property (nonatomic, strong) CCKLineChartView *chartView; 27 | 28 | @property (nonatomic, strong) CCSingleEventManager *eventManager; 29 | 30 | @property (nonatomic, strong) NSArray *taiItems; 31 | 32 | // 简单记录股票数据已加载到的时间点 33 | @property (nonatomic, assign) NSTimeInterval minTime; 34 | 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/RealTimeLineViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RealTimeLineViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | #import "NetworkHelper.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface RealTimeLineViewController : BaseViewController 15 | 16 | @property (nonatomic, strong) CCSingleEventManager *eventManager; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/VolumeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // VolumeViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "KLineViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface VolumeViewController : KLineViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/DafaultStyle/VolumeViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // VolumeViewController.m 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/11. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "VolumeViewController.h" 10 | 11 | @import CCTrendCharts; 12 | 13 | @interface VolumeViewController () 14 | 15 | @end 16 | 17 | @implementation VolumeViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view from its nib. 22 | 23 | // 配置数据视图以及轴信息 24 | CCVolumeChartView *view = [[CCVolumeChartView alloc] initWithFrame:CGRectMake(5, 8, SCREEN_WIDTH - 10, 250)]; 25 | view.indicatorStyle = UIScrollViewIndicatorStyleWhite; 26 | 27 | self.chartView = view; 28 | 29 | [self.contentView addSubview:view]; 30 | 31 | // 开启"最近优先", 数据将从右往左渲染 32 | view.recentFirst = YES; 33 | view.dataSource = self; 34 | view.delegate = self; 35 | view.backgroundColor = [UIColor stringToColor:@"#1a1a1a" opacity:1]; 36 | 37 | // 设置趋势图的边缘大小, 趋势图的尺寸减去边缘大小, 就是渲染区域的大小 38 | view.clipEdgeInsets = UIEdgeInsetsMake(24, 24, 5, 24); 39 | 40 | // 下面是针对x, y轴信息的配置, 不懂得可以自己修改后运行一下看看效果就懂了. 41 | view.leftAxis.labelCount = 5; 42 | view.leftAxis.labelPosition = CCYAxisLabelPositionInside; 43 | view.leftAxis.yLabelOffset = -5; 44 | view.leftAxis.labelColor = [UIColor stringToColor:@"#585858" opacity:1]; 45 | 46 | view.rightAxis.labelColor = [UIColor stringToColor:@"#585858" opacity:1]; 47 | view.rightAxis.labelCount = 4; 48 | view.rightAxis.yLabelOffset = -5; 49 | view.rightAxis.gridLineEnabled = NO; 50 | 51 | // 下面代码可以自定义X轴的文案格式化器, 默认格式化器就是直接把数据源的数据展示出来 52 | //view.xAxis.formatter = [[CCXAxisFixedFormatter alloc] init]; 53 | view.xAxis.formatter.modulusStartIndex = 0; 54 | view.xAxis.yLabelOffset = 0; 55 | view.xAxis.axisColor = [UIColor clearColor]; 56 | view.xAxis.labelColor = [UIColor stringToColor:@"#585858" opacity:1]; 57 | 58 | view.cursor.labelColor = [UIColor stringToColor:@"#c8c6c2" opacity:1]; 59 | [view setNeedsPrepareChart]; 60 | 61 | // 如果需要为趋势图配置指标的话, 按照下面代码配置即可, 需要多个就配置多个. 62 | CCTAIConfigItem *tai = [[CCTAIConfigItem alloc] init]; 63 | tai.label = @"MA05"; 64 | tai.color = [UIColor stringToColor:@"#f1983a" opacity:1]; 65 | tai.font = [UIFont systemFontOfSize:10]; 66 | tai.N = @(5); 67 | tai.dataSetClass = CCLineMADataSet.class; 68 | 69 | CCTAIConfigItem *tai2 = [[CCTAIConfigItem alloc] init]; 70 | tai2.label = @"MA30"; 71 | tai2.color = [UIColor stringToColor:@"#5786d2" opacity:1]; 72 | tai2.font = [UIFont systemFontOfSize:10]; 73 | tai2.N = @(30); 74 | tai2.dataSetClass = CCLineMADataSet.class; 75 | 76 | CCTAIConfigItem *tai3 = [[CCTAIConfigItem alloc] init]; 77 | tai3.label = @"MA55"; 78 | tai3.color = [UIColor stringToColor:@"#cb2fa6" opacity:1]; 79 | tai3.font = [UIFont systemFontOfSize:10]; 80 | tai3.N = @(55); 81 | tai3.dataSetClass = CCLineMADataSet.class; 82 | 83 | self.taiItems = @[tai, tai2, tai3]; 84 | 85 | CCTAIConfig *conf = [[CCTAIConfig alloc] initWithConfig:self.taiItems]; 86 | // 为视图配置技术指标 87 | [view setTAIConfig:conf]; 88 | } 89 | 90 | - (id)getDataSetFrom:(NSArray *)entities { 91 | return [[CCVolumeChartDataSet alloc] initWithEntities:entities withName:kCCVolumeChartDataSet]; 92 | } 93 | 94 | - (id)getEntityWith:(NSInteger)xIndex { 95 | return [[CCVolumeDataEntity alloc] initWithValue:0 xIndex:xIndex data:nil]; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/YunexStyle/YunexCursorRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // YunexCursorRenderer.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | @import CCTrendCharts; 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YunexCursorRenderer : CCDefaultCursorRenderer 14 | 15 | - (instancetype)initWithDefaultCursorRenderer:(CCDefaultCursorRenderer *)cursorRenderer; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/YunexStyle/YunexCursorRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // YunexCursorRenderer.m 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "YunexCursorRenderer.h" 10 | 11 | @implementation YunexCursorRenderer 12 | 13 | - (instancetype)initWithDefaultCursorRenderer:(CCDefaultCursorRenderer *)cursorRenderer { 14 | self = [super initWithCursor:cursorRenderer.cursor viewHandler:cursorRenderer.viewPixelHandler transform:cursorRenderer.transformer DataProvider:cursorRenderer.dataProvider]; 15 | self.leftAxis = cursorRenderer.leftAxis; 16 | self.rightAxis = cursorRenderer.rightAxis; 17 | self.xAxis = cursorRenderer.xAxis; 18 | return self; 19 | } 20 | 21 | - (void)renderLeftLabel:(CALayer *)layer center:(CGPoint)center { 22 | if (!self.leftAxis) { 23 | return; 24 | } 25 | 26 | if (center.y < self.viewPixelHandler.contentTop || center.y > self.viewPixelHandler.contentBottom) { 27 | return; 28 | } 29 | 30 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 31 | 32 | // 在label底部画一个绿色长方形, 这里只有一个颜色而且是固定的所以直接写死就可以了. 33 | // 当然可以重写CCDefaultCursor类把属性加到里面或者新建一个实现CCProtocolCursorBase协议的类即可. 34 | 35 | NSString *text = [self.leftAxis.formatter stringFromNumber:@([self.transformer pixelToPoint:CGPointMake(0, center.y) forAnimationPhaseY:1].y)]; 36 | 37 | CGSize textSize = [text sizeWithAttributes:@{ NSFontAttributeName: self.cursor.font }]; 38 | 39 | // 已知游标中心点, 以及文本的尺寸, 可以求得文本底部矩形的对应左轴上的位置. 40 | CGRect rect = CGRectMake(self.viewPixelHandler.contentLeft, center.y - textSize.height / 2, textSize.width + 16, textSize.height); 41 | 42 | CGContextSaveGState(ctx); 43 | { 44 | CGContextSetFillColorWithColor(ctx, [UIColor stringToColor:@"#55BE55" opacity:1].CGColor); 45 | // 画y轴上的矩形 46 | CGContextAddRect(ctx, rect); 47 | 48 | // 画x轴上的矩形 49 | CGContextFillPath(ctx); 50 | } 51 | CGContextRestoreGState(ctx); 52 | 53 | CGPoint textPoint = CGPointMake(self.viewPixelHandler.contentLeft + textSize.width / 2 + 8, center.y); 54 | [text drawTextIn:ctx x:textPoint.x y:textPoint.y anchor:CGPointMake(0.5, 0.5) attributes:@{ NSFontAttributeName: self.cursor.font, NSForegroundColorAttributeName: self.cursor.labelColor }]; 55 | } 56 | 57 | - (void)renderRightLabel:(CALayer *)layer center:(CGPoint)center { 58 | // 不需要渲染右侧信息 59 | } 60 | 61 | - (void)renderXLabel:(CALayer *)layer center:(CGPoint)center { 62 | if (!self.xAxis) { 63 | return; 64 | } 65 | 66 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 67 | 68 | // 简单同步xAxis上的实体 69 | NSInteger index = @([self.transformer pixelToPoint:CGPointMake(center.x, 0) forAnimationPhaseY:1].x).integerValue; 70 | 71 | if (index >= 0 && index < self.dataProvider.data.xVals.count) { 72 | NSString *text = self.xAxis.entities[index]; 73 | CGSize textSize = [text sizeWithAttributes:@{ NSFontAttributeName: self.cursor.font }]; 74 | 75 | CGRect rect = CGRectMake(center.x - textSize.width / 2 - 8, self.viewPixelHandler.contentBottom, textSize.width + 16, textSize.height); 76 | 77 | CGContextSaveGState(ctx); 78 | { 79 | CGContextSetFillColorWithColor(ctx, [UIColor stringToColor:@"#FF1F39" opacity:1].CGColor); 80 | // 绘制一个圆角矩形 81 | UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:rect.size.height/2]; 82 | CGContextAddPath(ctx, path.CGPath); 83 | CGContextFillPath(ctx); 84 | } 85 | CGContextRestoreGState(ctx); 86 | 87 | [text drawTextIn:ctx x:center.x y:self.viewPixelHandler.contentBottom anchor:CGPointMake(0.5, 0) attributes:@{ NSFontAttributeName: self.cursor.font, NSForegroundColorAttributeName: self.cursor.labelColor }]; 88 | } 89 | } 90 | 91 | 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/ViewDemo/YunexStyle/YunexViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // YunexViewController.h 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/16. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "AssembledViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YunexViewController : AssembledViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/CCTrendChartsDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CCTrendChartsDemo 4 | // 5 | // Created by Cocos on 2019/12/6. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | NSString * appDelegateClassName; 14 | @autoreleasepool { 15 | // Setup code that might create autoreleased objects goes here. 16 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 17 | } 18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 19 | } 20 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | platform :ios, '9.0' 4 | 5 | target 'CCTrendChartsDemo' do 6 | pod 'CCTrendCharts', :path => '../' 7 | pod 'CCEasyKVO' 8 | end 9 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CCEasyKVO (0.1.0) 3 | - CCTrendCharts (0.9.1): 4 | - CCEasyKVO 5 | 6 | DEPENDENCIES: 7 | - CCEasyKVO 8 | - CCTrendCharts (from `../`) 9 | 10 | SPEC REPOS: 11 | trunk: 12 | - CCEasyKVO 13 | 14 | EXTERNAL SOURCES: 15 | CCTrendCharts: 16 | :path: "../" 17 | 18 | SPEC CHECKSUMS: 19 | CCEasyKVO: 1aae5d892be60f07b9e5a3591008a4bd3b07a93e 20 | CCTrendCharts: a90ad70f5bebc61fa422a574c03338f3cb432782 21 | 22 | PODFILE CHECKSUM: c7a4f9e15720d1863dabc984da6b2b2c80f330e1 23 | 24 | COCOAPODS: 1.9.0.beta.2 25 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/CCEasyKVO/CCEasyKVO/Classes/NSObject+CCEasyKVO.h: -------------------------------------------------------------------------------- 1 | // 2 | // CCEasyKVO.h 3 | // OCSimpleView 4 | // 5 | // Created by Cocos on 2019/7/3. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | 14 | /** 15 | @abstract 回调函数 16 | @param object 状态发生变化的对象(被观察者) 17 | @param change 发生变化的信息 18 | */ 19 | 20 | typedef void (^CC_EasyBlock)(id object, NSDictionary *change); 21 | 22 | @interface NSObject (CCEasyKVO) 23 | 24 | 25 | /** 26 | 简易KVO 27 | 28 | @param observe 被观察者 29 | @param keyPath key 30 | @param options options 31 | @param block 回调函数 32 | */ 33 | - (void)cc_easyObserve:(id)observe forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(CC_EasyBlock) block; 34 | 35 | - (void)cc_easyRemoveAllKVO; 36 | 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/CCEasyKVO/CCEasyKVO/Classes/NSObject+CCEasyKVO.m: -------------------------------------------------------------------------------- 1 | // 2 | // CCEasyKVO.m 3 | // OCSimpleView 4 | // 5 | // Created by Cocos on 2019/7/3. 6 | // Copyright © 2019 Cocos. All rights reserved. 7 | // 8 | 9 | #import "NSObject+CCEasyKVO.h" 10 | #import 11 | 12 | #ifndef CCHashMapKey 13 | #define CCHashMapKey(id, path) [NSString stringWithFormat:@"%@_%@", id, path] 14 | 15 | #endif 16 | 17 | static void *_ccObserverKey = &_ccObserverKey; 18 | static void *_ccObserveMapKey = &_ccObserveMapKey; 19 | 20 | static void *_ccObserverBlockMapKey = &_ccObserverBlockMapKey; 21 | 22 | /** 23 | 内部观察者 24 | */ 25 | @interface CCInternalObserver : NSObject 26 | 27 | - (NSMapTable *)observeMap; 28 | 29 | - (void)removeAll; 30 | 31 | @end 32 | 33 | @implementation CCInternalObserver 34 | 35 | - (void)dealloc { 36 | [self removeAll]; 37 | } 38 | 39 | /** 40 | 持有观察者加入的block, 对block进行内存管理 41 | 42 | @return NSDictionary * 43 | */ 44 | - (NSMutableDictionary *)observerBlockDic { 45 | NSMutableDictionary *dic; 46 | dic = objc_getAssociatedObject(self, _ccObserverBlockMapKey); 47 | 48 | if (dic) { 49 | return dic; 50 | } 51 | 52 | dic = @{}.mutableCopy; 53 | objc_setAssociatedObject(self, _ccObserverBlockMapKey, dic, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 54 | return dic; 55 | } 56 | 57 | /** 58 | 哈希表, 存放被观察对象, 用于实现自动释放 59 | 60 | 0: 被观察者 61 | 62 | 1: 观察的key 63 | 64 | 2: context 65 | 66 | @return map 67 | */ 68 | - (NSMapTable *)observeMap { 69 | NSMapTable *map; 70 | map = objc_getAssociatedObject(self, _ccObserveMapKey); 71 | 72 | if (map) { 73 | return map; 74 | } 75 | 76 | // 默认强引用被观察者, 使用指针数据内容作为key标识符 77 | map = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality valueOptions:NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPointerPersonality capacity:1]; 78 | 79 | objc_setAssociatedObject(self, _ccObserveMapKey, map, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 80 | return map; 81 | } 82 | 83 | /** 84 | 移除所有观者对象 85 | */ 86 | - (void)removeAll { 87 | for (NSObject *obj in self.observeMap) { 88 | NSArray *arr = [self.observeMap objectForKey:obj]; 89 | // 这里移除每一个不同context指针. 90 | [arr[0] removeObserver:self forKeyPath:arr[1] context:(__bridge void *)(self.observerBlockDic[arr[2]])]; 91 | } 92 | } 93 | 94 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 95 | // 其实就是strong 96 | __strong CC_EasyBlock b = (__bridge CC_EasyBlock)context; 97 | b(object, change); 98 | } 99 | 100 | @end 101 | ////////// END 102 | 103 | @implementation NSObject (CCEasyKVO) 104 | 105 | /** 106 | 使用自定义的对象作为观者者 107 | 108 | @return observer 109 | */ 110 | - (CCInternalObserver *)observer { 111 | CCInternalObserver *obj; 112 | obj = objc_getAssociatedObject(self, _ccObserverKey); 113 | 114 | if (obj) { 115 | return obj; 116 | } 117 | 118 | obj = [[CCInternalObserver alloc] init]; 119 | objc_setAssociatedObject(self, _ccObserverKey, obj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 120 | return obj; 121 | } 122 | 123 | # pragma mark - API 124 | - (void)cc_easyObserve:(NSObject *)observe forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(CC_EasyBlock)block { 125 | 126 | // 用户传入的block可能是NSStackBlock, 这里把block copy到堆中, 然后用block在堆中的地址作为key, 存入哈希表中 127 | CC_EasyBlock b = [block copy]; 128 | NSString *bAddr = [NSString stringWithFormat:@"%p", b]; 129 | 130 | [self.observer.observeMap setObject:@[observe, keyPath, bAddr] forKey:[NSString stringWithFormat:@"%lu %p", (unsigned long)observe.hash, b]]; 131 | self.observer.observerBlockDic[bAddr] = b; 132 | 133 | [observe addObserver:self.observer forKeyPath:keyPath options:options context:(void *)b]; 134 | } 135 | 136 | - (void)cc_easyRemoveAllKVO { 137 | [self.observer removeAll]; 138 | } 139 | 140 | @end 141 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/CCEasyKVO/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 cocos543 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Local Podspecs/CCTrendCharts.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CCTrendCharts", 3 | "version": "0.9.1", 4 | "summary": "趋势图表库", 5 | "description": "趋势图表库, 支持股票K线图, 折线图, 柱型图; \n 支持分页加载数据, 支持定制指标信息(MD等);\n 支持长按指示器, 双指平滑缩放;\n 另外提供了基础绘制框架, 方便用户自行添加各种风格的渲染器;\n\n Trend chart library, support stock K-line chart (candle chart), line chart, bar chart;\n  Support pagination loading data, support custom indicator information (MD, etc.);\n  Support long press indicator, smooth zoom with two fingers;\n  In addition, a basic drawing framework is provided to facilitate users to add various styles of renderers by themselves;", 6 | "homepage": "https://github.com/cocos543/CCTrendCharts", 7 | "screenshots": [ 8 | "https://raw.githubusercontent.com/cocos543/CCTrendCharts/dev/Screenshot/screenshot002.jpg", 9 | "https://raw.githubusercontent.com/cocos543/CCTrendCharts/dev/Screenshot/screenshot006.jpg", 10 | "https://raw.githubusercontent.com/cocos543/CCTrendCharts/dev/Screenshot/screenshot007.jpg" 11 | ], 12 | "license": { 13 | "type": "MIT", 14 | "file": "LICENSE" 15 | }, 16 | "authors": { 17 | "Cocos543": "543314602@qq.com" 18 | }, 19 | "source": { 20 | "git": "https://github.com/cocos543/CCTrendCharts.git", 21 | "tag": "0.9.1" 22 | }, 23 | "platforms": { 24 | "ios": "9.0" 25 | }, 26 | "source_files": "CCTrendCharts/CCTrendCharts/**/*", 27 | "prefix_header_file": "CCTrendCharts/CCTrendCharts/PrefixHeader.pch", 28 | "dependencies": { 29 | "CCEasyKVO": [ 30 | 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CCEasyKVO (0.1.0) 3 | - CCTrendCharts (0.9.1): 4 | - CCEasyKVO 5 | 6 | DEPENDENCIES: 7 | - CCEasyKVO 8 | - CCTrendCharts (from `../`) 9 | 10 | SPEC REPOS: 11 | trunk: 12 | - CCEasyKVO 13 | 14 | EXTERNAL SOURCES: 15 | CCTrendCharts: 16 | :path: "../" 17 | 18 | SPEC CHECKSUMS: 19 | CCEasyKVO: 1aae5d892be60f07b9e5a3591008a4bd3b07a93e 20 | CCTrendCharts: a90ad70f5bebc61fa422a574c03338f3cb432782 21 | 22 | PODFILE CHECKSUM: c7a4f9e15720d1863dabc984da6b2b2c80f330e1 23 | 24 | COCOAPODS: 1.9.0.beta.2 25 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCEasyKVO/CCEasyKVO-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCEasyKVO/CCEasyKVO-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_CCEasyKVO : NSObject 3 | @end 4 | @implementation PodsDummy_CCEasyKVO 5 | @end 6 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCEasyKVO/CCEasyKVO-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCEasyKVO/CCEasyKVO-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "NSObject+CCEasyKVO.h" 14 | 15 | FOUNDATION_EXPORT double CCEasyKVOVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char CCEasyKVOVersionString[]; 17 | 18 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCEasyKVO/CCEasyKVO.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_ROOT = ${SRCROOT} 6 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/CCEasyKVO 7 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 8 | SKIP_INSTALL = YES 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCEasyKVO/CCEasyKVO.modulemap: -------------------------------------------------------------------------------- 1 | framework module CCEasyKVO { 2 | umbrella header "CCEasyKVO-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCEasyKVO/CCEasyKVO.release.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_ROOT = ${SRCROOT} 6 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/CCEasyKVO 7 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 8 | SKIP_INSTALL = YES 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCTrendCharts/CCTrendCharts-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.9.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCTrendCharts/CCTrendCharts-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_CCTrendCharts : NSObject 3 | @end 4 | @implementation PodsDummy_CCTrendCharts 5 | @end 6 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCTrendCharts/CCTrendCharts-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | // 14 | // PrefixHeader.pch 15 | // CCTrendCharts 16 | // 17 | // Created by Cocos on 2019/9/20. 18 | // Copyright © 2019 Cocos. All rights reserved. 19 | // 20 | 21 | #ifndef PrefixHeader_pch 22 | #define PrefixHeader_pch 23 | 24 | // Include any system framework and library headers here that should be included in all compilation units. 25 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 26 | 27 | //#import "UIColor+CCUtility.h" 28 | //#import "CCCoordinateUtility.h" 29 | //#import "CCBaseUtility.h" 30 | //#import "NSString+CCUtility.h" 31 | //#import "CALayer+CCUtility.h" 32 | 33 | #endif /* PrefixHeader_pch */ 34 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCTrendCharts/CCTrendCharts-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "CCTrendCharts.h" 14 | #import "CCProtocolAnimatorBase.h" 15 | #import "CALayer+CCUtility.h" 16 | #import "CCBaseUtility.h" 17 | #import "CCCoordinateUtility.h" 18 | #import "CCMacro.h" 19 | #import "CCSingleEventManager.h" 20 | #import "CCTAIConfig.h" 21 | #import "NSString+CCUtility.h" 22 | #import "CCProtocolBase.h" 23 | #import "UIColor+CCUtility.h" 24 | #import "CCDefaultXAxis.h" 25 | #import "CCDefaultYAxis.h" 26 | #import "CCBarChartDataSet.h" 27 | #import "CCChartData.h" 28 | #import "CCChartDataSetBase.h" 29 | #import "CCKLineChartData.h" 30 | #import "CCKLineChartDataSet.h" 31 | #import "CCLineChartDataSet.h" 32 | #import "CCVolumeChartDataSet.h" 33 | #import "CCDefaultCursor.h" 34 | #import "CCChartDataEntity.h" 35 | #import "CCKLineDataEntity.h" 36 | #import "CCVolumeDataEntity.h" 37 | #import "CCProtocolAxisBase.h" 38 | #import "CCProtocolChartDataProvider.h" 39 | #import "CCProtocolChartDataSet.h" 40 | #import "CCProtocolCursorBase.h" 41 | #import "CCProtocolKLineChartDataProvider.h" 42 | #import "CCProtocolTAIDataSet.h" 43 | #import "CCProtocolChartDataEntityBase.h" 44 | #import "CCLineMADataSet.h" 45 | #import "CCXAxisDefaultFormatter.h" 46 | #import "CCXAxisFixedFormatter.h" 47 | #import "CCProtocolXAxisFormatterBase.h" 48 | #import "CCChartTransformer.h" 49 | #import "CCChartViewPixelHandler.h" 50 | #import "CCGestureDefaultHandler.h" 51 | #import "CCGestureHandlerProtocol.h" 52 | #import "CCBarDataChartRenderer.h" 53 | #import "CCDataChartRenderer.h" 54 | #import "CCDefaultCursorRenderer.h" 55 | #import "CCDefaultMarkerRenderer.h" 56 | #import "CCDefaultXAxisRenderer.h" 57 | #import "CCDefaultYAxisRenderer.h" 58 | #import "CCKLineDataChartRenderer.h" 59 | #import "CCLineDataChartRenderer.h" 60 | #import "CCRendererBase+LayerCache.h" 61 | #import "CCRendererBase.h" 62 | #import "CCTAILegendRenderer.h" 63 | #import "CCVolumeDataChartRenderer.h" 64 | #import "CCProtocolAxisRenderer.h" 65 | #import "CCProtocolChartRendererBase.h" 66 | #import "CCProtocolCursorRenderer.h" 67 | #import "CCProtocolDataChartRenderer.h" 68 | #import "CCProtocolKLineDataChartRenderer.h" 69 | #import "CCProtocolLegendRenderer.h" 70 | #import "CCProtocolMarkerRenderer.h" 71 | #import "CCAssembledChartView.h" 72 | #import "CCBarChartView.h" 73 | #import "CCChartViewBase.h" 74 | #import "CCKLineChartView.h" 75 | #import "CCLineChartView.h" 76 | #import "CCVolumeChartView.h" 77 | #import "CCProtocolChartViewBase.h" 78 | #import "CCProtocolChartViewSync.h" 79 | 80 | FOUNDATION_EXPORT double CCTrendChartsVersionNumber; 81 | FOUNDATION_EXPORT const unsigned char CCTrendChartsVersionString[]; 82 | 83 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCTrendCharts/CCTrendCharts.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CCTrendCharts 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCTrendCharts/CCTrendCharts.modulemap: -------------------------------------------------------------------------------- 1 | framework module CCTrendCharts { 2 | umbrella header "CCTrendCharts-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/CCTrendCharts/CCTrendCharts.release.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CCTrendCharts 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## CCEasyKVO 5 | 6 | MIT License 7 | 8 | Copyright (c) 2019 cocos543 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | ## CCTrendCharts 30 | 31 | MIT License 32 | 33 | Copyright (c) 2019 cocos543 34 | 35 | Permission is hereby granted, free of charge, to any person obtaining a copy 36 | of this software and associated documentation files (the "Software"), to deal 37 | in the Software without restriction, including without limitation the rights 38 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 39 | copies of the Software, and to permit persons to whom the Software is 40 | furnished to do so, subject to the following conditions: 41 | 42 | The above copyright notice and this permission notice shall be included in all 43 | copies or substantial portions of the Software. 44 | 45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 51 | SOFTWARE. 52 | 53 | Generated by CocoaPods - https://cocoapods.org 54 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2019 cocos543 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | CCEasyKVO 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | MIT License 49 | 50 | Copyright (c) 2019 cocos543 51 | 52 | Permission is hereby granted, free of charge, to any person obtaining a copy 53 | of this software and associated documentation files (the "Software"), to deal 54 | in the Software without restriction, including without limitation the rights 55 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 56 | copies of the Software, and to permit persons to whom the Software is 57 | furnished to do so, subject to the following conditions: 58 | 59 | The above copyright notice and this permission notice shall be included in all 60 | copies or substantial portions of the Software. 61 | 62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 63 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 64 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 65 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 66 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 67 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 68 | SOFTWARE. 69 | 70 | License 71 | MIT 72 | Title 73 | CCTrendCharts 74 | Type 75 | PSGroupSpecifier 76 | 77 | 78 | FooterText 79 | Generated by CocoaPods - https://cocoapods.org 80 | Title 81 | 82 | Type 83 | PSGroupSpecifier 84 | 85 | 86 | StringsTable 87 | Acknowledgements 88 | Title 89 | Acknowledgements 90 | 91 | 92 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_CCTrendChartsDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_CCTrendChartsDemo 5 | @end 6 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/CCEasyKVO/CCEasyKVO.framework 3 | ${BUILT_PRODUCTS_DIR}/CCTrendCharts/CCTrendCharts.framework -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CCEasyKVO.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CCTrendCharts.framework -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/CCEasyKVO/CCEasyKVO.framework 3 | ${BUILT_PRODUCTS_DIR}/CCTrendCharts/CCTrendCharts.framework -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CCEasyKVO.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CCTrendCharts.framework -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_CCTrendChartsDemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_CCTrendChartsDemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO" "${PODS_CONFIGURATION_BUILD_DIR}/CCTrendCharts" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO/CCEasyKVO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CCTrendCharts/CCTrendCharts.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "CCEasyKVO" -framework "CCTrendCharts" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_CCTrendChartsDemo { 2 | umbrella header "Pods-CCTrendChartsDemo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /CCTrendChartsDemo/Pods/Target Support Files/Pods-CCTrendChartsDemo/Pods-CCTrendChartsDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO" "${PODS_CONFIGURATION_BUILD_DIR}/CCTrendCharts" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CCEasyKVO/CCEasyKVO.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CCTrendCharts/CCTrendCharts.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "CCEasyKVO" -framework "CCTrendCharts" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 cocos543 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CCTrendChart 2 | 3 | ![](https://img.shields.io/github/license/cocos543/CCTrendCharts) 4 | ![](https://img.shields.io/cocoapods/p/CCTrendCharts) 5 | ![](https://img.shields.io/github/last-commit/cocos543/CCTrendCharts) 6 | ![](https://img.shields.io/github/commit-activity/w/cocos543/CCTrendCharts) 7 | ![](https://img.shields.io/github/languages/code-size/cocos543/CCTrendCharts) 8 | 9 | > 项目正在积极开发中, 基本功能已完成, 即将添加使用Demo, 喜欢请点个start, 谢谢 ~ 10 | 11 | ## 安装方法 12 | CocoaPods方式 13 | 14 | ``` 15 | pod 'CCTrendCharts' 16 | ``` 17 | 18 | ## 已完成功能 19 | 20 | ### 一. 趋势图底层框架 21 | 22 | 1. 完成矩阵与坐标系的开发 23 | 2. 完成缩放功能的开发 24 | 3. 完成长按功能的开发 25 | 4. 完成滚动功能的开发 26 | 5. 完成图库模块化标准制定 27 | 6. 数据源接口标准制定 28 | 7. 渲染层接口标准制定 29 | 8. 支持组合视图, 共同响应手势. 30 | 31 | 32 | ### 二. 数据方面 33 | 34 | 1. 完成数据实体, 数据集, 数据整体的开发 35 | 2. 支持动态更新数据, 支持分页加载数据 36 | 3. 提供了两种数据的展示方式(从左到右:Default, 从右到左:RecentFirst) 37 | 38 | ### 三. 渲染方面 39 | 40 | 1. 支持实体按需渲染, 提高性能 41 | 2. 默认的左Y轴, 右Y轴模块的数据提供者和渲染器 42 | 3. 默认的X轴模块的数据提供者和渲染器 43 | 4. 默认的指示器模块的数据提供者和渲染器 44 | 5. 默认的标记模块的数据提供者和渲染器 45 | 6. K线(candlestick)数据提供者和渲染器 46 | 7. 交易量条状图渲染器 47 | 8. 折线图数据提供者和渲染器 48 | 9. 贝塞尔曲线 49 | 10. TAI指标图例渲染器 50 | 11. 支持便捷组合各种视图, 并提供事件同步协议, 能将多个视图只要组合到一起, 共同响应手势. 51 | 12. 条形图渲染器 52 | 53 | ### 四. 趋势图技术指标 (Technical Analysis Indicators) 54 | 55 | 设计一个方案, 用来自由配置各类技术指标, 目前已经开发完成的指标列表如下 56 | 57 | * 移动平均线MA(Moving average), 均线系数N可配置 58 | 59 | ### Demo 60 | 61 | * K线图+指标 62 | * 交易量图+指标 63 | * 分时图 64 | * 组合图 65 | * 条形图 66 | * Yunex交易所风格 67 | 68 | ## 正在开发 69 | 70 | * 各项趋势图的指标计算 71 | * 各类Demo 72 | 73 | ## 未完成功能 74 | 75 | * 选中高亮 76 | * 数据渲染器支持渐变 77 | * 数据渲染器支持定制动画 78 | * 各种风格的渲染器(涵盖主流证券公司的图表渲染器, 比如富途, 涨乐富, 蛋卷, 招商等等都将一一提供) 79 | * 详细的图库使用教程demo 80 | * 专业数据分析工具 81 | * 支持swift最新版本 82 | * 支持flutter? 83 | * 支持MacOS 84 |   85 | ## 开发中的界面预览 86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 |
95 | 96 | 97 | 滚动缩放画面稳定在60 FPS左右 98 |
99 | 100 |
101 | -------------------------------------------------------------------------------- /Screenshot/1575542732977187.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/1575542732977187.mp4 -------------------------------------------------------------------------------- /Screenshot/gpu_state.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/gpu_state.jpg -------------------------------------------------------------------------------- /Screenshot/screenshot002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/screenshot002.jpg -------------------------------------------------------------------------------- /Screenshot/screenshot003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/screenshot003.jpg -------------------------------------------------------------------------------- /Screenshot/screenshot004.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/screenshot004.jpg -------------------------------------------------------------------------------- /Screenshot/screenshot005.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/screenshot005.jpg -------------------------------------------------------------------------------- /Screenshot/screenshot006.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/screenshot006.jpg -------------------------------------------------------------------------------- /Screenshot/screenshot007.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocos543/CCTrendCharts/70981277d2b7e35138aedbec1a2854d4727a5cb8/Screenshot/screenshot007.jpg --------------------------------------------------------------------------------