Categories
React

Add Charts into Our React App with Nivo — Bump Chart

The Victory lets us add charts and data visualization into our React app.

In this article, we’ll look at how to add charts into our React app with Nivo.

Bump Chart

We can add bar charts into our React app with Nivo.

First, we have to install the @nivo/bump package by running:

npm i @nivo/bump

For instance, we can write:

import React from "react";
import { ResponsiveBump } from "@nivo/bump";

const data = [
  {
    id: "1",
    data: [
      {
        x: 2000,
        y: 7
      },
      {
        x: 2001,
        y: 11
      },
      {
        x: 2002,
        y: 2
      },
      {
        x: 2003,
        y: 5
      },
      {
        x: 2004,
        y: 1
      }
    ]
  },
  {
    id: "2",
    data: [
      {
        x: 2000,
        y: 6
      },
      {
        x: 2001,
        y: 9
      },
      {
        x: 2002,
        y: 7
      },
      {
        x: 2003,
        y: 4
      },
      {
        x: 2004,
        y: 7
      }
    ]
  },
  {
    id: "3",
    data: [
      {
        x: 2000,
        y: 12
      },
      {
        x: 2001,
        y: 6
      },
      {
        x: 2002,
        y: 6
      },
      {
        x: 2003,
        y: 12
      },
      {
        x: 2004,
        y: 2
      }
    ]
  },
  {
    id: "4",
    data: [
      {
        x: 2000,
        y: 5
      },
      {
        x: 2001,
        y: 1
      },
      {
        x: 2002,
        y: 3
      },
      {
        x: 2003,
        y: 2
      },
      {
        x: 2004,
        y: 4
      }
    ]
  },
  {
    id: "5",
    data: [
      {
        x: 2000,
        y: 2
      },
      {
        x: 2001,
        y: 4
      },
      {
        x: 2002,
        y: 11
      },
      {
        x: 2003,
        y: 8
      },
      {
        x: 2004,
        y: 3
      }
    ]
  },
  {
    id: "6",
    data: [
      {
        x: 2000,
        y: 1
      },
      {
        x: 2001,
        y: 5
      },
      {
        x: 2002,
        y: 9
      },
      {
        x: 2003,
        y: 10
      },
      {
        x: 2004,
        y: 9
      }
    ]
  },
  {
    id: "7",
    data: [
      {
        x: 2000,
        y: 3
      },
      {
        x: 2001,
        y: 12
      },
      {
        x: 2002,
        y: 12
      },
      {
        x: 2003,
        y: 7
      },
      {
        x: 2004,
        y: 6
      }
    ]
  },
  {
    id: "8",
    data: [
      {
        x: 2000,
        y: 11
      },
      {
        x: 2001,
        y: 2
      },
      {
        x: 2002,
        y: 5
      },
      {
        x: 2003,
        y: 9
      },
      {
        x: 2004,
        y: 5
      }
    ]
  },
  {
    id: "9",
    data: [
      {
        x: 2000,
        y: 10
      },
      {
        x: 2001,
        y: 3
      },
      {
        x: 2002,
        y: 8
      },
      {
        x: 2003,
        y: 3
      },
      {
        x: 2004,
        y: 11
      }
    ]
  },
  {
    id: "10",
    data: [
      {
        x: 2000,
        y: 8
      },
      {
        x: 2001,
        y: 10
      },
      {
        x: 2002,
        y: 10
      },
      {
        x: 2003,
        y: 1
      },
      {
        x: 2004,
        y: 8
      }
    ]
  },
  {
    id: "11",
    data: [
      {
        x: 2000,
        y: 4
      },
      {
        x: 2001,
        y: 8
      },
      {
        x: 2002,
        y: 1
      },
      {
        x: 2003,
        y: 6
      },
      {
        x: 2004,
        y: 12
      }
    ]
  },
  {
    id: "12",
    data: [
      {
        x: 2000,
        y: 9
      },
      {
        x: 2001,
        y: 7
      },
      {
        x: 2002,
        y: 4
      },
      {
        x: 2003,
        y: 11
      },
      {
        x: 2004,
        y: 10
      }
    ]
  }
];
const MyResponsiveBump = ({ data }) => (
  <ResponsiveBump
    data={data}
    margin={{ top: 40, right: 100, bottom: 40, left: 60 }}
    colors={{ scheme: "spectral" }}
    lineWidth={3}
    activeLineWidth={6}
    inactiveLineWidth={3}
    inactiveOpacity={0.15}
    pointSize={10}
    activePointSize={16}
    inactivePointSize={0}
    pointColor={{ theme: "background" }}
    pointBorderWidth={3}
    activePointBorderWidth={3}
    pointBorderColor={{ from: "serie.color" }}
    axisTop={{
      tickSize: 5,
      tickPadding: 5,
      tickRotation: 0,
      legend: "",
      legendPosition: "middle",
      legendOffset: -36
    }}
    axisRight={null}
    axisBottom={{
      tickSize: 5,
      tickPadding: 5,
      tickRotation: 0,
      legend: "",
      legendPosition: "middle",
      legendOffset: 32
    }}
    axisLeft={{
      tickSize: 5,
      tickPadding: 5,
      tickRotation: 0,
      legend: "ranking",
      legendPosition: "middle",
      legendOffset: -40
    }}
  />
);

