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
Refactors classes + bugfix + improves coverage #2405
Conversation
- Class chart was moved to its own script. - Class AxisInternal was moved to its own script. It's only needed by Class Axis - Definition of Chart removed from core.js - Definition of AxisInternal removed from axis.js
- Alias c3_chart_fn replaced by Chart.prototype where is due - Alias c3_chart_internal_fn replaced by ChartInternal.prototype where is due - spec/data.convets.js renamed to spec/data.convert-spec.js for clarity
- It was calling $$.updateAndRedraw({withLegend: true}); - It should call $$.updateAndRedraw({withLegend: false});
restores c3.js and c3.min.js to master version fixes linter error
6a685ac
to
15837d8
Compare
Codecov Report
@@ Coverage Diff @@
## master #2405 +/- ##
==========================================
+ Coverage 78.14% 80.75% +2.61%
==========================================
Files 52 54 +2
Lines 4136 4246 +110
==========================================
+ Hits 3232 3429 +197
+ Misses 904 817 -87
Continue to review full report at Codecov.
|
Thank you for the great work! @amenadiel I like this change of the way of referencing the prototypes of classes. This seems more natural to my eyes. And thanks for adding test cases! |
I'm going to wait for other members' opinion for a while. If there is no other opinion, then I'll merge and release this. |
@panthony it looks great. The main class has so many methods attached to the prototype that is pretty cumbersome to track what goes where, which in turn makes unit testing more difficult. I mean, to reach certain parts of the "private" methods switch of if...else statements, you must go as far as declaring new charts over and over, because said methods are called from elsewhere and tied to the initial options. |
src/util.js
Outdated
@@ -1,36 +1,18 @@ | |||
import {ChartInternal} from './chart-internal'; | |||
import {Chart} from './chart'; |
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 sure if this is the scope of this PR but in my opinion the util.js file should NOT import chart/chart internal.
This file should be as "low level" at it can be.
Otherwise we are bound to have circular dependency when importing this file
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.
You mean util.js
should be low level in the sense of being just a collection of functions? In that case, c3
could be elsewhere.
However, util.js
exports Component
which in turn is used by Axis
to extend ChartInternal
and c3.chart.internal
. This means Component
needs the definition of ChartInternal
and c3
(of course) and you can't define c3
without importing Chart
and ChartInternal
.
However, I'm confused, because Axis
is instanced as
$$.axis = new Axis($$)
(where $$ is the instance of ChartInternal).
And when instancing Axis, the side effect are:
1.- Axis (instance).owner = ChartInternal instance
2.- c3
is changed from:
var c3 = {
version: "0.6.3",
chart: {
fn: Chart.prototype,
internal: {
fn: ChartInternal.prototype,
}
},
generate: function(config) {
return new Chart(config);
}
};
to
var c3 = {
version: "0.6.3",
chart: {
fn: Chart.prototype,
internal: {
fn: ChartInternal.prototype,
axis: {
fn: Axis.prototype,
internal: {
fn: AxisInternal.prototype
}
}
}
},
generate: function(config) {
return new Chart(config);
}
};
the last one could be handled if we moved the definition of c3
to a separate file which imported Chart
, ChartInternal
, Axis
and AxisInternal
.
whereas the first one could be handled simply by defining Axis as
export default class Axis {
constructor(owner) {
this.owner = owner;
this.d3 = owner.d3;
this.internal = AxisInternal;
}
}
util.js
also exports functions isEmpty
and notEmpty
where the second one is defined as
export var notEmpty = function (o) {
return !ChartInternal.prototype.isEmpty(o);
};
again, this would mean that util.js
needs ChartInternal
. BUT, it would be as simple as declaring notEmpty
as
export var notEmpty = function (o) {
return !isEmpty(o);
};
Because it is by all means a static function, even if they are later attached to ChartInternal.prototype
.
I'll make some arrangements to see if, with some refactoring, this could pass the tests keeping util.js
just a bunch of static functions.
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 for such a short response to such a huge reply but:
You mean util.js should be low level in the sense of being just a collection of functions? In that case, c3 could be elsewhere.
That's exactly what I mean !
We shouldn't have to depend on the whole "ChartInternal" class for such small functions.
However, util.js exports Component which in turn is used by Axis to extend ChartInternal and c3.chart.internal. This means Component needs the definition of ChartInternal and c3 (of course) and you can't define c3 without importing Chart and ChartInternal.
And that is why :)
Because it is by all means a static function, even if they are later attached to
I think they shouldn't even be attached to the prototype... They are just static utility functions that you import when needed.
@kt3k Merging this PR should require ideally a major version bump (but I guess in c3js case a minor) as any workaround/fix people did overriding an internal method won't work anymore. |
@panthony I refactored a bit, based in your review.
|
bdddf40
to
886ac3a
Compare
|
Thanks for pointing it. I didn't intend to do breaking change in this PR. Now I think the overriding functionality is being kept in core.js ( https://github.com/c3js/c3/pull/2405/files#diff-7eb52b366866677666470e019283c8eaR24 ) |
At least the extensions I,ve seen attach themselves to c3.iternal.fn or c3.chart.internal.fn Regarding utils.js since it's a bunch of functions, if we don't attach it to the prototype there's no way to unit test. |
@amenadiel Thanks for this huge work, If I were nitpicky I'd say it would have been better without all the changes related to formatting. It's harder to see if there is something actually meaningful that were updated.
Not seeing why ? Create a @kt3k For the breaking change maybe I was wrong I though people where doing |
ccd66b5
to
700f266
Compare
Hmm, I ran jsbeautify to restore occurences of
Silly me, I was half asleep. Yeah, I forgot we could use ES6 imports in the specs. I'm used to run karma-jasmine on AMD builds while you're browserifying beforehand. So okay, I added |
700f266
to
a96293c
Compare
1103892
to
07e4dee
Compare
@amenadiel I think there is no issue remaining. I'm going to merge and release this. |
Released as 0.6.5. |
Uses classes prototype instead of their aliases
Chart
was moved to its own script.AxisInternal
was moved to its own script. It's only needed by ClassAxis
Chart
removed from core.jsAxisInternal
removed from axis.jsc3_chart_fn
replaced byChart.prototype
where is duec3_chart_internal_fn
replaced byChartInternal.prototype
where is duespec/data.convert.js
renamed tospec/data.convert-spec.js
for consistencyspec/*-helper.js
andspec/*-spec.js
Fixes
Chart.prototype.legend.hide
behaviorAlso, added some tests to improve coverage