NUI-Widgets documentation has moved to Storybook hosted on Github Pages.

BarChart

This component is currently in a Beta Release.
Although the component is available and supported, there is a chance there may be breaking changes that are not released as such.
import { BarChart } from '@concur/nui-charts';

Bar charts are charts with rectangular columns proportional to the values they represent - the larger the bar, the bigger the value. Bar charts are used to showcase categories that can only be certain values. Usually, one axis of the chart shows the specific categories being compared and the other axis represents a measured value.

Best Practices

  • Bar Charts are most effective when:
    • Showing change over time (e.g., total spend on advertising & marketing during a particular year)
    • Comparing values of one or many value sets or easily showing the low and high values in the data sets. (e.g., comparison of payment methods used each quarter)
    • Comparing parts of a whole (e.g., the impact of an expense report to the overall budget) — Stacked Bar Chart is especially effective in this case.
    • Understanding distribution of data, outliers, the normal tendency, and the range of information in the values. (e.g., yearly trends in budget and spend year over year)
  • Start the value axis at 0. Starting at a value above zero truncates the bars and doesn’t accurately reflect the full value.
  • Space bars appropriately. The space between bars should be roughly ½ bar width. Consider the the density of data and width of the chart container when determining if spacing is appropriate.
  • Use default colors. Colors have been defined for all bar charts to maintain consistency and appropriate color contrast. If you require additional colors, please talk to Core UI before creating overrides.
  • All bar charts must have a key. A key is linked to the data being graphically displayed in the plot area of the chart. You can choose from 2 types of keys depending on your page. See Keys: Data Table vs Legend for more information about available keys.

Bar Chart Variations

There are 4 variations of bar chart to choose from based on the type of data you are displaying and number of relevant data points, or identifiable elements in a data set represented by one color. For BarChart, each data point will be defined by a BarChart.Bar child component.

Bar charts can be aligned either vertically or horizontally. Vertical orientations are best used for chronological data. Horizontal orientations are best used when charting different categories, especially with long labels.

Simple Bar Charts (Single Data Point)

A Simple Bar Chart is used to represents data involving only one data point.

const data = [
    {year: 2013, meals: 415.00, airfare: 2575.00, hotel: 1245.87, car: 510.99, ent: 879.50},
    {year: 2014, meals: 379.00, airfare: 3225.00, hotel: 945.87, car: 410.99, ent: 313.00},
    {year: 2015, meals: 439.00, airfare: 1789.00, hotel: 1845.87, car: 510.99, ent: 1475.00},
    {year: 2016, meals: 515.00, airfare: 2650.00, hotel: 1245.87, car: 210.99, ent: 773.70}
];

<BarChart
    categoryDataKey='year'
    categoryLabel='Year'
    data={data}
    dataPointLabel='Expense Type'
    hideCategoryAxisLabel
    textNoData='No data'
    title='Spending Summary'
    valueFormatter={formatCurrencyNoDecimal}>
    <BarChart.Bar
        dataKey='meals'
        name='Meals' />
</BarChart>

<BarChart
    categoryDataKey='year'
    categoryLabel='Year'
    data={data}
    dataPointLabel='Expense Type'
    hideCategoryAxisLabel
    isHorizontal
    textNoData='No data'
    title='Spending Summary'
    valueFormatter={formatCurrencyNoDecimal}>
    <BarChart.Bar
        dataKey='meals'
        name='Meals' />
</BarChart>

Grouped Bar Charts (Multiple Data Points)

A Grouped Bar Chart allows you to show information about multiple data points within main categories, whereby individual bars represent each data point.

const data = [
    {year: 2013, meals: 415.00, airfare: 2575.00, hotel: 1245.87, car: 510.99, ent: 879.50},
    {year: 2014, meals: 379.00, airfare: 3225.00, hotel: 945.87, car: 410.99, ent: 313.00},
    {year: 2015, meals: 439.00, airfare: 1789.00, hotel: 1845.87, car: 510.99, ent: 1475.00},
    {year: 2016, meals: 515.00, airfare: 2650.00, hotel: 1245.87, car: 210.99, ent: 773.70}
];

<BarChart
    categoryDataKey='year'
    categoryLabel='Year'
    data={data}
    dataPointLabel='Expense Type'
    hideCategoryAxisLabel
    textNoData='No data'
    title='Spending Summary'
    valueFormatter={formatCurrencyNoDecimal}>
    <BarChart.Bar
        dataKey='airfare'
        name='Airfare' />
    <BarChart.Bar
        dataKey='hotel'
        name='Hotel' />
    <BarChart.Bar
        dataKey='car'
        name='Car Rental' />
