Reputation: 5
I am using react with d3js, but for some reason the d3 container div is not rendering. I suspect that something is not done correctly when selecting the local div, but I can't figure out what.
The index.html & the index.js files are just plain boilerplate code and the only modification is in the App.jsx file posted below
import React from "react";
import * as d3 from "d3";
function App() {
const data = [
{ name: "A", score: 70 },
{ name: "B", score: 90 },
{ name: "C", score: 50 }
];
const width = 800;
const height = 800;
const margin = { top: 50, bottom: 50, left: 50, right: 50 };
const svg = d3
.select("#container")
.append("svg")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.attr("viewbox", [0, 0, width, height]);
const x = d3
.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width - margin.right])
.padding(0.1);
const y = d3
.scaleLinear()
.domain([0, 100])
.range([height - margin.bottom, margin.top]);
svg
.append("g")
.attr("fill", "royalblue")
.selectAll("rect")
.data(data.sort((a, b) => d3.descending(a.score, b.score)))
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", (d) => y(d.score))
.attr("width", x.bandwidth())
.attr("height", (d) => y(0) - y(d.score));
svg.node();
return (
<div>
<h1>Chart</h1>
<div id="container"></div>
</div>
);
}
export default App;
Upvotes: 0
Views: 1655
Reputation: 2775
Think about the state of the world as your code runs:
App
component is rendered on page load.d3.select('#container')
, but nothing happens. There's no div with that ID on the page because we haven't gotten that far yet.#container
element but our selection code does not re-run, because nothing triggers the component to re-render.You might consider using a callback ref - here's a minimal example:
const doD3Stuff = (element) => {
const width = 800;
const height = 800;
const margin = { top: 50, bottom: 50, left: 50, right: 50 };
const svg = d3
// the select method can accept an actual element instead of a selector
.select(element)
.append("svg");
// etc.
};
const App = () => {
return (
<div>
<h1>Chart</h1>
<div id="container" ref={doD3Stuff} />
</div>
);
};
This is a starting point, but of course it doesn't get into what happens when data changes and you want to things to redraw, animate, etc.
React and D3 can work well together. But even when using just one of them by itself, it's good to understand the execution model - when code runs, and when it doesn't. When using them together, it's way more important to have this level of understanding, or things will happen that you'll have difficulty troubleshooting.
Upvotes: 2