Skip to main content
Default Gray Amethyst

Donut Chart

<mo-donut-chart> | MODonutChart
Since 1.7 stable

Donut chart is a variant of the Pie chart with a blank center that allows for additional information about the data which is usually the total.

<mo-donut-chart title="Donut chart" subtitle="Basic" id="first-example"></mo-donut-chart>

<script>
  const chart = document.querySelector('#first-example');
  const labels = [
    'Main Bearings Feed Engine',
    'Gear Spray System',
    'Gearbox',
    'Pinion and Ring Gear',
    'Main engine',
    'Switcher'
  ];
  const data = [4, 7, 9, 6, 8, 10];
  const datasets = [{ label: 'Component', data: data }];
  chart.labels = labels;
  chart.datasets = datasets;
</script>
import { MODonutChart } from '@metsooutotec/modes-web-components/dist/react';

const labels = [
  'Main Bearings Feed Engine',
  'Gear Spray System',
  'Gearbox',
  'Pinion and Ring Gear',
  'Main engine',
  'Switcher'
];
const data = [4, 7, 9, 6, 8, 10];
const datasets = [{ label: 'Component', data: data }];

const App = () => (
  <MODonutChart datasets={datasets} labels={labels} title="Donut chart" subtitle="Basic"></MODonutChart>
);

Examples

Pie chart

The donut and pie charts are almost the same thing. The difference is in the cutout option, where for the pie it is 0 (no cutout), and for the donut it defaults to 80% (20% thick outer band). Just setting the type to ‘pie’ will automatically make the cutout 0.

<mo-donut-chart type="pie" title="Pie chart" subtitle="Basic" id="pie-chart-example"></mo-donut-chart>

<script>
  const chart = document.querySelector('#pie-chart-example');
  const labels = ['Main Bearings Feed Engine', 'Gear Spray System', 'Gearbox', 'Pinion and Ring Gear'];
  const data = [1, 7, 9, 4];
  const datasets = [{ label: 'Component', data: data }];
  chart.labels = labels;
  chart.datasets = datasets;
</script>
import { MODonutChart } from '@metsooutotec/modes-web-components/dist/react';

const labels = ['Main Bearings Feed Engine', 'Gear Spray System', 'Gearbox', 'Pinion and Ring Gear'];
const data = [1, 7, 9, 4];
const datasets = [{ label: 'Component', data: data }];

const App = () => (
  <MODonutChart datasets={datasets} labels={labels} type="pie" title="Pie chart" subtitle="Basic"></MODonutChart>
);

Multiple datasets

A donut chart can have multiple datasets. Adding more than one dataset will add it inside the existing chart in its own area. The pie can also contain multiple datasets (multi series pie).

<div style="display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap">
  <mo-donut-chart
    style="flex-basis: 45%"
    title="Donut chart"
    subtitle="Multiple datasets"
    id="two-datasets"
  ></mo-donut-chart>
  <mo-donut-chart
    style="flex-basis: 45%"
    type="pie"
    title="Pie chart"
    subtitle="Multiple datasets"
    id="pie-two-datasets"
  ></mo-donut-chart>
</div>

<script>
  const chart = document.querySelector('#two-datasets');
  const pieChart = document.querySelector('#pie-two-datasets');
  const labels = ['Main Bearings Feed Engine', 'Gear Spray System', 'Gearbox', 'Pinion and Ring Gear'];
  const data = [3, 7, 9, 2];
  const data2 = [5, 4, 1, 6];
  const datasets = [
    { label: 'Component', data: data },
    { label: 'Component 2', data: data2 }
  ];
  chart.labels = labels;
  chart.datasets = datasets;
  pieChart.labels = labels;
  pieChart.datasets = datasets;
</script>
import { MODonutChart } from '@metsooutotec/modes-web-components/dist/react';

const labels = ['Main Bearings Feed Engine', 'Gear Spray System', 'Gearbox', 'Pinion and Ring Gear'];
const data = [3, 7, 9, 2];
const data2 = [5, 4, 1, 6];
const datasets = [
  { label: 'Component', data: data },
  { label: 'Component 2', data: data2 }
];

