Categories
React

Add Charts into Our React App with Victory — Shared and Dynamic Events

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.

VictorySharedEvents

We can add events shared between multiple charts with the VictorySharedEvents component.

For instance, we can write:

import React from "react";
import {
  VictoryBar,
  VictoryLabel,
  VictoryPie,
  VictorySharedEvents
} from "victory";

export default function App() {
  return (
    <svg viewBox="0 0 450 350">
      <VictorySharedEvents
        events={[
          {
            childName: ["pie", "bar"],
            target: "data",
            eventHandlers: {
              onMouseOver: () => {
                return [
                  {
                    childName: ["pie", "bar"],
                    mutation: (props) => {
                      return {
                        style: Object.assign({}, props.style, {
                          fill: "tomato"
                        })
                      };
                    }
                  }
                ];
              },
              onMouseOut: () => {
                return [
                  {
                    childName: ["pie", "bar"],
                    mutation: () => {
                      return null;
                    }
                  }
                ];
              }
            }
          }
        ]}
      >
        <g transform={"translate(150, 50)"}>
          <VictoryBar
            name="bar"
            width={300}
            standalone={false}
            style={{
              data: { width: 20 },
              labels: { fontSize: 25 }
            }}
            data={[
              { x: "a", y: 2 },
              { x: "b", y: 3 },
              { x: "c", y: 5 }
            ]}
            labels={["a", "b", "c"]}
            labelComponent={<VictoryLabel y={290} />}
          />
        </g>
        <g transform={"translate(0, -75)"}>
          <VictoryPie
            name="pie"
            width={250}
            standalone={false}
            style={{ labels: { fontSize: 25, padding: 10 } }}
            data={[
              { x: "a", y: 1 },
              { x: "b", y: 4 },
              { x: "c", y: 5 }
            ]}
          />
        </g>
      </VictorySharedEvents>
    </svg>
  );
}

In the events prop, we add an array with the eventsHandlers object to add event handlers for various events.

We have event handlers for mouseover with onMouseOver and one for mouseout with onMouseOut .

The mutation method lets us change the fill style of the segment we hover over.

childName has the name values of the charts we want to change.

Similarly, we have the onMouseOut event handler to return null to revert to the original style.

External Event Mutations

We can attach event mutations by changing states.

For instance, we can write:

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

const buttonStyle = {
  backgroundColor: "black",
  color: "white",
  padding: "10px",
  marginTop: "10px"
};

export default function App() {
  const [externalMutations, setExternalMutations] = useState({});
  const removeMutation = () => {
    setExternalMutations(undefined);
  };

const clearClicks = () => {
    setExternalMutations([
      {
        childName: "Bar-1",
        target: ["data"],
        eventKey: "all",
        mutation: () => ({ style: undefined }),
        callback: removeMutation
      }
    ]);
  };

return (
    <div>
      <button onClick={clearClicks} style={buttonStyle}>
        Reset
      </button>
      <VictoryChart
        domain={{ x: [0, 5] }}
        externalEventMutations={externalMutations}
        events={[
          {
            target: "data",
            childName: "Bar-1",
            eventHandlers: {
              onClick: () => ({
                target: "data",
                mutation: () => ({ style: { fill: "orange" } })
              })
            }
          }
        ]}
      >
        <VictoryBar
          name="Bar-1"
          style={{ data: { fill: "grey" } }}
          labels={() => "click me!"}
          data={[
            { x: 1, y: 2 },
            { x: 2, y: 4 },
            { x: 3, y: 1 },
            { x: 4, y: 5 }
          ]}
        />
      </VictoryChart>
    </div>
  );
}

to add click event handlers with the events prop on VictoryChart .

When we click on the bars, the fill changes to orange.

The Reset button calls clearClicks to clear all the click handlers by setting externalMutations to undefined .

clearClicks clear all the styles from the bars.

And we set externalEventMutations to externalMutations .

Conclusion

We can add event handlers dynamically and add shared events into charts 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 *