DEV Community

Cover image for Tutorial: How to create a ReactJS / NextJS Chart component using Shadcn UI
Fredy Andrei
Fredy Andrei

Posted on • Updated on

Tutorial: How to create a ReactJS / NextJS Chart component using Shadcn UI

Shadcn UI is a utility-first CSS library, made especially for React with the purpose of helping developers quickly create beautiful and easy-to-use UIs. It offers a large selection of components that simplify the process of building the front end of any app, website, or dashboard. Additionally, it is one of the fastest-growing libraries and it is based on the trending Radix UI!

The following are a few advantages of using Shadcn UI:

  • Efficiency: The Shadcn library gives you the option to pick and choose the elements you are going to use in your app, having a CLI through which you can download only the components you need, therefore having a lighter and more organized app.

  • Speed: The components not only follow the pre-defined class system of Tailwind CSS that most developers are accustomed to but are also structured so that users can easily combine and modify them to fit their needs.

  • Consistency: Developers can make sure that the design is the same across all pages and components by using the theme styling offered by the library.

  • Customizability: Since the Shadcn UI components are unstyled and follow a simple theme, you can easily add your style or adapt the components to your existing app's theme.

Most apps now have data displayed by charts, even if we speak of an admin dashboard or a stock exchange main page. This being said, here is how to make a chart card using Shadcn UI. 👇🏽


Step 1: Setting up the Tailwind CSS config file

Let’s set up our project by creating the Tailwind CSS config file and adding base CSS. Here we will use some colors, shadows, and more from the Horizon UI template for Shadcn UI.

tailwind.config.ts

const config = {
  darkMode: ['class'],
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    // Or if using `src` directory:
    './src/**/*.{js,ts,jsx,tsx,mdx}'
  ],
  prefix: '',
  theme: {
    extend: {
      fontFamily: {
        jakarta: ['Inter', 'sans-serif'],
        poppins: ['Poppins', 'sans-serif']
      },
      height: {
        '300px': '300px',
        '500px': '500px',
        sidebar: 'calc(100vh - 32px)'
      },
      colors: {
        border: 'hsl(var(--border))',
        input: 'hsl(var(--input))',
        ring: 'hsl(var(--ring))',
        background: 'hsl(var(--background))',
        foreground: 'hsl(var(--foreground))',
        primary: {
          DEFAULT: 'hsl(var(--primary))',
          foreground: 'hsl(var(--primary-foreground))'
        },
        secondary: {
          DEFAULT: 'hsl(var(--secondary))',
          foreground: 'hsl(var(--secondary-foreground))'
        },
        destructive: {
          DEFAULT: 'hsl(var(--destructive))',
          foreground: 'hsl(var(--destructive-foreground))'
        },
        muted: {
          DEFAULT: 'hsl(var(--muted))',
          foreground: 'hsl(var(--muted-foreground))'
        },
        accent: {
          DEFAULT: 'hsl(var(--accent))',
          foreground: 'hsl(var(--accent-foreground))'
        },
        popover: {
          DEFAULT: 'hsl(var(--popover))',
          foreground: 'hsl(var(--popover-foreground))'
        },
        card: {
          DEFAULT: 'hsl(var(--card))',
          foreground: 'hsl(var(--card-foreground))',
          border: 'hsl(var(--border))'
        }
      },
      borderRadius: {
        lg: 'var(--radius)',
        md: 'calc(var(--radius) - 2px)',
        sm: 'calc(var(--radius) - 4px)'
      },
      keyframes: {
        'accordion-down': {
          from: { height: '0' },
          to: { height: 'var(--radix-accordion-content-height)' }
        },
        'accordion-up': {
          from: { height: 'var(--radix-accordion-content-height)' },
          to: { height: '0' }
        }
      },
      animation: {
        'accordion-down': 'accordion-down 0.2s ease-out',
        'accordion-up': 'accordion-up 0.2s ease-out'
      }
    }
  }
};

export default config;
Enter fullscreen mode Exit fullscreen mode

styles/global.css


@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --radius: 8px;
  --chart: #0F172A; 
    --background: 0 0% 100%;
  --foreground: white; 
  --muted: 210 40% 96.1%;
  --muted-foreground: 215.4 16.3% 46.9%;
  --card: white;
  --card-foreground: white;
  --popover: white;
  --popover-foreground: white;
  --border: 214.3 31.8% 91.4%;
  --input: 214.3 31.8% 91.4%;
  --primary: 240 10% 4% ;
  --primary-foreground: 210 40% 98%;
  --secondary: 210 40% 96.1%;
  --secondary-foreground: white;
  --accent: 210 40% 96.1%;
  --accent-foreground: white;
  --destructive: 0 100% 50%;
  --destructive-foreground: 210 40% 98%;
  --ring: 0 0% 0%; 
  --chart-1: #52525b;
  --chart-2: #D4D4D8;
  --chart-3: #030712;
  --chart-4: #71717a;
  --chart-5: #a1a1aa;
}