const App = () => (
  <div style="display: flex;">
    <MODonutChart datasets={datasets} labels={labels} title="Donut chart" subtitle="Multiple datasets"></MODonutChart>
    <MODonutChart
      datasets={datasets}
      labels={labels}
      type="pie"
      title="Pie chart"
      subtitle="Multiple datasets"
    ></MODonutChart>
  </div>
);

Text in the middle

The showTotals property will add a text that shows the sum of the data entries in the middle. A unit can also be defined, which will be shown below the total. This example also shows how to add units to the data, which will be shown in the totals section in the middle, and in the tooltip. The unit property is a tuple that takes in the full unit name and the shorthand for it. See code below.

<mo-donut-chart showTotals title="Donut chart" subtitle="With totals" id="show-totals"></mo-donut-chart>

<script>
  const chart = document.querySelector('#show-totals');
  const labels = ['Crushing', 'Filtering', 'Loading'];
  const data = [125, 92, 37];
  const dataUnit = ['Hours', 'h'];
  const datasets = [{ label: 'Component', data: data }];
  chart.labels = labels;
  chart.unit = dataUnit;
  chart.datasets = datasets;
</script>
import { MODonutChart } from '@metsooutotec/modes-web-components/dist/react';

const labels = ['Crushing', 'Filtering', 'Loading'];
const data = [125, 92, 37];
const dataUnit = ['Hours', 'h'];

const datasets = [{ label: 'Component', data: data }];

const App = () => (
  <MODonutChart
    showTotals
    datasets={datasets}
    labels={labels}
    unit={dataUnit}
    title="Donut chart"
    subtitle="With totals"
  ></MODonutChart>
);

Show percentages

Enabling the showPercentages property will render the percentage value of each segment. The label is positioned outside donut charts, and inside pie charts (unless the segment is less than 36 degrees).

<div style="display: flex; justify-content: space-between; flex-wrap: wrap">
  <mo-donut-chart
    showPercentages
    showTotals
    title="Expenses breakdown"
    subtitle="With percentages"
    id="percentages"
  ></mo-donut-chart>
  <mo-donut-chart
    showPercentages
    type="pie"
    title="Expenses breakdown"
    subtitle="With percentages"
    id="percentages-pie"
  ></mo-donut-chart>
</div>

<script>
  const chart = document.querySelector('#percentages');
  const chartPie = document.querySelector('#percentages-pie');
  const labels = ['Salaries', 'Maintenance', 'Equipment', 'Taxes'];
  const data = [11400, 1200, 5600, 3600];
  const dataUnit = ['Dollars', '$'];
  const datasets = [{ label: 'Expenses', data: data }];
  chart.labels = labels;
  chart.unit = dataUnit;
  chart.datasets = datasets;
  chartPie.labels = labels;
  chartPie.unit = dataUnit;
  chartPie.datasets = datasets;
</script>
import { MODonutChart } from '@metsooutotec/modes-web-components/dist/react';

const labels = ['Salaries', 'Maintenance', 'Equipment', 'Taxes'];
const data = [11400, 1200, 5600, 3600];
const dataUnit = ['Dollars', '$'];
const datasets = [{ label: 'Expenses', data: data }];

const App = () => (
  <div style={{ display: 'flex', gap: '1rem' }}>
    <MODonutChart
      showPercentages
      datasets={datasets}
      labels={labels}
      title="Expenses breakdown"
      subtitle="With percentages"
    ></MODonutChart>
    <MODonutChart
      showPercentages
      datasets={datasets}
      labels={labels}
      type="pie"
      title="Expenses breakdown"
      subtitle="With percentages"
    ></MODonutChart>
  </div>
);

Custom legend positioning

The legend can be placed next to the chart using the legendPosition and legendAlignment attributes. See the example below on different permutations.

Top Left Bottom Right Start End
<div style="display: flex; gap: 16px;">
  <mo-select id="pos-select" value="right">
    <mo-option value="top">Top</mo-option>
    <mo-option value="left">Left</mo-option>
    <mo-option value="bottom">Bottom</mo-option>
    <mo-option value="right">Right</mo-option>
  </mo-select>
  <mo-select id="align-select" value="start">
    <mo-option value="start">Start</mo-option>
    <mo-option value="end">End</mo-option>
  </mo-select>