</BarChart>

<BarChart
    categoryDataKey='year'
    categoryLabel='Year'
    data={data}
    dataPointLabel='Expense Type'
    hideCategoryAxisLabel
    isHorizontal
    textNoData='No data'
    title='Spending Summary'
    valueFormatter={formatCurrencyNoDecimal}>
    <BarChart.Bar
        dataKey='airfare'
        name='Airfare' />
    <BarChart.Bar
        dataKey='hotel'
        name='Hotel' />
    <BarChart.Bar
        dataKey='car'
        name='Car Rental' />
</BarChart>

Stacked Bar Charts

A Stacked Bar Chart also contains multiple data points and allows you to showcase and compare part-to-whole relationships. To stack the bars, use the stackId property for BarChart.Bar.

const data = [
    {budget: 'Travel Budget', spend: 2500, pending: 600, available: 900}
];

<BarChart
    categoryAxisProps={{
        tickFormatter: () => {
            return '';
        }
    }}
    categoryDataKey='budget'
    categoryLabel='Budget'
    chartProps={{
        barSize: 60
    }}
    data={data}
    dataPointLabel='Status'
    height={250}
    hideCategoryAxisLabel
    textNoData='No data'
    title='Travel Budget'
    valueFormatter={formatCurrencyNoDecimal}
    valueLabel='Amount'>
    <BarChart.Bar
        dataKey='spend'
        name='Spend'
        stackId='a' />
    <BarChart.Bar
        dataKey='pending'
        name='Pending'
        stackId='a' />
    <BarChart.Bar
        dataKey='available'
        name='Available'
        stackId='a' />
</BarChart>

<BarChart
    categoryAxisProps={{
        axisLine: false,
        width: 0
    }}
    categoryDataKey='budget'
    categoryLabel='Travel Budget'
    data={data}
    dataPointLabel='Type'
    height={100}
    hideGrid
    isHorizontal
    textNoData='No data'
    title='Travel Budget'
    valueAxisProps={{
        axisLine: false,
        height: 0,
        tickCount: 0
    }}
    valueFormatter={formatCurrencyNoDecimal}>
    <BarChart.Bar
        dataKey='spend'
        name='Spend'
        stackId='a' />
    <BarChart.Bar
        dataKey='pending'
        name='Pending'
        stackId='a' />
    <BarChart.Bar
        dataKey='available'
        name='Available'
        stackId='a' />
</BarChart>

Segmented Bar Charts

Segmented Bar Charts are a type of stacked bar chart where each bar shows 100% of the discrete value. Segmented bar charts work especially well instead of pie charts or donut charts when communicating percentage distribution of categories rather than total value.

Keys: Data Table vs Legend

Data Table

By default, a Data Table is automatically generated in conjunction with the chart. While visually similar to a traditional legend, the data table provides colorblind users and users of screen readers with crucial content and data that they may not be able to gain from the chart itself. (See Accessibility for more details.)

The data table can be positioned in different locations relative to the chart. Use the tableLegendPosition property to set the position.

const dataExpenses = [
    {year: 2013, meals: 415.00, airfare: 2575.00, hotel: 1245.87, car: 510.99, ent: 879.50},
    {year: 2014, meals: 379.00, airfare: 3225.00, hotel: 945.87, car: 410.99, ent: 313.00},
    {year: 2015, meals: 439.00, airfare: 1789.00, hotel: 1845.87, car: 510.99, ent: 1475.00},
    {year: 2016, meals: 515.00, airfare: 2650.00, hotel: 1245.87, car: 210.99, ent: 773.70}
];

const dataBudget = [
    {budget: 'Travel Budget', spend: 2500, pending: 600, available: 900}
];

<BarChart
    categoryDataKey='year'
    categoryLabel='Year'
    data={dataExpenses.slice(0, 1)}
    dataPointLabel='Expense Category'
    height={200}
    hideCategoryAxisLabel
    hideValueAxisLabel
    tableLegendPosition={{
        placement: 'right',
        justify: 'center'
    }}
    textNoData='No data'
    title='Expenses'
    valueFormatter={formatCurrencyNoDecimal}
    valueLabel='Amount'>
    <BarChart.Bar
        dataKey='airfare'
        name='Air' />
    <BarChart.Bar
        dataKey='hotel'
        name='Hotel' />
    <BarChart.Bar
        dataKey='car'
        name='Car' />
</BarChart>