export default function App() {
  return (
    <div style={{ height: 300, width: 400 }}>
      <MyResponsiveBump data={data} />
    </div>
  );
}

We add the data for our our chart in the data array.

And we pass that into the data prop of the ResponsiveBump component.

The colors prop sets the series color.

lineWidth has the width of the lines in pixels.

activeLineWidth has the width of the lines in pixels.

We set similar settings with the pintSize .

pointColor has the point color.

pointBorderWidth has the point border width.

axisTop has the settings for the top axis.

tickSize has the tick size. tickPadding has the tick padding.

We have similar settings for axisBottom and axisLeft to configure the bottom and left axes.

Conclusion

We can add bump charts easily into our React app with Nivo.

Categories
React

Add Charts into Our React App with Nivo — Circle Packing Charts

The Victory lets us add charts and data visualization into our React app.

In this article, we’ll look at how to add charts into our React app with Nivo.

Circle Packing Charts

We can add bar charts into our React app with Nivo.

First, we have to install the @nivo/circle-packing package by running:

npm i @nivo/circle-packing

Then we can add the bubble chart by writing:

import React from "react";
import { ResponsiveBubble } from "@nivo/circle-packing";

const root = {
  name: "nivo",
  color: "hsl(264, 70%, 50%)",
  children: [
    {
      name: "viz",
      color: "hsl(137, 70%, 50%)",
      children: [
        {
          name: "stack",
          color: "hsl(209, 70%, 50%)",
          children: [
            {
              name: "cchart",
              color: "hsl(323, 70%, 50%)",
              loc: 159163
            },
            {
              name: "xAxis",
              color: "hsl(77, 70%, 50%)",
              loc: 135760
            }
          ]
        },
        {
          name: "ppie",
          color: "hsl(344, 70%, 50%)",
          children: [
            {
              name: "chart",
              color: "hsl(97, 70%, 50%)",
              children: [
                {
                  name: "pie",
                  color: "hsl(238, 70%, 50%)",
                  children: [
                    {
                      name: "outline",
                      color: "hsl(65, 70%, 50%)",
                      loc: 196552
                    },
                    {
                      name: "slices",
                      color: "hsl(189, 70%, 50%)",
                      loc: 15332
                    }
                  ]
                }
              ]
            },
            {
              name: "legends",
              color: "hsl(129, 70%, 50%)",
              loc: 38994
            }
          ]
        }
      ]
    },
    {
      name: "colors",
      color: "hsl(291, 70%, 50%)",
      children: [
        {
          name: "rgb",
          color: "hsl(263, 70%, 50%)",
          loc: 38690
        },
        {
          name: "hsl",
          color: "hsl(267, 70%, 50%)",
          loc: 81691
        }
      ]
    },
    {
      name: "utils",
      color: "hsl(204, 70%, 50%)",
      children: [
        {
          name: "randomize",
          color: "hsl(17, 70%, 50%)",
          loc: 85412
        },
        {
          name: "resetClock",
          color: "hsl(13, 70%, 50%)",
          loc: 183588
        }
      ]
    },
    {
      name: "generators",
      color: "hsl(21, 70%, 50%)",
      children: [
        {
          name: "address",
          color: "hsl(8, 70%, 50%)",
          loc: 106057
        },
        {
          name: "city",
          color: "hsl(189, 70%, 50%)",
          loc: 179311
        },
        {
          name: "animal",
          color: "hsl(23, 70%, 50%)",
          loc: 19629
        },
        {
          name: "movie",
          color: "hsl(131, 70%, 50%)",
          loc: 80528
        },
        {
          name: "user",
          color: "hsl(357, 70%, 50%)",
          loc: 192122
        }
      ]
    },
    {
      name: "set",
      color: "hsl(337, 70%, 50%)",
      children: [
        {
          name: "clone",
          color: "hsl(129, 70%, 50%)",
          loc: 141963
        },
        {
          name: "intersect",
          color: "hsl(275, 70%, 50%)",
          loc: 74219
        }
      ]
    },
    {
      name: "text",
      color: "hsl(171, 70%, 50%)",
      children: [
        {
          name: "trim",
          color: "hsl(211, 70%, 50%)",
          loc: 44996
        },
        {
          name: "slugify",
          color: "hsl(333, 70%, 50%)",
          loc: 56664
        },
        {
          name: "snakeCase",
          color: "hsl(319, 70%, 50%)",
          loc: 22892
        },
        {
          name: "camelCase",
          color: "hsl(27, 70%, 50%)",
          loc: 66898
        },
        {
          name: "repeat",
          color: "hsl(22, 70%, 50%)",
          loc: 189697
        },
        {
          name: "padLeft",
          color: "hsl(40, 70%, 50%)",
          loc: 79534
        },
        {
          name: "padRight",
          color: "hsl(233, 70%, 50%)",
          loc: 170579
        },
        {
          name: "sanitize",
          color: "hsl(156, 70%, 50%)",
          loc: 23012
        },
        {
          name: "ploucify",
          color: "hsl(48, 70%, 50%)",
          loc: 18720
        }
      ]
    },
    {
      name: "misc",
      color: "hsl(165, 70%, 50%)",
      children: [
        {
          name: "greetings",
          color: "hsl(180, 70%, 50%)",
          children: [
            {
              name: "hey",
              color: "hsl(44, 70%, 50%)",
              loc: 123441
            },
            {
              name: "hi",
              color: "hsl(199, 70%, 50%)",
              loc: 40101
            }
          ]
        },
        {
          name: "other",
          color: "hsl(303, 70%, 50%)",
          loc: 94851
        },
        {
          name: "path",
          color: "hsl(260, 70%, 50%)",
          children: [
            {
              name: "pathA",
              color: "hsl(242, 70%, 50%)",
              loc: 142944
            },
            {
              name: "pathB",
              color: "hsl(315, 70%, 50%)",
              children: [
                {
                  name: "pathB1",
                  color: "hsl(183, 70%, 50%)",
                  loc: 11757
                },
                {
                  name: "pathB2",
                  color: "hsl(34, 70%, 50%)",
                  loc: 137471
                }
              ]
            },
            {
              name: "pathC",
              color: "hsl(223, 70%, 50%)",
              children: [
                {
                  name: "pathC1",
                  color: "hsl(322, 70%, 50%)",
                  loc: 197027
                },
                {
                  name: "pathC2",
                  color: "hsl(314, 70%, 50%)",
                  loc: 161292
                }
              ]
            }
          ]
        }
      ]
    }
  ]
};

