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:
- Added
"d3": ">=5.9.1"to myassets/package.json - Added
import "d3"to myassets/js/app.js - 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
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
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
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.









