React

by Bryson Murray

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://d3js.org/d3.v7.min.js"></script>
<div id="root"></div>

React

// Ensure React and ReactDOM are available globally in the JSFiddle settings

const { useRef, useEffect, useState } = React;
const { render } = ReactDOM;

// Import D3.js from CDN
const d3 = window.d3;

const PieChart = ({ data, color1, color2 }) => {
    const ref = useRef();
    const [currentData, setCurrentData] = useState(data);
    const [parentData, setParentData] = useState(null);

    useEffect(() => {
        // Define the SVG area
        const svg = d3.select(ref.current);
        const width = 500;
        const height = 300;
        const radius = Math.min(width, height) / 2 - 50;
        const innerRadius = radius / 2;

        // Remove old chart content before redrawing
        svg.selectAll("*").remove();

        // Append a group to center the pie chart
        const g = svg.append("g")
            .attr("transform", `translate(${width / 2}, ${height / 2})`);

        // Create a color scale with gradient
        const color = d3.scaleLinear()
            .domain([0, currentData.length - 1])
            .range([color1, color2]);

        // Create the pie and arc generator
        const pie = d3.pie().value(d => d.value);
        const arc = d3.arc().innerRadius(innerRadius).outerRadius(radius);

        // Bind the data to the pie chart and append paths
        const arcs = g.selectAll("arc")
            .data(pie(currentData))
            .enter().append("g")
            .attr("class", "arc")
            .on("click", d => {
                if (d.data.locations) {
                    setParentData(currentData);
                    setCurrentData(d.data.locations.map(loc => ({
                        name: loc.name,
                        value: loc.employees
                    })));
                }
            });

        arcs.append("path")
            .attr("d", arc)
            .attr("fill", (d, i) => color(i));

        // Add labels to the pie slices
        arcs.append("text")
            .attr("transform", d =>...