d3 / d3-transition

Animated transitions for D3 selections.
https://d3js.org/d3-transition
ISC License
224 stars 65 forks source link

can't replicate v3 pattern ... have tried many things #57

Closed jonathanstrong closed 8 years ago

jonathanstrong commented 8 years ago

I'm having a lot of trouble replicating a pattern I used many times in v3, and after extensive searching have not identified any documentation for how to do this.

the v3 version:

let svg = d3.select('div#chart svg > g.margin');
let rects = svg.selectAll('rect.bar')
    .data(data);

// update
rects
    .transition() // <-- this is what I can't replicate in v4
    .duration(2000)
    .attr('x', compose(this.x, this.x.accessor))
    .attr('y', compose(this.y, this.y.accessor))
    .attr('width', this.x.bandwidth())
    .attr('height', compose((d) => h - d, this.y, this.y.accessor));

// enter
rects.enter().append('rect')
    .attr('class', 'bar')
    .attr('x', compose(this.x, this.x.accessor))
    .attr('y', compose(this.y, this.y.accessor))
    .attr('width', this.x.bandwidth())
    .attr('height', compose((d) => h - d, this.y, this.y.accessor));

fyi I'm using es6 imports of specific functions from the various modules in my v4 attempts:

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

etc

this is the problem replicated in the console; names reflecting the transpiling process:

var rects = d3_selection_1.select(this.elementName).selectAll('rect.bar').data(d3.range(10))
>> undefined
rects.transition()
>> Uncaught TypeError: rects.transition is not a function(…)

Then I learned about the new merge pattern, but that didn't offer any solace either.

var rects = d3_selection_1.select(this.elementName).selectAll('rect.bar').data(d3.range(10))
>> undefined
rects.enter().append('rect').attr('x', function(d){ return d; }).merge(rects).transition()
TypeError: rects.enter(...).append(...).attr(...).merge(...).transition is not a function(…)

So, how in the world do you call transition on an enter/update/exit selection? this has left me baffled. Thanks!

mbostock commented 8 years ago

If selection.transition is undefined, there’s a problem with your bundle / module loading / transpiling. You didn’t describe your transpiling process so unfortunately I can’t diagnose the issue. It looks like the bundler you are using is not correctly applying the side-effects of the d3-transition module, which adds selection.transition to the selection.prototype exported by d3-selection. Perhaps your bundler isn’t observing the module (formerly jsnext:main) entry point defined in the package.json?

I recommend using the default d3 bundle (d3.v4.js) during development. I’d also consider using Rollup, which does handle this sort of import correctly, as shown in the D3 Custom Bundle II example. Possibly related:

jonathanstrong commented 8 years ago

well - glad to know I wasn't just doing it wrong. importing the top-line d3 package solved the problem.

fyi the transpiling pipeline I'm using is my code is in typescript and the compiled js is bundled with the libraries with browserify. not sure what is going wrong along the way, it's hideously complicated.

while I was trying to figure this out I didn't anticipate that the imports had side effects on each other. Seems like that would be worth trying to minimize since it's error-prone and hard to debug.

mbostock commented 8 years ago

Side-effects are a feature of the ECMAScript standard import statement. Rather than avoid standard features, if you want to maximize long-term user happiness, I’d file a bug with the appropriate tool to ask them to support the standard. Thank you!