const MyResponsiveBubble = ({ root }) => (
  <ResponsiveBubble
    root={root}
    margin={{ top: 20, right: 20, bottom: 20, left: 20 }}
    identity="name"
    value="loc"
    colors={{ scheme: "nivo" }}
    padding={6}
    labelTextColor={{ from: "color", modifiers: [["darker", 0.8]] }}
    borderWidth={2}
    borderColor={{ from: "color" }}
    defs={[
      {
        id: "lines",
        type: "patternLines",
        background: "none",
        color: "inherit",
        rotation: -45,
        lineWidth: 5,
        spacing: 8
      }
    ]}
    fill={[{ match: { depth: 1 }, id: "lines" }]}
    animate={true}
    motionStiffness={90}
    motionDamping={12}
  />
);

export default function App() {
  return (
    <div style={{ height: 300, width: 400 }}>
      <MyResponsiveBubble root={root} />
    </div>
  );
}

We add the root object with the children properties to add an array of children objects.

Each object has the name , color , and loc properties.

name has a unique name for each item.

color has the color for each item. And loc has value.

In the MyResponsiveBubble component, we render the ResponsiveBubble component.

root has the data.

defs have the patterns for each circle.

labelTextColor have the text color for each circle label.

fill has the fill for each outer circle.

animate , motionStiffness , and motionDamping have the animation settings.

