Skip to main content
/
/
/
/
Line chart

Line chart

Basic line chart

Below is a basic line chart example. In order to get the gradient below the line, we're using the <AreaChart> component and a SVG linearGradient element with a unique id.

Code

CustomTooltip component
import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, } from "recharts"; import CustomTooltip from "../CustomToolTip"; const lineColor = "var(--bfc-attn)"; const locale = "en-us"; /** Convert a Date object to month & year string, e.g. "Jan 2023" */ const monthYearFormatter = new Intl.DateTimeFormat(locale, { month: "short", year: "numeric", }); /** Adds a thousand separator to large numbers, e.g. "1,337" */ const numberFormatter = new Intl.NumberFormat(locale); const data = [ { date: "2023-01", value: 242725 }, { date: "2023-02", value: 237632 }, { date: "2023-03", value: 216610 }, { date: "2023-04", value: 225223 }, { date: "2023-05", value: 210043 }, { date: "2023-06", value: 237577 }, { date: "2023-07", value: 266538 }, { date: "2023-08", value: 278820 }, { date: "2023-09", value: 252026 }, { date: "2023-10", value: 258326 }, { date: "2023-11", value: 260691 }, { date: "2023-12", value: 262566 }, { date: "2024-01", value: 276147 }, { date: "2024-02", value: 240784 }, { date: "2024-03", value: 274169 }, { date: "2024-04", value: 224765 }, { date: "2024-05", value: 211219 }, { date: "2024-06", value: 267703 }, { date: "2024-07", value: 274453 }, { date: "2024-08", value: 246658 }, ].map((x) => ({ ...x, formattedDate: monthYearFormatter.format(new Date(x.date)), })); export default function BasicLineChart() { return ( <ResponsiveContainer> <AreaChart data={data} margin={{ // adjust margins to fit your data left: 10, }} > <defs> <linearGradient id="basic-line-chart-gradient" x2="0" y2="1"> <stop offset="0%" stopColor={lineColor} stopOpacity={0.8} /> <stop offset="100%" stopColor={lineColor} stopOpacity={0} /> </linearGradient> </defs> <CartesianGrid strokeDasharray="5 5" vertical={false} stroke="var(--bfc-base-dimmed)" /> <XAxis dataKey="formattedDate" hide /> <YAxis axisLine={false} tickLine={false} type="number" tickFormatter={(value) => numberFormatter.format(value)} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dx={-8} /> <Tooltip content={<CustomTooltip />} /> <Area type="monotone" dataKey="value" stroke={lineColor} strokeWidth={2} fill="url(#basic-line-chart-gradient)" /> </AreaChart> </ResponsiveContainer> ); }
import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, } from "recharts"; import CustomTooltip from "../CustomToolTip"; const lineColor = "var(--bfc-attn)"; const locale = "en-us"; /** Convert a Date object to month & year string, e.g. "Jan 2023" */ const monthYearFormatter = new Intl.DateTimeFormat(locale, { month: "short", year: "numeric", }); /** Adds a thousand separator to large numbers, e.g. "1,337" */ const numberFormatter = new Intl.NumberFormat(locale); const data = [ { date: "2023-01", value: 242725 }, { date: "2023-02", value: 237632 }, { date: "2023-03", value: 216610 }, { date: "2023-04", value: 225223 }, { date: "2023-05", value: 210043 }, { date: "2023-06", value: 237577 }, { date: "2023-07", value: 266538 }, { date: "2023-08", value: 278820 }, { date: "2023-09", value: 252026 }, { date: "2023-10", value: 258326 }, { date: "2023-11", value: 260691 }, { date: "2023-12", value: 262566 }, { date: "2024-01", value: 276147 }, { date: "2024-02", value: 240784 }, { date: "2024-03", value: 274169 }, { date: "2024-04", value: 224765 }, { date: "2024-05", value: 211219 }, { date: "2024-06", value: 267703 }, { date: "2024-07", value: 274453 }, { date: "2024-08", value: 246658 }, ].map((x) => ({ ...x, formattedDate: monthYearFormatter.format(new Date(x.date)), })); export default function BasicLineChart() { return ( <ResponsiveContainer> <AreaChart data={data} margin={{ // adjust margins to fit your data left: 10, }} > <defs> <linearGradient id="basic-line-chart-gradient" x2="0" y2="1"> <stop offset="0%" stopColor={lineColor} stopOpacity={0.8} /> <stop offset="100%" stopColor={lineColor} stopOpacity={0} /> </linearGradient> </defs> <CartesianGrid strokeDasharray="5 5" vertical={false} stroke="var(--bfc-base-dimmed)" /> <XAxis dataKey="formattedDate" hide /> <YAxis axisLine={false} tickLine={false} type="number" tickFormatter={(value) => numberFormatter.format(value)} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dx={-8} /> <Tooltip content={<CustomTooltip />} /> <Area type="monotone" dataKey="value" stroke={lineColor} strokeWidth={2} fill="url(#basic-line-chart-gradient)" /> </AreaChart> </ResponsiveContainer> ); }

Two-line chart

Creating a two-line chart (technically two-"area") is as simple as adding another <AreaChart> component with corresponding gradients to the chart.

Code

import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, Legend, } from "recharts"; import CustomTooltip from "../CustomToolTip"; const data = [ { month: "Jan", avgMinTemp: -6.0, avgMaxTemp: -1.0 }, { month: "Feb", avgMinTemp: -5.0, avgMaxTemp: 0.0 }, { month: "March", avgMinTemp: -2.0, avgMaxTemp: 5.0 }, { month: "April", avgMinTemp: 2.0, avgMaxTemp: 10.0 }, { month: "May", avgMinTemp: 7.0, avgMaxTemp: 16.0 }, { month: "June", avgMinTemp: 12.0, avgMaxTemp: 20.0 }, { month: "July", avgMinTemp: 14.0, avgMaxTemp: 23.0 }, { month: "Aug", avgMinTemp: 13.0, avgMaxTemp: 22.0 }, { month: "Sept", avgMinTemp: 10.0, avgMaxTemp: 17.0 }, { month: "Oct", avgMinTemp: 4.0, avgMaxTemp: 10.0 }, { month: "Nov", avgMinTemp: -1.0, avgMaxTemp: 4.0 }, { month: "Dec", avgMinTemp: -4.0, avgMaxTemp: 0.0 }, ]; export default function TwolineChart() { return ( <ResponsiveContainer> <AreaChart data={data} margin={{ // adjust margins to fit your data left: -25, }} > <defs> <linearGradient id="chillGradient" x2="0" y2="1"> <stop offset="0%" stopColor="var(--bfc-chill)" stopOpacity={0.5} /> <stop offset="100%" stopColor="var(--bfc-chill)" stopOpacity={0} /> </linearGradient> <linearGradient id="attnGradient" x2="0" y2="1"> <stop offset="0%" stopColor="var(--bfc-attn)" stopOpacity={0.5} /> <stop offset="100%" stopColor="var(--bfc-attn)" stopOpacity={0} /> </linearGradient> </defs> <CartesianGrid strokeDasharray="5 5" vertical={false} stroke="var(--bfc-base-dimmed)" /> <XAxis axisLine={false} tickLine={false} dataKey="month" tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} /> <YAxis axisLine={false} tickLine={false} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dx={-8} /> <Tooltip content={<CustomTooltip />} /> <Area baseValue="dataMin" type="monotone" dataKey="avgMinTemp" name="Avg. Min Temp" strokeWidth={2} stroke="var(--bfc-chill)" fill="url(#chillGradient)" /> <Area baseValue="dataMin" type="monotone" dataKey="avgMaxTemp" name="Avg. Max Temp" strokeWidth={2} stroke="var(--bfc-attn)" fill="url(#attnGradient)" /> <Legend align="right" iconType="square" formatter={(value) => <span className="bfc-base-2"> {value}</span>} /> </AreaChart> </ResponsiveContainer> ); }
import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, Legend, } from "recharts"; import CustomTooltip from "../CustomToolTip"; const data = [ { month: "Jan", avgMinTemp: -6.0, avgMaxTemp: -1.0 }, { month: "Feb", avgMinTemp: -5.0, avgMaxTemp: 0.0 }, { month: "March", avgMinTemp: -2.0, avgMaxTemp: 5.0 }, { month: "April", avgMinTemp: 2.0, avgMaxTemp: 10.0 }, { month: "May", avgMinTemp: 7.0, avgMaxTemp: 16.0 }, { month: "June", avgMinTemp: 12.0, avgMaxTemp: 20.0 }, { month: "July", avgMinTemp: 14.0, avgMaxTemp: 23.0 }, { month: "Aug", avgMinTemp: 13.0, avgMaxTemp: 22.0 }, { month: "Sept", avgMinTemp: 10.0, avgMaxTemp: 17.0 }, { month: "Oct", avgMinTemp: 4.0, avgMaxTemp: 10.0 }, { month: "Nov", avgMinTemp: -1.0, avgMaxTemp: 4.0 }, { month: "Dec", avgMinTemp: -4.0, avgMaxTemp: 0.0 }, ]; export default function TwolineChart() { return ( <ResponsiveContainer> <AreaChart data={data} margin={{ // adjust margins to fit your data left: -25, }} > <defs> <linearGradient id="chillGradient" x2="0" y2="1"> <stop offset="0%" stopColor="var(--bfc-chill)" stopOpacity={0.5} /> <stop offset="100%" stopColor="var(--bfc-chill)" stopOpacity={0} /> </linearGradient> <linearGradient id="attnGradient" x2="0" y2="1"> <stop offset="0%" stopColor="var(--bfc-attn)" stopOpacity={0.5} /> <stop offset="100%" stopColor="var(--bfc-attn)" stopOpacity={0} /> </linearGradient> </defs> <CartesianGrid strokeDasharray="5 5" vertical={false} stroke="var(--bfc-base-dimmed)" /> <XAxis axisLine={false} tickLine={false} dataKey="month" tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} /> <YAxis axisLine={false} tickLine={false} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dx={-8} /> <Tooltip content={<CustomTooltip />} /> <Area baseValue="dataMin" type="monotone" dataKey="avgMinTemp" name="Avg. Min Temp" strokeWidth={2} stroke="var(--bfc-chill)" fill="url(#chillGradient)" /> <Area baseValue="dataMin" type="monotone" dataKey="avgMaxTemp" name="Avg. Max Temp" strokeWidth={2} stroke="var(--bfc-attn)" fill="url(#attnGradient)" /> <Legend align="right" iconType="square" formatter={(value) => <span className="bfc-base-2"> {value}</span>} /> </AreaChart> </ResponsiveContainer> ); }

Multi-line chart

Below is a bit more complex line chart example. The chart has a clickable legend which lets you toggle lines on and off, and highlights the corresponding line when hovering.

Code

import { Checkbox, Inline } from "@intility/bifrost-react"; import { useState } from "react"; import { CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis, } from "recharts"; import CustomTooltip from "../CustomToolTip"; const locale = "en-us"; /** Convert a Date object to month & year string, e.g. "Jan 2023" */ const monthYearFormatter = new Intl.DateTimeFormat(locale, { month: "short", year: "numeric", }); const data = [ { 1: 231, 2: 210, 3: 276, 4: 323, date: "2023-01" }, { 1: 202, 2: 182, 3: 237, 4: 254, date: "2023-02" }, { 1: 223, 2: 169, 3: 286, 4: 315, date: "2023-03" }, { 1: 210, 2: 176, 3: 241, 4: 275, date: "2023-04" }, { 1: 220, 2: 197, 3: 221, 4: 306, date: "2023-05" }, { 1: 209, 2: 190, 3: 236, 4: 287, date: "2023-06" }, { 1: 225, 2: 203, 3: 224, 4: 285, date: "2023-07" }, { 1: 236, 2: 160, 3: 280, 4: 314, date: "2023-08" }, { 1: 233, 2: 177, 3: 242, 4: 327, date: "2023-09" }, { 1: 237, 2: 160, 3: 284, 4: 342, date: "2023-10" }, { 1: 226, 2: 197, 3: 267, 4: 318, date: "2023-11" }, { 1: 207, 2: 192, 3: 281, 4: 338, date: "2023-12" }, { 1: 235, 2: 167, 3: 229, 4: 308, date: "2024-01" }, { 1: 232, 2: 208, 3: 265, 4: 324, date: "2024-02" }, { 1: 233, 2: 173, 3: 264, 4: 305, date: "2024-03" }, { 1: 227, 2: 163, 3: 293, 4: 291, date: "2024-04" }, { 1: 236, 2: 171, 3: 205, 4: 321, date: "2024-05" }, { 1: 210, 2: 173, 3: 223, 4: 275, date: "2024-06" }, { 1: 228, 2: 161, 3: 207, 4: 331, date: "2024-07" }, { 1: 222, 2: 196, 3: 271, 4: 314, date: "2024-08" }, ].map((x) => ({ ...x, formattedDate: monthYearFormatter.format(new Date(x.date)), })); const lines = [ { dataKey: "1", name: "Data 1", className: "bf-theme-green" }, { dataKey: "2", name: "Data 2", className: "bf-theme-pink" }, { dataKey: "3", name: "Data 3", className: "bf-theme-purple" }, { dataKey: "4", name: "Data 4", className: "bf-theme-yellow" }, ]; export default function MultiLineChart() { const [hoveredLine, setHoveredLine] = useState<string>(); const [hiddenLines, setHiddenLines] = useState<string[]>([]); const toggleLine = (lineName: string) => { setHiddenLines((prevState) => { if (prevState.includes(lineName)) { return prevState.filter((name) => name !== lineName); } else { return [...prevState, lineName]; } }); }; return ( <ResponsiveContainer> <LineChart data={data} margin={{ left: -20 }}> <CartesianGrid strokeDasharray="5 5" vertical={false} stroke="var(--bfc-base-dimmed)" /> <XAxis axisLine={false} tickLine={false} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dataKey="formattedDate" dy={8} /> <YAxis axisLine={false} tickLine={false} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dx={-8} /> <Tooltip content={<CustomTooltip />} /> {lines.map((line) => ( <Line isAnimationActive={false} key={line.dataKey} type="monotone" dot={false} strokeWidth={2} stroke="var(--bfc-theme)" opacity={hoveredLine && hoveredLine !== line.dataKey ? 0.3 : 1} hide={hiddenLines.includes(line.dataKey)} {...line} /> ))} <Legend content={() => ( <Inline style={{ marginTop: 12 }}> <Inline.Separator /> {lines.map(({ dataKey, name, className }) => ( <Checkbox key={dataKey} label={name} checked={!hiddenLines.includes(dataKey)} onChange={() => toggleLine(dataKey)} labelProps={{ onMouseEnter: () => setHoveredLine(dataKey), onMouseLeave: () => setHoveredLine(undefined), className: `bfc-base-2 ${className}`, }} /> ))} </Inline> )} /> </LineChart> </ResponsiveContainer> ); }
import { Checkbox, Inline } from "@intility/bifrost-react"; import { useState } from "react"; import { CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis, } from "recharts"; import CustomTooltip from "../CustomToolTip"; const locale = "en-us"; /** Convert a Date object to month & year string, e.g. "Jan 2023" */ const monthYearFormatter = new Intl.DateTimeFormat(locale, { month: "short", year: "numeric", }); const data = [ { 1: 231, 2: 210, 3: 276, 4: 323, date: "2023-01" }, { 1: 202, 2: 182, 3: 237, 4: 254, date: "2023-02" }, { 1: 223, 2: 169, 3: 286, 4: 315, date: "2023-03" }, { 1: 210, 2: 176, 3: 241, 4: 275, date: "2023-04" }, { 1: 220, 2: 197, 3: 221, 4: 306, date: "2023-05" }, { 1: 209, 2: 190, 3: 236, 4: 287, date: "2023-06" }, { 1: 225, 2: 203, 3: 224, 4: 285, date: "2023-07" }, { 1: 236, 2: 160, 3: 280, 4: 314, date: "2023-08" }, { 1: 233, 2: 177, 3: 242, 4: 327, date: "2023-09" }, { 1: 237, 2: 160, 3: 284, 4: 342, date: "2023-10" }, { 1: 226, 2: 197, 3: 267, 4: 318, date: "2023-11" }, { 1: 207, 2: 192, 3: 281, 4: 338, date: "2023-12" }, { 1: 235, 2: 167, 3: 229, 4: 308, date: "2024-01" }, { 1: 232, 2: 208, 3: 265, 4: 324, date: "2024-02" }, { 1: 233, 2: 173, 3: 264, 4: 305, date: "2024-03" }, { 1: 227, 2: 163, 3: 293, 4: 291, date: "2024-04" }, { 1: 236, 2: 171, 3: 205, 4: 321, date: "2024-05" }, { 1: 210, 2: 173, 3: 223, 4: 275, date: "2024-06" }, { 1: 228, 2: 161, 3: 207, 4: 331, date: "2024-07" }, { 1: 222, 2: 196, 3: 271, 4: 314, date: "2024-08" }, ].map((x) => ({ ...x, formattedDate: monthYearFormatter.format(new Date(x.date)), })); const lines = [ { dataKey: "1", name: "Data 1", className: "bf-theme-green" }, { dataKey: "2", name: "Data 2", className: "bf-theme-pink" }, { dataKey: "3", name: "Data 3", className: "bf-theme-purple" }, { dataKey: "4", name: "Data 4", className: "bf-theme-yellow" }, ]; export default function MultiLineChart() { const [hoveredLine, setHoveredLine] = useState<string>(); const [hiddenLines, setHiddenLines] = useState<string[]>([]); const toggleLine = (lineName: string) => { setHiddenLines((prevState) => { if (prevState.includes(lineName)) { return prevState.filter((name) => name !== lineName); } else { return [...prevState, lineName]; } }); }; return ( <ResponsiveContainer> <LineChart data={data} margin={{ left: -20 }}> <CartesianGrid strokeDasharray="5 5" vertical={false} stroke="var(--bfc-base-dimmed)" /> <XAxis axisLine={false} tickLine={false} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dataKey="formattedDate" dy={8} /> <YAxis axisLine={false} tickLine={false} tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }} dx={-8} /> <Tooltip content={<CustomTooltip />} /> {lines.map((line) => ( <Line isAnimationActive={false} key={line.dataKey} type="monotone" dot={false} strokeWidth={2} stroke="var(--bfc-theme)" opacity={hoveredLine && hoveredLine !== line.dataKey ? 0.3 : 1} hide={hiddenLines.includes(line.dataKey)} {...line} /> ))} <Legend content={() => ( <Inline style={{ marginTop: 12 }}> <Inline.Separator /> {lines.map(({ dataKey, name, className }) => ( <Checkbox key={dataKey} label={name} checked={!hiddenLines.includes(dataKey)} onChange={() => toggleLine(dataKey)} labelProps={{ onMouseEnter: () => setHoveredLine(dataKey), onMouseLeave: () => setHoveredLine(undefined), className: `bfc-base-2 ${className}`, }} /> ))} </Inline> )} /> </LineChart> </ResponsiveContainer> ); }

Try it yourself

import { Box, Checkbox, Grid, Inline } from "@intility/bifrost-react";
import { useState } from "react";
import {
  CartesianGrid,
  Legend,
  Line,
  LineChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";

const locale = "en-us"; // "nb-no" for Norwegian

/** Convert Date to month & year string, e.g. "Jan 2023" for en-us */
const monthYearFormatter = new Intl.DateTimeFormat(locale, {
  month: "short",
  year: "numeric",
});

const data = [
  { 1: 231, 2: 210, 3: 276, 4: 323, date: "2023-01" },
  { 1: 202, 2: 182, 3: 237, 4: 254, date: "2023-02" },
  { 1: 223, 2: 169, 3: 286, 4: 315, date: "2023-03" },
  { 1: 210, 2: 176, 3: 241, 4: 275, date: "2023-04" },
  { 1: 220, 2: 197, 3: 221, 4: 306, date: "2023-05" },
  { 1: 209, 2: 190, 3: 236, 4: 287, date: "2023-06" },
  { 1: 225, 2: 203, 3: 224, 4: 285, date: "2023-07" },
  { 1: 236, 2: 160, 3: 280, 4: 314, date: "2023-08" },
  { 1: 233, 2: 177, 3: 242, 4: 327, date: "2023-09" },
  { 1: 237, 2: 160, 3: 284, 4: 342, date: "2023-10" },
  { 1: 226, 2: 197, 3: 267, 4: 318, date: "2023-11" },
  { 1: 207, 2: 192, 3: 281, 4: 338, date: "2023-12" },
  { 1: 235, 2: 167, 3: 229, 4: 308, date: "2024-01" },
  { 1: 232, 2: 208, 3: 265, 4: 324, date: "2024-02" },
  { 1: 233, 2: 173, 3: 264, 4: 305, date: "2024-03" },
  { 1: 227, 2: 163, 3: 293, 4: 291, date: "2024-04" },
  { 1: 236, 2: 171, 3: 205, 4: 321, date: "2024-05" },
  { 1: 210, 2: 173, 3: 223, 4: 275, date: "2024-06" },
  { 1: 228, 2: 161, 3: 207, 4: 331, date: "2024-07" },
  { 1: 222, 2: 196, 3: 271, 4: 314, date: "2024-08" },
].map((x) => ({
  ...x,
  formattedDate: monthYearFormatter.format(new Date(x.date)),
}));

const lines = [
  { dataKey: "1", name: "Data 1", className: "bf-theme-green" },
  { dataKey: "2", name: "Data 2", className: "bf-theme-pink" },
  { dataKey: "3", name: "Data 3", className: "bf-theme-purple" },
  { dataKey: "4", name: "Data 4", className: "bf-theme-yellow" },
];

/** Adds thousands separator to large numbers, e.g. "1,337" for en-us */
const numberFormatter = new Intl.NumberFormat(locale);

function CustomTooltip({
  payload,
  label,
}: {
  label?: string | number;
  payload?: any[];
}) {
  return (
    <Box background radius shadow padding={14}>
      <Grid gap={4}>
        <strong className="bf-large">{label}</strong>
        <div>
          {payload?.map((entry, index) => (
            <div key={index}>
              {entry.name}:{" "}
              <strong>
                {typeof entry.value === "number"
                  ? numberFormatter.format(entry.value)
                  : entry.value}
              </strong>
            </div>
          ))}
        </div>
      </Grid>
    </Box>
  );
}

export default function MultiLineChart() {
  const [hoveredLine, setHoveredLine] = useState<string>();
  const [hiddenLines, setHiddenLines] = useState<string[]>([]);

  const toggleLine = (lineName: string) => {
    setHiddenLines((prevState) => {
      if (prevState.includes(lineName)) {
        return prevState.filter((name) => name !== lineName);
      } else {
        return [...prevState, lineName];
      }
    });
  };

  return (
    <ResponsiveContainer height={300}>
      <LineChart data={data} margin={{ left: -20 }}>
        <CartesianGrid
          strokeDasharray="5 5"
          vertical={false}
          stroke="var(--bfc-base-dimmed)"
        />
        <XAxis
          axisLine={false}
          tickLine={false}
          tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }}
          dataKey="formattedDate"
          dy={8}
        />
        <YAxis
          axisLine={false}
          tickLine={false}
          tick={{ fill: "var(--bfc-base-c-2)", fontSize: 14 }}
          dx={-8}
        />
        <Tooltip content={<CustomTooltip />} />
        {lines.map((line) => (
          <Line
            isAnimationActive={false}
            key={line.dataKey}
            type="monotone"
            dot={false}
            strokeWidth={2}
            stroke="var(--bfc-theme)"
            opacity={hoveredLine && hoveredLine !== line.dataKey ? 0.3 : 1}
            hide={hiddenLines.includes(line.dataKey)}
            {...line}
          />
        ))}
        <Legend
          content={() => (
            <Inline style={{ marginTop: 12 }}>
              <Inline.Separator />
              {lines.map(({ dataKey, name, className }) => (
                <Checkbox
                  key={dataKey}
                  label={name}
                  checked={!hiddenLines.includes(dataKey)}
                  onChange={() => toggleLine(dataKey)}
                  labelProps={{
                    onMouseEnter: () => setHoveredLine(dataKey),
                    onMouseLeave: () => setHoveredLine(undefined),
                    className: `bfc-base-2 ${className}`,
                  }}
                />
              ))}
            </Inline>
          )}
        />
      </LineChart>
    </ResponsiveContainer>
  );
}