</div>
<mo-divider></mo-divider>
<mo-donut-chart
  showPercentages
  legendPosition="right"
  legendAlignment="start"
  showTotals
  title="Expenses breakdown"
  subtitle="With percentages"
  id="legends"
></mo-donut-chart>

<script>
  const chart = document.querySelector('#legends');
  const posSelect = document.querySelector('#pos-select');
  const alignSelect = document.querySelector('#align-select');
  posSelect.addEventListener('mo-change', e => {
    const newPos = e.target.value;
    chart.legendPosition = newPos;
  });

  alignSelect.addEventListener('mo-change', e => {
    const newAlign = e.target.value;
    chart.legendAlignment = newAlign;
  });
  const labels = ['Salaries', 'Maintenance', 'Equipment', 'Taxes'];
  const data = [11400, 1200, 5600, 3600];
  const dataUnit = ['Dollars', '$'];
  const datasets = [{ label: 'Expenses', data: data }];
  chart.labels = labels;
  chart.unit = dataUnit;
  chart.datasets = datasets;
</script>
import { MODonutChart, MODivider, MOSelect, MOOption } from '@metsooutotec/modes-web-components/dist/react';

const donutChartRef = useRef(null);

const labels = ['Salaries', 'Maintenance', 'Equipment', 'Taxes'];
const data = [11400, 1200, 5600, 3600];
const dataUnit = ['Dollars', '$'];
const datasets = [{ label: 'Expenses', data: data }];

const updatePos = e => {
  donutChartRef.legendPosition = e.target.value;
};

const updateAlign = e => {
  donutChartRef.legendAlignment = e.target.value;
};

const App = () => (
  <>
    <div style={{ display: 'flex', gap: '16px' }}>
      <MOSelect onMoChange={updatePos} value="right">
        <MOOption value="top">Top</MOOption>
        <MOOption value="left">Left</MOOption>
        <MOOption value="bottom">Bottom</MOOption>
        <MOOption value="right">Right</MOOption>
      </MOSelect>
      <MOSelect onMoChange={updateAlign} value="start">
        <MOOption value="start">Start</MOOption>
        <MOOption value="end">End</MOOption>
      </MOSelect>
    </div>
    <MODivider></MODivider>
    <MODonutChart
      datasets={datasets}
      labels={labels}
      unit={unit}
      legendPosition="right"
      legendAlignment="start"
      subtitle="Data from Weather Spark"
      title="Avg. temp. by month"
      ref={donutChartRef}
    ></MODonutChart>
  </>
);

Custom colors

This example shows the option of having custom colors, e.g., to be used as status colors. If the dark mode custom colors are omitted, the chart will use the specified light mode colors for dark mode as well.

<mo-donut-chart type="pie" showPercentages title="Pie chart" subtitle="With custom colors" id="colors"></mo-donut-chart>

<script>
  const chart = document.querySelector('#colors');
  const labels = ['Crushing', 'Filtering', 'Idle', 'Off'];
  const data = [251, 120, 72, 96];
  const colors = ['--mo-color-data-1', '--mo-color-data-2', '--mo-color-secondary-15', '--mo-color-secondary-70'];
  const dataUnit = ['Hours', 'h'];
  const datasets = [{ label: 'Component', data: data }];
  chart.labels = labels;
  chart.customColors = colors;
  chart.unit = dataUnit;
  chart.datasets = datasets;
</script>
import { MODonutChart } from '@metsooutotec/modes-web-components/dist/react';
const labels = ['Crushing', 'Filtering', 'Idle', 'Off'];
const data = [251, 120, 72, 96];
const colors = {
  light: ['#6730BF', '#16A889', '#262626', '#B3B3B3'],
  dark: ['#8B5CD6', '#2BE3BB', '#E6E6E6', '#4D4D4D']
};
const dataUnit = ['Hours', 'h'];
const datasets = [{ label: 'Component', data: data }];

