Using Webpack with d3, jQuery, and Bootstrap

Hey guys,

Total Webpack (and es6/modern frontend practices) newbie here, so sorry if this is a dumb question.

I’m trying to build a d3 dataviz project using modern web dev standards and am having a lot of trouble getting it up and running — specifically, I’m getting a weird Uncaught (in promise) TypeError when I launch the local webpack dev server, and none of my d3 elements are displaying. I’m sure it’s something very dumb that I’m overlooking but I’ve been scouring the internet for what feels like forever and unfortunately haven’t made any progress. Any guidance would be so, so appreciated.

Full disclosure: this is for a college course, but my teacher knows nothing about modern webdev standards, so I am fully on my own in choosing to develop it this way. I just wanted to give myself a trial by fire in the world of modern JS and now I’m regretting it, lol…

The work-in-progress project is up on GitHub if you need to see any of the other moving parts, and please don’t hesitate to let me know if you have questions! Thanks so much.

package.json

"scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "webpack --progress -p",
    "watch": "webpack --progress --watch",
    "start": "webpack-dev-server --open"
},

"dependencies": {
    "bootstrap": "^4.0.0",
    "d3": "^5.0.0",
    "d3pie": "^0.2.1",
    "jquery": "^3.3.1",
    "popper.js": "^1.14.1"
},

"devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.6.1",
    "css-loader": "^0.28.11",
    "style-loader": "^0.20.3",
    "webpack": "^4.2.0",
    "webpack-cli": "^2.0.13",
    "webpack-dev-server": "^3.1.1"
}

webpack.config.js

var webpack = require('webpack');

module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.js'
  },
  plugins: [
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                "window.jQuery": "jquery",
                d3: 'd3'
            })
        ],
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env']
          }
        }
      }
    ]
  },
  module: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
};

index.js (imports only)

import 'bootstrap/dist/js/bootstrap.min.js';
import 'bootstrap/dist/css/bootstrap.min.css';
import $ from 'jquery';
import * as d3 from "d3";
import 'd3pie';

.babelrc

{
"presets": [ "env" ]
}

Answer

The problem is that the d3.csv function in version 5 of d3 (which you’re using in the project) uses promises rather than callbacks in order to get the final data. This is how the function should be called:

d3.csv("thanksgiving-2015-poll-data.csv").then((data) => {
  var thanksCSV = data;
  // ...

When you were calling it as

d3.csv("thanksgiving-2015-poll-data.csv", (data) => {

that was only a mapping function over each row – the argument is meant to be a row, not the whole array of rows.

But you have another problem – your import 'd3pie'; does not give you a d3pie constructor to work with. Your import statement should look like this instead:

import d3pie from 'd3pie';

But then there’s yet another problem – d3pie requires window.d3 to be defined, which you haven’t done. So, below your imports, add:

window.d3 = d3;

Then, the pie graph will load properly.

Leave a Reply

Your email address will not be published. Required fields are marked *