Skip to content
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

PoC - d3v4 support #1363

Closed
wants to merge 42 commits into from
Closed

PoC - d3v4 support #1363

wants to merge 42 commits into from

Conversation

kum-deepak
Copy link
Collaborator

Reference:
#1173

@kum-deepak kum-deepak mentioned this pull request Feb 18, 2018
@gordonwoodhull
Copy link
Contributor

Thanks @kum-deepak! This sounds like a good approach.

The selection behavior has also changed a lot, since d3v3 used to automatically merge the enter selection into the modify selection. I guess maybe your compatibility layer can handle this, but when eventually removing the compatibility layer, it is still going to be tricky.

Please continue to update with your progress and I'll be happy to review or help out as you go.

@kum-deepak
Copy link
Collaborator Author

Thanks for your inputs. I have been meditating for past two days on best way to handle changes to selection behavior.

.enter() is currently used in 36 places. Writing a wrapper is possible but quite clumsy, the effort to test the wrapper is going to be more than direct changes (which anyway will need to be done).

I understand that it is not pragmatic to maintain support for both versions in the same branch. At the same time due to nature of changes it is likely that support for D3v3 and D3v4 will need to co-exist for significant time.

So, I was thinking - as far as possible - to modify in the code in a way that modified code works with D3v3 as well. So far there are following known changes

  • accessing nodes from a selection
  • behavior of selectAll in regard to .enter()

I think both of these can be created a functions that can be implemented for D3v3 and D3v4.

I will commit again when I reach someplace.

@gordonwoodhull
Copy link
Contributor

I think it's perfectly acceptable to simply move to d3v4. This was how I planned to make the port when I find time.

It's true, there will be some overlap, and fixes will have to be applied separately to two branches for a while. But once we get d3v4 fully working, it should be fine to drop d3v3, since the rest of the world has already moved on.

My two cents. Thank you for taking this challenge, and feel free to pursue it however you think is best.

@kum-deepak
Copy link
Collaborator Author

Thanks! I will proceed with making direct changes. That will actually make the changes simpler :)

I was going through the code - the more complex changes brush() and dispatch() are used only once each.

@kum-deepak
Copy link
Collaborator Author

Your message was really timely :)

@gordonwoodhull
Copy link
Contributor

Great! I think the scatter plot modifies the brush a little bit too, but otherwise yes that should be it.

@kum-deepak
Copy link
Collaborator Author

Have been able to get more chart types to work. One setback - the stack API has changed beyond recognition. Spent some time on that but was not able to move it. Good thing, it is a relatively isolated code in D3v3, extracted relevant part and placed in the d3-compat file. That has allowed me to go ahead. I will come back to it when other issues are under control.

Next target for me is brushes.

@gordonwoodhull
Copy link
Contributor

Awesome! Yes, having read CHANGES.md, it looks like every interface has changed somewhat, and many in fundamental ways.

So grateful you are taking the time to work on this.

@kum-deepak
Copy link
Collaborator Author

Brushing itself works :) New brush APIs are simpler and is likely to yield a simpler code.

I am facing a very stupid doubt, brush needs to be told the region brushing is allowed. For this I need the width and height of the chart area. How do I get that?

@gordonwoodhull
Copy link
Contributor

That's great!

You can use .effectiveWidth() and .effectiveHeight() to get the chart extent. They are defined in the marginMixin.

@kum-deepak
Copy link
Collaborator Author

kum-deepak commented Feb 28, 2018

Started seeing end of the tunnel. Many examples have started working. Key pending dev work:

  • Zoom
  • Brush - need to implement 2D brushing for scatter plots, refactor general brush
  • Area - lines are working, area is not

Examples that are not working as of now:

@gordonwoodhull
Copy link
Contributor

Wow! You're really getting there!

Amazing work.

@kum-deepak
Copy link
Collaborator Author

Zoom and focus works now. :)

@gordonwoodhull
Copy link
Contributor

Completely agree. Looks like we're almost there - congratulations!

@gordonwoodhull
Copy link
Contributor

gordonwoodhull commented Mar 17, 2018

I was able to do some testing today, so I ran through all the examples.

Here are the issues I found, mostly to do with initial values for elements that are entering.