We also need the width and height on the outer div for the chart to render.

Conclusion

We can add circle packing charts into our React app with Nivo.

Categories
React

Add Charts into Our React App with Nivo

The Victory lets us add charts and data visualization into our React app.

In this article, we’ll look at how to add charts into our React app with Nivo.

Installation

We can start by installing the @nivo/core package by running:

npm i `@nivo/core`

Add a Chart

After we installed the package, we can add a chart.

We can add an area bump chart with the @nivo/bump package.

For instance, we can write:

import React from "react";
import { ResponsiveAreaBump } from "@nivo/bump";

const data = [
  {
    id: "JavaScript",
    data: [
      {
        x: 2000,
        y: 13
      },
      {
        x: 2001,
        y: 24
      },
      {
        x: 2002,
        y: 16
      },
      {
        x: 2003,
        y: 15
      },
      {
        x: 2004,
        y: 29
      },
      {
        x: 2005,
        y: 23
      }
    ]
  },
  {
    id: "ReasonML",
    data: [
      {
        x: 2000,
        y: 27
      },
      {
        x: 2001,
        y: 28
      },
      {
        x: 2002,
        y: 30
      },
      {
        x: 2003,
        y: 25
      },
      {
        x: 2004,
        y: 12
      },
      {
        x: 2005,
        y: 17
      }
    ]
  },
  {
    id: "TypeScript",
    data: [
      {
        x: 2000,
        y: 18
      },
      {
        x: 2001,
        y: 23
      },
      {
        x: 2002,
        y: 19
      },
      {
        x: 2003,
        y: 18
      },
      {
        x: 2004,
        y: 14
      },
      {
        x: 2005,
        y: 10
      }
    ]
  },
  {
    id: "Elm",
    data: [
      {
        x: 2000,
        y: 25
      },
      {
        x: 2001,
        y: 16
      },
      {
        x: 2002,
        y: 26
      },
      {
        x: 2003,
        y: 26
      },
      {
        x: 2004,
        y: 16
      },
      {
        x: 2005,
        y: 10
      }
    ]
  },
  {
    id: "CoffeeScript",
    data: [
      {
        x: 2000,
        y: 27
      },
      {
        x: 2001,
        y: 27
      },
      {
        x: 2002,
        y: 22
      },
      {
        x: 2003,
        y: 28
      },
      {
        x: 2004,
        y: 24
      },
      {
        x: 2005,
        y: 24
      }
    ]
  }
];

