Categories
React

Add Charts into Our React App with Victory — Events and Layouts

Spread the love

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.

Simple Events

We can attach events straight onto the chart components.

For instance, we can write:

import React from "react";
import { Bar, VictoryBar } from "victory";

export default function App() {
  return (
    <VictoryBar
      data={[
        { x: 1, y: 2 },
        { x: 2, y: 4 },
        { x: 3, y: 7 },
        { x: 4, y: 3 },
        { x: 5, y: 5 }
      ]}
      dataComponent={
        <Bar
          events={{
            onClick: (evt) => alert(`(${evt.clientX}, ${evt.clientY})`)
          }}
        />
      }
    />
  );
}

to attach a click handler to the Bar component with the events prop.

We get the click coordinates with the clientX and clientY properties from the event object.

Events on Custom Components

Also, we can attach event handlers to custom components.

For instance, we can write:

import React from "react";
import { VictoryChart, VictoryScatter } from "victory";

const ScatterPoint = ({ x, y, datum }) => {
  const [selected, setSelected] = React.useState(false);
  const [hovered, setHovered] = React.useState(false);

return (
    <circle
      cx={x}
      cy={y}
      r={datum.x * datum.y}
      stroke={hovered ? "purple" : "white"}
      strokeWidth={2}
      fill={selected ? "cyan" : "magenta"}
      onClick={() => setSelected(!selected)}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
    />
  );
};

export default function App() {
  return (
    <VictoryChart>
      <VictoryScatter
        data={[
          { x: 1, y: 7 },
          { x: 2, y: 5 },
          { x: 3, y: 7 },
          { x: 4, y: 2 },
          { x: 5, y: 1 }
        ]}
        dataComponent={<ScatterPoint />}
      />
    </VictoryChart>
  );
}

to create the ScatterPoint component.

We add the onMouseEnter , onMouseLeave and onClick props to add the event handlers for those mouse events.

Layout

We can change the render order to change which component appears above which one.

For example, we can write:

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

export default function App() {
  return (
    <div>
      <VictoryChart>
        <VictoryScatter
          y={(data) => Math.sin(2 * Math.PI * data.x)}
          samples={25}
          size={5}
          style={{ data: { fill: "tomato" } }}
        />
        <VictoryLine
          style={{ data: { stroke: "orange" } }}
          y={(data) => Math.sin(2 * Math.PI * data.x)}
        />
        <VictoryAxis />
        <VictoryAxis dependentAxis />
      </VictoryChart>
    </div>
  );
}

to render the scatter points below the other components since it’s rendered first.

The items that are rendered earlier go below the ones that are rendered later.

VictoryPortal

We can also use the VictoryPortal component to render components in a top-level container.

This way, they appear above other components.

For instance, we wrap the VictoryLabel in the VictoryPortal :

import React from "react";
import {
  VictoryAxis,
  VictoryBar,
  VictoryChart,
  VictoryLabel,
  VictoryLine,
  VictoryPortal,
  VictoryScatter,
  VictoryStack
} from "victory";

export default function App() {
  return (
    <div>
      <VictoryChart domainPadding={40}>
        <VictoryStack
          colorScale={["gold", "orange", "tomato"]}
          style={{
            data: { width: 30 },
            labels: { padding: -20 }
          }}
          labelComponent={
            <VictoryPortal>
              <VictoryLabel />
            </VictoryPortal>
          }
        >
          <VictoryBar
            data={[
              { x: 1, y: 3, label: "C" },
              { x: 2, y: 4, label: "C" },
              { x: 3, y: 2, label: "C" }
            ]}
          />
          <VictoryBar
            data={[
              { x: 1, y: 3, label: "B" },
              { x: 2, y: 4, label: "B" },
              { x: 3, y: 2, label: "B" }
            ]}
          />
          <VictoryBar
            data={[
              { x: 1, y: 3, label: "A" },
              { x: 2, y: 4, label: "A" },
              { x: 3, y: 2, label: "A" }
            ]}
          />
        </VictoryStack>
        <VictoryAxis />
      </VictoryChart>
    </div>
  );
}

to render the labels above the other components.

Conclusion

We can render chart components in different orders and attach events to components with React Victory.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *