-
-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ChartViewBase cleanup #3034
ChartViewBase cleanup #3034
Conversation
Codecov Report
@@ Coverage Diff @@
## 4.0.0 #3034 +/- ##
=========================================
- Coverage 20.9% 20.88% -0.02%
=========================================
Files 111 111
Lines 15458 15390 -68
Branches 250 251 +1
=========================================
- Hits 3231 3214 -17
+ Misses 12187 12136 -51
Partials 40 40
Continue to review full report at Codecov.
|
|
||
/// This property is deprecated - Use `chartDescription.text` instead. | ||
@objc @available(*, deprecated: 1.0, message: "Use `chartDescription.text` instead.") | ||
open var descriptionText: String | ||
{ | ||
get { return chartDescription?.text ?? "" } | ||
set { chartDescription?.text = newValue } | ||
get { return chartDescription.text ?? "" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems we have a future conflict that these will be removed, but we change it now?
I'm not sure if we should merge #2996 into master now or for 4.0. I don't think it's worthy to refactor what will be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s not a big deal though, and I will likely be the one handling merge conflicts. In this case, these deprecations need to be changed in order for the project to build.
I think we should merge into master, and I’ll handle any merge conflicts when we merge into 4.0 in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have merged #2996 to make things easier.
btw, I need to think about if changing to lazy fits. something like description or empty texts should be released if not used later, not retaining all the time (though memory pressure is no longer a thing, but we should keep a good habit?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conflicts are resolved
@@ -500,8 +463,7 @@ open class ChartViewBase: NSUIView, ChartDataProvider, AnimatorDelegate | |||
/// - parameter callDelegate: Should the delegate be called for this change | |||
@objc open func highlightValue(x: Double, y: Double, dataSetIndex: Int, callDelegate: Bool) | |||
{ | |||
guard let data = _data else | |||
{ | |||
guard let data = _data else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code style is make {
a separate line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -443,19 +410,15 @@ open class ChartViewBase: NSUIView, ChartDataProvider, AnimatorDelegate | |||
/// null or an empty array to undo all highlighting. | |||
/// This should be used to programmatically highlight values. | |||
/// This method *will not* call the delegate. | |||
@objc open func highlightValues(_ highs: [Highlight]?) | |||
@objc open func highlightValues(_ highs: [Highlight]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember highlight objects are allowed to be nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted
} | ||
_indicesToHighlight = highs ?? [] | ||
|
||
lastHighlighted = _indicesToHighlight.isEmpty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one line is enough for ?:
(code style here just uses one line)
if entry == nil | ||
{ | ||
h = nil | ||
var high = highlight |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm feeling this rewrite makes harder to understand the logic (the guard else{} part). If we cannot find a better one, I suggest add simple comment here.
@@ -519,7 +480,7 @@ open class ChartViewBase: NSUIView, ChartDataProvider, AnimatorDelegate | |||
/// CandleStick-Chart. | |||
@objc open func getHighlightByTouchPoint(_ pt: CGPoint) -> Highlight? | |||
{ | |||
if _data === nil | |||
guard _data != nil else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not feeling guard is better here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The convention is as the Swift Book states:
You use a guard statement to require that a condition must be true in order for the code after the guard statement to be executed.
While technically it doesn't matter if we use an if
or a guard
, the guard
does make it clear that we need a condition to be true
to continue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree with @jjatie on this one - we are used to C-style languages, while Swift does not aim at being one... For Swift it's more natural to put a guard
{ | ||
continue | ||
} | ||
guard entryIndex <= Int(Double(set.entryCount) * _animator.phaseX) else { continue } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is guard in swift as fast as if, in terms of assembling code? I'm feeling we are using lots of guard, when it just means if condition. If guard is slower than if, I would rather not to use too many.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They compile the same. I think you're just not used to seeing guard
yet since it isn't in objc.
The convention is as the Swift Book states:
You use a guard statement to require that a condition must be true in order for the code after the guard statement to be executed.
While technically it doesn't matter if we use an if
or a guard
, the guard
does make it clear that we need a condition to be true
to continue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of what you know as "optionals", and stuff that work with optionals, and guards and stuff - are compile time. You want to be sure that something is not null and unwrap it, and unwrapping does not mean that you have more code there - it just means that the compiler trusts the non-null object and allows you to refer to it without the ?
operator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I have time, I would create a sample app and check what guard and if implementation looks like in asm code. Ideally should not "that" impact the performance. I was just obsessed a little recently about the asm code 😂
{ | ||
val = 0.999 | ||
switch newValue { | ||
case ..<0.0: _dragDecelerationFrictionCoef = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where can I find this magic definition.. I just can find things like case 1..<5:
in the manual.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One Sided Ranges are new in Swift 4.
#endif | ||
|
||
_animator = Animator() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so if we uses lazy, how do we override the property in subclass to a new class object? e.g some users may write their own animator class, or XAxis class, and just override initialize() to replace them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are still able to do this exactly the same as they have before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we should add some comments/notes that people should override initialize() to replace the objects with their classes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? We never did before. As far as the consumer is concerned, nothing has changed other than it is no longer an implicitly unwrapped optional. Swift initialization already works that way where you must override the initializer to provide a different default value for a stored property.
Fixed using wrong axis (Issue #2257)
* Removed redundant ivars in favour of proper access control * Moved initialization of axes to their declaration to keep the same optionality exposed.
* Replaced relevant `ChartUtils` methods with `Double` extensions Improves readability. `nextUp` is built in and provides the same functionality. * Updated `ChartUtilsTests` to match changes
* add option to build demo projects unit tests on iOS * add ChartsDemo-OSX build test.
@jjatie I'm confused. We have a card for PRs merged to master, and 4.0 card merge to 4.0 branch. You moved most of them from master to 4.0 card, shall we change the branch? |
Yep! I missed a couple I guess. Things will be easier if I just move them to 4.0 and they aren't adding/changing functionality so they can wait until 4.0 |
alright, one last comment. do you think any chance anyone would nil out some of those old optionals? Like legend. |
You're looking at the internal properties. The consumer facing properties were already non-optional. |
Let's try the new tests then. looks good to me |
|
||
/// object responsible for animations | ||
internal var _animator: Animator! | ||
internal lazy var _animator: Animator = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code style for blocks? { another line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess so?
|
||
attrs[NSAttributedStringKey.font] = description.font | ||
attrs[NSAttributedStringKey.foregroundColor] = description.textColor | ||
let attrs: [NSAttributedStringKey : Any] = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about [
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking through the rest of library, [
and (
seems to be on the same line.
h = nil | ||
var high = highlight | ||
guard | ||
let h = high, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use single let here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, no. I tried, but couldn't find a way because we need to assign the original highlight.
guard | ||
let h = high, | ||
let entry = _data?.entryForHighlight(h) | ||
else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry about missing these code style, { another line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we agreed this was the style for multiline guard statements?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh is it? sorry don't remember.
{ | ||
_indicesToHighlight = [h!] | ||
} | ||
if callDelegate { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry about missing these code style, { another line
// set the indices to highlight | ||
_indicesToHighlight = [h] | ||
|
||
if callDelegate { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry about missing these code style, { another line
if val < 0.0 | ||
{ | ||
val = 0.0 | ||
switch newValue { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ another line or?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess so. Seems weird to me on switch statements.
@jjatie looks like these commits are no with latest rake file. Feel free to just test on your side or merge master(like practice rebase) |
Oops! Fixing now. |
any idea why the UT is not latest? |
4.0.0 is out of sync with master |
fix a small bug
please merge and rebase on master, once the CI passed, this can be merged I think. |
For the most part, condensing logic and using `guard` where appropriate Removed optionality of many internal variables as they were only optional to allow for deferred initialization. This is now replaced with lazy vars. Removed empty initializer overrides. `fileprivate` is now `private`
* Renamed `IMarker` to `Marker` following Swift API guidelines. * Renamed `IAxisValueFormatter` to `AxisValueFormatter` * Renamed `IFillFormatter` to `FillFormatter` * Renamed `IValueFormatter` to `ValueFormatter` * Renamed `IHighlighter` to `Highlighter` * Renamed `I*DataSet` to `*DataSetProtocol` to follow Swift API guidelines * Fixed naming of `LineRadarChartDataSetProtocol` and `RadarChartDataSetProtocol` from previous commit * Renamed "Interfaces" to "DataProviders" for clarity * Updated Demos to for new type naming
* Renderer is now a protocol Renamed Renderers, and organized the Renderer folder. * DataRenderer is now a protocol * AxisRenderer is now a protocol
I still don't understand how you want me to rebase 4.0.0 branch since I can't push it up without review. I rebased this PR, but obviously 4.0.0 has not been rebased. Also, I noticed that when I rebased from master, the merging took many old commits that I had to manually correct whereas pulling master did not. Very frustrating. |
Oh I see. If you see the old conflicts you already resolved but once again appear when you rebase, you are on the "right rebase way" I'm talking about, and yes, it's frustrating. What I meant in the other thread is, I hope you no longer need to have those "merging from upstream master..." commits in your commit log by using rebase. When you rebase, the old conflicts you resolved will jump again, and if it's easy to fix again, just continue. If it's a lot of burden, let's simply pull master, and then we squash the commits when we want to merge the pull requests on github page. The whole point using rebase with this project is to squash the commits into one or remove useless commits before filing the PR or updating the PR. The purpose is to make the project commit logs simple and easy to search. Hope this clarify? For this PR, I saw conflicts now, you can just revert back to the commit you think is all good and pull master then, let CI pass and click "squash and merge", don't need to rebase then. |
You can't undo a rebase like this. I figured out what my problem is with the rebasing in this case. You can't rebase from two different branches at the same time which is what we need to do for PRs going into 4.0.0. You can either rebase from master OR 4.0.0, not both. In order for rebasing to work here, 4.0.0 needs to be regularly rebased from master, and then PRs for 4.0.0 need to rebase off the freshly rebased 4.0.0. The problem with this is that there is no way rebase 4.0.0 without review. Most guides will tell you that you should never rebase a branch someone else might touch, which in this case is the 4.0.0 branch. While I disagree with rebasing in general because you lose history, I'm okay doing it for PR branches. If we are going to rebase, all PRs should be rebasing from the branch they are PRing into. I'll create an issue about this and we can update the docs from there for future PRs to be accepted. This PR is garbage now, but luckily #3045 includes all the changes I made here. I will update that PR with the current 4.0.0. They should have been the same PR in the first place, but I wasn't sure what changes might be accepted at the time I made them. |
to clarify, can't rebase abort action plus |
Not when you need to rebase from multiple branches |
For the most part, condensing logic and using
guard
where appropriateRemoved optionality of many internal variables as they were only optional to allow for deferred initialization. This is now replaced with lazy vars.
Removed empty initializer overrides.
fileprivate
is nowprivate