const MyResponsiveAreaBump = ({ data }) => (
  <ResponsiveAreaBump
    data={data}
    margin={{ top: 40, right: 100, bottom: 40, left: 100 }}
    spacing={8}
    colors={{ scheme: "nivo" }}
    blendMode="multiply"
    defs={[
      {
        id: "dots",
        type: "patternDots",
        background: "inherit",
        color: "#38bcb2",
        size: 4,
        padding: 1,
        stagger: true
      },
      {
        id: "lines",
        type: "patternLines",
        background: "inherit",
        color: "#eed312",
        rotation: -45,
        lineWidth: 6,
        spacing: 10
      }
    ]}
    fill={[
      {
        match: {
          id: "CoffeeScript"
        },
        id: "dots"
      },
      {
        match: {
          id: "TypeScript"
        },
        id: "lines"
      }
    ]}
    startLabel="id"
    axisTop={{
      tickSize: 5,
      tickPadding: 5,
      tickRotation: 0,
      legend: "",
      legendPosition: "middle",
      legendOffset: -36
    }}
    axisBottom={{
      tickSize: 5,
      tickPadding: 5,
      tickRotation: 0,
      legend: "",
      legendPosition: "middle",
      legendOffset: 32
    }}
  />
);

export default function App() {
  return (
    <div style={{ height: 300, width: 400 }}>
      <MyResponsiveAreaBump data={data} />
    </div>
  );
}

to add the chart.

We have to define the width and height of the wrapper div for the chart to render.

The data array has an array of data that we use to render the chart.

Next, we add the MyResponsiveAreaBump component to add the chart.

We set the data array as the value of the data prop.

margin has the margins.

spacing has the spacing between the bumps.

defs have the patterns for the bumps.

fill has the fill styles.

axisTop has the settings for the axes.

tickSize has the tick size. tickPadding has the tick padding.

axisBottom has the bottom axis settings.

Conclusion

We can add an area bump chart into our React app easily with Nivo.

Categories
React

Add Charts into Our React App with Nivo — Bar Charts

The Victory lets us add charts and data visualization into our React app.

In this article, we’ll look at how to add charts into our React app with Nivo.

Bar Charts

We can add bar charts into our React app with Nivo.

First, we have to install the @nivo/bar package by running:

npm i @nivo/bar

Then we can add the bar chart by writing:

import React from "react";
import { ResponsiveBar } from "@nivo/bar";

const data = [
  {
    country: "AD",
    "hot dog": 81,
    "hot dogColor": "hsl(154, 70%, 50%)",
    burger: 193,
    burgerColor: "hsl(304, 70%, 50%)",
    sandwich: 50,
    sandwichColor: "hsl(222, 70%, 50%)",
    kebab: 154,
    kebabColor: "hsl(241, 70%, 50%)",
    fries: 68,
    friesColor: "hsl(331, 70%, 50%)",
    donut: 49,
    donutColor: "hsl(259, 70%, 50%)"
  },
  {
    country: "AE",
    "hot dog": 46,
    "hot dogColor": "hsl(33, 70%, 50%)",
    burger: 96,
    burgerColor: "hsl(70, 70%, 50%)",
    sandwich: 10,
    sandwichColor: "hsl(348, 70%, 50%)",
    kebab: 18,
    kebabColor: "hsl(191, 70%, 50%)",
    fries: 93,
    friesColor: "hsl(262, 70%, 50%)",
    donut: 54,
    donutColor: "hsl(118, 70%, 50%)"
  },
  {
    country: "AF",
    "hot dog": 123,
    "hot dogColor": "hsl(17, 70%, 50%)",
    burger: 24,
    burgerColor: "hsl(122, 70%, 50%)",
    sandwich: 12,
    sandwichColor: "hsl(35, 70%, 50%)",
    kebab: 141,
    kebabColor: "hsl(102, 70%, 50%)",
    fries: 33,
    friesColor: "hsl(191, 70%, 50%)",
    donut: 8,
    donutColor: "hsl(183, 70%, 50%)"
  }
];

