Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

How to get d3.select().transition to work #117

Closed
mattma opened this issue Sep 16, 2016 · 8 comments
Closed

How to get d3.select().transition to work #117

mattma opened this issue Sep 16, 2016 · 8 comments
Labels

Comments

@mattma
Copy link

mattma commented Sep 16, 2016

I am using Angular 2.0.0 final, with d3 v4.3.2, typescript to test out some basic feature.

I am using 'd3-selection' module with @types/d3-selection.

import {Selection, select } from 'd3-selection';

...

    // create element typed with selection
   el: Selection<any, any, any, any>

Here is my first question, how do I use it? it will give me an error with "Generic type 'Selection<GElement, Datum, PElement, PDatum>'". I know that I need to give a type of it. so that I just give all 'any' to bypass this step. An explanation how to correctly set those four fields would be very helpful

My main question is, When I select an element on the page, I do not have "transition" method attached on the prototype. I could not chain with '.transition()' method to make it animate. Any hints would be really appreciated.

If I comment out the 'transition()' method, selected element could use 'attr' method, since it is on its prototype. When I chained 'transition()' method, it won't work. I got an error "select(...).transition" is not a function

someMethod () {
   this.el = select(<HTMLElement>'someDiv');

  this.el
     .transition()
      ....
     .attr('key', 'value')
}

Please, help. I have no idea how to do it to be able to chain with 'transition()'

@mattma
Copy link
Author

mattma commented Sep 16, 2016

Just tried this weird thing and it works.

import {Selection, select } from 'd3-selection';
import {transition} from 'd3-transition';
...
transition(select(<HTMLElement>'someDiv'))
    .select('someChildElement')
    .transition()
    ....
    .attr('key', 'value')

...

Is this how it works in V4 and typescript? look weird to you?

By default, const el: Selection<any, any, any, any> = select(<HTMLElement>'someDiv'). after I wrap it in transition(el), I run into an error Selection<any, any, any, any> is not assignable to parameter of type Transition<any, any, any, any>. I thought Transition is extended from Selection. How should I type the

@tomwanzek
Copy link
Owner

The short answers are the following. Note that, everything under (1) assumes you are using module imports (not vanilla scripts).

(1) Getting transitions to work on an existing selection

With the new D3 version 4, the d3-transition module extends the d3-selection module's Selection. This means, you need to import it for the side-effect (at a minimum):

import { select, Selection } from 'd3-selection';
import 'd3-transition';

This will extend the Selection to expose the someSelection.transition(...) method you were looking for. You can use it then in accordance with the documentation on d3-transition. Of course, you can also import other objects/interfaces from d3-transition, if you need them, e.g.:

import { select, Selection } from 'd3-selection';
import { transition, Transition } from 'd3-transition';

The transition(...) function as exported by d3-transition is what you can use to generate a transition directly as opposed to from an existing selection.

**(2) The meaning of the Generics

From a level-setting perspective, the new definitions for the Selection and Transition interfaces are driven by four generics:

  1. A generic corresponding to the type of element in the selection (groups)
  2. A generic corresponding to the type of datum associated with a selected element as per 1.
  3. A generic corresponding to the type of element in the parents property of the selection
  4. A generic corresponding to the type of datum associated with a parents element as per 3.

Now that the definitions are essentially migrated to DefinitelyTyped and the official API docs for v4 have stabilized, it is time to complete some of the JSDoc comments. It's already flagged as a todo.

Hope the above helps.

@tomwanzek tomwanzek changed the title d3.select().transition does not work How to get d3.select().transition to work Sep 16, 2016
@tomwanzek
Copy link
Owner

PS. I forgot, you mentioned that you are using Angular 2. I have published a simple/straight-forward Angular 2 Service to get D3 up and running in an ng2 project quickly (i.e. with TS2 support)

You can find it at:

It's peer dependencies are up to date with the latest Angular Final release.

I build a demo at:

The demo is still on Angular RC.5/angular-cli (v beta.11-webpack.8) Will update it shortly and beef up the README a bit.

@mattma
Copy link
Author

mattma commented Sep 16, 2016

Thank @tomwanzek very much for your in-depth knowledge on how transition works. I am definitely interested on the first method that you mentioned. (1) Getting transitions to work on an existing selection

I have been followed with your process on D4 V4 typescript updates for a while. Because I was limited to system.js and typescript 1.8, i can not play around with the new shining stuffs. I even asked you one time on when is the support going to land on TS 1.8. Well, that was not the case any more.

With the solid release of Angular 2.0.0, Angular-cli v1.0.0.beta.14. Most of the people should be on TS 2.0.2, using @types instead of typings should be a nature thing for most of angular devs.