const App = () => (
  <MODonutChart
    showTotals
    datasets={datasets}
    labels={labels}
    unit={dataUnit}
    colors={colors}
    title="Pie chart"
    subtitle="With custom colors"
  ></MODonutChart>
);

Patterns

Like the bar chart, the donut and pie chart offer the option of including patterns in the segments. This can aid users with visual deficiencies, especially color blindness. Enable patterns with the patterns boolean property.

<div style="display: flex;">
  <mo-donut-chart patterns title="Donut chart" subtitle="With patterns" id="with-patterns-donut"></mo-donut-chart>
  <mo-donut-chart
    patterns
    type="pie"
    title="Pie chart"
    subtitle="With patterns"
    id="with-patterns-pie"
  ></mo-donut-chart>
</div>

<script>
  const chart = document.querySelector('#with-patterns-donut');
  const pieChart = document.querySelector('#with-patterns-pie');
  const labels = ['Main Bearings Feed Engine', 'Gear Spray System', 'Gearbox', 'Pinion and Ring Gear'];
  const data = [3, 7, 9, 2];
  const datasets = [{ label: 'Component', data: data }];
  chart.labels = labels;
  chart.datasets = datasets;
  pieChart.labels = labels;
  pieChart.datasets = datasets;
</script>
import { MODonutChart } from '@metsooutotec/modes-web-components/dist/react';

const labels = ['Main Bearings Feed Engine', 'Gear Spray System', 'Gearbox', 'Pinion and Ring Gear'];
const data = [3, 7, 9, 2];
const datasets = [{ label: 'Component', data: data }];

const App = () => (
  <div style="display: flex;">
    <MODonutChart
      patterns
      datasets={datasets}
      labels={labels}
      title="Donut chart"
      subtitle="With patterns"
    ></MODonutChart>
    <MODonutChart
      patterns
      datasets={datasets}
      labels={labels}
      type="pie"
      title="Pie chart"
      subtitle="With patterns"
    ></MODonutChart>
  </div>
);

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Bundler React Script

To import this component using a bundler:

import '@metsooutotec/modes-web-components/dist/components/donut-chart/donut-chart.js';

To import this component as a React component:

import MODonutChart from '@metsooutotec/modes-web-components/dist/react/donut-chart/';

To import this component using a script tag:

<script type="module" src="https://modes-web.metso.com/dist/components/cdn/components/donut-chart/donut-chart.js"></script>

Properties

Name Description Reflects Type Default
canvas Query for the canvas element instantiated in the html template. HTMLCanvasElement -
type Type of chart. ChartType 'doughnut'
chart Reference to the chart itself. Chart -
datasets Datasets for the chart. ChartDataset[] []
labels Labels to show on the x-axis. string[] []
customColors Custom colors for the chart. string[] | undefined undefined
patterns Whether to show patterns on top of the areas. boolean false
showTotals Whether bars should be stacked. boolean false
showPercentages Whether to show percentages on top of the areas. boolean false
percentagePosition Where the percentage labels are labels. Defaults to inside the segments. Applies only to the pie chart. 'inside' | 'outside' 'inside'
percentageAngleLimit The limit in radians under which the percentages are not drawn anymore to prevent overlapping values. number 0.0
title Title to be shown above the chart. string ''
subtitle Subtitle to be shown above the chart, but below title. string ''
legendAlignment Alignment of the legends. 'start' | 'end' 'start'
legendPosition Position of the legends. 'bottom' | 'right' | 'left' | 'top' 'bottom'
unit Measurement unit associated with the data. Tuple with the full name and the shorthand. Full name used in middle text, shorthand in tooltip. [string, string] ['', '']
options Additional options for the chart. ChartOptions {}
customPlugins
custom-plugins
Use this property to add custom plugins to the created chart.js instance Plugin[] []
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Parts

Name Description
base The container wrapping all the different parts of the donut chart.
canvas-div The div containing the canvas element.
canvas The canvas element the chart is rendered in.
legends The custom legends below the chart.

Learn more about customizing CSS parts.