Categories
Visx

Add TreeMaps into Our React App 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 treemaps into our React app.

Install Required Packages

We have to install a few modules.

To get started, we run:

npm i @visx/group @visx/hierarchy @visx/mock-data @visx/responsive @visx/scale

to install the packages.

Add the TreeMap

We can add the treemap into our React app by writing:

import React, { useState } from "react";
import { Group } from "@visx/group";
import {
  Treemap,
  hierarchy,
  stratify,
  treemapSquarify,
  treemapBinary,
  treemapDice,
  treemapResquarify,
  treemapSlice,
  treemapSliceDice
} from "@visx/hierarchy";
import shakespeare from "@visx/mock-data/lib/mocks/shakespeare";
import { scaleLinear } from "@visx/scale";

const color1 = "#f3e9d2";
const color2 = "#4281a4";
const background = "#114b5f";

const colorScale = scaleLinear({
  domain: [0, Math.max(...shakespeare.map((d) => d.size || 0))],
  range: [color2, color1]
});

const data = stratify()
  .id((d) => d.id)
  .parentId((d) => d.parent)(shakespeare)
  .sum((d) => d.size || 0);

const tileMethods = {
  treemapSquarify,
  treemapBinary,
  treemapDice,
  treemapResquarify,
  treemapSlice,
  treemapSliceDice
};

const defaultMargin = { top: 10, left: 10, right: 10, bottom: 10 };

function Example({ width, height, margin = defaultMargin }) {
  const [tileMethod, setTileMethod] = useState("treemapSquarify");
  const xMax = width - margin.left - margin.right;
  const yMax = height - margin.top - margin.bottom;
  const root = hierarchy(data).sort((a, b) => (b.value || 0) - (a.value || 0));

  return width < 10 ? null : (
    <div>
      <label>tile method</label>{" "}
      <select
        onClick={(e) => e.stopPropagation()}
        onChange={(e) => setTileMethod(e.target.value)}
        value={tileMethod}
      >
        {Object.keys(tileMethods).map((tile) => (
          <option key={tile} value={tile}>
            {tile}
          </option>
        ))}
      </select>
      <div>
        <svg width={width} height={height}>
          <rect width={width} height={height} rx={14} fill={background} />
          <Treemap
            top={margin.top}
            root={root}
            size={[xMax, yMax]}
            tile={tileMethods[tileMethod]}
            round
          >
            {(treemap) => (
              <Group>
                {treemap
                  .descendants()
                  .reverse()
                  .map((node, i) => {
                    const nodeWidth = node.x1 - node.x0;
                    const nodeHeight = node.y1 - node.y0;
                    return (
                      <Group
                        key={`node-${i}`}
                        top={node.y0 + margin.top}
                        left={node.x0 + margin.left}
                      >
                        {node.depth === 1 && (
                          <rect
                            width={nodeWidth}
                            height={nodeHeight}
                            stroke={background}
                            strokeWidth={4}
                            fill="transparent"
                          />
                        )}
                        {node.depth > 2 && (
                          <rect
                            width={nodeWidth}
                            height={nodeHeight}
                            stroke={background}
                            fill={colorScale(node.value || 0)}
                          />
                        )}
                      </Group>
                    );
                  })}
              </Group>
            )}
          </Treemap>
        </svg>
      </div>
    </div>
  );
}

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

We add the colors for the treemap partitions with the color1 and color2 variables.

background has the background color.

We create the colorScale variable to create color variants for the partitions.

Then we convert the data into a structure that can be used with the treemap with the stratify method.

Next, in the Example component, we add a dropdown to display the tile method choices.

This lets us set the tile format for the treemap.

After this, we add the Treemap component to add the treemap.

In its render prop, we call descendants to get the descendants.

Then we call reverse to reverse the data.

map maps them to rect s so that we render the partitions.

We render them differently depending on the depth level.

Conclusion

We can add treemaps easily into our React app with 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 *