I am trying to use D3 in a React component within an Express app. It seems like it should be a rather easy task, but following various tutorials not targeted to an Express app did not work: in the example below, I get an empty svg (<!DOCTYPE html><div><p>D3 Example</p><svg></svg></div>
) without the red circle.
A possible explanation is that React.useEffect
does not run on server. However, I do not understand why this does not run after the Javascript is loaded. In any case, I cannot find how to work around this problem, so any help to understand it better or a solution will be appreciated :)
I list my relevant code below. I am rather new with Node, so I tried to stick to Express example conventions.
var simulationRouter = require('./routes/simulation');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());
...
app.use('/simulation', simulationRouter);
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('d3_show_nolib');
});
module.exports = router;
import React, { useEffect, useRef } from "react";
import { select } from "d3";
export default function App() {
const svgRef = useRef();
useEffect(() => {
const svg = select(svgRef.current);
const getData = () => {
svg
.append("circle")
.attr("r", 15)
.attr("fill", "red")
.attr("stroke", 1.5);
};
getData();
}, []);
return (
<div>
<p>D3 Exemple</p>
<svg ref={svgRef}></svg>
</div>
);
}
(I expect this to work as the following single html file:
<html>
<head>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<svg id='svg'></svg>
<script>
var svg = d3.select('#svg');
svg.attr('width', 100)
.attr('height', 100);
svg
.append("circle")
.attr("r", 15)
.attr("fill", "red")
.attr("stroke", 1.5)
.attr('cx', 10)
.attr('cy', 10);
</script>
</body>
</html>
)