Requirejs, d3 and nvd3 integration

笑着哭i 提交于 2020-01-12 05:30:09

问题


I'm facing the problem of integrating requirejs with d3 and nvd3, and i found an easy solution using require's shim. Using the shim i can export a variable, and i can also define dependencies:

d3: { exports: 'd3' },
nvd3: {
  exports: 'nv',
  deps: ['d3']
},

In this way, i simply install d3 and other packages with bower, and include them with require, and it is really quick and clean.

Nonetheless, i faced the following problem: there are probably some clashes between the global d3 variable and the local one (the one injected in the requiring modules). It is a d3 / require / nvd3 integration problem related to transitions and selections. I don't fully understand the problem, but i can already make some considerations.

  • jquery has the same problem with require, and they provide the noconflict method to fix it
  • many libraries have this behavior, they export a global symbol, but as far as i know there is no ready fix from requirejs for the general problem
  • the problem is fixed if i rename all global references to d3 into d3 source to another name. I still have d3 in the injected module, but it is not conflicting anymore

As far as i can see, all d3 functionalities work this way, but one of the nvd3 charts has transitions broken probably because a selection or dispatcher is overwritten. It requires deep understanding of d3 internals to spot precisely the error, but probably a simple yet correct handling of the global symbol will clear the whole tally of similar problems.

Probably, due to the way requirejs handles shim dependencies, the global d3 symbol is exposed to nvd3. The same symbol, anyway, is not available to requiring modules, and will be overwritten somehow if injected (included in the module dependencies).

I tried also to wrap d3 in a module and properly return a local d3 variable, but looks like the problem still persists.

I also asked help about this on this d3 group discussion which hosts some previous posts about d3 and modules.


I added a test case here: https://github.com/danse/requirenvd3


回答1:


The problem doesn't appear to be your RequireJS configuration but rather the fact that you're using d3.v3 and not d3.v2. I downgraded d3 in your test case, and the transitions worked fine. (The popups are still all off to the side, which I don't think they should be, but that doesn't seem to be what you are presently concerned about.) It's my understanding that nvd3 has a few problems with d3.v3, this probably being one. Also, note the version of d3 in ddotsenko's jsFiddle. That could explain why his solution didn't work when you implemented it using your own d3.v3 library.




回答2:


First, you can bypass shim You don't need it to return anything for plain-JS. Just use globals.

Loading Angular from CDN via RequireJS is not injected

Second, while shim is semi-useful for declaring dependencies for scripts, you can do them explicitly as well:

require(['path/to/d3.min'], function(){
    // nesting to insure d3 loads before nvd3
    require(
        [
            'path/to/mylogic' // <- AMD module
            ,'path/to/nvd3.min' // <- actually a plain JS file
        ]
        , function(mylogic /*, we ignore what nvd3 returns */){
            window.nv // is available for you
        }
    )
})



回答3:


Look at what I do in this main.js file (using "depend" requirejs plugin) and then in other files that require something that should be exported to a global variable I do:


    define(['d3'], function (d3) {
        // Code here ...
    });

The depend plugin is really nice and allows you to setup hierarchical loading via depend!plugin[dependancy1, dependancy2] ("plugin" loads after "dependancy1" and "dependancy2" have loaded.



来源:https://stackoverflow.com/questions/15269535/requirejs-d3-and-nvd3-integration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!