<BarChart
    categoryAxisProps={{
        axisLine: false,
        width: 0
    }}
    categoryDataKey='budget'
    categoryLabel='Budget'
    data={dataBudget}
    dataPointLabel='Status'
    gridProps={{
        vertical: false
    }}
    height={75}
    hideCategoryAxisLabel
    hideValueAxisLabel
    isHorizontal
    tableLegendPosition={{
        placement: 'top',
        justify: 'center'
    }}
    textNoData='No data'
    title='Travel Budget'
    valueAxisProps={{
        axisLine: false,
        height: 0,
        tickCount: 0
    }}
    valueFormatter={formatCurrencyNoDecimal}
    valueLabel='Amount'>
    <BarChart.Bar
        dataKey='spend'
        name='Spend'
        stackId='a' />,
    <BarChart.Bar
        dataKey='pending'
        name='Pending'
        stackId='a' />,
    <BarChart.Bar
        dataKey='available'
        name='Available'
        stackId='a' />
</BarChart>

<BarChart
    categoryDataKey='year'
    categoryLabel='Year'
    data={dataExpenses.slice(2, 4)}
    dataPointLabel='Expense Category'
    height={200}
    hideCategoryAxisLabel
    hideValueAxisLabel
    tableLegendPosition={{
        placement: 'left',
        justify: 'start'
    }}
    textNoData='No data'
    title='Expenses'
    valueFormatter={formatCurrencyNoDecimal}
    valueLabel='Amount'>
    <BarChart.Bar
        dataKey='airfare'
        name='Air' />,
    <BarChart.Bar
        dataKey='hotel'
        name='Hotel' />
</BarChart>

Legend

If there is already a data table on the page, or if you intend to display a data table when a user clicks a trigger (link), you may use the traditional Legend that only displays category labels and associated colors.

The traditional legend can also be positioned in different locations relative to the chart. Use the imageLegendPosition property to set the position.

Customizations

NUI Charts is intended to give consumers a simple, easy-to-use API for generating default charts. However, there are a number of customizations that consumers can use to access the full capability of the underlying chart library.

The example below shows a number of customizations:

  • Showing the chart’s legend (Not the data table. See Keys: Data Table vs Legend for the difference) with custom positioning and icon shapes
  • Bar sizes (widths) and space between bars
  • Horizontal and vertical dashed grid lines
  • Showing the tooltip with custom styling
  • Using a separate data table in place of the auto-generated companion data table

See Recharts.org for more information about customizations.

const dataExpenses = [
    {year: 2013, airfare: 2575.00, hotel: 1245.87, car: 510.99, total: 4331.86},
    {year: 2014, airfare: 3225.00, hotel: 945.87, car: 410.99, total: 4581.86},
    {year: 2015, airfare: 1789.00, hotel: 1845.87, car: 510.99, total: 4145.86},
    {year: 2016, airfare: 2650.00, hotel: 1245.87, car: 210.99, total: 4106.86}
];

<BarChart
    categoryDataKey='year'
    categoryLabel='Year'
    chartProps={{
        barGap: 5,
        barSize: 15
    }}
    data={dataExpenses}
    dataPointLabel='Expense Type'
    gridProps={{
        horizontal: true,
        vertical: true,
        strokeDasharray: '3'
    }}
    hideCategoryAxisLabel
    imageLegendPosition={{
        verticalAlign: 'bottom',
        align: 'center'
    }}
    imageLegendProps={{
        iconType: 'triangle',
        layout: 'horizontal'
    }}
    showImageLegend
    showTooltip
    tableLegendExternalId='custom-table'
    textNoData='No data'
    title='Spending Summary'
    tooltipProps={{
        separator: ' = ',
        wrapperStyle: {
            backgroundColor: '#333',
            borderRadius: '4px'
        },
        labelStyle: {
            color: '#ccc',
            fontSize: '18px',
            fontWeight: 'bold'
        },
        itemStyle: {
            color: '#fff'
        }
    }}
    valueFormatter={formatCurrencyNoDecimal}>
    <BarChart.Bar
        dataKey='airfare'
        name='Airfare' />
    <BarChart.Bar
        dataKey='hotel'
        name='Hotel' />
    <BarChart.Bar
        dataKey='car'
        name='Car Rental' />
</BarChart>

<DataGrid
    columns={[
        {propertyName: 'year', headerContent: 'Year'},
        {propertyName: 'airfare', align: 'right', headerContent: 'Airfare', bodyContent: (row) => {
            return formatCurrencyNoDecimal(row.airfare);
        }},
        {propertyName: 'hotel', align: 'right', headerContent: 'Hotel', bodyContent: (row) => {
            return formatCurrencyNoDecimal(row.hotel);
        }},
        {propertyName: 'car', align: 'right', headerContent: 'Car Rental', bodyContent: (row) => {
            return formatCurrencyNoDecimal(row.car);
        }},
        {propertyName: 'total', align: 'right', headerContent: 'Total', bodyContent: (row) => {
            return formatCurrencyNoDecimal(row.total);
        }}
    ]}
    data={dataExpenses}
    empty={{
        title: 'No data'
    }}
    id='custom-table' />

