Compare commits

..

105 Commits

Author SHA1 Message Date
Terry Worona 5f8863ede1 updated changeling 2015-08-12 09:07:14 -07:00
Terry Worona bf8d5de61e updated pod spec 2015-08-12 08:49:11 -07:00
Terry Worona 23935a3b55 small cleanup 2015-08-12 08:47:26 -07:00
terryworona f7d15d4905 Merge pull request #183 from 0xPr0xy/master
Return the available height instead of 0
2015-08-12 08:43:08 -07:00
Peter IJlst 372b69ff4a Merge branch 'release/fix-invisible-bars' 2015-08-12 09:16:22 +02:00
Peter IJlst b17a37c1d7 in normalizedHeightForRawHeight () method return availableHeight instead of 0.
Fixes: http://stackoverflow.com/questions/24123794/color-of-bar-chart-not-displaying-in-jbchartview
2015-08-12 09:12:33 +02:00
terryworona a1f34f78fb updated changelog and pod spec 2015-04-30 15:20:27 -07:00
terryworona 15e73af3b3 Merge pull request #165 from eventualbuddha/nil-delegate-and-datasource-on-dealloc
Nil out delegate and datasource on dealloc
2015-04-30 15:13:33 -07:00
Brian Donovan aac41605aa Add dealloc methods to the demos.
This is proper Cocoa etiquette and may help others prevent crashes in
their own apps.
2015-04-30 11:48:47 -07:00
Brian Donovan 0bfc904f58 Ensure our own subviews with a delegate are cleaned up.
This can potentially cause a crash if the `linesView` or `dotsView`
were to send a message to its delegate after the delegate was dealloc’d.
2015-04-30 11:45:25 -07:00
terryworona b54f27e67d Updated changelog and podspec 2015-04-16 11:54:01 -07:00
terryworona ff17a56eff Fixes #157 2015-04-16 11:52:27 -07:00
terryworona 93d98d7b87 updated changeling and pod spec 2015-04-13 12:48:49 -07:00
terryworona ba0a44ba3f Fixed radius width on demo line charts 2015-04-13 11:54:53 -07:00
terryworona 621e9a7386 removed extra synthesize calls for #154 2015-04-13 11:44:21 -07:00
terryworona 28ad5d7557 Merge pull request #154 from amro/master
Fix warnings when building w/ Xcode 6.3
2015-04-13 11:37:32 -07:00
Amro Mousa d299cd6e7e Fix warnings in Xcode 6.3
These warnings are problematic for those who
build with warnings as errors.
2015-04-09 09:43:18 -07:00
Terry Worona abf14f342a Updated readme for issue #150 2015-04-01 12:33:11 -07:00
Terry Worona 299405efe1 Updated pod spec 2015-03-30 20:07:03 -07:00
Terry Worona 27ebf131c9 Updated changelog 2015-03-30 19:07:34 -07:00
Terry Worona e3c8fb2794 Fixes #118 - access to bar and dot views 2015-03-30 19:03:44 -07:00
Terry Worona 93bea88b47 updated readme and header comments for #99 2015-03-30 16:03:45 -07:00
Terry Worona fe7f8bbae7 Fixes issue #99 - radius is now a true dot radius (not diameter) 2015-03-30 15:59:34 -07:00
Terry Worona 394bb70599 Cleaned up pr 143 2015-03-30 15:19:48 -07:00
terryworona 4e1411c302 Merge pull request #143 from ADVSENSOR/empty_data
Fix crash and warnings that can occur when a chart line has no data
2015-03-30 15:15:48 -07:00
Terry Worona 21bc7d3a3e List updates 2015-03-30 15:09:31 -07:00
terryworona 21dc1d004a Merge pull request #144 from ADVSENSOR/tooltip_zorder
Keep tooltip subviews above line subviews
2015-03-30 14:21:25 -07:00
Terry Worona 40e4434e18 Readme update 2015-03-30 14:13:04 -07:00
Terry Worona ac3c379af4 Code cleanup 2015-03-30 14:12:07 -07:00
Terry Worona 2c803e87dd cleaned up strings 2015-03-30 14:09:58 -07:00
Terry Worona 7efeaa1ef1 updated line chart docs 2015-03-30 14:04:35 -07:00
Terry Worona a454e221a6 Updated readme 2015-03-30 14:02:52 -07:00
terryworona 7046cf7045 Merge pull request #116 from sebastianreloaded/missing_values
Add ability to have the line start or end at any given point
2015-03-30 13:56:08 -07:00
terryworona e4b0fddd16 Merge pull request #142 from skywinder/add-change-log-file
Add automatically generated change log file.
2015-03-30 13:46:29 -07:00
Sebastian Opel b1c632f5a3 added docu in readme 2015-03-25 11:56:51 +01:00
Sebastian Opel 162619b825 coding style fixes 2015-03-17 10:45:37 +01:00
Sebastian Opel 32cbb39d0b if all points are NAN no need to continue the path 2015-03-17 10:43:46 +01:00
Trevor Harmon 3a0fac18c5 Keep tooltip subviews above line subviews 2015-03-07 16:43:51 -08:00
Trevor Harmon 4c0a22d962 Fix crash and warnings that can occur when a chart line has no data 2015-03-07 14:27:24 -08:00
Petr Korolev 76c1c41886 Added automatically generated change log file 2015-03-05 15:29:07 +02:00
Terry Worona e3b8ccd704 Fixed #140 2015-03-04 22:34:39 -08:00
terryworona b179f20ef9 Merge pull request #127 from paal123/patch-1
Update README.md
2014-11-25 08:56:52 -08:00
paal123 d89472dea5 Update README.md
Removed a small typo resulting in errors during execution.
2014-11-25 16:12:02 +01:00
Sebastian Opel 907a4f25ae added missing points to new example fake data 2014-10-23 17:08:03 +02:00
Sebastian Opel 51454fe3f6 added a copy of linechart example as a new example for missing points 2014-10-23 17:06:09 +02:00
Sebastian Opel 131f251df8 added handling of missing values within a linechart
JBLineChartView uses numberOfVerticalValuesAtLineIndex to define the number
of points, but subsequently requires that all chartPoints have a value anyway.
This commit allows you to use NAN within the charts data.
2014-10-23 16:44:44 +02:00
Terry Worona 64451dd5ac pod spec and read me updates 2014-09-22 19:05:18 -07:00
Terry Worona 36d72ce510 change log and comments 2014-09-22 19:03:25 -07:00
Terry Worona efd8f97335 Removed changes for setFrame 2014-09-22 19:00:10 -07:00
Terry Worona 243c28cffb update to change log, read me, pod spec, etc 2014-09-22 11:18:11 -07:00
Terry Worona 66bf3b14e8 Fixed #111 2014-09-22 11:16:48 -07:00
Terry Worona 7287712da3 More cleanup of compiler warnings on iOS 8 2014-09-22 11:11:32 -07:00
Terry Worona e71db56a76 updated read me, change log, etc 2014-09-19 19:41:52 -07:00
Terry Worona 4be903eda7 fixed some compiler warnings 2014-09-19 19:35:37 -07:00
Terry Worona d5210eff99 Updated read me, change log and pod spec 2014-09-08 22:35:27 -07:00
Terry Worona 956386c7db Cleanup 2014-09-08 22:17:52 -07:00
terryworona c6dfb48047 Merge pull request #106 from eventualbuddha/reduce-numberOfLinesInLineChartView-calls
Only call `numberOfLinesInLineChartView:` once per loop.
2014-09-08 22:17:06 -07:00
terryworona fff2bd22d6 Merge pull request #107 from thefirstnikhil/master
iOS Framework Support
2014-09-08 22:08:46 -07:00
Nikhil Kalra 23e8e3084a iOS Framework Support
Added a UIKit import statement for use when JBChartView is added to a
Xcode project as a framework (iOS 8).
2014-09-05 21:48:15 -07:00
Brian Donovan d04eaa2622 Only call numberOfLinesInLineChartView: once per loop. 2014-09-05 11:18:21 -07:00
Terry Worona e24d2487f1 updated pod spec 2014-08-29 15:23:25 -07:00
Terry Worona d3a92dd70f updated read me and change log fixed issue #100 2014-08-29 15:22:56 -07:00
Terry Worona c73f494034 added custom dot view hide functionality on selection events 2014-08-29 15:19:49 -07:00
Terry Worona 80708acda1 Updated pod spec 2014-08-28 14:52:58 -07:00
Terry Worona 6308ee1b19 Updated read me and change log 2014-08-28 14:50:42 -07:00
Terry Worona 62965bbd9f Finished line chart padding extension properties 2014-08-28 13:51:33 -07:00
Terry Worona 06bf8b5033 Finished bar chart padding extension properties 2014-08-28 13:37:39 -07:00
Terry Worona c2a16d0fbb added optional protocol for footer/header padding extensions 2014-08-28 13:24:13 -07:00
Terry Worona 9548b2ab32 Don't extend selection views into padding 2014-08-28 13:14:58 -07:00
Terry Worona 295fb40a0b Fixed up bar charts to utilize padding properly 2014-08-28 13:01:57 -07:00
Terry Worona e29ebd39ab Updated line chart view for footer padding 2014-08-28 12:10:35 -07:00
Terry Worona 27b0493b9b Added footer padding property and updated bar chart to use it 2014-08-28 12:00:04 -07:00
Terry Worona 04f40aac1a Updated read me 2014-08-27 11:35:42 -07:00
Terry Worona 833f6e9080 Fixed issue #97 2014-08-27 11:27:58 -07:00
Terry Worona eb48db2e73 Updated comment 2014-08-27 11:21:45 -07:00
Terry Worona 55b6dae956 Cleaned up bar pop animations 2014-08-27 11:19:45 -07:00
Terry Worona c44b276ae1 fixed vertical selection adjustment 2014-08-26 19:14:15 -07:00
Terry Worona 93f3d1862e simplified bar chart animations and added invert flag 2014-08-26 19:02:06 -07:00
Terry Worona 19a4a0bf5c Updated pod spec 2014-08-26 15:49:59 -07:00
Terry Worona 9d43c6dd23 updated read me and pod spec 2014-08-26 15:49:21 -07:00
Terry Worona 8598ff1488 Fixed issue #93 2014-08-26 15:46:03 -07:00
Terry Worona b9d28bfd59 Updated pod spec 2014-08-26 15:40:00 -07:00
Terry Worona dd1dce758e updated read me and change log 2014-08-26 15:39:25 -07:00
Terry Worona 9fce2fc1c0 Fixed #95 2014-08-26 15:35:40 -07:00
Terry Worona ab1cf713e6 Fixed bar chart selection view for non-homogenous bar widths 2014-08-26 15:29:05 -07:00
Terry Worona 4363147303 updated read me 2014-08-22 18:19:34 -07:00
Terry Worona 8a1770c6df Updated pod spec 2014-08-22 18:13:52 -07:00
Terry Worona f84f322598 updated read me 2014-08-22 18:13:20 -07:00
Terry Worona 04e1aa5b98 Hide custom dots on selector for now 2014-08-22 18:10:30 -07:00
Terry Worona ab07aa2399 Fixed padding issues 2014-08-22 15:36:08 -07:00
Terry Worona f01e11a0e2 Added custom dot views to line chart 2014-08-22 14:21:06 -07:00
Terry Worona 76984c7c7c added protocols for custom dots 2014-08-22 12:07:09 -07:00
Terry Worona d38a04a70d Added dot radius on a per horizontal index basis 2014-08-22 11:52:53 -07:00
Terry Worona 385d5b3589 Updated pod spec 2014-08-14 19:26:18 -07:00
Terry Worona 90100c7277 updated read me and change log 2014-08-14 19:25:39 -07:00
Terry Worona eca1c0507e Cleaned up PR #90 2014-08-14 19:23:19 -07:00
terryworona ac870e45ce Merge pull request #90 from mszaro/master
Add per-line vertical selection color support.
2014-08-14 19:17:19 -07:00
mszaro 74f588b7e6 Update comment. 2014-08-14 18:51:48 -07:00
mszaro 406b64ae0c Implement per-line vertical selection colors 2014-08-14 18:50:55 -07:00
Terry Worona 92e56d78c5 updates specs and read me 2014-08-14 18:01:04 -07:00
Terry Worona 36ec328346 Fixed issue #89 2014-08-14 17:57:39 -07:00
Terry Worona b763ae540c updated version 2014-08-07 13:33:46 -07:00
Terry Worona 7ffdf6d9da Fixed issue #83 2014-08-07 13:30:48 -07:00
Terry Worona 6531c68574 version update 2014-08-04 13:37:33 -07:00
Terry Worona ebae36bd2f Pushed base datasource and delegate protocols up to JBChartView (for extensibility) 2014-08-04 13:17:04 -07:00
18 changed files with 1579 additions and 380 deletions
+504 -129
View File
@@ -1,166 +1,541 @@
# Changelog
# Change Log
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.7.0">2.7.1</a>
#### 08/04/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/77">#77</a>.
## [Unreleased](https://github.com/Jawbone/JBChartView/tree/HEAD)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.7.0">2.7.0</a>
#### 08/02/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/76">#76</a>.
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.14...HEAD)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.6.3">2.6.3</a>
#### 07/31/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/75">#75</a>.
**Implemented enhancements:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.6.2">2.6.2</a>
#### 07/25/14
- Added new controller (JBAreaChartViewController) to demonstrate area charts.
- Suggestion for the README.md [\#176](https://github.com/Jawbone/JBChartView/issues/176)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.6.1">2.6.1</a>
#### 07/25/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/74">#74</a>.
**Fixed bugs:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.6.0">2.6.0</a>
#### 07/24/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/71">#71</a>.
- Line color overlap issue [\#168](https://github.com/Jawbone/JBChartView/issues/168)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.5">2.5.5</a>
#### 05/13/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/57">#57</a>.
**Closed issues:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.4">2.5.4</a>
#### 05/07/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/53">#53</a>.
- JBLineChart reloadData problem [\#181](https://github.com/Jawbone/JBChartView/issues/181)
- JBLineChartView: wrong width on iPhone6/6+ [\#177](https://github.com/Jawbone/JBChartView/issues/177)
- Is there anyway to plot two vertical values for one horizontal index in the bar chart? [\#172](https://github.com/Jawbone/JBChartView/issues/172)
- Charts not rendering properly [\#171](https://github.com/Jawbone/JBChartView/issues/171)
- How can you set the bar chart to fill the width of a UIView? [\#170](https://github.com/Jawbone/JBChartView/issues/170)
- Adding X and Y Values [\#169](https://github.com/Jawbone/JBChartView/issues/169)
- Undefined symbols for architecture i386 [\#167](https://github.com/Jawbone/JBChartView/issues/167)
- Not All Data Points Visible in Flexible View [\#166](https://github.com/Jawbone/JBChartView/issues/166)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.3">2.5.3</a>
#### 05/06/14
- More compiler warning fixes.
**Merged pull requests:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.2">2.5.2</a>
#### 05/06/14
- Fixed compiler warnings.
- Return the available height instead of 0 [\#183](https://github.com/Jawbone/JBChartView/pull/183) ([0xPr0xy](https://github.com/0xPr0xy))
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.1">2.5.1</a>
#### 05/05/14
- Additional fixes to issue <a href="https://github.com/Jawbone/JBChartView/pull/48">#48</a>.
## [v2.8.14](https://github.com/Jawbone/JBChartView/tree/v2.8.14) (2015-04-30)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.13...v2.8.14)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.0">2.5.0</a>
#### 05/04/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/48">#48</a>.
**Closed issues:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.3">2.4.3</a>
#### 05/04/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/49">#49</a>.
- Will JBChartView integrated with React Native? [\#164](https://github.com/Jawbone/JBChartView/issues/164)
- white dot+dotted lines sometimes does not appear when touched. [\#161](https://github.com/Jawbone/JBChartView/issues/161)
- Small offset when using a footer for a x-axis [\#160](https://github.com/Jawbone/JBChartView/issues/160)
- gradient for bar chart is lost / sizing problem [\#158](https://github.com/Jawbone/JBChartView/issues/158)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.2">2.4.2</a>
#### 04/30/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/46">#46</a>.
**Merged pull requests:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.1">2.4.1</a>
#### 04/30/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/45">#45</a>.
- Nil out delegate and datasource on dealloc [\#165](https://github.com/Jawbone/JBChartView/pull/165) ([eventualbuddha](https://github.com/eventualbuddha))
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.0">2.4.0</a>
#### 04/28/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/23">#23</a>.
## [v2.8.13](https://github.com/Jawbone/JBChartView/tree/v2.8.13) (2015-04-16)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.12...v2.8.13)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.3.0">2.3.0</a>
#### 04/17/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/34">#34</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.2.0">2.2.0</a>
#### 04/14/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/37">#37</a>.
**Fixed bugs:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.6">2.1.6</a>
#### 04/11/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/33">#33</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.5">2.1.5</a>
#### 04/10/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/30">#30</a>.
- Wrong calculation of the lineIndex [\#157](https://github.com/Jawbone/JBChartView/issues/157)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.4">2.1.4</a>
#### 04/10/14
- Added ability to specify a radius for dotted lines.
**Closed issues:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.3">2.1.3</a>
#### 04/03/14
- Added the ability to force a chart's state.
- Swift round up for respondsToSelector\(\) and sizeWithFont\(\) [\#156](https://github.com/Jawbone/JBChartView/issues/156)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.2">2.1.2</a>
#### 04/02/14
- Added dynamic padding to JBLineChartView (based on max line width).
## [v2.8.12](https://github.com/Jawbone/JBChartView/tree/v2.8.12) (2015-04-13)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.11...v2.8.12)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.1">2.1.1</a>
#### 04/02/14
- Fixed minimumValue and maximumValue getter functions.
**Fixed bugs:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.0">2.1.0</a>
#### 03/30/14
- Added minimumValue and maximumValue properties.
- Changed default min value implementation from 0 to chart's actual minimum value.
- Footer and Header view Swift implementation [\#152](https://github.com/Jawbone/JBChartView/issues/152)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.0.2">2.0.2</a>
#### 03/27/14
- Added the ability to add point dots for lines in JBLineChartView.
- Streamlined line styling.
**Closed issues:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.0.1">2.0.1</a>
#### 03/19/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/22">#22</a>.
- Problems with selection when JBLineChartView is within UITableView [\#155](https://github.com/Jawbone/JBChartView/issues/155)
- Show chart selection permanently [\#151](https://github.com/Jawbone/JBChartView/issues/151)
- Crash when returning NAN [\#150](https://github.com/Jawbone/JBChartView/issues/150)
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.0.0">2.0.0</a>
#### 03/18/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/21">#21</a>.
- Added multi-line support for JBLineChartView.
- Added position delegation on touch events.
- Added tooltip views (demo-only).
**Merged pull requests:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.1.6">1.1.6</a>
#### 03/02/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/15">#15</a>.
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/14">#14</a>.
- Fix warnings when building w/ Xcode 6.3 [\#154](https://github.com/Jawbone/JBChartView/pull/154) ([amro](https://github.com/amro))
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.1.5">1.1.5</a>
#### 02/11/14
- Chart selection improvements.
- Animation performance improvements.
## [v2.8.11](https://github.com/Jawbone/JBChartView/tree/v2.8.11) (2015-03-31)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.10...v2.8.11)
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.1.4">1.1.4</a>
#### 02/06/14
- Fixed compilation warnings.
**Implemented enhancements:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.1.3">1.1.3</a>
#### 01/06/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/11">#11</a>.
- Pass back barView & dot instances on selection [\#118](https://github.com/Jawbone/JBChartView/issues/118)
- Add ability to have the line start or end at any given point [\#115](https://github.com/Jawbone/JBChartView/issues/115)
- Consolidate dot view selection/unselection/color calls [\#101](https://github.com/Jawbone/JBChartView/issues/101)
- Change dot radius to dot diameter [\#99](https://github.com/Jawbone/JBChartView/issues/99)
- need Swift implementation details and example [\#80](https://github.com/Jawbone/JBChartView/issues/80)
- Add bar/line caching for only visible content. [\#61](https://github.com/Jawbone/JBChartView/issues/61)
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.1.2">1.1.2</a>
#### 01/03/14
- Added CGFloat support for chart heights intead of integers.
**Closed issues:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.1.1">1.1.1</a>
#### 01/02/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/7">#7</a>.
- Pie Chart support [\#149](https://github.com/Jawbone/JBChartView/issues/149)
- hi is it possible to have x,y value because in example there is no y value and only 2 x value [\#141](https://github.com/Jawbone/JBChartView/issues/141)
- imports without pods [\#140](https://github.com/Jawbone/JBChartView/issues/140)
- How can I group Bars? [\#139](https://github.com/Jawbone/JBChartView/issues/139)
- request: AreaChart - fillColorForLineAtLineIndex - add custom color for a specific X axis range [\#137](https://github.com/Jawbone/JBChartView/issues/137)
- smallest value is shown as a blank bar [\#136](https://github.com/Jawbone/JBChartView/issues/136)
- Is there any way I can use JBBarChartView as horizontal bars? [\#135](https://github.com/Jawbone/JBChartView/issues/135)
- Multiple colors to a line graph [\#134](https://github.com/Jawbone/JBChartView/issues/134)
- Overriding - \(void\)barChartView:\(JBBarChartView \*\)barChartView didSelectBarAtIndex:\(NSUInteger\)index is not showing selection view? [\#133](https://github.com/Jawbone/JBChartView/issues/133)
- Exception thrown on setState: [\#132](https://github.com/Jawbone/JBChartView/issues/132)
- X and Y scale and reference values [\#131](https://github.com/Jawbone/JBChartView/issues/131)
- Determine x-value of a certain point by a number instead of it's index in the input array? [\#130](https://github.com/Jawbone/JBChartView/issues/130)
- How to accomplish similar didUnselectBarChartView [\#129](https://github.com/Jawbone/JBChartView/issues/129)
- Is posible - scroll chart [\#126](https://github.com/Jawbone/JBChartView/issues/126)
- Crash when vertical value for horizontal at index x less than zero [\#125](https://github.com/Jawbone/JBChartView/issues/125)
- JBBarChartView does not display all the bars [\#124](https://github.com/Jawbone/JBChartView/issues/124)
- "automatically normalized across the entire chart" [\#123](https://github.com/Jawbone/JBChartView/issues/123)
- reloadData in viewDidLayoutSubviews does not trigger didDeselectLineInLineChartView on first selection [\#122](https://github.com/Jawbone/JBChartView/issues/122)
- Question [\#121](https://github.com/Jawbone/JBChartView/issues/121)
- Sublayers not properly resized [\#120](https://github.com/Jawbone/JBChartView/issues/120)
- It will be really cool if "while on tap on line charts dots I can get the dot object do some scale animation" or something? [\#119](https://github.com/Jawbone/JBChartView/issues/119)
- Is there any way I can pass new bar view while user selects particular bar? [\#117](https://github.com/Jawbone/JBChartView/issues/117)
- Typo error in README [\#114](https://github.com/Jawbone/JBChartView/issues/114)
- Dynamic/append values [\#113](https://github.com/Jawbone/JBChartView/issues/113)
- It needs better documentation [\#112](https://github.com/Jawbone/JBChartView/issues/112)
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.1.0">1.1.0</a>
#### 12/26/13
- Updated JBBarChartView datasource to request UIView subclasses for bars.
**Merged pull requests:**
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.0.3">1.0.3</a>
#### 12/23/13
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/4">#4</a>.
- Keep tooltip subviews above line subviews [\#144](https://github.com/Jawbone/JBChartView/pull/144) ([vocaro](https://github.com/vocaro))
- Fix crash and warnings that can occur when a chart line has no data [\#143](https://github.com/Jawbone/JBChartView/pull/143) ([vocaro](https://github.com/vocaro))
- Add automatically generated change log file. [\#142](https://github.com/Jawbone/JBChartView/pull/142) ([skywinder](https://github.com/skywinder))
- Update README.md [\#127](https://github.com/Jawbone/JBChartView/pull/127) ([paal123](https://github.com/paal123))
- Add ability to have the line start or end at any given point [\#116](https://github.com/Jawbone/JBChartView/pull/116) ([sebastianreloaded](https://github.com/sebastianreloaded))
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.0.2">1.0.2</a>
#### 12/17/13
- Additional fixes for issue <a href="https://github.com/Jawbone/JBChartView/pull/2">#2</a>.
## [v2.8.10](https://github.com/Jawbone/JBChartView/tree/v2.8.10) (2014-09-23)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.9...v2.8.10)
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.0.1">1.0.1</a>
#### (12/14/13)
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/2">#2</a>.
## [v2.8.9](https://github.com/Jawbone/JBChartView/tree/v2.8.9) (2014-09-22)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.8...v2.8.9)
## <a href="https://github.com/Jawbone/JBChartView/tree/v1.0">1.0</a>
#### 12/10/13
- Initial public release.
- Base line and bar charts.
- Basic customization; color, positioning, selections.
**Closed issues:**
- JBLineChartView doesn't resize its subviews [\#111](https://github.com/Jawbone/JBChartView/issues/111)
## [v2.8.8](https://github.com/Jawbone/JBChartView/tree/v2.8.8) (2014-09-20)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.7...v2.8.8)
**Fixed bugs:**
- iOS 8 warnings [\#110](https://github.com/Jawbone/JBChartView/issues/110)
**Closed issues:**
- Noob level tutorial [\#109](https://github.com/Jawbone/JBChartView/issues/109)
- Data points with uneavenly distributed x-values? [\#108](https://github.com/Jawbone/JBChartView/issues/108)
## [v2.8.7](https://github.com/Jawbone/JBChartView/tree/v2.8.7) (2014-09-09)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.6...v2.8.7)
**Implemented enhancements:**
- Add hide custom dot functionality [\#100](https://github.com/Jawbone/JBChartView/issues/100)
- Add footer padding [\#98](https://github.com/Jawbone/JBChartView/issues/98)
- DotView is hidden when inside selected table view cell [\#82](https://github.com/Jawbone/JBChartView/issues/82)
**Closed issues:**
- There should be flexibility to change to touch point to nearest data point so vertical selection view just jumps from one data point to another in JBLineChartView. [\#105](https://github.com/Jawbone/JBChartView/issues/105)
- barWidth Method and barPadding property should be in JBBarChartView header file. [\#104](https://github.com/Jawbone/JBChartView/issues/104)
- Why minimum and maximum should be positive? [\#102](https://github.com/Jawbone/JBChartView/issues/102)
**Merged pull requests:**
- iOS Framework Support [\#107](https://github.com/Jawbone/JBChartView/pull/107) ([thefirstnikhil](https://github.com/thefirstnikhil))
- Only call `numberOfLinesInLineChartView:` once per loop. [\#106](https://github.com/Jawbone/JBChartView/pull/106) ([eventualbuddha](https://github.com/eventualbuddha))
## [v2.8.6](https://github.com/Jawbone/JBChartView/tree/v2.8.6) (2014-08-29)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.5...v2.8.6)
## [v2.8.5](https://github.com/Jawbone/JBChartView/tree/v2.8.5) (2014-08-28)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.4...v2.8.5)
**Implemented enhancements:**
- Invert option for bar charts [\#97](https://github.com/Jawbone/JBChartView/issues/97)
## [v2.8.4](https://github.com/Jawbone/JBChartView/tree/v2.8.4) (2014-08-27)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.3...v2.8.4)
## [v2.8.3](https://github.com/Jawbone/JBChartView/tree/v2.8.3) (2014-08-26)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.2...v2.8.3)
**Implemented enhancements:**
- return type of barPaddingForBarChartView: [\#93](https://github.com/Jawbone/JBChartView/issues/93)
- Custom dot functionality [\#92](https://github.com/Jawbone/JBChartView/issues/92)
## [v2.8.2](https://github.com/Jawbone/JBChartView/tree/v2.8.2) (2014-08-26)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.1...v2.8.2)
**Fixed bugs:**
- Selection view width should equal bar width [\#96](https://github.com/Jawbone/JBChartView/issues/96)
**Closed issues:**
- Changing dot radius in dotRadiusForLineAtLineIndex has no effect [\#95](https://github.com/Jawbone/JBChartView/issues/95)
## [v2.8.1](https://github.com/Jawbone/JBChartView/tree/v2.8.1) (2014-08-23)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.8.0...v2.8.1)
## [v2.8.0](https://github.com/Jawbone/JBChartView/tree/v2.8.0) (2014-08-15)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.7.4...v2.8.0)
**Closed issues:**
- Don't bring selection view to front with line view [\#89](https://github.com/Jawbone/JBChartView/issues/89)
**Merged pull requests:**
- Add per-line vertical selection color support. [\#90](https://github.com/Jawbone/JBChartView/pull/90) ([mszaro](https://github.com/mszaro))
## [v2.7.4](https://github.com/Jawbone/JBChartView/tree/v2.7.4) (2014-08-15)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.7.3...v2.7.4)
**Implemented enhancements:**
- Not able to create Y-Axis labels or background grid [\#20](https://github.com/Jawbone/JBChartView/issues/20)
**Closed issues:**
- \[Enhancement\] Provide an option to disable Y-axis normalization for line graphs [\#88](https://github.com/Jawbone/JBChartView/issues/88)
- Add left padding to the graph for y-axis labels [\#87](https://github.com/Jawbone/JBChartView/issues/87)
- Error Protocol not implemented [\#86](https://github.com/Jawbone/JBChartView/issues/86)
- What if I want to animate the LineChartView progression? [\#85](https://github.com/Jawbone/JBChartView/issues/85)
- Enabling smooth lines in line chart view results in line graph clipping \(Out of bounds\)? [\#83](https://github.com/Jawbone/JBChartView/issues/83)
## [v2.7.3](https://github.com/Jawbone/JBChartView/tree/v2.7.3) (2014-08-07)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.7.2...v2.7.3)
**Closed issues:**
- Can I animate bar charts? [\#79](https://github.com/Jawbone/JBChartView/issues/79)
- Create generic dataSource and delegate for extensibility. [\#78](https://github.com/Jawbone/JBChartView/issues/78)
## [v2.7.2](https://github.com/Jawbone/JBChartView/tree/v2.7.2) (2014-08-04)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.7.1...v2.7.2)
## [v2.7.1](https://github.com/Jawbone/JBChartView/tree/v2.7.1) (2014-08-04)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.7.0...v2.7.1)
**Closed issues:**
- Typo in JBBarChartView.h [\#77](https://github.com/Jawbone/JBChartView/issues/77)
- Refactor datasource and delegate functions [\#76](https://github.com/Jawbone/JBChartView/issues/76)
## [v2.7.0](https://github.com/Jawbone/JBChartView/tree/v2.7.0) (2014-08-02)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.6.3...v2.7.0)
**Closed issues:**
- Incorrect padding on line widths [\#75](https://github.com/Jawbone/JBChartView/issues/75)
## [v2.6.3](https://github.com/Jawbone/JBChartView/tree/v2.6.3) (2014-07-31)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.6.2...v2.6.3)
## [v2.6.2](https://github.com/Jawbone/JBChartView/tree/v2.6.2) (2014-07-25)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.6.1...v2.6.2)
## [v2.6.1](https://github.com/Jawbone/JBChartView/tree/v2.6.1) (2014-07-25)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.6.0...v2.6.1)
**Merged pull requests:**
- iOS 6 support [\#74](https://github.com/Jawbone/JBChartView/pull/74) ([luosheng](https://github.com/luosheng))
## [v2.6.0](https://github.com/Jawbone/JBChartView/tree/v2.6.0) (2014-07-24)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.5.5...v2.6.0)
**Closed issues:**
- Allow setting views for lines as well as bars [\#73](https://github.com/Jawbone/JBChartView/issues/73)
- Requires iOS 7 or later [\#72](https://github.com/Jawbone/JBChartView/issues/72)
- How to Know the x,width of each bar [\#70](https://github.com/Jawbone/JBChartView/issues/70)
- Multiple y-axis [\#69](https://github.com/Jawbone/JBChartView/issues/69)
- NSInternalInconsistencyException - JBLineChartView // dataSource must implement [\#68](https://github.com/Jawbone/JBChartView/issues/68)
- Zoom and scrolling? \(Question\) [\#65](https://github.com/Jawbone/JBChartView/issues/65)
- Support for missing data points rather than going to 0? [\#63](https://github.com/Jawbone/JBChartView/issues/63)
- Interesting behavior 'barViewAtIndex' and 'colorForBarViewAtIndex'. [\#62](https://github.com/Jawbone/JBChartView/issues/62)
- In LineChart x-axis, splits into more numbers and not able view x-axis last point [\#60](https://github.com/Jawbone/JBChartView/issues/60)
- Overlay more than 1 chart? [\#59](https://github.com/Jawbone/JBChartView/issues/59)
- Footer Views - Can they be perpendicular to the x-axis [\#58](https://github.com/Jawbone/JBChartView/issues/58)
**Merged pull requests:**
- Fill Color on Line Chart [\#71](https://github.com/Jawbone/JBChartView/pull/71) ([legranddamien](https://github.com/legranddamien))
- Added documentation for usage in a Swift project [\#67](https://github.com/Jawbone/JBChartView/pull/67) ([jonparker](https://github.com/jonparker))
## [v2.5.5](https://github.com/Jawbone/JBChartView/tree/v2.5.5) (2014-05-14)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.5.4...v2.5.5)
**Implemented enhancements:**
- Ability to draw lines with negative values [\#51](https://github.com/Jawbone/JBChartView/issues/51)
**Closed issues:**
- How to adjust selected bar height for LineChart in demo project [\#56](https://github.com/Jawbone/JBChartView/issues/56)
- Line Chart Collapse Animation Changed? [\#54](https://github.com/Jawbone/JBChartView/issues/54)
**Merged pull requests:**
- Fixed barView's frame. [\#57](https://github.com/Jawbone/JBChartView/pull/57) ([pala](https://github.com/pala))
- Update sample code in readme [\#55](https://github.com/Jawbone/JBChartView/pull/55) ([pala](https://github.com/pala))
## [v2.5.4](https://github.com/Jawbone/JBChartView/tree/v2.5.4) (2014-05-07)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.5.3...v2.5.4)
**Merged pull requests:**
- Add delegate method barChartView:colorForBarViewAtIndex: to JBBarChartViewDataSource [\#53](https://github.com/Jawbone/JBChartView/pull/53) ([skywinder](https://github.com/skywinder))
- Compiling warrnings and typos [\#52](https://github.com/Jawbone/JBChartView/pull/52) ([skywinder](https://github.com/skywinder))
## [v2.5.3](https://github.com/Jawbone/JBChartView/tree/v2.5.3) (2014-05-06)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.5.2...v2.5.3)
## [v2.5.2](https://github.com/Jawbone/JBChartView/tree/v2.5.2) (2014-05-06)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.5.1...v2.5.2)
## [v2.5.1](https://github.com/Jawbone/JBChartView/tree/v2.5.1) (2014-05-05)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.5.0...v2.5.1)
**Closed issues:**
- non-evenly distributed plots [\#50](https://github.com/Jawbone/JBChartView/issues/50)
- Using minimum of 0 as default [\#48](https://github.com/Jawbone/JBChartView/issues/48)
## [v2.5.0](https://github.com/Jawbone/JBChartView/tree/v2.5.0) (2014-05-04)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.4.3...v2.5.0)
## [v2.4.3](https://github.com/Jawbone/JBChartView/tree/v2.4.3) (2014-05-04)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.4.2...v2.4.3)
**Closed issues:**
- Bars not drawn when all have the same height [\#47](https://github.com/Jawbone/JBChartView/issues/47)
- Moving podspec to root [\#46](https://github.com/Jawbone/JBChartView/issues/46)
**Merged pull requests:**
- fixed typo, renamed mininum -\> minimum [\#49](https://github.com/Jawbone/JBChartView/pull/49) ([simonnickel](https://github.com/simonnickel))
## [v2.4.2](https://github.com/Jawbone/JBChartView/tree/v2.4.2) (2014-05-01)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.4.1...v2.4.2)
## [v2.4.1](https://github.com/Jawbone/JBChartView/tree/v2.4.1) (2014-04-30)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.4.0...v2.4.1)
**Implemented enhancements:**
- Curved line charts [\#23](https://github.com/Jawbone/JBChartView/issues/23)
**Closed issues:**
- JBChartView demo footerview problem [\#44](https://github.com/Jawbone/JBChartView/issues/44)
**Merged pull requests:**
- Smooth curve fix [\#45](https://github.com/Jawbone/JBChartView/pull/45) ([ktran03](https://github.com/ktran03))
## [v2.4.0](https://github.com/Jawbone/JBChartView/tree/v2.4.0) (2014-04-28)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.3.0...v2.4.0)
**Closed issues:**
- Aligning X-axis, padding? [\#43](https://github.com/Jawbone/JBChartView/issues/43)
- `JBLineChartFooterView` Value Marks are Inaccurate [\#41](https://github.com/Jawbone/JBChartView/issues/41)
**Merged pull requests:**
- smooth curve using bezierpath [\#39](https://github.com/Jawbone/JBChartView/pull/39) ([ktran03](https://github.com/ktran03))
## [v2.3.0](https://github.com/Jawbone/JBChartView/tree/v2.3.0) (2014-04-18)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.2.0...v2.3.0)
**Closed issues:**
- Crash, lineChartView "must implement numberOfPointsInLineChartView" ? [\#38](https://github.com/Jawbone/JBChartView/issues/38)
## [v2.2.0](https://github.com/Jawbone/JBChartView/tree/v2.2.0) (2014-04-14)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.1.6...v2.2.0)
**Closed issues:**
- Typo in readme? [\#36](https://github.com/Jawbone/JBChartView/issues/36)
- Nav bar background remains black [\#35](https://github.com/Jawbone/JBChartView/issues/35)
**Merged pull requests:**
- Added delegate method to configure the width of the vertical selection bar in a line chart. [\#37](https://github.com/Jawbone/JBChartView/pull/37) ([ghost](https://github.com/ghost))
## [v2.1.6](https://github.com/Jawbone/JBChartView/tree/v2.1.6) (2014-04-11)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.1.5...v2.1.6)
**Closed issues:**
- `showsLineSelection` Does Nothing [\#33](https://github.com/Jawbone/JBChartView/issues/33)
- cocoapods [\#31](https://github.com/Jawbone/JBChartView/issues/31)
## [v2.1.5](https://github.com/Jawbone/JBChartView/tree/v2.1.5) (2014-04-10)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.1.4...v2.1.5)
**Merged pull requests:**
- JBChartView: needs initWithCoder initializer for inflation from a xib [\#30](https://github.com/Jawbone/JBChartView/pull/30) ([gumbypp](https://github.com/gumbypp))
## [v2.1.4](https://github.com/Jawbone/JBChartView/tree/v2.1.4) (2014-04-10)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.1.3...v2.1.4)
**Closed issues:**
- Stach bars? [\#29](https://github.com/Jawbone/JBChartView/issues/29)
- Problem with Bar Height [\#28](https://github.com/Jawbone/JBChartView/issues/28)
- Selection does not work without Auto Layout in iPhone 3.5" [\#27](https://github.com/Jawbone/JBChartView/issues/27)
## [v2.1.3](https://github.com/Jawbone/JBChartView/tree/v2.1.3) (2014-04-03)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.1.2...v2.1.3)
## [v2.1.2](https://github.com/Jawbone/JBChartView/tree/v2.1.2) (2014-04-02)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.1.1...v2.1.2)
## [v2.1.1](https://github.com/Jawbone/JBChartView/tree/v2.1.1) (2014-04-02)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.1.0...v2.1.1)
**Closed issues:**
- representing negative values [\#26](https://github.com/Jawbone/JBChartView/issues/26)
- Real time [\#25](https://github.com/Jawbone/JBChartView/issues/25)
## [v2.1.0](https://github.com/Jawbone/JBChartView/tree/v2.1.0) (2014-03-31)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.0.2...v2.1.0)
## [v2.0.2](https://github.com/Jawbone/JBChartView/tree/v2.0.2) (2014-03-27)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.0.1...v2.0.2)
**Closed issues:**
- Negative Bars? [\#24](https://github.com/Jawbone/JBChartView/issues/24)
## [v2.0.1](https://github.com/Jawbone/JBChartView/tree/v2.0.1) (2014-03-19)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v2.0.0...v2.0.1)
**Closed issues:**
- NSAssert on bar height in JBBarChartView, \> 0 when it should be \>= [\#22](https://github.com/Jawbone/JBChartView/issues/22)
## [v2.0.0](https://github.com/Jawbone/JBChartView/tree/v2.0.0) (2014-03-19)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.1.6...v2.0.0)
**Implemented enhancements:**
- Multiple Lines on chart [\#6](https://github.com/Jawbone/JBChartView/issues/6)
**Closed issues:**
- JBBarChartView Bar Height Problem With Storyboard/Autolayout [\#19](https://github.com/Jawbone/JBChartView/issues/19)
- blank result [\#18](https://github.com/Jawbone/JBChartView/issues/18)
- Bar Highlight Offset Issue [\#17](https://github.com/Jawbone/JBChartView/issues/17)
- Following the tutorial creates an empty/blank view [\#16](https://github.com/Jawbone/JBChartView/issues/16)
**Merged pull requests:**
- Multiple Line Support & Tooltips [\#21](https://github.com/Jawbone/JBChartView/pull/21) ([terryworona](https://github.com/terryworona))
## [v1.1.6](https://github.com/Jawbone/JBChartView/tree/v1.1.6) (2014-03-03)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.1.5...v1.1.6)
**Merged pull requests:**
- Added customization for line width [\#15](https://github.com/Jawbone/JBChartView/pull/15) ([kmcbride](https://github.com/kmcbride))
- fix spelling mistake [\#14](https://github.com/Jawbone/JBChartView/pull/14) ([Undo1](https://github.com/Undo1))
## [v1.1.5](https://github.com/Jawbone/JBChartView/tree/v1.1.5) (2014-02-12)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.1.4...v1.1.5)
## [v1.1.4](https://github.com/Jawbone/JBChartView/tree/v1.1.4) (2014-02-06)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.1.3...v1.1.4)
**Closed issues:**
- What about ios6 [\#13](https://github.com/Jawbone/JBChartView/issues/13)
- Could the Bar Chart data be nil ? [\#12](https://github.com/Jawbone/JBChartView/issues/12)
## [v1.1.3](https://github.com/Jawbone/JBChartView/tree/v1.1.3) (2014-01-06)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.1.2...v1.1.3)
**Closed issues:**
- heightForIndex should return CGFloat instead of NSInteger [\#9](https://github.com/Jawbone/JBChartView/issues/9)
**Merged pull requests:**
- Fixes small typos in README [\#11](https://github.com/Jawbone/JBChartView/pull/11) ([sampage](https://github.com/sampage))
## [v1.1.2](https://github.com/Jawbone/JBChartView/tree/v1.1.2) (2014-01-03)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.1.1...v1.1.2)
## [v1.1.1](https://github.com/Jawbone/JBChartView/tree/v1.1.1) (2014-01-02)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.1.0...v1.1.1)
**Closed issues:**
- reloadData is not reducing height of other bars [\#7](https://github.com/Jawbone/JBChartView/issues/7)
- Add barViewAtIndex: to datasource [\#5](https://github.com/Jawbone/JBChartView/issues/5)
**Merged pull requests:**
- Reset cached max height on data reload Fixes \#7 [\#8](https://github.com/Jawbone/JBChartView/pull/8) ([l4u](https://github.com/l4u))
## [v1.1.0](https://github.com/Jawbone/JBChartView/tree/v1.1.0) (2013-12-26)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.0.3...v1.1.0)
## [v1.0.3](https://github.com/Jawbone/JBChartView/tree/v1.0.3) (2013-12-23)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.0.2...v1.0.3)
**Closed issues:**
- Single press on bar [\#3](https://github.com/Jawbone/JBChartView/issues/3)
## [v1.0.2](https://github.com/Jawbone/JBChartView/tree/v1.0.2) (2013-12-17)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.0.1...v1.0.2)
## [v1.0.1](https://github.com/Jawbone/JBChartView/tree/v1.0.1) (2013-12-15)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v1.0...v1.0.1)
**Merged pull requests:**
- If there is no footer view, bars won't be added to the chart. [\#2](https://github.com/Jawbone/JBChartView/pull/2) ([joelkraut](https://github.com/joelkraut))
## [v1.0](https://github.com/Jawbone/JBChartView/tree/v1.0) (2013-12-11)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/0.2.0...v1.0)
**Merged pull requests:**
- JBChartViewDemo and JBChartView [\#1](https://github.com/Jawbone/JBChartView/pull/1) ([terryworona](https://github.com/terryworona))
## [0.2.0](https://github.com/Jawbone/JBChartView/tree/0.2.0) (2013-08-20)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/1.0...0.2.0)
## [1.0](https://github.com/Jawbone/JBChartView/tree/1.0) (2012-04-23)
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/1.0.0...1.0)
## [1.0.0](https://github.com/Jawbone/JBChartView/tree/1.0.0) (2012-04-23)
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
+39 -20
View File
@@ -9,24 +9,9 @@
// Views
#import "JBChartView.h"
@protocol JBBarChartViewDataSource;
@protocol JBBarChartViewDelegate;
@class JBBarChartView;
@interface JBBarChartView : JBChartView
@property (nonatomic, weak) id<JBBarChartViewDataSource> dataSource;
@property (nonatomic, weak) id<JBBarChartViewDelegate> delegate;
/**
* Vertical highlight overlayed on bar during touch events.
*
* Default: YES.
*/
@property (nonatomic, assign) BOOL showsVerticalSelection;
@end
@protocol JBBarChartViewDataSource <NSObject>
@protocol JBBarChartViewDataSource <JBChartViewDataSource>
@required
@@ -55,12 +40,12 @@
@end
@protocol JBBarChartViewDelegate <NSObject>
@protocol JBBarChartViewDelegate <JBChartViewDelegate>
@required
/**
* Height for a bar at a given index (left to right). There is no ceiling on the the height;
* Height for a bar at a given index (left to right). There is no ceiling on the the height;
* the chart will automatically normalize all values between the overal min and max heights.
*
* @param barChartView The bar chart object requesting this information.
@@ -126,6 +111,40 @@
*
* @return Horizontal width (in pixels) between each bar.
*/
- (NSUInteger)barPaddingForBarChartView:(JBBarChartView *)barChartView;
- (CGFloat)barPaddingForBarChartView:(JBBarChartView *)barChartView;
@end
@interface JBBarChartView : JBChartView
@property (nonatomic, weak) id<JBBarChartViewDataSource> dataSource;
@property (nonatomic, weak) id<JBBarChartViewDelegate> delegate;
/**
* Vertical highlight overlayed on bar during touch events.
*
* Default: YES.
*/
@property (nonatomic, assign) BOOL showsVerticalSelection;
/*
* Bars can be (vertically) positoned top to bottom instead of bottom up.
* If this property is set to YES, both the bar and the selection view will be inverted.
* For the inverted orientation to take effect, reloadData must be called.
*
* Default: NO.
*/
@property (nonatomic, assign, getter=isInverted) BOOL inverted;
/**
* The bar view at a particular index.
*
* Default: nil.
*
* @param index The 0-based index of a given bar (left to right, x-axis).
*
* @return The UIView representing the bar view at a given index or nil if the index is out of range.
*/
- (UIView *)barViewAtIndex:(NSUInteger)index;
@end
+153 -63
View File
@@ -12,7 +12,7 @@
CGFloat static const kJBBarChartViewBarBasePaddingMutliplier = 50.0f;
CGFloat static const kJBBarChartViewUndefinedCachedHeight = -1.0f;
CGFloat static const kJBBarChartViewStateAnimationDuration = 0.05f;
CGFloat static const kJBBarChartViewPopOffset = 10.0f; // used to offset bars for 'pop' animations
CGFloat static const kJBBarChartViewStatePopOffset = 10.0f;
NSInteger static const kJBBarChartViewUndefinedBarIndex = -1;
// Colors (JBChartView)
@@ -29,6 +29,7 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
@property (nonatomic, strong) NSDictionary *chartDataDictionary; // key = column, value = height
@property (nonatomic, strong) NSArray *barViews;
@property (nonatomic, strong) NSArray *cachedBarViewHeights;
@property (nonatomic, assign) CGFloat barPadding;
@property (nonatomic, assign) CGFloat cachedMaxHeight;
@property (nonatomic, assign) CGFloat cachedMinHeight;
@@ -40,9 +41,8 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
// View quick accessors
- (CGFloat)availableHeight;
- (CGFloat)normalizedHeightForRawHeight:(NSNumber*)rawHeight;
- (CGFloat)normalizedHeightForRawHeight:(NSNumber *)rawHeight;
- (CGFloat)barWidth;
- (CGFloat)popOffset;
// Touch helpers
- (NSInteger)barViewIndexForPoint:(CGPoint)point;
@@ -57,6 +57,9 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
@implementation JBBarChartView
@dynamic dataSource;
@dynamic delegate;
#pragma mark - Alloc/Init
+ (void)initialize
@@ -167,9 +170,12 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
[barView removeFromSuperview];
}
self.cachedBarViewHeights = nil;
CGFloat xOffset = 0;
NSUInteger index = 0;
NSMutableArray *mutableBarViews = [NSMutableArray array];
NSMutableArray *mutableCachedBarViewHeights = [NSMutableArray array];
for (NSNumber *key in [[self.chartDataDictionary allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
UIView *barView = nil; // since all bars are visible at once, no need to cache this view
@@ -195,11 +201,13 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
barView.backgroundColor = backgroundColor;
}
barView.tag = index;
CGFloat height = [self normalizedHeightForRawHeight:[self.chartDataDictionary objectForKey:key]];
CGFloat extensionHeight = height > 0.0 ? kJBBarChartViewPopOffset : 0.0;
barView.frame = CGRectMake(xOffset, self.bounds.size.height - height - self.footerView.frame.size.height, [self barWidth], height + extensionHeight);
barView.frame = CGRectMake(xOffset, self.bounds.size.height - height - self.footerView.frame.size.height, [self barWidth], height);
[mutableBarViews addObject:barView];
[mutableCachedBarViewHeights addObject:[NSNumber numberWithFloat:height]];
// Add new bar
if (self.footerView)
@@ -215,6 +223,7 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
index++;
}
self.barViews = [NSArray arrayWithArray:mutableBarViews];
self.cachedBarViewHeights = [NSArray arrayWithArray:mutableCachedBarViewHeights];
};
/*
@@ -229,7 +238,25 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
self.verticalSelectionView = nil;
}
self.verticalSelectionView = [[JBChartVerticalSelectionView alloc] initWithFrame:CGRectMake(0, 0, [self barWidth], self.bounds.size.height - self.footerView.frame.size.height)];
CGFloat verticalSelectionViewHeight = self.bounds.size.height - self.headerView.frame.size.height - self.footerView.frame.size.height - self.headerPadding - self.footerPadding;
if ([self.dataSource respondsToSelector:@selector(shouldExtendSelectionViewIntoHeaderPaddingForChartView:)])
{
if ([self.dataSource shouldExtendSelectionViewIntoHeaderPaddingForChartView:self])
{
verticalSelectionViewHeight += self.headerPadding;
}
}
if ([self.dataSource respondsToSelector:@selector(shouldExtendSelectionViewIntoFooterPaddingForChartView:)])
{
if ([self.dataSource shouldExtendSelectionViewIntoFooterPaddingForChartView:self])
{
verticalSelectionViewHeight += self.footerPadding;
}
}
self.verticalSelectionView = [[JBChartVerticalSelectionView alloc] initWithFrame:CGRectMake(0, 0, [self barWidth], verticalSelectionViewHeight)];
self.verticalSelectionView.alpha = 0.0;
self.verticalSelectionView.hidden = !self.showsVerticalSelection;
if ([self.delegate respondsToSelector:@selector(barSelectionColorForBarChartView:)])
@@ -248,6 +275,8 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
{
[self addSubview:self.verticalSelectionView];
}
self.verticalSelectionView.transform = self.inverted ? CGAffineTransformMakeScale(1.0, -1.0) : CGAffineTransformIdentity;
};
createDataDictionaries();
@@ -267,10 +296,10 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
- (CGFloat)availableHeight
{
return self.bounds.size.height - self.headerView.frame.size.height - self.footerView.frame.size.height - self.headerPadding;
return self.bounds.size.height - self.headerView.frame.size.height - self.footerView.frame.size.height - self.headerPadding - self.footerPadding;
}
- (CGFloat)normalizedHeightForRawHeight:(NSNumber*)rawHeight
- (CGFloat)normalizedHeightForRawHeight:(NSNumber *)rawHeight
{
CGFloat minHeight = [self minimumValue];
CGFloat maxHeight = [self maximumValue];
@@ -278,7 +307,7 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
if ((maxHeight - minHeight) <= 0)
{
return 0;
return [self availableHeight];
}
return ((value - minHeight) / (maxHeight - minHeight)) * [self availableHeight];
@@ -296,42 +325,85 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
return 0;
}
- (CGFloat)popOffset
{
return self.bounds.size.height - self.footerView.frame.size.height;
}
#pragma mark - Setters
- (void)setState:(JBChartViewState)state animated:(BOOL)animated force:(BOOL)force callback:(void (^)())callback
{
[super setState:state animated:animated force:force callback:callback];
__weak JBBarChartView* weakSelf = self;
void (^updateBarView)(UIView *barView, BOOL popBar);
updateBarView = ^(UIView *barView, BOOL popBar) {
if (weakSelf.inverted)
{
if (weakSelf.state == JBChartViewStateExpanded)
{
if (popBar)
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, barView.frame.size.width, [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue] + kJBBarChartViewStatePopOffset);
}
else
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, barView.frame.size.width, [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue]);
}
}
else if (weakSelf.state == JBChartViewStateCollapsed)
{
if (popBar)
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, barView.frame.size.width, [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue] + kJBBarChartViewStatePopOffset);
}
else
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, barView.frame.size.width, 0.0f);
}
}
}
else
{
if (weakSelf.state == JBChartViewStateExpanded)
{
if (popBar)
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.bounds.size.height - weakSelf.footerView.frame.size.height - weakSelf.footerPadding - [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue] - kJBBarChartViewStatePopOffset, barView.frame.size.width, [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue] + kJBBarChartViewStatePopOffset);
}
else
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.bounds.size.height - weakSelf.footerView.frame.size.height - weakSelf.footerPadding - [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue], barView.frame.size.width, [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue]);
}
}
else if (weakSelf.state == JBChartViewStateCollapsed)
{
if (popBar)
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.bounds.size.height - weakSelf.footerView.frame.size.height - weakSelf.footerPadding - [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue] - kJBBarChartViewStatePopOffset, barView.frame.size.width, [[weakSelf.cachedBarViewHeights objectAtIndex:barView.tag] floatValue] + kJBBarChartViewStatePopOffset);
}
else
{
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.bounds.size.height, barView.frame.size.width, 0.0f);
}
}
}
};
dispatch_block_t callbackCopy = [callback copy];
if ([self.barViews count] > 0)
{
if (animated)
{
CGFloat popOffset = [self popOffset];
NSUInteger index = 0;
for (UIView *barView in self.barViews)
{
[UIView animateWithDuration:kJBBarChartViewStateAnimationDuration delay:(kJBBarChartViewStateAnimationDuration * 0.5) * index options:UIViewAnimationOptionBeginFromCurrentState animations:^{
barView.frame = CGRectMake(barView.frame.origin.x, popOffset - barView.frame.size.height, barView.frame.size.width, barView.frame.size.height);
updateBarView(barView, YES);
} completion:^(BOOL finished) {
[UIView animateWithDuration:kJBBarChartViewStateAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
if (state == JBChartViewStateExpanded)
{
barView.frame = CGRectMake(barView.frame.origin.x, popOffset - barView.frame.size.height + kJBBarChartViewPopOffset, barView.frame.size.width, barView.frame.size.height);
}
else if (state == JBChartViewStateCollapsed)
{
barView.frame = CGRectMake(barView.frame.origin.x, self.bounds.size.height, barView.frame.size.width, barView.frame.size.height);
}
updateBarView(barView, NO);
} completion:^(BOOL lastBarFinished) {
if (index == [self.barViews count] - 1)
if ((NSUInteger)barView.tag == [self.barViews count] - 1)
{
if (callbackCopy)
{
@@ -347,14 +419,7 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
{
for (UIView *barView in self.barViews)
{
if (state == JBChartViewStateExpanded)
{
barView.frame = CGRectMake(barView.frame.origin.x, (self.bounds.size.height + kJBBarChartViewPopOffset) - (barView.frame.size.height + self.footerView.frame.size.height), barView.frame.size.width, barView.frame.size.height);
}
else if (state == JBChartViewStateCollapsed)
{
barView.frame = CGRectMake(barView.frame.origin.x, self.bounds.size.height, barView.frame.size.width, barView.frame.size.height);
}
updateBarView(barView, NO);
}
if (callbackCopy)
{
@@ -376,6 +441,33 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
[self setState:state animated:animated force:NO callback:callback];
}
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible animated:(BOOL)animated
{
_verticalSelectionViewVisible = verticalSelectionViewVisible;
if (animated)
{
[UIView animateWithDuration:kJBChartViewDefaultAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.verticalSelectionView.alpha = self.verticalSelectionViewVisible ? 1.0 : 0.0;
} completion:nil];
}
else
{
self.verticalSelectionView.alpha = _verticalSelectionViewVisible ? 1.0 : 0.0;
}
}
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible
{
[self setVerticalSelectionViewVisible:verticalSelectionViewVisible animated:NO];
}
- (void)setShowsVerticalSelection:(BOOL)showsVerticalSelection
{
_showsVerticalSelection = showsVerticalSelection;
self.verticalSelectionView.hidden = _showsVerticalSelection ? NO : YES;
}
#pragma mark - Getters
- (CGFloat)cachedMinHeight
@@ -416,6 +508,15 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
return self.cachedMaxHeight;
}
- (UIView *)barViewAtIndex:(NSUInteger)index
{
if (index < [self.barViews count])
{
return [self.barViews objectAtIndex:index];
}
return nil;
}
#pragma mark - Touch Helpers
- (NSInteger)barViewIndexForPoint:(CGPoint)point
@@ -472,6 +573,24 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
CGRect barViewFrame = barView.frame;
CGRect selectionViewFrame = self.verticalSelectionView.frame;
selectionViewFrame.origin.x = barViewFrame.origin.x;
selectionViewFrame.size.width = barViewFrame.size.width;
if ([self.dataSource respondsToSelector:@selector(shouldExtendSelectionViewIntoHeaderPaddingForChartView:)])
{
if ([self.dataSource shouldExtendSelectionViewIntoHeaderPaddingForChartView:self])
{
selectionViewFrame.origin.y = self.headerView.frame.size.height;
}
else
{
selectionViewFrame.origin.y = self.headerView.frame.size.height + self.headerPadding;
}
}
else
{
selectionViewFrame.origin.y = self.headerView.frame.size.height + self.headerPadding;
}
self.verticalSelectionView.frame = selectionViewFrame;
[self setVerticalSelectionViewVisible:YES animated:YES];
@@ -501,35 +620,6 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
}
}
#pragma mark - Setters
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible animated:(BOOL)animated
{
_verticalSelectionViewVisible = verticalSelectionViewVisible;
if (animated)
{
[UIView animateWithDuration:kJBChartViewDefaultAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.verticalSelectionView.alpha = self.verticalSelectionViewVisible ? 1.0 : 0.0;
} completion:nil];
}
else
{
self.verticalSelectionView.alpha = _verticalSelectionViewVisible ? 1.0 : 0.0;
}
}
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible
{
[self setVerticalSelectionViewVisible:verticalSelectionViewVisible animated:NO];
}
- (void)setShowsVerticalSelection:(BOOL)showsVerticalSelection
{
_showsVerticalSelection = showsVerticalSelection;
self.verticalSelectionView.hidden = _showsVerticalSelection ? NO : YES;
}
#pragma mark - Touches
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+53
View File
@@ -7,9 +7,12 @@
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
extern CGFloat const kJBChartViewDefaultAnimationDuration;
@class JBChartView;
/**
* At a minimum, a chart can support two states, along with animations to-and-from.
*/
@@ -24,8 +27,48 @@ typedef NS_ENUM(NSInteger, JBChartViewState){
JBChartViewStateCollapsed
};
@protocol JBChartViewDataSource <NSObject>
@optional
/**
* Returns whether or not the chart's selection view should extend into the header padding.
*
* Default: NO
*
* @param chartView The chart object requesting this information.
*
* @return Whether or not a chart's selection view should extend into the header padding.
*/
- (BOOL)shouldExtendSelectionViewIntoHeaderPaddingForChartView:(JBChartView *)chartView;
/**
* Returns whether or not the chart's selection view should extend into the footer padding.
*
* Default: NO
*
* @param chartView The chart object requesting this information.
*
* @return Whether or not a chart's selection view should extend into the footer padding.
*/
- (BOOL)shouldExtendSelectionViewIntoFooterPaddingForChartView:(JBChartView *)chartView;
@end
@protocol JBChartViewDelegate <NSObject>
// Extend (via subclass) to add custom functionality
@end
@interface JBChartView : UIView
/*
* Base dataSource and delegate protocols.
*/
@property (nonatomic, weak) id<JBChartViewDataSource> dataSource;
@property (nonatomic, weak) id<JBChartViewDelegate> delegate;
/**
* Header and footer views are shown above and below the chart respectively.
* Each view will be stretched horizontally to fill width of chart.
@@ -36,9 +79,18 @@ typedef NS_ENUM(NSInteger, JBChartViewState){
/**
* The vertical padding between the header and highest chart point (bar, line, etc).
* By default, the selection view will extend into the header padding area. To modify this behaviour,
* implement the dataSource protocol - (BOOL)shouldExtendSelectionViewIntoHeaderPaddingForChartView:(JBChartView *)chartView.
*/
@property (nonatomic, assign) CGFloat headerPadding;
/**
* The vertical padding between the footer and lowest chart point (bar, line, etc).
* By default, the selection view will extend into the footer padding area. To modify this behaviour,
* implement the dataSource protocol - (BOOL)shouldExtendSelectionViewIntoFooterPaddingForChartView:(JBChartView *)chartView.
*/
@property (nonatomic, assign) CGFloat footerPadding;
/**
* The minimum and maxmimum values of the chart.
* If no value(s) are supplied:
@@ -68,6 +120,7 @@ typedef NS_ENUM(NSInteger, JBChartViewState){
/**
* Acts similiar to a UITableView's reloadData function.
* The entire chart will be torn down and re-constructed via datasource and delegate protocls.
* If a chart's frame changes, reloadData must be called directly afterwards for the changes to take effect.
*/
- (void)reloadData;
+85 -41
View File
@@ -8,6 +8,8 @@
#import "JBChartView.h"
@class JBLineChartView;
/**
* Current support for two line styles: solid (default) and dashed.
*/
@@ -22,33 +24,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
JBLineChartViewLineStyleDashed
};
@protocol JBLineChartViewDataSource;
@protocol JBLineChartViewDelegate;
@interface JBLineChartView : JBChartView
@property (nonatomic, weak) id<JBLineChartViewDataSource> dataSource;
@property (nonatomic, weak) id<JBLineChartViewDelegate> delegate;
/**
* Vertical highlight overlayed on a line graph during touch events.
*
* Default: YES.
*/
@property (nonatomic, assign) BOOL showsVerticalSelection;
/**
* A highlight shown on a line within the graph during touch events. The highlighted line
* is the closest line to the touch point and corresponds to the lineIndex delegatd back via
* didSelectChartAtHorizontalIndex:atLineIndex: and didUnSlectChartAtHorizontalIndex:atLineIndex:
*
* Default: YES.
*/
@property (nonatomic, assign) BOOL showsLineSelection;
@end
@protocol JBLineChartViewDataSource <NSObject>
@protocol JBLineChartViewDataSource <JBChartViewDataSource>
@required
@@ -78,7 +54,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
* Dot size is relative to the line width and not adjustable.
* Dot color is equal to the line color and not adjustable.
*
* Default: NO
* Default: NO.
*
* @param lineChartView The line chart object requesting this information.
* @param lineIndex An index number identifying a line in the chart.
@@ -90,7 +66,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
/**
* Returns whether or not a line should be rendered with curved connections and rounded end caps.
*
* Default: NO
* Default: NO.
*
* @param lineChartView The line chart object requesting this information.
* @param lineIndex An index number identifying a line in the chart.
@@ -99,15 +75,48 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
*/
- (BOOL)lineChartView:(JBLineChartView *)lineChartView smoothLineAtLineIndex:(NSUInteger)lineIndex;
/**
* Returns a (custom) UIView instance representing a dot (x,y point) within the chart.
* For this value to apply, showsDotsForLineAtLineIndex: must return YES for the line at lineIndex.
* This protocol supercedes colorForDotAtHorizontalIndex: and dotRadiusForDotAtHorizontalIndex:.
* If nil is returned. the original dot protocols will take precedence. During selection events, a custom
* dot view will not be hidden unless lineChartView:shouldHideDotViewOnSelectionAtHorizontalIndex:atLineIndex:
* is implemented.
*
* Default: nil.
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).
* @param lineIndex An index number identifying a line in the chart.
*
* @return A custom UIView instance representing a dot at a particular horizontal index within a dotted line.
*/
- (UIView *)lineChartView:(JBLineChartView *)lineChartView dotViewAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
/**
* Returns whether or not a (custom) dot view should be hidden on selection events.
*
* Default: NO.
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).
* @param lineIndex An index number identifying a line in the chart.
*
* @return Whether or not a (custom) dot view should be hidden on selection events.
*/
- (BOOL)lineChartView:(JBLineChartView *)lineChartView shouldHideDotViewOnSelectionAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
@end
@protocol JBLineChartViewDelegate <NSObject>
@protocol JBLineChartViewDelegate <JBChartViewDelegate>
@required
/**
* Vertical value for a line point at a given index (left to right). There is no ceiling on the the height;
* the chart will automatically normalize all values between the overal min and max heights.
* NAN may able be retuend to indicate missing values. The chart's line will begin at the first non-NAN value and end at the last non-NAN value.
* Furthermore, the line will interopolate any NAN values in between (ie. the line will not be interrupted).
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).
@@ -128,7 +137,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
*
* @param lineChartView A line chart object informing the delegate about the new selection.
* @param lineIndex An index number identifying the closest line in the chart to the current touch
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).point.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).
* @param touchPoint The touch point in relation to the chart's bounds (excludes footer and header).
*/
- (void)lineChartView:(JBLineChartView *)lineChartView didSelectLineAtIndex:(NSUInteger)lineIndex horizontalIndex:(NSUInteger)horizontalIndex touchPoint:(CGPoint)touchPoint;
@@ -173,7 +182,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
* Default: black color.
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).point.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis)
* @param lineIndex An index number identifying a line in the chart.
*
* @return The color to be used to color a dot within a dotted line in the chart.
@@ -197,14 +206,15 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
* For this value to apply, showsDotsForLineAtLineIndex: must return YES for the line at lineIndex.
* Any value can be returned for lineIndex's that don't support dots, as it will never be called.
*
* Default: line width x 3.
* Default: line width x 6.
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).
* @param lineIndex An index number identifying a line in the chart.
*
* @return The radius of the dots within a dotted line in the chart.
*/
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
/**
* Returns the width of the (vertical) selection view to be overlayed on the chart during touch events.
@@ -220,17 +230,16 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
- (CGFloat)verticalSelectionWidthForLineChartView:(JBLineChartView *)lineChartView;
/**
* Returns the (vertical) selection color to be overlayed on the chart during touch events.
* Returns the (vertical) selection color to be overlayed on the chart during touch events on a given line.
* The color is automically faded to transparent (vertically). The property showsVerticalSelection
* must be YES for the color to apply.
*
* Default: white color (faded to transparent).
*
* @param lineChartView The line chart object requesting this information.
* @param lineIndex An index number identifying a line in the chart.
*
* @return The color of the selection view used during chart selections.
* @return The color of the selection view used during chart selections of the given line.
*/
- (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView;
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView verticalSelectionColorForLineAtLineIndex:(NSUInteger)lineIndex;
/**
* Returns the selection color to be overlayed on a line within the chart during touch events.
@@ -265,7 +274,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
* Default: white color.
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).point.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).
* @param lineIndex An index number identifying a line in the chart.
*
* @return The color to be used to highlight a dot within a dotted line during chart selections.
@@ -276,7 +285,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
* Returns the line style of a particular line at lineIndex within the chart.
* See JBLineChartViewLineStyle for line style descriptions.
*
* Default: JBLineChartViewLineStyleSolid
* Default: JBLineChartViewLineStyleSolid.
*
* @param lineChartView The line chart object requesting this information.
* @param lineIndex An index number identifying a line in the chart.
@@ -286,3 +295,38 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
- (JBLineChartViewLineStyle)lineChartView:(JBLineChartView *)lineChartView lineStyleForLineAtLineIndex:(NSUInteger)lineIndex;
@end
@interface JBLineChartView : JBChartView
@property (nonatomic, weak) id<JBLineChartViewDataSource> dataSource;
@property (nonatomic, weak) id<JBLineChartViewDelegate> delegate;
/**
* Vertical highlight overlayed on a line graph during touch events.
*
* Default: YES.
*/
@property (nonatomic, assign) BOOL showsVerticalSelection;
/**
* A highlight shown on a line within the graph during touch events. The highlighted line
* is the closest line to the touch point and corresponds to the lineIndex delegatd back via
* didSelectChartAtHorizontalIndex:atLineIndex: and didUnSlectChartAtHorizontalIndex:atLineIndex:
*
* Default: YES.
*/
@property (nonatomic, assign) BOOL showsLineSelection;
/**
* The dot view within a particular line at a horizontalIndex.
*
* Default: nil.
*
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis)
* @param lineIndex An index number identifying a line in the chart.
*
* @return The UIView representing the dot view at a given horizontalIndex within a line or nil if any index is out of range.
*/
- (UIView *)dotViewAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
@end
+283 -101
View File
@@ -75,6 +75,7 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
@interface JBLineChartPoint : NSObject
@property (nonatomic, assign) CGPoint position;
@property (nonatomic, assign) BOOL hidden;
@end
@@ -137,7 +138,9 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView widthForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
- (UIView *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotViewAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
- (BOOL)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView shouldHideDotViewOnSelectionAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
- (CGFloat)paddingForLineChartDotsView:(JBLineChartDotsView *)lineChartDotsView;
- (BOOL)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex;
@@ -184,6 +187,9 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
@implementation JBLineChartView
@dynamic dataSource;
@dynamic delegate;
#pragma mark - Alloc/Init
+ (void)initialize
@@ -265,7 +271,8 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
NSMutableArray *mutableChartData = [NSMutableArray array];
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
NSUInteger numberOfLines = [self.dataSource numberOfLinesInLineChartView:self];
for (NSUInteger lineIndex=0; lineIndex<numberOfLines; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
@@ -274,14 +281,20 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat rawHeight = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(rawHeight >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
NSAssert(isnan(rawHeight) || (rawHeight >= 0), @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0 OR NAN");
JBLineChartPoint *chartPoint = [[JBLineChartPoint alloc] init];
if(isnan(rawHeight))
{
chartPoint.hidden = YES;
rawHeight = 0; //set to 0 so we can calculate the x position
}
CGFloat normalizedHeight = [self normalizedHeightForRawHeight:rawHeight];
yOffset = mainViewRect.size.height - normalizedHeight;
JBLineChartPoint *chartPoint = [[JBLineChartPoint alloc] init];
chartPoint.position = CGPointMake(xOffset, yOffset);
[chartPointData addObject:chartPoint];
xOffset += pointSpace;
}
@@ -299,6 +312,7 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
// Remove old line view
if (self.linesView)
{
self.linesView.delegate = nil;
[self.linesView removeFromSuperview];
self.linesView = nil;
}
@@ -326,6 +340,7 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
// Remove old dot view
if (self.dotsView)
{
self.dotsView.delegate = nil;
[self.dotsView removeFromSuperview];
self.dotsView = nil;
}
@@ -360,15 +375,28 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
selectionViewWidth = MIN([self.delegate verticalSelectionWidthForLineChartView:self], self.bounds.size.width);
}
self.verticalSelectionView = [[JBChartVerticalSelectionView alloc] initWithFrame:CGRectMake(0, 0, selectionViewWidth, self.bounds.size.height - self.footerView.frame.size.height)];
CGFloat verticalSelectionViewHeight = self.bounds.size.height - self.headerView.frame.size.height - self.footerView.frame.size.height - self.headerPadding - self.footerPadding;
if ([self.dataSource respondsToSelector:@selector(shouldExtendSelectionViewIntoHeaderPaddingForChartView:)])
{
if ([self.dataSource shouldExtendSelectionViewIntoHeaderPaddingForChartView:self])
{
verticalSelectionViewHeight += self.headerPadding;
}
}
if ([self.dataSource respondsToSelector:@selector(shouldExtendSelectionViewIntoFooterPaddingForChartView:)])
{
if ([self.dataSource shouldExtendSelectionViewIntoFooterPaddingForChartView:self])
{
verticalSelectionViewHeight += self.footerPadding;
}
}
self.verticalSelectionView = [[JBChartVerticalSelectionView alloc] initWithFrame:CGRectMake(0, 0, selectionViewWidth, verticalSelectionViewHeight)];
self.verticalSelectionView.alpha = 0.0;
self.verticalSelectionView.hidden = !self.showsVerticalSelection;
if ([self.delegate respondsToSelector:@selector(verticalSelectionColorForLineChartView:)])
{
UIColor *selectionViewBackgroundColor = [self.delegate verticalSelectionColorForLineChartView:self];
NSAssert(selectionViewBackgroundColor != nil, @"JBLineChartView // delegate function - (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView must return a non-nil UIColor");
self.verticalSelectionView.bgColor = selectionViewBackgroundColor;
}
// Add new selection bar
if (self.footerView)
@@ -407,7 +435,7 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
if ((maxHeight - minHeight) <= 0)
{
return 0;
return [self availableHeight];
}
return ((rawHeight - minHeight) / (maxHeight - minHeight)) * [self availableHeight];
@@ -415,15 +443,16 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
- (CGFloat)availableHeight
{
return self.bounds.size.height - self.headerView.frame.size.height - self.footerView.frame.size.height - self.headerPadding;
return self.bounds.size.height - self.headerView.frame.size.height - self.footerView.frame.size.height - self.headerPadding - self.footerPadding;
}
- (CGFloat)padding
{
CGFloat maxLineWidth = 0.0f;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
NSInteger numberOfLines = [self.dataSource numberOfLinesInLineChartView:self];
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
for (NSInteger lineIndex=0; lineIndex<numberOfLines; lineIndex++)
{
BOOL showsDots = NO;
if ([self.dataSource respondsToSelector:@selector(lineChartView:showsDotsForLineAtLineIndex:)])
@@ -437,16 +466,78 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
lineWidth = [self.delegate lineChartView:self widthForLineAtLineIndex:lineIndex];
}
CGFloat dotRadius = lineWidth * kJBLineChartDotsViewDefaultRadiusFactor; // default
CGFloat maxDotLength = 0;
if (showsDots)
{
if ([self.delegate respondsToSelector:@selector(lineChartView:dotRadiusForLineAtLineIndex:)])
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
for (NSUInteger horizontalIndex=0; horizontalIndex<dataCount; horizontalIndex++)
{
dotRadius = [self.delegate lineChartView:self dotRadiusForLineAtLineIndex:lineIndex];
BOOL shouldEvaluateDotSize = NO;
// Left dot
if (horizontalIndex == 0)
{
shouldEvaluateDotSize = YES;
}
// Right dot
else if (horizontalIndex == (dataCount - 1))
{
shouldEvaluateDotSize = YES;
}
else
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat height = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
// Top
if (height == [self cachedMaxHeight])
{
shouldEvaluateDotSize = YES;
}
// Bottom
else if (height == [self cachedMinHeight])
{
shouldEvaluateDotSize = YES;
}
}
if (shouldEvaluateDotSize)
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:dotViewAtHorizontalIndex:atLineIndex:)])
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:dotViewAtHorizontalIndex:atLineIndex:)])
{
UIView *customDotView = [self.dataSource lineChartView:self dotViewAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
if (customDotView.frame.size.width > maxDotLength || customDotView.frame.size.height > maxDotLength)
{
maxDotLength = fmaxf(customDotView.frame.size.width, customDotView.frame.size.height);
}
}
}
else if ([self.delegate respondsToSelector:@selector(lineChartView:dotRadiusForDotAtHorizontalIndex:atLineIndex:)])
{
CGFloat dotRadius = ([self.delegate lineChartView:self dotRadiusForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex] * 2.0f);
if (dotRadius > maxDotLength)
{
maxDotLength = dotRadius;
}
}
else
{
CGFloat defaultDotRadius = ((lineWidth * kJBLineChartDotsViewDefaultRadiusFactor) * 2.0f);
if (defaultDotRadius > maxDotLength)
{
maxDotLength = defaultDotRadius;
}
}
}
}
}
CGFloat currentMaxLineWidth = MAX(dotRadius, lineWidth);
CGFloat currentMaxLineWidth = MAX(maxDotLength, lineWidth);
if (currentMaxLineWidth > maxLineWidth)
{
maxLineWidth = currentMaxLineWidth;
@@ -459,7 +550,8 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
NSUInteger dataCount = 0;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
NSInteger numberOfLines = [self.dataSource numberOfLinesInLineChartView:self];
for (NSInteger lineIndex=0; lineIndex<numberOfLines; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger lineDataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
@@ -580,16 +672,31 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
return kJBLineChartLinesViewStrokeWidth;
}
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
if ([self.delegate respondsToSelector:@selector(lineChartView:dotRadiusForLineAtLineIndex:)])
if ([self.delegate respondsToSelector:@selector(lineChartView:dotRadiusForDotAtHorizontalIndex:atLineIndex:)])
{
return [self.delegate lineChartView:self dotRadiusForLineAtLineIndex:lineIndex];
return [self.delegate lineChartView:self dotRadiusForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
else
return [self lineChartDotsView:lineChartDotsView widthForLineAtLineIndex:lineIndex] * kJBLineChartDotsViewDefaultRadiusFactor;
}
- (UIView *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotViewAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:dotViewAtHorizontalIndex:atLineIndex:)])
{
return [self lineChartDotsView:lineChartDotsView widthForLineAtLineIndex:lineIndex] * kJBLineChartDotsViewDefaultRadiusFactor;
return [self.dataSource lineChartView:self dotViewAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
return nil;
}
- (BOOL)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView shouldHideDotViewOnSelectionAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:shouldHideDotViewOnSelectionAtHorizontalIndex:atLineIndex:)])
{
return [self.dataSource lineChartView:self shouldHideDotViewOnSelectionAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
return NO;
}
- (CGFloat)paddingForLineChartDotsView:(JBLineChartDotsView *)lineChartDotsView
@@ -670,6 +777,33 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
[self setState:state animated:animated force:NO callback:callback];
}
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible animated:(BOOL)animated
{
_verticalSelectionViewVisible = verticalSelectionViewVisible;
if (animated)
{
[UIView animateWithDuration:kJBChartViewDefaultAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.verticalSelectionView.alpha = self.verticalSelectionViewVisible ? 1.0 : 0.0;
} completion:nil];
}
else
{
self.verticalSelectionView.alpha = _verticalSelectionViewVisible ? 1.0 : 0.0;
}
}
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible
{
[self setVerticalSelectionViewVisible:verticalSelectionViewVisible animated:NO];
}
- (void)setShowsVerticalSelection:(BOOL)showsVerticalSelection
{
_showsVerticalSelection = showsVerticalSelection;
self.verticalSelectionView.hidden = _showsVerticalSelection ? NO : YES;
}
#pragma mark - Getters
- (CGFloat)cachedMinHeight
@@ -678,7 +812,8 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
CGFloat minHeight = FLT_MAX;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
NSUInteger numberOfLines = [self.dataSource numberOfLinesInLineChartView:self];
for (NSUInteger lineIndex=0; lineIndex<numberOfLines; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
@@ -686,8 +821,8 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat height = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(height >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
if (height < minHeight)
NSAssert(isnan(height) || (height >= 0), @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0 OR NAN");
if (!isnan(height) && height < minHeight)
{
minHeight = height;
}
@@ -704,7 +839,8 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
CGFloat maxHeight = 0;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
NSUInteger numberOfLines = [self.dataSource numberOfLinesInLineChartView:self];
for (NSUInteger lineIndex=0; lineIndex<numberOfLines; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
@@ -712,8 +848,8 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat height = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(height >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
if (height > maxHeight)
NSAssert(isnan(height) || (height >= 0), @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0 OR NAN");
if (!isnan(height) && height > maxHeight)
{
maxHeight = height;
}
@@ -742,6 +878,16 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
return self.cachedMaxHeight;
}
- (UIView *)dotViewAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
NSArray *dotViews = [self.dotsView.dotViewsDict objectForKey:@(lineIndex)];
if (horizontalIndex < [dotViews count])
{
return [dotViews objectAtIndex:horizontalIndex];
}
return nil;
}
#pragma mark - Touch Helpers
- (CGPoint)clampPoint:(CGPoint)point toBounds:(CGRect)bounds padding:(CGFloat)padding
@@ -759,9 +905,9 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
for (JBLineChartPoint *lineChartPoint in lineData)
{
BOOL clamped = (indexClamp == JBLineChartHorizontalIndexClampNone) ? YES : (indexClamp == JBLineChartHorizontalIndexClampLeft) ? (point.x - lineChartPoint.position.x >= 0) : (point.x - lineChartPoint.position.x <= 0);
if ((abs(point.x - lineChartPoint.position.x)) < currentDistance && clamped == YES)
if ((fabs(point.x - lineChartPoint.position.x)) < currentDistance && clamped == YES)
{
currentDistance = (abs(point.x - lineChartPoint.position.x));
currentDistance = (fabs(point.x - lineChartPoint.position.x));
selectedIndex = index;
}
index++;
@@ -800,9 +946,10 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
NSUInteger shortestDistance = INT_MAX;
NSInteger selectedIndex = kJBLineChartUnselectedLineIndex;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
NSUInteger numberOfLines = [self.dataSource numberOfLinesInLineChartView:self];
// Iterate all lines
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
for (NSUInteger lineIndex=0; lineIndex<numberOfLines; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
if ([self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex] > rightHorizontalIndex)
@@ -826,7 +973,7 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
// Insersection point
CGPoint interesectionPoint = CGPointMake(normalizedTouchPoint.x, (lineSlope * (normalizedTouchPoint.x - leftPoint.x)) + leftPoint.y);
CGFloat currentDistance = abs(interesectionPoint.y - normalizedTouchPoint.y);
CGFloat currentDistance = fabs(interesectionPoint.y - normalizedTouchPoint.y);
if (currentDistance < shortestDistance)
{
shortestDistance = currentDistance;
@@ -841,27 +988,50 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
{
if (self.state == JBChartViewStateCollapsed || [self.chartData count] <= 0)
{
return;
return; // no touch for no data or collapsed
}
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [self clampPoint:[touch locationInView:self.linesView] toBounds:self.linesView.bounds padding:[self padding]];
NSUInteger lineIndex = self.linesView.selectedLineIndex != kJBLineChartLinesViewUnselectedLineIndex ? self.linesView.selectedLineIndex : [self lineIndexForPoint:touchPoint];
if (lineIndex == kJBLineChartLinesViewUnselectedLineIndex || [[self.chartData objectAtIndex:lineIndex] count] <= 0)
{
return; // no touch for line without data
}
if ([self.delegate respondsToSelector:@selector(lineChartView:didSelectLineAtIndex:horizontalIndex:touchPoint:)])
{
NSUInteger lineIndex = self.linesView.selectedLineIndex != kJBLineChartLinesViewUnselectedLineIndex ? self.linesView.selectedLineIndex : [self lineIndexForPoint:touchPoint];
NSUInteger horizontalIndex = [self horizontalIndexForPoint:touchPoint indexClamp:JBLineChartHorizontalIndexClampNone lineData:[self.chartData objectAtIndex:lineIndex]];
[self.delegate lineChartView:self didSelectLineAtIndex:lineIndex horizontalIndex:horizontalIndex touchPoint:[touch locationInView:self]];
}
if ([self.delegate respondsToSelector:@selector(lineChartView:didSelectLineAtIndex:horizontalIndex:)])
{
NSUInteger lineIndex = self.linesView.selectedLineIndex != kJBLineChartLinesViewUnselectedLineIndex ? self.linesView.selectedLineIndex : [self lineIndexForPoint:touchPoint];
[self.delegate lineChartView:self didSelectLineAtIndex:lineIndex horizontalIndex:[self horizontalIndexForPoint:touchPoint indexClamp:JBLineChartHorizontalIndexClampNone lineData:[self.chartData objectAtIndex:lineIndex]]];
}
if ([self.delegate respondsToSelector:@selector(lineChartView:verticalSelectionColorForLineAtLineIndex:)])
{
UIColor *verticalSelectionColor = [self.delegate lineChartView:self verticalSelectionColorForLineAtLineIndex:lineIndex];
NSAssert(verticalSelectionColor != nil, @"JBLineChartView // delegate function - (UIColor *)lineChartView:(JBLineChartView *)lineChartView verticalSelectionColorForLineAtLineIndex:(NSUInteger)lineIndex must return a non-nil UIColor");
self.verticalSelectionView.bgColor = verticalSelectionColor;
}
CGFloat xOffset = fmin(self.bounds.size.width - self.verticalSelectionView.frame.size.width, fmax(0, touchPoint.x - (ceil(self.verticalSelectionView.frame.size.width * 0.5))));
self.verticalSelectionView.frame = CGRectMake(xOffset, self.verticalSelectionView.frame.origin.y, self.verticalSelectionView.frame.size.width, self.verticalSelectionView.frame.size.height);
CGFloat yOffset = self.headerView.frame.size.height + self.headerPadding;
if ([self.dataSource respondsToSelector:@selector(shouldExtendSelectionViewIntoHeaderPaddingForChartView:)])
{
if ([self.dataSource shouldExtendSelectionViewIntoHeaderPaddingForChartView:self])
{
yOffset = self.headerView.frame.size.height;
}
}
self.verticalSelectionView.frame = CGRectMake(xOffset, yOffset, self.verticalSelectionView.frame.size.width, self.verticalSelectionView.frame.size.height);
[self setVerticalSelectionViewVisible:YES animated:YES];
}
@@ -886,37 +1056,6 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
}
}
#pragma mark - Setters
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible animated:(BOOL)animated
{
_verticalSelectionViewVisible = verticalSelectionViewVisible;
[self bringSubviewToFront:self.verticalSelectionView];
if (animated)
{
[UIView animateWithDuration:kJBChartViewDefaultAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.verticalSelectionView.alpha = self.verticalSelectionViewVisible ? 1.0 : 0.0;
} completion:nil];
}
else
{
self.verticalSelectionView.alpha = _verticalSelectionViewVisible ? 1.0 : 0.0;
}
}
- (void)setVerticalSelectionViewVisible:(BOOL)verticalSelectionViewVisible
{
[self setVerticalSelectionViewVisible:verticalSelectionViewVisible animated:NO];
}
- (void)setShowsVerticalSelection:(BOOL)showsVerticalSelection
{
_showsVerticalSelection = showsVerticalSelection;
self.verticalSelectionView.hidden = _showsVerticalSelection ? NO : YES;
}
#pragma mark - Gestures
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
@@ -1068,6 +1207,11 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
NSUInteger lineIndex = 0;
for (NSArray *lineData in chartData)
{
if (lineData.count == 0)
{
continue;
}
UIBezierPath *path = [UIBezierPath bezierPath];
path.miterLimit = kJBLineChartLinesViewMiterLimit;
@@ -1077,16 +1221,22 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
NSAssert([self.delegate respondsToSelector:@selector(lineChartLinesView:smoothLineAtLineIndex:)], @"JBLineChartLinesView // delegate must implement - (BOOL)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView smoothLineAtLineIndex:(NSUInteger)lineIndex");
BOOL smoothLine = [self.delegate lineChartLinesView:self smoothLineAtLineIndex:lineIndex];
NSUInteger index = 0;
BOOL visiblePointFound = NO;
NSArray *sortedLineData = [lineData sortedArrayUsingSelector:@selector(compare:)];
CGFloat firstXPosition = 0.0f;
CGFloat lastXPosition = 0.0f;
for (JBLineChartPoint *lineChartPoint in sortedLineData)
for (NSUInteger index = 0; index < [sortedLineData count]; index++)
{
if (index == 0)
JBLineChartPoint *lineChartPoint = [sortedLineData objectAtIndex:index];
if(lineChartPoint.hidden) {
continue;
}
if (!visiblePointFound)
{
[path moveToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)))];
firstXPosition = lineChartPoint.position.x;
visiblePointFound = YES;
}
else
{
@@ -1122,7 +1272,6 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
previousSlope = currentSlope;
}
previousLineChartPoint = lineChartPoint;
index++;
}
JBLineLayer *shapeLayer = [self lineLayerForLineIndex:lineIndex];
@@ -1172,9 +1321,12 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
// Continue the path for the fill layer (close and fill)
UIBezierPath *fillPath = [path copy];
[fillPath addLineToPoint:CGPointMake(lastXPosition, self.bounds.size.height - padding)];
[fillPath addLineToPoint:CGPointMake(firstXPosition, self.bounds.size.height - padding)];
if(visiblePointFound)
{
[fillPath addLineToPoint:CGPointMake(lastXPosition, self.bounds.size.height - padding)];
[fillPath addLineToPoint:CGPointMake(firstXPosition, self.bounds.size.height - padding)];
}
shapeFillLayer.path = fillPath.CGPath;
shapeFillLayer.frame = self.bounds;
@@ -1343,22 +1495,34 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
if ([self.delegate lineChartDotsView:self showsDotsForLineAtLineIndex:lineIndex]) // line at index contains dots
{
NSMutableArray *mutableDotViews = [NSMutableArray array];
NSUInteger horizontalIndex = 0;
for (JBLineChartPoint *lineChartPoint in [lineData sortedArrayUsingSelector:@selector(compare:)])
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:dotRadiusForLineAtLineIndex:)], @"JBLineChartDotsView // delegate must implement - (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex");
CGFloat dotRadius = [self.delegate lineChartDotsView:self dotRadiusForLineAtLineIndex:lineIndex];
NSArray *sortedLineData = [lineData sortedArrayUsingSelector:@selector(compare:)];
for (NSUInteger horizontalIndex = 0; horizontalIndex < [sortedLineData count]; horizontalIndex++)
{
JBLineChartPoint *lineChartPoint = [sortedLineData objectAtIndex:horizontalIndex];
if(lineChartPoint.hidden)
{
continue;
}
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:dotViewAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIView *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotViewAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
UIView *currentDotView = [self.delegate lineChartDotsView:self dotViewAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
JBLineChartDotView *dotView = [[JBLineChartDotView alloc] initWithRadius:dotRadius];
dotView.center = CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)));
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:colorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self colorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
[mutableDotViews addObject:dotView];
[self addSubview:dotView];
horizontalIndex++;
// System dot
if (currentDotView == nil)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:dotRadiusForLineAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat dotRadius = [self.delegate lineChartDotsView:self dotRadiusForLineAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
currentDotView = [[JBLineChartDotView alloc] initWithRadius:dotRadius];
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:colorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
currentDotView.backgroundColor = [self.delegate lineChartDotsView:self colorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
currentDotView.center = CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)));
[mutableDotViews addObject:currentDotView];
[self addSubview:currentDotView];
}
[mutableDotViewsDict setObject:[NSArray arrayWithArray:mutableDotViews] forKey:[NSNumber numberWithInteger:lineIndex]];
}
@@ -1378,22 +1542,40 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
dispatch_block_t adjustDots = ^{
[weakSelf.dotViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSUInteger horizontalIndex = 0;
for (JBLineChartDotView *dotView in (NSArray *)obj)
for (UIView *dotView in (NSArray *)obj)
{
if ([key isKindOfClass:[NSNumber class]])
{
NSInteger lineIndex = [((NSNumber *)key) intValue];
if (weakSelf.selectedLineIndex == lineIndex)
// Internal dot
if ([dotView isKindOfClass:[JBLineChartDotView class]])
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:selectedColorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self selectedColorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
if (weakSelf.selectedLineIndex == lineIndex)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:selectedColorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self selectedColorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
else
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:colorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self colorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
dotView.alpha = (weakSelf.selectedLineIndex == kJBLineChartDotsViewUnselectedLineIndex) ? 1.0f : 0.0f; // hide dots on off-selection
}
}
// Custom dot
else
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:colorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self colorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
dotView.alpha = (weakSelf.selectedLineIndex == kJBLineChartDotsViewUnselectedLineIndex) ? 1.0f : 0.0f; // hide dots on off-selection
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:shouldHideDotViewOnSelectionAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (BOOL)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView shouldHideDotViewOnSelectionAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
BOOL hideDotView = [self.delegate lineChartDotsView:self shouldHideDotViewOnSelectionAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
if (weakSelf.selectedLineIndex == lineIndex)
{
dotView.alpha = hideDotView ? 0.0f : 1.0f;
}
else
{
dotView.alpha = 1.0;
}
}
}
horizontalIndex++;
@@ -1426,11 +1608,11 @@ static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
- (id)initWithRadius:(CGFloat)radius
{
self = [super initWithFrame:CGRectMake(0, 0, radius, radius)];
self = [super initWithFrame:CGRectMake(0, 0, (radius * 2.0f), (radius * 2.0f))];
if (self)
{
self.clipsToBounds = YES;
self.layer.cornerRadius = (radius * 0.5);
self.layer.cornerRadius = ((radius * 2.0f) * 0.5f);
}
return self;
}
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "JBChartView"
s.version = "2.7.1"
s.version = "2.8.15"
s.summary = "Jawbone's iOS-based charting library for both line and bar graphs."
s.homepage = "https://github.com/Jawbone/JBChartView"
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
s.author = { "Terry Worona" => "tworona@jawbone.com" }
s.source = {
:git => "https://github.com/Jawbone/JBChartView.git",
:tag => "v2.7.1"
:tag => "v2.8.15"
}
s.platform = :ios, '6.0'
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
94BDFC3419F933B2007492F6 /* JBLineChartMissingPointsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94BDFC3319F933B2007492F6 /* JBLineChartMissingPointsViewController.m */; };
9B0725211829822A0052109B /* JBChartListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0725201829822A0052109B /* JBChartListViewController.m */; };
9B2E530518218CF20079B9D2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B2E530418218CF20079B9D2 /* Foundation.framework */; };
9B2E530718218CF20079B9D2 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B2E530618218CF20079B9D2 /* CoreGraphics.framework */; };
@@ -45,6 +46,8 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
94BDFC3219F933B2007492F6 /* JBLineChartMissingPointsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JBLineChartMissingPointsViewController.h; sourceTree = "<group>"; };
94BDFC3319F933B2007492F6 /* JBLineChartMissingPointsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JBLineChartMissingPointsViewController.m; sourceTree = "<group>"; };
9B07251F1829822A0052109B /* JBChartListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JBChartListViewController.h; sourceTree = "<group>"; };
9B0725201829822A0052109B /* JBChartListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JBChartListViewController.m; sourceTree = "<group>"; };
9B2E530118218CF20079B9D2 /* JBChartViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JBChartViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -196,6 +199,8 @@
9B6A68DD1829BE63006DB3BF /* JBBarChartViewController.m */,
9B07251F1829822A0052109B /* JBChartListViewController.h */,
9B0725201829822A0052109B /* JBChartListViewController.m */,
94BDFC3219F933B2007492F6 /* JBLineChartMissingPointsViewController.h */,
94BDFC3319F933B2007492F6 /* JBLineChartMissingPointsViewController.m */,
9B6A68DF1829BED5006DB3BF /* JBLineChartViewController.h */,
9B6A68E01829BED5006DB3BF /* JBLineChartViewController.m */,
);
@@ -407,6 +412,7 @@
9B603D4E182C7163000A76D0 /* JBBaseTableViewController.m in Sources */,
9B6A68DE1829BE63006DB3BF /* JBBarChartViewController.m in Sources */,
9B4437AD18D7686800682EF0 /* JBChartTooltipTipView.m in Sources */,
94BDFC3419F933B2007492F6 /* JBLineChartMissingPointsViewController.m in Sources */,
9BE0B0AD182AD26400232023 /* JBLineChartView.m in Sources */,
9BEE694618D2789E005D9BA7 /* JBBaseChartViewController.m in Sources */,
9B6A68E11829BED5006DB3BF /* JBLineChartViewController.m in Sources */,
@@ -38,3 +38,12 @@
#define kJBStringLabelHours localize(@"label.hours", @"h")
#define kJBStringLabelMoon localize(@"label.moon", @"Moon")
#define kJBStringLabelSun localize(@"label.sun", @"Sun")
#pragma mark - Labels (Missing Points Line Chart)
#define kJBStringLabel2014 localize(@"label.2014", @"2014")
#define kJBStringLabelCyclingDistances localize(@"label.cycling.distances", @"Cycling Distances")
#define kJBStringLabelCyclingCurrentLastWeek2014 localize(@"label.cycling.current.last.week.2014", @"Current/Last Week - 2014")
#define kJBStringLabelKm2014 localize(@"label.km", @"Km")
#define kJBStringLabelLastWeek localize(@"label.last.week", @"Last Week")
#define kJBStringLabelCurrentWeek localize(@"label.current.week", @"Current Week")
@@ -43,6 +43,8 @@ CGFloat const kJBBaseChartViewControllerAnimationDuration = 0.25f;
[self.view addSubview:self.tooltipView];
}
[self.view bringSubviewToFront:self.tooltipView];
if (!self.tooltipTipView)
{
self.tooltipTipView = [[JBChartTooltipTipView alloc] init];
@@ -50,6 +52,8 @@ CGFloat const kJBBaseChartViewControllerAnimationDuration = 0.25f;
[self.view addSubview:self.tooltipTipView];
}
[self.view bringSubviewToFront:self.tooltipTipView];
dispatch_block_t adjustTooltipPosition = ^{
CGPoint originalTouchPoint = [self.view convertPoint:touchPoint fromView:chartView];
CGPoint convertedTouchPoint = originalTouchPoint; // modified
@@ -28,6 +28,12 @@
[self.view addSubview:self.tableView];
}
- (void)dealloc
{
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
@@ -84,6 +84,12 @@ NSString * const kJBAreaChartViewControllerNavButtonViewKey = @"view";
return self;
}
- (void)dealloc
{
_lineChartView.delegate = nil;
_lineChartView.dataSource = nil;
}
#pragma mark - Data
- (void)initFakeData
@@ -235,7 +241,7 @@ NSString * const kJBAreaChartViewControllerNavButtonViewKey = @"view";
return kJBAreaChartViewControllerChartLineWidth;
}
- (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView verticalSelectionColorForLineAtLineIndex:(NSUInteger)lineIndex
{
return [UIColor whiteColor];
}
@@ -18,10 +18,10 @@
CGFloat const kJBBarChartViewControllerChartHeight = 250.0f;
CGFloat const kJBBarChartViewControllerChartPadding = 10.0f;
CGFloat const kJBBarChartViewControllerChartHeaderHeight = 80.0f;
CGFloat const kJBBarChartViewControllerChartHeaderPadding = 10.0f;
CGFloat const kJBBarChartViewControllerChartHeaderPadding = 20.0f;
CGFloat const kJBBarChartViewControllerChartFooterHeight = 25.0f;
CGFloat const kJBBarChartViewControllerChartFooterPadding = 5.0f;
NSUInteger kJBBarChartViewControllerBarPadding = 1;
CGFloat const kJBBarChartViewControllerBarPadding = 1.0f;
NSInteger const kJBBarChartViewControllerNumBars = 12;
NSInteger const kJBBarChartViewControllerMaxBarHeight = 10;
NSInteger const kJBBarChartViewControllerMinBarHeight = 5;
@@ -78,6 +78,12 @@ NSString * const kJBBarChartViewControllerNavButtonViewKey = @"view";
return self;
}
- (void)dealloc
{
_barChartView.delegate = nil;
_barChartView.dataSource = nil;
}
#pragma mark - Date
- (void)initFakeData
@@ -85,7 +91,7 @@ NSString * const kJBBarChartViewControllerNavButtonViewKey = @"view";
NSMutableArray *mutableChartData = [NSMutableArray array];
for (int i=0; i<kJBBarChartViewControllerNumBars; i++)
{
NSInteger delta = (kJBBarChartViewControllerNumBars - abs((kJBBarChartViewControllerNumBars - i) - i)) + 2;
NSInteger delta = (kJBBarChartViewControllerNumBars - labs((kJBBarChartViewControllerNumBars - i) - i)) + 2;
[mutableChartData addObject:[NSNumber numberWithFloat:MAX((delta * kJBBarChartViewControllerMinBarHeight), arc4random() % (delta * kJBBarChartViewControllerMaxBarHeight))]];
}
@@ -108,6 +114,7 @@ NSString * const kJBBarChartViewControllerNavButtonViewKey = @"view";
self.barChartView.dataSource = self;
self.barChartView.headerPadding = kJBBarChartViewControllerChartHeaderPadding;
self.barChartView.minimumValue = 0.0f;
self.barChartView.inverted = NO;
self.barChartView.backgroundColor = kJBColorBarChartBackground;
JBChartHeaderView *headerView = [[JBChartHeaderView alloc] initWithFrame:CGRectMake(kJBBarChartViewControllerChartPadding, ceil(self.view.bounds.size.height * 0.5) - ceil(kJBBarChartViewControllerChartHeaderHeight * 0.5), self.view.bounds.size.width - (kJBBarChartViewControllerChartPadding * 2), kJBBarChartViewControllerChartHeaderHeight)];
@@ -137,6 +144,18 @@ NSString * const kJBBarChartViewControllerNavButtonViewKey = @"view";
[self.barChartView setState:JBChartViewStateExpanded];
}
#pragma mark - JBChartViewDataSource
- (BOOL)shouldExtendSelectionViewIntoHeaderPaddingForChartView:(JBChartView *)chartView
{
return YES;
}
- (BOOL)shouldExtendSelectionViewIntoFooterPaddingForChartView:(JBChartView *)chartView
{
return NO;
}
#pragma mark - JBBarChartViewDataSource
- (NSUInteger)numberOfBarsInBarChartView:(JBBarChartView *)barChartView
@@ -177,7 +196,7 @@ NSString * const kJBBarChartViewControllerNavButtonViewKey = @"view";
return [UIColor whiteColor];
}
- (NSUInteger)barPaddingForBarChartView:(JBBarChartView *)barChartView
- (CGFloat)barPaddingForBarChartView:(JBBarChartView *)barChartView
{
return kJBBarChartViewControllerBarPadding;
}
@@ -12,13 +12,15 @@
#import "JBBarChartViewController.h"
#import "JBLineChartViewController.h"
#import "JBAreaChartViewController.h"
#import "JBLineChartMissingPointsViewController.h"
// Views
#import "JBChartTableCell.h"
typedef NS_ENUM(NSInteger, JBChartListViewControllerRow){
JBChartListViewControllerRowLineChart,
JBChartListViewControllerRowBarChart,
JBChartListViewControllerRowLineChartMissingPoints,
JBChartListViewControllerRowBarChart,
JBChartListViewControllerRowAreaChart,
JBChartListViewControllerRowCount
};
@@ -63,6 +65,11 @@ NSInteger const kJBChartListViewControllerCellHeight = 100;
detailText = kJBStringLabelSanFrancisco2013;
type = JBChartTableCellTypeLineChart;
break;
case JBChartListViewControllerRowLineChartMissingPoints:
text = kJBStringLabelCyclingDistances;
detailText = kJBStringLabelCyclingCurrentLastWeek2014;
type = JBChartTableCellTypeLineChart;
break;
case JBChartListViewControllerRowBarChart:
text = kJBStringLabelAverageMonthlyTemperature;
detailText = kJBStringLabelWorldwide2012;
@@ -99,6 +106,11 @@ NSInteger const kJBChartListViewControllerCellHeight = 100;
JBLineChartViewController *lineChartController = [[JBLineChartViewController alloc] init];
[self.navigationController pushViewController:lineChartController animated:YES];
}
else if (indexPath.row == JBChartListViewControllerRowLineChartMissingPoints)
{
JBLineChartMissingPointsViewController *lineChartController = [[JBLineChartMissingPointsViewController alloc] init];
[self.navigationController pushViewController:lineChartController animated:YES];
}
else if (indexPath.row == JBChartListViewControllerRowBarChart)
{
JBBarChartViewController *barChartController = [[JBBarChartViewController alloc] init];
@@ -0,0 +1,13 @@
//
// JBLineChartMissingPointsViewController.h
// JBChartViewDemo
//
// Created by Sebastian Opel on 23.10.14.
// Copyright (c) 2014 Jawbone. All rights reserved.
//
#import "JBBaseChartViewController.h"
@interface JBLineChartMissingPointsViewController : JBBaseChartViewController
@end
@@ -0,0 +1,309 @@
//
// JBLineChartMissingPointsViewController.m
// JBChartViewDemo
//
// Created by Sebastian Opel on 23.10.14.
// Copyright (c) 2014 Jawbone. All rights reserved.
//
#import "JBLineChartMissingPointsViewController.h"
// Views
#import "JBLineChartView.h"
#import "JBChartHeaderView.h"
#import "JBLineChartFooterView.h"
#import "JBChartInformationView.h"
#define ARC4RANDOM_MAX 0x010000000
typedef NS_ENUM(NSInteger, JBLineChartLine){
JBLineChartLineSolid,
JBLineChartLineDashed,
JBLineChartLineCount
};
// Numerics
CGFloat const kJBLineChartMissingPointsViewControllerChartHeight = 250.0f;
CGFloat const kJBLineChartMissingPointsViewControllerChartPadding = 10.0f;
CGFloat const kJBLineChartMissingPointsViewControllerChartHeaderHeight = 75.0f;
CGFloat const kJBLineChartMissingPointsViewControllerChartHeaderPadding = 20.0f;
CGFloat const kJBLineChartMissingPointsViewControllerChartFooterHeight = 20.0f;
CGFloat const kJBLineChartMissingPointsViewControllerChartSolidLineWidth = 6.0f;
CGFloat const kJBLineChartMissingPointsViewControllerChartSolidLineDotRadius = 5.0f;
CGFloat const kJBLineChartMissingPointsViewControllerChartDashedLineWidth = 2.0f;
NSInteger const kJBLineChartMissingPointsViewControllerMaxNumChartPoints = 7;
// Strings
NSString * const kJBLineChartMissingPointsViewControllerNavButtonViewKey = @"view";
@interface JBLineChartMissingPointsViewController () <JBLineChartViewDelegate, JBLineChartViewDataSource>
@property (nonatomic, strong) JBLineChartView *lineChartView;
@property (nonatomic, strong) JBChartInformationView *informationView;
@property (nonatomic, strong) NSArray *chartData;
@property (nonatomic, strong) NSArray *daysOfWeek;
// Buttons
- (void)chartToggleButtonPressed:(id)sender;
// Helpers
- (void)initFakeData;
- (NSArray *)largestLineData; // largest collection of fake line data
@end
@implementation JBLineChartMissingPointsViewController
#pragma mark - Alloc/Init
- (id)init
{
self = [super init];
if (self)
{
[self initFakeData];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self initFakeData];
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
[self initFakeData];
}
return self;
}
- (void)dealloc
{
_lineChartView.delegate = nil;
_lineChartView.dataSource = nil;
}
#pragma mark - Data
- (void)initFakeData
{
NSMutableArray *mutableLineCharts = [NSMutableArray array];
for (int lineIndex=0; lineIndex<JBLineChartLineCount; lineIndex++)
{
NSMutableArray *mutableChartData = [NSMutableArray array];
for (int i=0; i<kJBLineChartMissingPointsViewControllerMaxNumChartPoints; i++)
{
if(i < 2 || i > 5 || i == 3)
{
[mutableChartData addObject:[NSNumber numberWithFloat:NAN]];
} else {
[mutableChartData addObject:[NSNumber numberWithFloat:((double)arc4random() / ARC4RANDOM_MAX)]]; // random number between 0 and 1
}
}
[mutableLineCharts addObject:mutableChartData];
}
_chartData = [NSArray arrayWithArray:mutableLineCharts];
_daysOfWeek = [[[NSDateFormatter alloc] init] shortWeekdaySymbols];
}
- (NSArray *)largestLineData
{
NSArray *largestLineData = nil;
for (NSArray *lineData in self.chartData)
{
if ([lineData count] > [largestLineData count])
{
largestLineData = lineData;
}
}
return largestLineData;
}
#pragma mark - View Lifecycle
- (void)loadView
{
[super loadView];
self.view.backgroundColor = kJBColorLineChartControllerBackground;
self.navigationItem.rightBarButtonItem = [self chartToggleButtonWithTarget:self action:@selector(chartToggleButtonPressed:)];
self.lineChartView = [[JBLineChartView alloc] init];
self.lineChartView.frame = CGRectMake(kJBLineChartMissingPointsViewControllerChartPadding, kJBLineChartMissingPointsViewControllerChartPadding, self.view.bounds.size.width - (kJBLineChartMissingPointsViewControllerChartPadding * 2), kJBLineChartMissingPointsViewControllerChartHeight);
self.lineChartView.delegate = self;
self.lineChartView.dataSource = self;
self.lineChartView.headerPadding = kJBLineChartMissingPointsViewControllerChartHeaderPadding;
self.lineChartView.backgroundColor = kJBColorLineChartBackground;
JBChartHeaderView *headerView = [[JBChartHeaderView alloc] initWithFrame:CGRectMake(kJBLineChartMissingPointsViewControllerChartPadding, ceil(self.view.bounds.size.height * 0.5) - ceil(kJBLineChartMissingPointsViewControllerChartHeaderHeight * 0.5), self.view.bounds.size.width - (kJBLineChartMissingPointsViewControllerChartPadding * 2), kJBLineChartMissingPointsViewControllerChartHeaderHeight)];
headerView.titleLabel.text = [kJBStringLabelCyclingDistances uppercaseString];
headerView.titleLabel.textColor = kJBColorLineChartHeader;
headerView.titleLabel.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.25];
headerView.titleLabel.shadowOffset = CGSizeMake(0, 1);
headerView.subtitleLabel.text = kJBStringLabel2014;
headerView.subtitleLabel.textColor = kJBColorLineChartHeader;
headerView.subtitleLabel.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.25];
headerView.subtitleLabel.shadowOffset = CGSizeMake(0, 1);
headerView.separatorColor = kJBColorLineChartHeaderSeparatorColor;
self.lineChartView.headerView = headerView;
JBLineChartFooterView *footerView = [[JBLineChartFooterView alloc] initWithFrame:CGRectMake(kJBLineChartMissingPointsViewControllerChartPadding, ceil(self.view.bounds.size.height * 0.5) - ceil(kJBLineChartMissingPointsViewControllerChartFooterHeight * 0.5), self.view.bounds.size.width - (kJBLineChartMissingPointsViewControllerChartPadding * 2), kJBLineChartMissingPointsViewControllerChartFooterHeight)];
footerView.backgroundColor = [UIColor clearColor];
footerView.leftLabel.text = [[self.daysOfWeek firstObject] uppercaseString];
footerView.leftLabel.textColor = [UIColor whiteColor];
footerView.rightLabel.text = [[self.daysOfWeek lastObject] uppercaseString];;
footerView.rightLabel.textColor = [UIColor whiteColor];
footerView.sectionCount = [[self largestLineData] count];
self.lineChartView.footerView = footerView;
[self.view addSubview:self.lineChartView];
self.informationView = [[JBChartInformationView alloc] initWithFrame:CGRectMake(self.view.bounds.origin.x, CGRectGetMaxY(self.lineChartView.frame), self.view.bounds.size.width, self.view.bounds.size.height - CGRectGetMaxY(self.lineChartView.frame) - CGRectGetMaxY(self.navigationController.navigationBar.frame))];
[self.informationView setValueAndUnitTextColor:[UIColor colorWithWhite:1.0 alpha:0.75]];
[self.informationView setTitleTextColor:kJBColorLineChartHeader];
[self.informationView setTextShadowColor:nil];
[self.informationView setSeparatorColor:kJBColorLineChartHeaderSeparatorColor];
[self.view addSubview:self.informationView];
[self.lineChartView reloadData];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.lineChartView setState:JBChartViewStateExpanded];
}
#pragma mark - JBChartViewDataSource
- (BOOL)shouldExtendSelectionViewIntoHeaderPaddingForChartView:(JBChartView *)chartView
{
return YES;
}
- (BOOL)shouldExtendSelectionViewIntoFooterPaddingForChartView:(JBChartView *)chartView
{
return NO;
}
#pragma mark - JBLineChartViewDataSource
- (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView
{
return [self.chartData count];
}
- (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex
{
return [[self.chartData objectAtIndex:lineIndex] count];
}
- (BOOL)lineChartView:(JBLineChartView *)lineChartView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex
{
return lineIndex == JBLineChartViewLineStyleDashed;
}
- (BOOL)lineChartView:(JBLineChartView *)lineChartView smoothLineAtLineIndex:(NSUInteger)lineIndex
{
return lineIndex == JBLineChartViewLineStyleSolid;
}
#pragma mark - JBLineChartViewDelegate
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
return [[[self.chartData objectAtIndex:lineIndex] objectAtIndex:horizontalIndex] floatValue];
}
- (void)lineChartView:(JBLineChartView *)lineChartView didSelectLineAtIndex:(NSUInteger)lineIndex horizontalIndex:(NSUInteger)horizontalIndex touchPoint:(CGPoint)touchPoint
{
NSNumber *valueNumber = [[self.chartData objectAtIndex:lineIndex] objectAtIndex:horizontalIndex];
if(isnan([valueNumber floatValue])) {
[self.informationView setHidden:YES animated:YES];
} else {
[self.informationView setValueText:[NSString stringWithFormat:@"%.2f", [valueNumber floatValue]] unitText:kJBStringLabelKm2014];
[self.informationView setTitleText:lineIndex == JBLineChartLineSolid ? kJBStringLabelLastWeek : kJBStringLabelCurrentWeek];
[self.informationView setHidden:NO animated:YES];
}
[self setTooltipVisible:YES animated:YES atTouchPoint:touchPoint];
[self.tooltipView setText:[[self.daysOfWeek objectAtIndex:horizontalIndex] uppercaseString]];
}
- (void)didDeselectLineInLineChartView:(JBLineChartView *)lineChartView
{
[self.informationView setHidden:YES animated:YES];
[self setTooltipVisible:NO animated:YES];
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView colorForLineAtLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidLineColor: kJBColorLineChartDefaultDashedLineColor;
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidLineColor: kJBColorLineChartDefaultDashedLineColor;
}
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView widthForLineAtLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? kJBLineChartMissingPointsViewControllerChartSolidLineWidth: kJBLineChartMissingPointsViewControllerChartDashedLineWidth;
}
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? 0.0 : kJBLineChartMissingPointsViewControllerChartSolidLineDotRadius;
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView verticalSelectionColorForLineAtLineIndex:(NSUInteger)lineIndex
{
return [UIColor whiteColor];
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForLineAtLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidSelectedLineColor: kJBColorLineChartDefaultDashedSelectedLineColor;
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidSelectedLineColor: kJBColorLineChartDefaultDashedSelectedLineColor;
}
- (JBLineChartViewLineStyle)lineChartView:(JBLineChartView *)lineChartView lineStyleForLineAtLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? JBLineChartViewLineStyleSolid : JBLineChartViewLineStyleDashed;
}
#pragma mark - Buttons
- (void)chartToggleButtonPressed:(id)sender
{
UIView *buttonImageView = [self.navigationItem.rightBarButtonItem valueForKey:kJBLineChartMissingPointsViewControllerNavButtonViewKey];
buttonImageView.userInteractionEnabled = NO;
CGAffineTransform transform = self.lineChartView.state == JBChartViewStateExpanded ? CGAffineTransformMakeRotation(M_PI) : CGAffineTransformMakeRotation(0);
buttonImageView.transform = transform;
[self.lineChartView setState:self.lineChartView.state == JBChartViewStateExpanded ? JBChartViewStateCollapsed : JBChartViewStateExpanded animated:YES callback:^{
buttonImageView.userInteractionEnabled = YES;
}];
}
#pragma mark - Overrides
- (JBChartView *)chartView
{
return self.lineChartView;
}
@end
@@ -29,6 +29,7 @@ CGFloat const kJBLineChartViewControllerChartHeaderHeight = 75.0f;
CGFloat const kJBLineChartViewControllerChartHeaderPadding = 20.0f;
CGFloat const kJBLineChartViewControllerChartFooterHeight = 20.0f;
CGFloat const kJBLineChartViewControllerChartSolidLineWidth = 6.0f;
CGFloat const kJBLineChartViewControllerChartSolidLineDotRadius = 5.0f;
CGFloat const kJBLineChartViewControllerChartDashedLineWidth = 2.0f;
NSInteger const kJBLineChartViewControllerMaxNumChartPoints = 7;
@@ -85,6 +86,12 @@ NSString * const kJBLineChartViewControllerNavButtonViewKey = @"view";
return self;
}
- (void)dealloc
{
_lineChartView.delegate = nil;
_lineChartView.dataSource = nil;
}
#pragma mark - Data
- (void)initFakeData
@@ -171,6 +178,18 @@ NSString * const kJBLineChartViewControllerNavButtonViewKey = @"view";
[self.lineChartView setState:JBChartViewStateExpanded];
}
#pragma mark - JBChartViewDataSource
- (BOOL)shouldExtendSelectionViewIntoHeaderPaddingForChartView:(JBChartView *)chartView
{
return YES;
}
- (BOOL)shouldExtendSelectionViewIntoFooterPaddingForChartView:(JBChartView *)chartView
{
return NO;
}
#pragma mark - JBLineChartViewDataSource
- (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView
@@ -231,12 +250,12 @@ NSString * const kJBLineChartViewControllerNavButtonViewKey = @"view";
return (lineIndex == JBLineChartLineSolid) ? kJBLineChartViewControllerChartSolidLineWidth: kJBLineChartViewControllerChartDashedLineWidth;
}
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? 0.0: (kJBLineChartViewControllerChartDashedLineWidth * 4);
return (lineIndex == JBLineChartLineSolid) ? 0.0: kJBLineChartViewControllerChartSolidLineDotRadius;
}
- (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView verticalSelectionColorForLineAtLineIndex:(NSUInteger)lineIndex
{
return [UIColor whiteColor];
}
+48 -15
View File
@@ -38,12 +38,8 @@ Build and run the <i>JBChartViewDemo</i> project in Xcode. The demo demonstrates
Simply add the following line to your <code>Podfile</code>:
pod 'JBChartView'
Your Podfile should look something like:
platform :ios, '6.0'
pod 'JBChartView', '~> 2.7.1'
pod 'JBChartView'
### The Old School Way
@@ -62,9 +58,9 @@ All JBChartView implementations have a similiar data source and delgate pattern
To use JBCartView in a Swift project add the following to your bridging header (JBChartView-Bridging-Header.h):
#import <UIKit/UIKit.h>
#import "JBChartView/JBChartView.h"
#import "JBChartView/JBBarChartView.h"
#import "JBChartView/JBLineChartView.h"
#import "JBChartView.h"
#import "JBBarChartView.h"
#import "JBLineChartView.h"
For more information about adding bridging headers see <a href="https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html" target="_blank">Swift and Objective-C in the Same Project</a>.
@@ -76,6 +72,15 @@ To initialize a <i>JBBarChartView</i>, you only need a few lines of code (see be
barChartView.dataSource = self;
barChartView.delegate = self;
[self addSubview:barChartView];
Just like you would for a `UITableView`, ensure you clear these properties in your `dealloc`:
- (void)dealloc
{
JBBarChartView *barChartView = ...; // i.e. _barChartView
barChartView.delegate = nil;
barChartView.dataSource = nil;
}
At a minimum, you need to inform the data source how many bars are in the chart:
@@ -86,7 +91,7 @@ At a minimum, you need to inform the data source how many bars are in the chart:
Secondly, you need to inform the delegate the height of each bar (automatically normalized across the entire chart):
- (CGFloat)barChartView:(JBBarChartView *)barChartView heightForBarViewAtAtIndex:(NSUInteger)index
- (CGFloat)barChartView:(JBBarChartView *)barChartView heightForBarViewAtIndex:(NSUInteger)index
{
return ...; // height of bar at index
}
@@ -95,15 +100,26 @@ Lastly, ensure you have set the *frame* of your barChartView & call *reloadData*
barChartView.frame = CGRectMake( ... );
[barChartView reloadData];
**Note**: subsequent changes to the chart's frame will not invoke *reloadData*; it must be called directly afterwards for any changes to take effect.
#### JBLineChartView
Similiarily, to initialize a JBLineChartView, you only need a few lines of code (see below). Line charts can also be initialized via a <b>nib</b> or with a <b>frame</b>.
JBLineChartView *lineChartView = [[JBLineChartView alloc] init];
lineChartView.dataSource = self;
lineChartView.delegate = self;
[self addSubview:lineChartView];
lineChartView.dataSource = self;
lineChartView.delegate = self;
[self addSubview:lineChartView];
Just like you would for a `UITableView`, ensure you clear these properties in your `dealloc`:
- (void)dealloc
{
JBLineChartView *lineChartView = ...; // i.e. _lineChartView
lineChartView.delegate = nil;
lineChartView.dataSource = nil;
}
At a minimum, you need to inform the data source how many lines and vertical data points (for each line) are in the chart:
@@ -124,11 +140,16 @@ Secondly, you need to inform the delegate of the y-position of each point (autom
return ...; // y-position (y-axis) of point at horizontalIndex (x-axis)
}
**Note**: You can return NAN instead of CGFloat to indicate missing values. The chart's line will begin at the first non-NAN value and end at the last non-NAN value. The line will interopolate any NAN values in between (ie. the line will not be interrupted).
return [[NSNumber numberWithFloat:NAN] floatValue];
Lastly, ensure you have set the *frame* of your lineChartView & call *reloadData* at least once:
lineChartView.frame = CGRectMake( ... );
[lineChartView reloadData];
**Note**: subsequent changes to the chart's frame will not invoke *reloadData*; it must be called directly afterwards for any changes to take effect.
## Customization
@@ -150,6 +171,10 @@ Lastly, any JBChartView subclass can be collapsed or expanded programmatically v
#### JBBarChartView
A bar chart can be inverted such that it's orientation is top->down (including the selection view) by setting the following property:
@property (nonatomic, assign, getter=isInverted) BOOL inverted;
By default, a chart's bars will be black and flat. They can be customized by supplying a UIView subclass through the <i>optional</i> protocol:
- (UIView *)barChartView:(JBBarChartView *)barChartView barViewAtIndex:(NSUInteger)index
@@ -208,7 +233,7 @@ The color, width and style of each line in the chart can be customized via the <
Furthermore, the color and width of the selection view along with the color of the selected line can be customized via the <i>optional</i> protocols:
- (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView verticalSelectionColorForLineAtLineIndex:(NSUInteger)lineIndex
{
return ...; // color of selection view
}
@@ -232,9 +257,9 @@ By default, each line will not show dots for each point. To enable this on a per
- (BOOL)lineChartView:(JBLineChartView *)lineChartView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex;
To customize the size of each dot (default 3x the line width), implement:
To the radius of each dot (default is 6x the line width, or 3x the diameter), implement:
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
To customize the color of each dot during selection and non-selection events (default is white and black respectively), implement:
@@ -242,6 +267,14 @@ To customize the color of each dot during selection and non-selection events (de
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
Alternatively, you can supply your own UIView instead of using the default impelmentation:
- (UIView *)lineChartView:(JBLineChartView *)lineChartView dotViewAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
Custom dot views are automatically shown when selected unless the following is implemented:
- (BOOL)lineChartView:(JBLineChartView *)lineChartView shouldHideDotViewOnSelectionAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
As well, by default, each line will have squared off end caps and connection points. To enable rounded connections and end caps:
- (BOOL)lineChartView:(JBLineChartView *)lineChartView smoothLineAtLineIndex:(NSUInteger)lineIndex;