BarChart
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 Chartis 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 dataobject. | 
| children | Any | Required | One or more BarChart.Barcomponents 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 XAxisorYAxis) 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 BarChartcomponent in the underlying chart library. See Recharts.org for more information. | |
| containerProps | Object | Passthrough properties for the ResponsiveContainercomponent 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 CartesianGridcomponent 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 Legendcomponent in the underlying chart library. See Recharts.org for more information. | |
| imageLegendPosition | Object | The position of the chart legend relative to the chart. See imageLegendPositionfor details about the available properties. NOTE:showImageLegendmust be set totruefor these properties to have any effect. | |
| isHorizontal | Boolean | false | When true, the category axis will appear on theYAxis, the value axis will appear on theXAxisand 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 tableLegendPositionfor details about the available properties. | |
| tableLegendWidth | String | 'auto' | Will be set as an inline widthstyle 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 Tooltipcomponent in the underlying chart library. See Recharts.org for more information. | |
| valueAxisProps | Object | Passthrough properties for the value axis (either YAxisorXAxis) 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 aplacementoftoporbottom, 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.
