Categories
Visx

Create a React Chord Diagram with the Visx Library

Spread the love

Visx is a library that lets us add graphics to our React app easily.

In this article, we’ll look at how to use it to add chord diagrams into our React app.

Install Required Packages

We have to install a few modules.

To get started, we run:

npm i @visx/chord @visx/gradient @visx/group @visx/responsive @visx/scale @visx/shape

to install the packages.

Create the Diagram

We can create the chart by adding the items provided by the modules.

We use the data from the @visx/mock-data module.

To create the chord diagram, we write:

import React from "react";
import { Arc } from "@visx/shape";
import { Group } from "@visx/group";
import { Chord, Ribbon } from "@visx/chord";
import { scaleOrdinal } from "@visx/scale";
import { LinearGradient } from "@visx/gradient";

const pink = "#ff2fab";
const orange = "#ffc62e";
const purple = "#dc04ff";
const purple2 = "#7324ff";
const red = "#d04376";
const green = "#52f091";
const blue = "#04a6ff";
const lime = "#00ddc6";
const bg = "#e4e3d8";

const dataMatrix = [
  [11975, 5871, 8916, 2868],
  [1951, 10048, 2060, 6171],
  [8010, 16145, 8090, 8045],
  [1013, 990, 940, 6907]
];

function descending(a, b) {
  return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

const color = scaleOrdinal({
  domain: [0, 1, 2, 3],
  range: [
    "url(#gpinkorange)",
    "url(#gpurplered)",
    "url(#gpurplegreen)",
    "url(#gbluelime)"
  ]
});

function Example({ width, height, centerSize = 20, events = false }) {
  height -= 77;
  const outerRadius = Math.min(width, height) * 0.5 - (centerSize + 10);
  const innerRadius = outerRadius - centerSize;

return width < 10 ? null : (
    <div className="chords">
      <svg width={width} height={height}>
        <LinearGradient
          id="gpinkorange"
          from={pink}
          to={orange}
          vertical={false}
        />
        <LinearGradient
          id="gpurplered"
          from={purple}
          to={red}
          vertical={false}
        />
        <LinearGradient
          id="gpurplegreen"
          from={purple2}
          to={green}
          vertical={false}
        />
        <LinearGradient id="gbluelime" from={blue} to={lime} vertical={false} />
        <rect width={width} height={height} fill={bg} rx={14} />
        <Group top={height / 2} left={width / 2}>
          <Chord matrix={dataMatrix} padAngle={0.05} sortSubgroups={descending}>
            {({ chords }) => (
              <g>
                {chords.groups.map((group, i) => (
                  <Arc
                    key={`key-${i}`}
                    data={group}
                    innerRadius={innerRadius}
                    outerRadius={outerRadius}
                    fill={color(i)}
                    onClick={() => {
                      if (events) alert(`${JSON.stringify(group)}`);
                    }}
                  />
                ))}
                {chords.map((chord, i) => {
                  return (
                    <Ribbon
                      key={`ribbon-${i}`}
                      chord={chord}
                      radius={innerRadius}
                      fill={color(chord.target.index)}
                      fillOpacity={0.75}
                      onClick={() => {
                        if (events) alert(`${JSON.stringify(chord)}`);
                      }}
                    />
                  );
                })}
              </g>
            )}
          </Chord>
        </Group>
      </svg>
      <style jsx>{`
        .chords {
          display: flex;
          flex-direction: column;
          user-select: none;
        }
        svg {
          margin: 1rem 0;
          cursor: pointer;
        }
        .deets {
          display: flex;
          flex-direction: row;
          font-size: 12px;
        }
        .deets > div {
          margin: 0.25rem;
        }
      `}</style>
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      <Example width={500} height={300} />
    </div>
  );
}

We add the variables with the color codes to set the colors for the chords.

The dataMatrix variable has the data for the chords.

The descending function returns a number according to the values of a and b to change the sorting to descending order.

Next, we create the color variable to add the color range for the chords.

In the Example component, we add the chord diagram.

We add the LinearGradient component to add the gradient for the chords.

Then we add the Chord components inside the Group component to add the chords.

We create chord groups by rendering Arc components.

And we render the chords themselves with the Ribbon component.

Finally, we have some styles to position the chord diagram.

Conclusion

We can create the chord chart easily with the React components provided by the Visx library.

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 *