Lattice Grid

blog

Pie Chart of Revenue Share by Channel

Building…
Loading a live grid…

If you are the channel manager reporting on the quarter, the question is not how much revenue came in. It is how much of it each sales channel brought, so the room can see at once which channels carry the business and which are a sliver of it.

A pie chart answers that. The whole circle is the quarter’s revenue, each slice is one channel’s share, and the long tail is grouped into a single slice called Other so the small channels do not crowd the edge. The chart above is bound to the grid beneath it, one row per channel and month, so filtering the rows redraws the chart. Filter the Month column to March and see whether the shares moved.

Why a pie and not a bar chart

A bar chart is the better tool for comparing channels that are close in size, because bars share a baseline. A pie is the better tool when the point is the whole: the slices must add up to the quarter, and a reader sees straight away that Direct is about a third of it. Keep the slices few, which is what grouping the tail as Other is for.

The chart over a grid

The chart reads the grid’s rows, so there is nothing to keep in step. A pie takes a column for the category, x, and a measure, y, that sizes each slice. Here the channel is x and the revenue is y. Here is the example in plain JavaScript, with sample rows inline in place of your own.

import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { createChart } from '@toclocoinc/lattice-grid/modules/charts';

const rows = [
  { id: 1, channel: 'Direct', revenue: 1310 }, { id: 2, channel: 'Search', revenue: 908 },
  { id: 3, channel: 'Email', revenue: 533 }, { id: 4, channel: 'Partners', revenue: 380 },
  { id: 5, channel: 'Social', revenue: 288 }, { id: 6, channel: 'Marketplace', revenue: 217 },
  { id: 7, channel: 'Other', revenue: 316 },
];

const gridEl = document.createElement('div');
const chartEl = document.createElement('div');
gridEl.style.height = '260px';
chartEl.style.height = '320px';
document.body.append(gridEl, chartEl);

const grid = createGrid(gridEl, {
  rowKey: 'id',
  rows,
  columns: [
    { field: 'channel', title: 'Channel', filter: { type: 'set' } },
    { field: 'revenue', title: 'Revenue (thousands)', type: 'number' },
  ],
});

createChart({ grid, container: chartEl, type: 'pie', x: 'channel', y: 'revenue',
  legend: { values: true }, title: 'Revenue share by channel' });

The same thing in React

The React adapter is a factory, so you build the component once at module scope. The ref’s grid is the real grid, which is what the chart binds to.

import React, { useEffect, useRef } from 'react';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { createLatticeGrid } from '@toclocoinc/lattice-grid/modules/react';
import { createChart } from '@toclocoinc/lattice-grid/modules/charts';

const LatticeGrid = createLatticeGrid({ React, createGrid });
const rows = [
  { id: 1, channel: 'Direct', revenue: 1310 }, { id: 2, channel: 'Search', revenue: 908 },
  { id: 3, channel: 'Email', revenue: 533 }, { id: 4, channel: 'Partners', revenue: 380 },
  { id: 5, channel: 'Social', revenue: 288 }, { id: 6, channel: 'Marketplace', revenue: 217 },
  { id: 7, channel: 'Other', revenue: 316 },
];
const columns = [
  { field: 'channel', title: 'Channel', filter: { type: 'set' } },
  { field: 'revenue', title: 'Revenue (thousands)', type: 'number' },
];

export function RevenueShare() {
  const gridRef = useRef(null);
  const chartRef = useRef(null);
  useEffect(() => {
    const chart = createChart({ grid: gridRef.current.grid, container: chartRef.current,
      type: 'pie', x: 'channel', y: 'revenue', legend: { values: true } });
    return () => chart.destroy();
  }, []);
  return (<>
    <LatticeGrid ref={gridRef} rowKey="id" columns={columns} rows={rows} style={{ height: 220 }} />
    <div ref={chartRef} style={{ height: 280 }} />
  </>);
}

The options used

These are the rows of the charts reference for the options in the listings above.

Option Type What it does
grid Grid Required. The grid to read.
container Element or string Required. Where to draw.
type string 'pie' here, one of the chart types the charts module draws.
x / y string Category and measure columns. Here x is the channel, which gets one slice, and y is the revenue that sizes it.
legend boolean or object Shows the legend. values: true appends each channel’s own total after its name.
title string Drawn above the plot.

Reading the slices

The wider the slice, the bigger the channel’s share. In the example, Direct and Search together bring more than half the quarter, and Email is the clear third. Marketplace and the grouped Other slice are small, which is the signal that the long tail is worth watching rather than worth a slice each. The grid still drives it: filter to one month, or to a few channels, and every slice is sized again from the rows that are left.

Next

See the pie beside the other part-to-whole charts in the bar, line and pie family demo, read the full list of chart types on the charts page, or follow the how-to for a chart that follows the grid.

Read next

  • Heatmap of Sign-ups by Hour and Weekday

    Bind a heatmap to a grid of sign-ups: shade every weekday and hour by volume to time a campaign send, and filter the rows to redraw it.

  • Violin Chart of Salary Bands by Level

    Bind a violin chart to a grid of salaries: see the shape of pay at each level, including two bands inside one, and filter the rows to redraw it.

  • Ridgeline Chart of Hourly Demand by Weekday

    Bind a ridgeline chart to a grid of store orders: stack each weekday by hour to see how Saturday differs from Tuesday, and filter to redraw it.

All posts RSS