reactjsnext.jsd3.js

D3.js + Next.js (React) cannot parse csv


I'm trying to import a csv using d3.csvParse, but for some reason it's not loading my csv file. I'm using the latest version of Next.js (v14.2.5)

Here's my project structure:

project/
  - public/
  - src/
    - app/
      - page.tsx
    - data/
      - us-counties.csv
// page.tsx
export default function Home() {
  const data = d3.csvParse('/data/us-counties.csv');
  console.log(data) // always console log's an empty array no matter the path

  return (
    // ...
  )
}

I've tried changing the path for the csvParse command to src/data/us-counties.csv, but it didn't work. I also tried moving the dataset into the public folder, but that didn't work either.

I've seen some people online say that to use a csv in React with D3.js you have to import csv, but when I try that I get an error.

import dataset from '../data/us-counties.csv'; // Cannot find module '../data/us-counties.csv' or its corresponding type declarations. ts(2307)

If I try to ignore the error and still pass it into csvParse, I get another error:

export default function Home() {
  const data = d3.csvParse(dataset);
  // ...
}

Module parse failed: Invalid number (2:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

Any ideas on how to fix this?


Solution

  • d3.csvParse is used to parse CSV strings into JavaScript objects. It doesn't handle loading files from disk. Instead, you should fetch the CSV file content first, then parse it.

    You'll need to use fetch to get the CSV data from the public folder (or wherever it’s hosted) and then parse it.

    import { useEffect, useState } from 'react';
    import * as d3 from 'd3';
    
    export default function Home() {
      const [data, setData] = useState<any[]>([]);
    
      useEffect(() => {
        fetch('/data/us-counties.csv')
          .then((response) => response.text())
          .then((text) => {
            const parsedData = d3.csvParse(text);
            setData(parsedData);
          })
          .catch((error) => console.error('Error fetching or parsing data:', error));
      }, []);
    
      console.log(data);
    
      return (
        //Your other code to here :)
      );
    }
    

    Other Issue; Could be that always faced with: you might need to declare the CSV module so TypeScript knows how to handle it. Create a declarations.d.ts file in your project root (or inside the src folder) and add:

    declare module '*.csv' {   const content: any;   export default content; }