.dark { 
  --background: 240 10% 4%;
  --foreground: white;
  --chart: white;
  --muted: 210 40% 96.1%;
  --muted-foreground: 215.4 16.3% 46.9%;
  --card: 240 10% 4%; 
  --card-foreground: 0 0% 100%;
  --popover: 240 10% 4%;
  --popover-foreground: 0 0% 100%;
  --border: 240 4% 16%;
  --input: 240 4% 16%;
  --primary: 0  0%  100%;
  --primary-foreground: 240 10% 4%;
  --secondary: 210 40% 96.1%;
  --secondary-foreground: 222.2 47.4% 11.2%;
  --accent: 240 4% 16%;
  --accent-foreground: 222.2 47.4% 11.2%;
  --destructive: 0 100% 50%;
  --destructive-foreground: 210 40% 98%;
  --ring: 0 0% 0%;
  --chart-1: white;
  --chart-2: #71717A;
  --chart-3: #030712;
  --chart-4: #71717a;
  --chart-5: #a1a1aa;
}

body {
  font-family: 'Inter', sans-serif;
}

html {
  scroll-behavior: smooth;
  font-family: 'Inter', sans-serif;
  color-scheme: unset !important;
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Import Shadcn chart components via CLI

Simply use the following command in your terminal to add the Shadcn Chart component :

npx shadcn@latest add chart
Enter fullscreen mode Exit fullscreen mode

Step 3: Import the components provided by Shadcn and add them to your component

In this example, we are going to create a bar chart, which has a custom tooltip when the user hovers the cart, as well as a cartesian grid background. Below the chart, we will later add an axis to better display the timespan of the data.

To adapt the chart to:

  • First, import the following components:
import {
  ChartConfig, // this is the type for typescript users!
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent
} from '@/components/ui/chart';


import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts';
Enter fullscreen mode Exit fullscreen mode
  • For the chart to be adapted to the theme, we have to write some simple, but effective config:
const chartConfig = {
  desktop: {
    label: 'Desktop',
    color: 'var(--chart-1)'
  },
  mobile: {
    label: 'Mobile',
    color: 'var(--chart-2)'
  }
} satisfies ChartConfig; // this is the type for typescript users!
Enter fullscreen mode Exit fullscreen mode
  • This is the structure of the default chart, without any addons. It follows the data in the example:
const chartData = [
  { month: 'January', desktop: 186, mobile: 80 },
  { month: 'February', desktop: 305, mobile: 200 },
  { month: 'March', desktop: 237, mobile: 120 },
  { month: 'April', desktop: 73, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'June', desktop: 214, mobile: 140 }
];

export default function BarChartComponent() {
  return (
    <ChartContainer
      className="aspect-auto h-[300px] xl:h-[200px] 2xl:h-[250px] w-full"
      config={chartConfig}
    >
      <BarChart accessibilityLayer data={chartData}>
        <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
        <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
      </BarChart>
    </ChartContainer>
  );
}
Enter fullscreen mode Exit fullscreen mode

Up until now, it should look something like this:

shadcn ui chart component - horizon ui

  • To add the addons, just add the following components (XAxis, CartesianGrid, and ChartTooltip):
const chartData = [
  { month: 'January', desktop: 186, mobile: 80 },
  { month: 'February', desktop: 305, mobile: 200 },
  { month: 'March', desktop: 237, mobile: 120 },
  { month: 'April', desktop: 73, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'June', desktop: 214, mobile: 140 }
];

export default function BarChartComponent() {
  return (
    <ChartContainer
      className="aspect-auto h-[300px] xl:h-[200px] 2xl:h-[250px] w-full"
      config={chartConfig}
    >
      <BarChart accessibilityLayer data={chartData}>
          <CartesianGrid vertical={false} />
          <XAxis
            dataKey="month"
            tickLine={false}
            tickMargin={10}
            axisLine={false}
            tickFormatter={(value) => value.slice(0, 3)}
          />
          <ChartTooltip
            cursor={false}
            content={<ChartTooltipContent indicator="dashed" />}
          />
        <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
        <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
      </BarChart>
    </ChartContainer>
  );
}
Enter fullscreen mode Exit fullscreen mode

Step 4: You’re done! 🎉

Now the component is ready to use in your project. You can add the custom data, or change the styles in the global.css file to your liking. This is the final result :

shadcn ui chart component - horizon ui


In conclusion, Shadcn UI can be used for a variety of tasks when it comes to UI, including ones like charts, cards, and more, which can be uniformly modified by changing the main theme.

More cards like the one we made, components like navbars, dropdowns, and so on, are available in Horizon AI Boilerplate!

Top comments (4)

Collapse
 
andrewbaisden profile image
Andrew Baisden • Edited

Cool tutorial. This is just a heads up that you can add highlighting to the code blocks if you'd like. Just change:

code block with no colors example

... to specify the language:

code block with colors example

More details in the editor guide!

Collapse
 
fredy profile image
Fredy Andrei

Thanks a lot, Andrew! Everything should be fine now.

Collapse
 
rarestoma profile image
Toma Rares

looks good!

Collapse
 
vldmihalache profile image
Vlad Mihalache - vbz™

Shadcn has some pretty good charts!