Usage

BarChart

Properties

Property Type Default Description
categoryDataKey String Required Name of the category data element in the data object.
children Any Required One or more BarChart.Bar components to be rendered in the chart.
data Array Required Source data for the chart and associated data table.
textNoData String Required Localized text for the associated data table if no data exists.
title String Required The title of the chart. Will be offscreen, but still read by screen readers.
categoryAxisProps Object   Passthrough properties for the category axis (either XAxis or YAxis) in the underlying chart library. See Recharts.org for more information.
categoryLabel String   Localized text label for the category axis.
chartProps Object   Passthrough properties for the BarChart component in the underlying chart library. See Recharts.org for more information.
containerProps Object   Passthrough properties for the ResponsiveContainer component in the underlying chart library. See Recharts.org for more information.
dataPointLabel String   Localized text label for the collection of data points (bars).
gridProps Object   Passthrough properties for the CartesianGrid component in the underlying chart library. See Recharts.org for more information.
height Number 300 Height of the chart container (in pixels).
hideCategoryAxisLabel Boolean false When true, the text label for the category axis will not appear.
hideGrid Boolean false When true, the grid lines on the chart will not appear.
hideValueAxisLabel Boolean false When true, the text label for the value axis will not appear.
imageLegendProps Object   Passthrough properties for the Legend component in the underlying chart library. See Recharts.org for more information.
imageLegendPosition Object   The position of the chart legend relative to the chart. See imageLegendPosition for details about the available properties. NOTE: showImageLegend must be set to true for these properties to have any effect.
isHorizontal Boolean false When true, the category axis will appear on the YAxis, the value axis will appear on the XAxis and bars will be drawn horizontally.
showImageLegend Boolean false When true, the chart legend will be drawn. NOTE: The chart legend itself is not accessible so it is typically only used when the associated table data is either in a linked table or is not immediately visible.
showTooltip Boolean false When true, the chart tooltip feature will be enabled. NOTE: The chart tooltip is not accessible so it is only used to augment functionality for users without sight or motor skill impairments.
tableLegendExternalId String   The DOM ID of a data table on the page that contains the data found in the chart. Setting this property will not render the companion data table, but rather link the chart to the table with this ID.
tableLegendPosition Object   The position of the companion data table relative to the chart. See tableLegendPosition for details about the available properties.
tableLegendWidth String 'auto' Will be set as an inline width style on the companion data table. Make sure to include the unit with any value (e.g. ‘400px’ or ‘100%’).
tooltipProps Object   Passthrough properties for the Tooltip component in the underlying chart library. See Recharts.org for more information.
valueAxisProps Object   Passthrough properties for the value axis (either YAxis or XAxis) in the underlying chart library. See Recharts.org for more information.
valueLabel String   Localized text label for the value axis.

Callbacks

Property Parameters Description
valueFormatter value (Number) Function to format values on the value axis, the companion data table and the tooltip, if used.

Shape: tableLegendPosition

Properties
Property Type Default Description
justify String 'center' Justification of the table within the data table container. Available values are 'start', 'center', 'end'. If using a placement of top or bottom, these values will go from left to right, otherwise they will go from top to bottom.
placement String 'bottom' Placement of the data table container relative to the chart. Available values are 'top', 'bottom', 'left', 'right'.

Shape: imageLegendPosition

Properties
Property Type Default Description
align String 'right' Horizontal alignment of the legend relative to the chart. Available values are 'left', 'center', 'right'.
verticalAlign String 'top' Vertical alignment of the legend relative to the chart. Available values are 'top', 'middle', 'bottom'.

BarChart.Bar

Properties

See Recharts.org for more information.

Accessibility

Consumers of bar charts must:

  • Provide a relevant title for all charts and graphs
  • Utilize the default data table to ensure that all non-text content that is presented to the user has a text alternative that serves the equivalent purpose

By default, CoreUI components help assistive technology read a bar chart’s content by building the following into the default component:

  • When utilizing charts and graphs, keep in mind that all non-text content that is presented to the user has a text alternative that serves the equivalent purpose. Additionally, tables of data must not be turned into images. Utilize the default data table to ensure this guideline is met.
  • Colors are provided to ensure that color not only meets proper color contrast requirements, but that they aren’t used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.

Resources