5

I'm trying to load d3-path using RequireJS. Looking at the minified d3-path source code, it looks like it's AMD-compliant since I see this in the first line:

!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s(t.d3=t.d3||{})}

My index.html looks like

<script>
    require.config({
        paths: {
            "d3": "https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min",
            "d3-path": "https://d3js.org/d3-path.v1.min",
            "underscore": "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min",
            "jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"
        }
    });
</script>

And my JS file that I'm trying to load d3.path() looks like

require([
    "d3",
    "d3-path",
    "underscore"
],
function(
    d3,
    d3_path,
    _
) {
    // d3, d3_path, and _ are defined
    // but d3.path() isn't defined 
});

I can use d3-path by doing d3_path.path() but I would ideally like to do d3.path(). However if I set both d3 and d3-path to d3 then d3-path overrides d3 and I lose the main d3 functions.

I'm also open to RequireJS best practices since I'm not sure if I'm using the best method. Thanks!

2 Answers 2

6

Preliminary note : you're trying to load d3 V3 with a V4 module, that's not going to mesh very well.

Onto your question : that's the way it is intended to work when you use the micro modules. You load isolated functionalities and combine them.

You only get a d3 global when you use the vanilla environments as said in the docs: try

require.config({
    paths: {
        "d3": "https://d3js.org/d3.v4.min"
    }
});

require(['d3'], function(myd3) {
    console.log(window.d3); // undefined
    console.log(myd3); // d3 object
});

Note that if you load the whole d3 v4 library, you will get d3.path :

require(['d3'], function(myd3) {
    console.log(myd3.path); // function
});

Finally, if you intend to use multiple micro modules, you could use a mapped configuration:

require.config({
    paths: {
        d3src: 'https://d3js.org'
    },
    map: {
        '*': {
            'd3':  'd3src/d3.v4.min',
            'd3-selection':  'd3src/d3-selection.v1.min',
            'd3-path': 'd3src/d3-path.v1.min',
        }
    }
});


// if you want to load the selection and the path modules
require(['d3-selection', 'd3-path'], function(selection, path) {
    // ...
});

// if you want to load d3
require(['d3'], function(d3) {
    // ...
});
Sign up to request clarification or add additional context in comments.

2 Comments

can i load only d3/path for example?, without load 'd3'?
@drmartin You can, but you will only have access to the functionalities given by d3.path, you won't have the rest of d3. Try the last exemple without loading d3 and see where that goes.
0

In addition to nikoshr's answer on using d3 micro libraries: You should name the d3 modules in hyphens style, e.g. d3-selection, because some d3 libraries depend on other ones and require them in this syntax.

Moreover you can create your own d3 object in your modules, so you don't have to change your code and can use d3.path().

require(['d3-selection', 'd3-path'], function(d3Selection, d3Path) {
    let d3 = Object.assign({}, d3Selection, d3Path);

    d3.path();
});

2 Comments

The OP is already "nam[ing] the d3 modules in hyphens style". What specific problem that the OP presented are you addressing?
@Louis The first point relates to nikoshr's answer, he is using slashes instead. Unfortunately I cannot comment on his answer. The questioner wanted to use d3.path() instead of d3_path.path(), which is solved by Object.assign().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.