const MyResponsiveBar = ({ data }) => (
  <ResponsiveBar
    data={data}
    keys={["hot dog", "burger", "sandwich", "kebab", "fries", "donut"]}
    indexBy="country"
    margin={{ top: 50, right: 130, bottom: 50, left: 60 }}
    padding={0.3}
    valueScale={{ type: "linear" }}
    indexScale={{ type: "band", round: true }}
    colors={{ scheme: "nivo" }}
    defs={[
      {
        id: "dots",
        type: "patternDots",
        background: "inherit",
        color: "#38bcb2",
        size: 4,
        padding: 1,
        stagger: true
      },
      {
        id: "lines",
        type: "patternLines",
        background: "inherit",
        color: "#eed312",
        rotation: -45,
        lineWidth: 6,
        spacing: 10
      }
    ]}
    fill={[
      {
        match: {
          id: "fries"
        },
        id: "dots"
      },
      {
        match: {
          id: "sandwich"
        },
        id: "lines"
      }
    ]}
    borderColor={{ from: "color", modifiers: [["darker", 1.6]] }}
    axisTop={null}
    axisRight={null}
    axisBottom={{
      tickSize: 5,
      tickPadding: 5,
      tickRotation: 0,
      legend: "country",
      legendPosition: "middle",
      legendOffset: 32
    }}
    axisLeft={{
      tickSize: 5,
      tickPadding: 5,
      tickRotation: 0,
      legend: "food",
      legendPosition: "middle",
      legendOffset: -40
    }}
    labelSkipWidth={12}
    labelSkipHeight={12}
    labelTextColor={{ from: "color", modifiers: [["darker", 1.6]] }}
    legends={[
      {
        dataFrom: "keys",
        anchor: "bottom-right",
        direction: "column",
        justify: false,
        translateX: 120,
        translateY: 0,
        itemsSpacing: 2,
        itemWidth: 100,
        itemHeight: 20,
        itemDirection: "left-to-right",
        itemOpacity: 0.85,
        symbolSize: 20,
        effects: [
          {
            on: "hover",
            style: {
              itemOpacity: 1
            }
          }
        ]
      }
    ]}
    animate={true}
    motionStiffness={90}
    motionDamping={15}
  />
);

export default function App() {
  return (
    <div style={{ height: 300, width: 400 }}>
      <MyResponsiveBar data={data} />
    </div>
  );
}

The data array has an array with the key names for each bar segment.

The numbers are the values, and the strings are the color codes for each bar segment.

Next, we add the MyResponsiveBar component and render the ResponsiveBar component inside.

The keys array has the keys for the bar segments.

margin has the margins.

valueScale has the scale for the values. linear scale doesn’t transform the values.

defs have the fill pattern definitions for the bar segments.

color have the background color for each pattern.

fill have the id of the fill patterns that we defined in defs set.

axisBottom has the settings for the x-axis.

We set the tick size, tick padding, legend has the x-axis text.

axisLeft has the settings for the y-axis.

We have the same settings set.

legends have the legend settings.

We set the anchor property to the location of the legend.

And we set the itemSpacing , itemWidth , itemHeight and itemDirection to set the legend items styles.

In the effects property, we have the on property to set when the effect is applied and set the itemOpacity when we hover over the legend.

We also have the animate prop to enable animation, and motionStiffness and motionDamping to set the animation settings.

Conclusion

We can add bar charts into our React app with Nivo.

Categories
React

Add Charts into Our React App with Victory — Tooltip Customization

The Victory lets us add charts and data visualization into our React app.

In this article, we’ll look at how to add charts into our React app with Victory.

Mouse Following Tooltip

We can add a tooltip with a pointer that stretches when we move the mouse.

