grantwest

grantwest

D3.js and Phoenix

I am really struggling with getting D3.js working in my Phoenix app. I have a default Phoenix umbrella app with webpack.

Steps that I have done so far:

  1. Added "d3": ">=5.9.1" to my assets/package.json
  2. Added import "d3" to my assets/js/app.js
  3. Confirmed that the app.js that is loaded in the browser does indeed contain the d3 library.

But no matter what I seem to do every time I try to use d3 I get:

ReferenceError: d3 is not defined

I’m not a web developer. Phoenix generally has been easy enough to figure out because I am pretty good with Elixir, but I am having a really hard time getting this javascript stuff to work. Are my above steps correct? What else am I supposed to be doing?

Most Liked

peerreynders

peerreynders

Using tutorial: Simple Bar Chart Video Tutorial

$ mix phx.new d3jsDemo --no-ecto

    * creating d3jsDemo/config/config.exs
    ...
    * creating d3jsDemo/assets/static/favicon.ico

    Fetch and install dependencies? [Yn] Y
    * running mix deps.get
    * running cd assets && npm install && node node_modules/webpack/bin/webpack.js --mode development
    * running mix deps.compile

    We are almost there! The following steps are missing:

        $ cd d3jsDemo

    Start your Phoenix app with:

        $ mix phx.server

$ cd d3jsDemo
d3jsDemo $ mix phx.server

    Compiling 12 files (.ex)
    Generated d3jsDemo app
    [info] Running D3jsDemoWeb.Endpoint with cowboy 2.6.1 at 0.0.0.0:4000 (http)
    [info] Access D3jsDemoWeb.Endpoint at http://localhost:4000

    Webpack is watching the files…

    Hash: b9775afde64001345ea9
    Version: webpack 4.4.0
    Time: 382ms
                    Asset       Size       Chunks             Chunk Names
           ../css/app.css   10.6 KiB  ./js/app.js  [emitted]  ./js/app.js
                   app.js   7.23 KiB  ./js/app.js  [emitted]  ./js/app.js
           ../favicon.ico   1.23 KiB               [emitted]  
            ../robots.txt  202 bytes               [emitted]  
    ../images/phoenix.png   13.6 KiB               [emitted]  
       [0] multi ./js/app.js 28 bytes {./js/app.js} [built]
    [../deps/phoenix_html/priv/static/phoenix_html.js] 2.17 KiB {./js/app.js} [built]
    [./css/app.css] 39 bytes {./js/app.js} [built]
    [./js/app.js] 493 bytes {./js/app.js} [built]
        + 2 hidden modules
    Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!css/app.css:
        [./node_modules/css-loader/dist/cjs.js!./css/app.css] 284 bytes {mini-css-extract-plugin} [built]
        [./node_modules/css-loader/dist/cjs.js!./css/phoenix.css] 10.9 KiB {mini-css-extract-plugin} [built]
            + 1 hidden module

Check in the browser http://localhost:4000/ to see the “Phoenix Framework” page.

^C

    BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
           (v)ersion (k)ill (D)b-tables (d)istribution
a
d3jsDemo $ cd assets
assets $ npm i d3 -D
    npm WARN assets No description

    + d3@5.9.2
    added 33 packages from 1 contributor and audited 14506 packages in 7.422s
    found 2 low severity vulnerabilities
      run `npm audit fix` to fix them, or `npm audit` for details
assets $

Edit d3jsDemo/assets/js/app.js

import css from '../css/app.css'
import 'phoenix_html'
import { select } from 'd3-selection'

const chartData = [30, 86, 168, 281, 303, 365]

select('.chart')
  .selectAll('div')
  .data(chartData)
  .enter()
  .append('div')
  .style('width', d => d.toString() + 'px' )
  .text(d => d)

Edit d3jsDemo/assets/styles/app.css

@import "./phoenix.css";

.chart div {
  font: 10px sans-serif;
  background-color: steelblue;
  text-align: right;
  padding: 3px;
  margin: 1px;
  color: white;
}

Edit d3jsDemo/lib/d3jsDemo_web/templates/page/index.html.eex at the end

  </article>
</section>
<section class="chart"></section>
assets $ cd ..
d3jsDemo $ mix phx.server
    [info] Running D3jsDemoWeb.Endpoint with cowboy 2.6.1 at 0.0.0.0:4000 (http)
    [info] Access D3jsDemoWeb.Endpoint at http://localhost:4000

    Webpack is watching the files…

    Hash: 9560b5464b76ab875009
    Version: webpack 4.4.0
    Time: 547ms
                    Asset       Size       Chunks             Chunk Names
           ../css/app.css   10.8 KiB  ./js/app.js  [emitted]  ./js/app.js
                   app.js   80.7 KiB  ./js/app.js  [emitted]  ./js/app.js
           ../favicon.ico   1.23 KiB               [emitted]  
            ../robots.txt  202 bytes               [emitted]  
    ../images/phoenix.png   13.6 KiB               [emitted]  
       [0] multi ./js/app.js 28 bytes {./js/app.js} [built]
    [../deps/phoenix_html/priv/static/phoenix_html.js] 2.17 KiB {./js/app.js} [built]
    [./css/app.css] 39 bytes {./js/app.js} [built]
    [./js/app.js] 314 bytes {./js/app.js} [built]
        + 53 hidden modules
    Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!css/app.css:
        [./node_modules/css-loader/dist/cjs.js!./css/app.css] 433 bytes {mini-css-extract-plugin} [built]
        [./node_modules/css-loader/dist/cjs.js!./css/phoenix.css] 10.9 KiB {mini-css-extract-plugin} [built]
            + 1 hidden module
    [info] Replied phoenix:live_reload :ok

Checking the browser at http://localhost:4000/ you should see:

kokolegorille

kokolegorille

Hello, welcome to the forum,

Between 1 and 2 You should

npm install (or yarn install)

I am not sure for your syntax in 2, I think it should be something like

import d3 from 'd3';
adrianrl

adrianrl

Hi, welcome to the forum!

import * as d3 from 'd3';

should work as mentioned above, you can also add it to the Webpack dependencies by creating a new entry point:

entry: {
  app: ['./js/app.js', './css/app.css'],
  vendor: ['d3'],
},

or using a more complex configuration, so Webpack takes care of splitting your vendor dependencies:

optimization: {
  splitChunks: {
    cacheGroups: {
      commons: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendor',
        chunks: 'all',
      },
    },
  },
},

I didn’t test it with D3, but should work. Have in mind that D3 is a heavy dependency, so splitting your JavaScript files in smaller chunks should help to build a better experience for your users.

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

Other popular topics Top

joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42716 114
New

We're in Beta

About us Mission Statement