I have seen your project d3-ng2-service. it is a simple wrapper for the entire d3 library. In my mind, the goal of the project is to give back d3 developers the same old way on chaining all the methods. It is good and a purpose. One thing that I want to ask is, since the d3-ng2-service is injected into the application as a whole sale. I believe that all exported modules will be included in the build time.

As an angular power user, I want to take advantage of webpack 2 tree shaking to drop off all the dead code. If I do use the service, I believe that the final build should import all of the exported modules. even though that you do the separated imports. since the service is a singleton object, which consider that imports everything. I lost the best part of the ES6 module import + tree shaking.

Correct me if I am wrong?

BTW, how stable of d3-v4-definitelytyped? Is it already in the stable channels of DT? Since I can do npm install @types/d3-selection --save-dev. Everything marks as stable in the docs / definitions with check mark should cover all the current d3 functions as version v4.3.2?

@tomwanzek
Copy link
Owner

Thx.

TS 1.8 Definitions
I closed the matter in this repo, but raised it in the main thread on DefinitelyTyped (see Issue 9936) It's at his point a cost benefits issue. Stripping out TS2-specific features, rewrapping, publishing separately and maintaining it at least for some time. Personally, I do not have the cycles for such a parallel effort at this time.

TS2 Definitions Stability
Everything you get from @types is the latest and essentially in synch with this repo as of now. I will pull a contribution related to d3-scale-chromatic through here and migrate it concurrently to DefinitelyTyped -> @types. I am not aware of any bugs with any of the definitions at this point, bar the following:

  • The definition for the "bundle" itself could not be migrated yet to DT/types-2.0 as it needs a structural change to fully support parallel versions
  • The module level definitions do not expose a global d3 which is merged into by all loaded individual scripts as D3 itself does (TypeScript issue)
  • There is an enhancement request/PR to vet all the definitions for strictNullChecking and then enable it (will be done in DT as a follow-up)
  • Improve JSDoc comments. Will be done in DT as follow-up

I.e. I will wind this repo down and provide a header section update to the README when I am done.

d3_ng2_service
You are right, currently it is a simple wrapper reflecting the standard bundle with a couple of tweaks. It's quick and efficient for rapid prototyping. Yes, for production use, treeshaking is not ideally supported this way. I have opened up a Roadmap issue in the D3 Services repo, to discuss possibile future improvements. There are a number of paths to consider to get a bit more kick out of it, without completely over-complicating it. Given that ng2/D3 projects can vary widely, It may sometimes be easiest to start with a fairly complete service for prototyping and then as the scope settles, replace the imported service with a project specific version. The latter could use the exact same pattern, but shake the tree manually (at module or event feature level)

Given that I will not portrait omniscience of how people are going to use it, the d3_ng2_service may very well evolve with community input.

@kirillgroshkov
Copy link

Having the same issue...

@coder-mike
Copy link

coder-mike commented Nov 18, 2018

I also encountered this issue. For people coming across this thread for the same reason I did, the reason turned out to be that there were two separate package instances of d3-selection, of slightly different versions. One instance was being patched with transition and the other instance was actually being used.

The two different version resolutions were apparent in my yarn.lock file as follows:

d3-selection@1, d3-selection@^1.1.0:
  version "1.3.2"
  resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.2.tgz#6e70a9df60801c8af28ac24d10072d82cbfdf652"
  integrity sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ==

d3-selection@1.3.0:
  version "1.3.0"
  resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
  integrity sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==

The work-around for me was to manipulate the package lock file directly so that all d3-selection references resolve to the same version, and then run yarn --force to install them as such. The edited lock file looked as follows:

d3-selection@1, d3-selection@1.3.0, d3-selection@^1.1.0:
  version "1.3.0"
  resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
  integrity sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==

I think this may be a problem of D3 plugins specifying d3-selection in dependencies instead of in peerDependencies, giving npm/yarn permission to install multiple copies of the library to meet the varying version ranges.

@drxwat
Copy link

drxwat commented Jul 3, 2019

To solve this issue and avoid hard coding css classes (in angular) you can use next code:

transition.call(this.el)
  .select(() => this.el.node())
  .duration(700)

Note: this.el should correspond to element you want to animate. For example, you want to change d attribute of svg path element. Firstly, you should save the link to your path selection, then call transition on it. Here is the full code:

@ViewChild('plot', { read: ElementRef, static: false })
private plotEl: ElementRef;


this.plotRoot = select(this.plotEl.nativeElement);  // Or just select('MyCssSelector')
this.plotPath = this.plotRoot.append('path');

...

private drawPath(pathData: any) {
  transition.call(this.plotPath)
    .select(() => this.plotPath.node())
    .duration(700)
    .attr('d', pathData)
}

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

No branches or pull requests

5 participants