We don't need to fix these before putting out the alpha, but we'll definitely need to fix them, as well as using the d3v4 stack implementation, before releasing 3.0.0. I'll open issues for any that you don't fix before we merge this PR.

bar charts

  • introductory transition on bars is from lower left instead of just from bottom
  • bar labels transition from upper left instead of just being there at start
  • multi focus example: bars turn grey before being filtered/focused (?) out instead of just disappearing. Not sure which behavior is better here, but we should figure out what is going on here and decide one way or the other.

line charts

  • dots transition from upper left instead of just being there
  • range series example: brush handles not removed when clicking to remove brush. probably because composite chart?

heat map

  • squares transition from upper right instead of just fading in

Transitions have many, many issues, but at least we shouldn't regress with this release.

@kum-deepak
Copy link
Collaborator Author

Thanks for your review.

I have committed now draft version of upgrade guide. I now realize that other than changes to the user code for d3 changes, there are only two changes.

It is possible to make those two backward compatible, will wait for your feedback.

@kum-deepak
Copy link
Collaborator Author

I think we have reached a stage where we can baseline it as a single commit, and split for work on localized/specific issues.

My current (non exhaustive list):

  • Cleanup of zoom behavior. Testing of restrict panning etc.
  • dc.event.trigger
  • exit/enter/update sequence - this is an important one
  • Additional test cases for dc.util.add and dc.util.subtract
  • One for each new chart type - original PRs from community
  • Consider removing transitions for zooming and brushing
  • d3 stack to D3v4
  • Changing .tension call in lineChart
  • http://localhost:8888/web/examples/filter-stacks.html
    (fading is peculiar)
  • http://localhost:8888/web/zoom/restrict-panning.html
    Need to increase height of range chart - currently height of
    brushable area is zero. New implementation needs it be more than zero.
  • Issues with transitions (d3 behavior might have changed, or I clobbered some functionality as I did not understand that)

I will describe each of these on the individual issue/PR.

I will keep working one/few at a time. Will love to hear your prioritization/grouping of the above.

@kum-deepak
Copy link
Collaborator Author

It was my first experience with working with D3 - completing a month now. :)

I now realize that behavior of .selectAll in D3v4 implicitly favors code that first handles exiting elements, following by entering and updating. The current dc code does it in sequence enter, update and exit.

Making the change will make the code cleaner and more manageable. However I am not sure if will make any adverse noticeable change for the user. In any case I wanted first a working version before attempting this one.

In the current code sometimes, .enter is called in a function other than the function that called .selectAll. I was needed to return the entering collection from the function as it it is needed for the call to .merge. A more maintainable code will be to call .enter in the same function as .selectAll and adjust the parameters accordingly.

I think that when we make the above change - some subtle bugs would get fixed - which may be related to updating elements not behaving properly.

Will wait for your suggestion before proceeding on this one.

@kum-deepak
Copy link
Collaborator Author

@gordonwoodhull can you please merge this pull request as a new branch (say d3v4) as a single commit. I will use that as base to continue further work.

Thanks!

@gordonwoodhull
Copy link
Contributor

Yes I'll create a 3.0 branch today. Sorry for the delay - yesterday I got bogged down thinking about whether we should be backward compatible. (It's easy enough so I think we should.)

Please start opening issues for the remaining work. I'll create 3.0 milestone now.

@kum-deepak
Copy link
Collaborator Author

After having done everything, looks like we can actually be backward compatible, only two changes, which can both be extended to mimic the current API behavior.

As we can move towards 3.0 we can start putting deprecation notices as suggestions to update.

@kum-deepak
Copy link
Collaborator Author

There may still remain some incompatibility around tension in interpolate/curve function. Which may impact very few users.

gordonwoodhull pushed a commit that referenced this pull request Mar 21, 2018
Squashed from #1363

pie-charts all test cases passing with d3v4

Better alignment to build infrastructure

.selectAll('anything')[0] -> .selectAll('anything').nodes()

interpolate and tension semantics have changed.

Updated for semantics of D3v4 .enter()
Fixed test cases

Discovered that more D3 functions that are used.

Updated for semantics of D3v4 .enter()

Updated for semantics of D3v4 .enter() and fixed test cases.

All test cases for number display and row chart passing

