Skip to content
This repository has been archived by the owner on Nov 17, 2019. It is now read-only.

How to make d3-selection and d3-selection-multi work together? #6

Closed
LeartS opened this issue Jun 19, 2016 · 4 comments
Closed

How to make d3-selection and d3-selection-multi work together? #6

LeartS opened this issue Jun 19, 2016 · 4 comments

Comments

@LeartS
Copy link

LeartS commented Jun 19, 2016

I've installed both d3-selection and d3-selection-multi with npm, and using rollout with the rollout-plugin-node-resolve.

This is my code.

import select from 'd3-selection';
import 'd3-selection-multi';
import { default as range } from 'lodash-es/range';

var chart = select('svg');

var days = chart.selectAll('rect.day')
        .data(range(365));

days.enter()
    .append('rect')
    .merge(days)
    .attrs({
        'x': d =>d * 12,
        'y': 10,
        'width': 10,
        'height': 10,
        'class': 'day',
    });

I get, in the browser:

TypeError: days.enter(...).append(...).merge(...).style(...).attr(...).attr(...).attr(...).attr(...).attrs is not a function

I tried explicitly importing selection:

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

Still same error. Howewer, If I change select('svg') with selection().select('svg') it works, but I don't think that's how we are supposed to do it.
What's the correct way to import both selection and multi-selection and have the latter apply to the imported methods of the first?

@mbostock
Copy link
Member

mbostock commented Jun 19, 2016

There’s no default export from d3-selection, so you have to use this pattern:

import {selection, select} from "d3-selection";
import "d3-selection-multi";

Here’s a live example (using d3-transition instead of d3-selection-multi, but it’s the same principle):

https://bl.ocks.org/mbostock/97557a39b4bfc8229786c8bccb54074d

A major gotcha is that if you have a different version of d3-selection installed than the one d3-selection-multi depends on, then Rollup will bundle those versions separately, and as a result d3-selection-multi will modify its internal copy of d3-selection that is not exposed. This is pretty unfortunate, but I’m not sure how to prevent that.

I recommend using the latest versions of d3-selection-multi (0.3.0) and d3-selection (0.9.0) for now. (It should get easier next week after I cut a 1.0 release of d3-selection.) You may also need to rm -rf node_modules && npm install because of npm’s nondeterministic behavior with incremental installs.

If that doesn’t fix it, let me know and I’ll reopen to investigate.

@LeartS
Copy link
Author

LeartS commented Jun 19, 2016

Thanks for the explanation.

I've deleted node_modules and reinstalled them with npm install, here is the dependencies part of my package.json: (in case something may conflict)

  "scripts": {},
  "devDependencies": {
    "babel-cli": "^6.10.1",
    "babel-preset-es2015": "^6.9.0",
    "rollup-plugin-node-resolve": "^1.7.0",
    "rollup-plugin-uglify": "^1.0.0",
    "rollup-watch": "^2.4.0"
  },
  "dependencies": {
    "d3-selection": "^0.9.0",
    "d3-selection-multi": "^0.3.0",
    "lodash-es": "^4.13.1"
  }

I checked the installed versions:

> npm ls | grep d3                                                                                                                                               31s  18:46:49
├── [email protected]
├── [email protected]

And, using the two import statements you said, I still get the same error.

I'm also using babel (with the es2015-rollup preset), could that be a problem? This is my rollup.config.js:

import babel from 'rollup-plugin-babel';
import nodeResolve from 'rollup-plugin-node-resolve';
import uglify from 'rollup-plugin-uglify'
import { minify } from 'uglify-js'

export default {
    entry: 'vita.js',
    format: 'iife',
    plugins: [
        babel({
            babelrc: false,
            presets: ["es2015-rollup"],
        }),
        nodeResolve({
            jsnext: true,
            preferBuiltins: false,
        }),
        // uglify({}, minify) // commented for testing
    ],
    dest: 'bundle.js'
};

Apart from babel (which anyway I've tried to remove and still got the same error), another difference is that instead of creating a "custom d3 bundle" as you do in the linked block, i directly bundle up my script/app which has the import statements of d3-selection and d3-selection-multi.

@mbostock
Copy link
Member

Yeah, this looks like a bug in Rollup where the import with side-effects is ignored unless your bundle exports the thing that was modified by the side-effects. Here’s an example with a workaround:

http://bl.ocks.org/mbostock/648fa00c52c6ad141ab73ac020af5e84

I’ll file an issue with Rollup and cc you.

@LeartS
Copy link
Author

LeartS commented Jun 19, 2016

Great, thanks!
Browser support for ES6 modules can't come soon enough!

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

No branches or pull requests

2 participants