在require.js模块中使用D3.JS和sankey插件

时间:2016-02-24 10:38:38

标签: javascript d3.js requirejs splunk sankey-diagram

我正在尝试构建一个requirejs模块,为客户端代码提供使用d3.js呈现内容的选项。我想要使​​用的第一个插件是sankey diagram。 到目前为止我的模块:

define(['d3'], function(ignore) {

    console.log("bef", d3);
    require(['sankey.js']);
    console.log("aft", d3);
    d3.sankey();

    return {
        ...
        d3: d3,
        renderSankey: function(options) {
           ...
        }
    }

sankey.js脚本使用全局d3变量并添加函数sankey()。 (我尝试了btw,define(['d3'], function(ignore)define(['d3'], function(d3),结果完全相同)。 错误:TypeError: d3.sankey is not a function,无论我是尝试直接在代码中显示它,还是在this.d3.sankey()函数中使用renderSankey

控制台输出显示(require(...)调用之前和之后的两次:

sankey: d3.sankey()

Screenshot FF Console

无论我尝试什么,它都不会起作用。我觉得我错过了JS特定的关于阴影的东西,但为什么有一个sankey函数,当我console.log对象和一行之后,当我尝试调用时我得到一个错误?我做错了什么?

info:

  • 我在splunk html仪表板中使用它,这可能很重要......
  • 我不希望客户端代码导入依赖项(大约有100个插件来,这会很痛苦)
  • 当我只是将sankey.js的内容复制到我的模块中时,一切正常

/ edit:这是Require配置(由Splunk仪表板给出)

require.config({
    baseUrl: "{{SPLUNKWEB_URL_PREFIX}}/static/js",
    waitSeconds: 0 // Disable require.js load timeout
});

2 个答案:

答案 0 :(得分:0)

您用于加载rake db:migrate的{​​{1}}调用是异步的。它将启动require的加载,但在sankey返回时,sankey未加载。您应该将代码更改为:

require

我认为sankey也泄漏了全局空间中的符号define(['d3', 'sankey'], function (d3) { d3.sankey(); ,但AMD模块不应该依赖全局符号,除非它们是运行时环境的一部分(例如d3d3)。

您还需要设置RequireJS配置,使window依赖document,因为上面的sankey本身不 确保{{1}将在d3之前加载。所以你需要在配置中使用它:

define

这使d3依赖于sankey。 (请注意,shim只能用于影响加载不正确的AMD模块的文件。shim: { sankey: ['d3'] } 不会调用sankey来注册自己,因此不是正确的AMD模块,我们可以使用d3。)

此外,模块名称通常不应包含sankey,因此当您要加载插件时,请将其加载为define,而不是shim

答案 1 :(得分:0)

好吧,我认为@Louis和我只是误解了对方。这可能是由于我自己的愚蠢造成的,因为我不知道require.js的配置可以在任何地方完成(而不只是在根文件中完成一次)。然而,仍然得到Splunk特定部分我发布这个答案(而不是接受Louis'):

我在我的splunk环境中添加了一个新应用程序(一个应用程序)。我实际上首先配置了依赖项(在其他splunk应用程序可加载的d3-viz模块中):

require.config({
    paths: {
        'd3': '../app/D3_Viz/d3',         // d3.js
        'sankey': '../app/D3_Viz/sankey', // sankey.js 
        'XYZ': 'all the paths go here'
    },
    shim: {
        'sankey': ['d3'],
        'XYZ': ['d3'],
         // all the dependecies go here
    }
});

define(['splunkjs/ready!', 'jquery', 'd3'],
    function(mvc, $, ignore) {

    var d3Vis =  {
        ...
        renderSankey: function(options) {
            // load dependencies dynamically 
            require(['sankey'], function() {
                // actually render things
            });
        },
        renderXYZ: function(options) {
            require(['XYZ'], function() {
                ...
            });
        },
        ...


        }
    }
    return d3Vis;

我的所有依赖项都可以在viz-app中配置(而不是在使用app的客户端代码中,这是我对require.js的基本误解);唯一要做的就是将app / viz作为一个整体加载(在这个例子中是HTML仪表板:

require([
    "splunkjs/mvc",
    "splunkjs/mvc/utils",
    "splunkjs/mvc/tokenutils",
    "underscore",
    "jquery",
    "splunkjs/mvc/simplexml",
    "splunkjs/mvc/headerview",
    "splunkjs/mvc/footerview",
    ...
    "../app/D3_Viz/viz"
    ],
    function(
        mvc,
        utils,
        TokenUtils,
        _,
        $,
        DashboardController,
        HeaderView,
        FooterView,
        ...
        d3Viz
    ){
        ... splunk specific stuff
        // No dependencies have to be configured 
        // in the client code
        d3Viz.renderSankey({...});
    }
);