Tests passing

Axis, Scales - temp

Added d3-compat to examples

Brushing - initial work

Many examples working :)

Zoom and focus working

Home page charts works (issue with brushes)

Fixing some of the specs

X Axis brushing

Brushing for Scatter Plot

Brush extents and background color

Brush extent specs

Brushing works :)

Current status

Bar width corrected

Area is working

geoChoroplethChart

Functional completeness

dispatch directly implemented, compatibility code discarded.
base-mixin test cases passing

All specs passing

All specs passing

Merged D3v3-compat

Minor cleanup

Merge d3 compat

Cleanup brush related code

Updated test case

Travis

Inline docs - d3 documentation links and minor changes

Language correction

Upgrade guide draft

Update copyright notice

Cleanup
@gordonwoodhull
Copy link
Contributor

Sorry for the delay - I'm still not able to work much. I've created the 3.0 branch now!

BTW you're not following the jshint/jscs style guides. I guess maybe you never ran plain grunt with no parameters, which installs some useful commit hooks. If you don't want the hooks just run grunt lint to check everything. It doesn't matter to me if those don't pass every time, but you might want to start out with a single commit to fix these since it will touch a lot of files.

From now on, please select 3.0 as the base for your future PRs. I'll close this PR now, although there has not been an official release yet.

@@ -123,9 +128,9 @@ dc.bubbleChart = function (parent, chartGroup) {
// override default x axis brush from parent chart
};

_chart.redrawBrush = function () {
_chart.redrawBrush = function (g, selection, doTransition) {
Copy link
Contributor

@gordonwoodhull gordonwoodhull Apr 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops - looks like you added some arguments here but never pass them anywhere. I just ran into this because I wanted to add a dontSetBrush argument. Do you remember what you were trying to do here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically, it looks like you changed the signature to take the current filter/selection, but this also takes g and doTransition - so I guess it's a simple fix since those are unused.

if (_chart.filter() && _chart.brush().empty()) {
_chart.brush().extent(_chart.filter());
}
_chart.redrawBrush = function (selection) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove doTransition here? _brush.move can take a transition or a selection, just like the old brush could be applied to either a selection or transition.

It's not a big deal, just a tiny feature that makes chart resizing work better, but it makes me worry when functionality is removed with no explanation. In the future, could you please try to document the things that you disable or remove?

I guess I need to go over this PR with a fine-toothed comb before we release 3.0. We don't have full test coverage, especially where transitions are concerned - it's unclear how to test them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for letting me know, I will mark in future if I remove or change any functionality.

This one, in my initial implementation, was aggravating the infinite recursion. However the current code, may not suffer from that.

I will be more comfortable if you could go through the entire change set considering it to be my first encounter with both dc and d3.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, you probably simplified it in order to figure out why it was recursive, and then didn't restore the feature when you were done.

No harm done. Yes, I'll read over all the changes before we release.

gordonwoodhull added a commit that referenced this pull request Apr 2, 2018
@Justus-Maier
Copy link

Justus-Maier commented Apr 3, 2018

@gordonwoodhull how far are you through code review? Would you publish an alpha asap please?

@kum-deepak
Copy link
Collaborator Author

@Justus-Maier there are lot of changes, so it will take a while. Meanwhile you can install from 3.0 branch. Code can be considered alpha.

@gordonwoodhull
Copy link
Contributor

gordonwoodhull commented Apr 3, 2018

Yes, as @kum-deepak says, review is taking a while. Although I've started giving them alpha numbers (we're at 2 going on 3) I am not sure when I will publish to npm & cdnjs. Hopefully later this week.

(The trouble is that a lot of people will take the latest version even if it says alpha, and then complain about it. Bug reports are welcome of course!)

Meanwhile, if you're using npm, you can change your dependency in package.json to:

    "dc": "git://github.com/dc-js/dc.js#3.0",

to install directly from the github branch.

* unexpected results. Note also that when used as a getter, this function is not chainable: it
* returns the axis, not the chart,
* {@link https://github.com/dc-js/dc.js/wiki/FAQ#why-does-everything-break-after-a-call-to-xaxis-or-yaxis
* so attempting to call chart functions after calling `.yAxis()` will fail}.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants