Funnel

Funnel Charts are Freeform charts which display a single series of data in progressively decreasing or increasing proportions that are organized in segments, where each segment represents the value for the particular item from the series.

The values of the items can also influence the height and the shape of the corresponding segments. The Funnel Charts are useful for representing stages in a sales process and for displaying the amount of potential revenues from each stage. They are also suitable for identifying potential problem areas in the sales processes of an organization and for displaying several values.

Basic Usage

The following example demonstrates the Funnel Chart in action.

import React from 'react';
import ReactDOM from 'react-dom';
import {
  Chart,
  ChartTitle,
  ChartLegend,
  ChartTooltip,
  ChartSeries,
  ChartSeriesItem,
  ChartSeriesLabels
} from '@progress/kendo-react-charts';
import data from './funnel-data.json';

const tooltipRender = (({ point = {} }) => (point.category));

const ChartContainer = () => (
  <Chart style={{ margin: '0 auto', width: 300 }} >
    <ChartTitle text="Sales funnel" />
    <ChartSeries>
      <ChartSeriesItem type="funnel" data={data} categoryField="stat" field="count" colorField="color">
        <ChartSeriesLabels color="white" background="none" format="N0" />
      </ChartSeriesItem>
    </ChartSeries>
    <ChartTooltip render={tooltipRender} />
    <ChartLegend visible={false} />
  </Chart>
);

ReactDOM.render(
  <ChartContainer />,
  document.querySelector('my-app')
);
[ {
    "stat": "Impressions ",
    "count": 434823,
    "color": "#0e5a7e"
}, {
    "stat": "Clicks",
    "count": 356854,
    "color": "#166f99"
}, {
    "stat": "Unique Visitors",
    "count": 280022,
    "color": "#2185b4"
}, {
    "stat": "Downloads",
    "count": 190374,
    "color": "#319fd2"
}, {
    "stat": "Purchases",
    "count": 120392,
    "color": "#3eaee2"
} ]

Controlling the Funnel Shape

You can influence the form of the funnel by setting the "neck ratio". The neck ratio is the ratio between the width of the base and the width of the funnel top. The default value of the neck ratio is 0.3. This means that the width of the base is 30% of the width of the top. If you set the neck ratio to values that are larger than 1, then the funnel will reverse and turn into a pyramid.

import React from 'react';
import ReactDOM from 'react-dom';
import { NumericTextBox } from '@progress/kendo-react-inputs';
import {
  Chart,
  ChartTitle,
  ChartLegend,
  ChartTooltip,
  ChartSeries,
  ChartSeriesItem,
  ChartSeriesLabels
} from '@progress/kendo-react-charts';
import data from './funnel-data.json';

const tooltipRender = (({ point = {} }) => (point.category));

class ChartContainer extends React.Component {
    state = { neckRation: 0.3 }
    render() {
        const { neckRation } = this.state;

        return (
          <div>
            <div className="example-config">
              <label for="neckRatio">Neck ratio ({neckRation})
              <br/>
              <NumericTextBox
                  onChange={(num) => this.setState({ neckRation: num.value })}
                  value={neckRation}
                  spinners={true}
                  min={0}
                  max={5}
                  step={0.1}
                />
              </label>
            </div>
            <Chart style={{ margin: '0 auto', width: 300 }} >
              <ChartTitle text="Sales funnel" />
              <ChartSeries>
                <ChartSeriesItem type="funnel" data={data} categoryField="stat" field="count" colorField="color" neckRatio={neckRation}>
                  <ChartSeriesLabels color="white" background="none" format="N0" />
                </ChartSeriesItem>
              </ChartSeries>
              <ChartTooltip render={tooltipRender} />
              <ChartLegend visible={false} />
            </Chart>
          </div>);
    }
}

ReactDOM.render(
  <ChartContainer />,
  document.querySelector('my-app')
);
[ {
    "stat": "Impressions ",
    "count": 434823,
    "color": "#0e5a7e"
}, {
    "stat": "Clicks",
    "count": 356854,
    "color": "#166f99"
}, {
    "stat": "Unique Visitors",
    "count": 280022,
    "color": "#2185b4"
}, {
    "stat": "Downloads",
    "count": 190374,
    "color": "#319fd2"
}, {
    "stat": "Purchases",
    "count": 120392,
    "color": "#3eaee2"
} ]

Dynamic Slope and Height

By default, the slope and height of the funnel segments is linear. You can change the rendering of the slope and height based on the value of the specific segment.

import React from 'react';
import ReactDOM from 'react-dom';
import {
  Chart,
  ChartTitle,
  ChartLegend,
  ChartTooltip,
  ChartSeries,
  ChartSeriesItem,
  ChartSeriesLabels
} from '@progress/kendo-react-charts';
import data from './funnel-data.json';

const tooltipRender = (({ point = {} }) => (point.category));
const style = { marginLeft: 5, marginRight: 5 };

class ChartContainer extends React.Component {
    state = { dynamicSlope: false, dynamicHeight: false }
    render() {
        const { dynamicSlope, dynamicHeight } = this.state;

        return (
          <div>
            <div className="example-config">
              <label for="neckRatio">Dynamic Slope
                <input style={style} type="checkbox" checked={dynamicSlope} onChange={(e) => (this.setState({ dynamicSlope: e.target.checked }))} />
              </label>
              <label for="neckRatio">Dynamic Height
                <input style={style} type="checkbox" checked={dynamicHeight} onChange={(e) => (this.setState({ dynamicHeight: e.target.checked }))} />
              </label>
            </div>
            <Chart style={{ margin: '0 auto', width: 300 }} >
              <ChartTitle text="Sales funnel" />
              <ChartSeries>
                <ChartSeriesItem
                  type="funnel"
                  data={data}
                  categoryField="stat"
                  field="count"
                  colorField="color"
                  dynamicSlope={dynamicSlope}
                  dynamicHeight={dynamicHeight}
                >
                  <ChartSeriesLabels color="white" background="none" format="N0" />
                </ChartSeriesItem>
              </ChartSeries>
              <ChartTooltip render={tooltipRender} />
              <ChartLegend visible={false} />
            </Chart>
          </div>);
    }
}


ReactDOM.render(
  <ChartContainer />,
  document.querySelector('my-app')
);
[ {
    "stat": "Impressions ",
    "count": 434823,
    "color": "#0e5a7e"
}, {
    "stat": "Clicks",
    "count": 356854,
    "color": "#166f99"
}, {
    "stat": "Unique Visitors",
    "count": 280022,
    "color": "#2185b4"
}, {
    "stat": "Downloads",
    "count": 190374,
    "color": "#319fd2"
}, {
    "stat": "Purchases",
    "count": 120392,
    "color": "#3eaee2"
} ]

In this article