To add it, we write:

import React from "react";
import {
  VictoryAxis,
  VictoryChart,
  VictoryLine,
  VictoryScatter,
  VictoryTooltip,
  VictoryVoronoiContainer
} from "victory";

export default function App() {
  return (
    <VictoryChart
      domain={{ y: [0, 6] }}
      containerComponent={
        <VictoryVoronoiContainer
          mouseFollowTooltips
          voronoiDimension="x"
          labels={({ datum }) => `y: ${datum.y}`}
        />
      }
    >
      <VictoryScatter
        style={{ data: { fill: "red" }, labels: { fill: "red" } }}
        data={[
          { x: 0, y: 2 },
          { x: 2, y: 3 },
          { x: 4, y: 4 },
          { x: 6, y: 5 }
        ]}
      />
      <VictoryScatter
        data={[
          { x: 2, y: 2 },
          { x: 4, y: 3 },
          { x: 6, y: 4 },
          { x: 8, y: 5 }
        ]}
      />
    </VictoryChart>
  );
}

We add the mouseFollowTooltips prop to the VictoryVoronoiContainer component to add this feature.

Also, we can listen to other events with the events prop.

For instance, we can write:

import React from "react";
import { VictoryBar, VictoryChart, VictoryTooltip } from "victory";

export default function App() {
  return (
    <VictoryChart domain={{ x: [0, 11], y: [-10, 10] }}>
      <VictoryBar
        labelComponent={<VictoryTooltip />}
        data={[
          { x: 2, y: 5, label: "A" },
          { x: 4, y: -6, label: "B" },
          { x: 6, y: 4, label: "C" },
          { x: 8, y: -5, label: "D" },
          { x: 10, y: 7, label: "E" }
        ]}
        style={{
          data: { fill: "tomato", width: 20 }
        }}
        events={[
          {
            target: "data",
            eventHandlers: {
              onMouseOver: () => {
                return [
                  {
                    target: "data",
                    mutation: () => ({ style: { fill: "gold", width: 30 } })
                  },
                  {
                    target: "labels",
                    mutation: () => ({ active: true })
                  }
                ];
              },
              onMouseOut: () => {
                return [
                  {
                    target: "data",
                    mutation: () => {}
                  },
                  {
                    target: "labels",
                    mutation: () => ({ active: false })
                  }
                ];
              }
            }
          }
        ]}
      />
    </VictoryChart>
  );
}

We have the onMouseOver and onMouseOut properties with the target property to set which item to mutate.

And the mutation method to change the styles by returning an object with the styles we want.

Custom Tooltip

We can add a custom tooltip by creating our own tooltip component.

For instance, we can write:

import React from "react";
import { VictoryBar, VictoryChart, VictoryTooltip } from "victory";

const CustomTooltip = (props) => {
  const { x, y } = props;
  const rotation = `rotate(-45 ${x} ${y})`;
  return (
    <g transform={rotation}>
      <VictoryTooltip {...props} renderInPortal={false} />
    </g>
  );
};
CustomTooltip.defaultEvents = VictoryTooltip.defaultEvents;

export default function App() {
  return (
    <VictoryChart domain={{ x: [0, 11], y: [-10, 10] }}>
      <VictoryBar
        labelComponent={<CustomTooltip />}
        data={[
          { x: 2, y: 5, label: "A" },
          { x: 4, y: -6, label: "B" },
          { x: 6, y: 4, label: "C" },
          { x: 8, y: -5, label: "D" },
          { x: 10, y: 7, label: "E" }
        ]}
        style={{
          data: { fill: "tomato", width: 20 }
        }}
      />
    </VictoryChart>
  );
}

to create the CustomTooltip component.

We have to set the defaultEvents property to VictoryTooltip.defaultEvents for the tooltip to work since it adds the required event handlers for the tooltip.

Conclusion

We can add a mouse following tooltip and custom tooltips into our React charts with Victory.