Bar chart Since 0.3.0
Series arranged in categories but with data displayed as bars.
Our bar chart component currently renders horizontal bar charts. By limiting to horizontal bars it reduces some of the issues of label sizes and allows us to expand the chart vertically - it would be harder to expand horizontally without shrinking the size of the bars/labels. Javascript adds tooltips and can make legend items interactive. Hovering over a series in a legend will fade the other series and shift the highlighted series to the left to allow easier comparison.Usage
To use this component in a Nunjucks template you would add the following (assumes you've loaded OI Lume Viz into componentNamespace: 'oi'
):
{% comp 'oi.chart.bar', { "config": config } %}{% endcomp %}
where config
is replaced by an object that contains some or all of these variables:
data
- Either a reference to a CSV file in the Lume site or an array of rows with named attributescolumns
- As with many of the visualisation types you can optionally add virtual columns.colours
- Define some visualisation-specific named colours.width
- Set a specific width for the visualisation.height
- Set a specific height for the visualisation.axis
- Define thex
(horizontal) axis.legend
- Define the legend.category
- The title of the column that contains the categories (vertical groups).series
- An ordered array of series. Each one is of the form:title
- The display name of the series.value
- The title of the column to use for the value of the bar.colour
- The hex code to use to colour this series.tooltip
- Either a string, template string, or the column heading to use to build a tooltip.
gap
- Add spacing between the bars as a fraction of the bar width. The default is 0.stacked
- (boolean) This lets us stack the series within each category. The default is false.percent
- (boolean) Used withstacked
to build 100% width stacked bar charts. This creates virtual columns in your data with the same name as the original columns but with_percent
appended. Note that the normalised columns will be created before any virtual columns that you have created. The default is false.attribution
- Add a line of attribution text under the visualisation.
Examples
- One series - minimal config with auto scaling and auto-ticks
- One series - defined scaling and ticks
- Two series - customised tooltips
- Multi series - customised colours
- Stacked bar chart - auto scaling
- Stacked bar chart - defined scaling
- Stacked bar chart - 100% chart
- Data object
1. One series - minimal config with auto scaling and auto-ticks§
If you have regularly updated "live" data you may not know the scale that will be needed for the values in advance. In that case you can set a axis → x → tick → spacing
and let the chart calculate an automatic range and tick marks.
This example was made with config
:
data:
- category: First category
series1: 20
- category: Second category
series1: 10
- category: Third category
series1: 43
- category: Fourth category
series1: 15
category: category
series:
- title: Series One
value: series1
axis:
x:
tick:
spacing: 7.5
{
"data": [{
"category": "First category",
"series1": 20
},{
"category": "Second category",
"series1": 10
},{
"category": "Third category",
"series1": 43
},{
"category": "Fourth category",
"series1": 15
}],
"category": "category",
"series": [{
"title": "Series One",
"value": "series1"
}],
"axis": {
"x": {
"tick": {
"spacing": 7.5
}
}
}
}
2. One series - defined scaling and ticks§
A simple one series bar chart showing four categories. The x-axis (value) can use a customised axis → x → min
/axis → x → max
and you can specify which tick marks are shown and what their labels are using axis → x → ticks
. This gives the flexibility of very customised labels or no labels for ticks.
This example was made with config
:
data:
- category: First category
series1: 20
- category: Second category
series1: 10
- category: Third category
series1: 45
- category: Fourth category
series1: 15
legend:
show: true
position: top
axis:
x:
min: 0
max: 60
grid:
stroke-dasharray: 6 2
stroke-width: 1
ticks:
- value: 10
label: 10%
- value: 20
label: 20%
- value: 30
label: 30%
- value: 40
label: 40%
- value: 50
label: 50%
'y':
grid:
stroke-width: 0.5
category: category
series:
- title: Series One
value: series1
{
"data": [{
"category": "First category",
"series1": 20
},{
"category": "Second category",
"series1": 10
},{
"category": "Third category",
"series1": 45
},{
"category": "Fourth category",
"series1": 15
}],
"legend": {
"show": true,
"position": "top"
},
"axis": {
"x": {
"min": 0,
"max": 60,
"grid": {
"stroke-dasharray": "6 2",
"stroke-width": 1
},
"ticks": [{
"value": 10,
"label": "10%"
},{
"value": 20,
"label": "20%"
},{
"value": 30,
"label": "30%"
},{
"value": 40,
"label": "40%"
},{
"value": 50,
"label": "50%"
}]
},
"y": {
"grid": {
"stroke-width": 0.5
}
}
},
"category": "category",
"series": [{
"title": "Series One",
"value": "series1"
}]
}
3. Two series - customised tooltips§
Add two series to a horizontal bar chart. Each series gets its own colour. Javascript is used to make the legend interactive (hovering over a series will highlight that series). We can set a tooltip
for each series which can either refer to a specific column/virtual column in the data or be a string template.
This example was made with config
:
data:
- Ethnic group: Ethnic Group A
Aspect 1 (%): 34
Aspect 2 (%): 23
- Ethnic group: Ethnic Group B
Aspect 1 (%): 45
Aspect 2 (%): 35
- Ethnic group: Ethnic Group C
Aspect 1 (%): 36
Aspect 2 (%): 10
legend:
show: true
position: top
axis:
x:
min: 15
max: 58
grid:
stroke-dasharray: 6 2
stroke-width: 1
ticks:
- value: 20
label: 20%
- value: 30
label: 30%
- value: 40
label: 40%
- value: 50
label: 50%
'y':
grid:
stroke-width: 0.5
category: Ethnic group
series:
- title: Aspect 1
value: Aspect 1 (%)
tooltip: 'Aspect 1<br />{{ Ethnic group}}: {{ Aspect 1 (%) }}%'
- title: Aspect 2
value: Aspect 2 (%)
tooltip: 'Aspect 2<br />{{ Ethnic group}}: {{ Aspect 2 (%) }}%'
{
"data": [{
"Ethnic group": "Ethnic Group A",
"Aspect 1 (%)": 34,
"Aspect 2 (%)": 23
},{
"Ethnic group": "Ethnic Group B",
"Aspect 1 (%)": 45,
"Aspect 2 (%)": 35
},{
"Ethnic group": "Ethnic Group C",
"Aspect 1 (%)": 36,
"Aspect 2 (%)": 10
}],
"legend": {
"show": true,
"position": "top"
},
"axis": {
"x": {
"min": 15,
"max": 58,
"grid": {
"stroke-dasharray": "6 2",
"stroke-width": 1
},
"ticks": [{
"value": 20,
"label": "20%"
},{
"value": 30,
"label": "30%"
},{
"value": 40,
"label": "40%"
},{
"value": 50,
"label": "50%"
}]
},
"y": {
"grid": {
"stroke-width": 0.5
}
}
},
"category": "Ethnic group",
"series": [{
"title": "Aspect 1",
"value": "Aspect 1 (%)",
"tooltip": "Aspect 1<br />{{ Ethnic group}}: {{ Aspect 1 (%) }}%"
},{
"title": "Aspect 2",
"value": "Aspect 2 (%)",
"tooltip": "Aspect 2<br />{{ Ethnic group}}: {{ Aspect 2 (%) }}%"
}]
}
4. Multi series - customised colours§
Add spacing between series' bars as a fraction of the bar width. Explicitly set the colours of each series (as either a hex colour, an RGB colour or a named CSS colour).
This example was made with config
:
data:
- Reason: Reason 1
School: 10
College: 15
University: 20
- Reason: Reason 2
School: 10
College: 15
University: 20
- Reason: Reason 3
School: 10
College: 15
University: 20
summary: Employers were not asked separately about each type of placement
legend:
show: true
position: top
axis:
x:
min: 0
max: 60
grid:
stroke-dasharray: 6 2
stroke-width: 1
ticks:
- value: 10
label: 10%
- value: 20
label: 20%
- value: 30
label: 30%
- value: 40
label: 40%
- value: 50
label: 50%
'y':
grid:
stroke-width: 0.5
gap: 0.2
category: Reason
series:
- title: School
value: School
colour: '#E52E36'
tooltip: '{{ Reason }}<br />School: {{ School }}%'
- title: College
value: College
colour: '#F7AB3D'
tooltip: '{{ Reason }}<br />College: {{ College }}%'
- title: University
value: University
colour: '#69C2C9'
tooltip: '{{ Reason }}<br />University: {{ University }}%'
{
"data": [{
"Reason": "Reason 1",
"School": 10,
"College": 15,
"University": 20
},{
"Reason": "Reason 2",
"School": 10,
"College": 15,
"University": 20
},{
"Reason": "Reason 3",
"School": 10,
"College": 15,
"University": 20
}],
"summary": "Employers were not asked separately about each type of placement",
"legend": {
"show": true,
"position": "top"
},
"axis": {
"x": {
"min": 0,
"max": 60,
"grid": {
"stroke-dasharray": "6 2",
"stroke-width": 1
},
"ticks": [{
"value": 10,
"label": "10%"
},{
"value": 20,
"label": "20%"
},{
"value": 30,
"label": "30%"
},{
"value": 40,
"label": "40%"
},{
"value": 50,
"label": "50%"
}]
},
"y": {
"grid": {
"stroke-width": 0.5
}
}
},
"gap": 0.2,
"category": "Reason",
"series": [{
"title": "School",
"value": "School",
"colour": "#E52E36",
"tooltip": "{{ Reason }}<br />School: {{ School }}%"
},{
"title": "College",
"value": "College",
"colour": "#F7AB3D",
"tooltip": "{{ Reason }}<br />College: {{ College }}%"
},{
"title": "University",
"value": "University",
"colour": "#69C2C9",
"tooltip": "{{ Reason }}<br />University: {{ University }}%"
}]
}
5. Stacked bar chart - auto scaling§
Rather than side-by-side bars, sometimes we need to stack bars. As stacked-bar charts don't do a good job of allowing you to compare any series other than the first, we use Javascript to make the legend interactive; hovering over a series will shift this series to the left of the chart to make comparison across categories easier.
This example was made with config
:
colours:
test: '#999000'
data:
- Year: 2018
u19: 150
19-24: 15
25+: 20
- Year: 2019
u19: 190
19-24: 35
25+: 45
- Year: 2020
u19: 300
19-24: 65
25+: 55
stacked: true
legend:
show: true
position: top
axis:
x:
grid:
stroke-dasharray: 6 2
stroke-width: 1
tick:
spacing: 100
'y':
grid:
stroke-width: 0.5
category: Year
series:
- title: Under 19
value: u19
colour: '#69C2C9'
- title: 19-24
value: 19-24
colour: '#7D2248'
- title: 25+
value: 25+
colour: '#4A783C'
{
"colours": {
"test": "#999000"
},
"data": [{
"Year": 2018,
"u19": 150,
"19-24": 15,
"25+": 20
},{
"Year": 2019,
"u19": 190,
"19-24": 35,
"25+": 45
},{
"Year": 2020,
"u19": 300,
"19-24": 65,
"25+": 55
}],
"stacked": true,
"legend": {
"show": true,
"position": "top"
},
"axis": {
"x": {
"grid": {
"stroke-dasharray": "6 2",
"stroke-width": 1
},
"tick": {
"spacing": 100
}
},
"y": {
"grid": {
"stroke-width": 0.5
}
}
},
"category": "Year",
"series": [{
"title": "Under 19",
"value": "u19",
"colour": "#69C2C9"
},{
"title": "19-24",
"value": "19-24",
"colour": "#7D2248"
},{
"title": "25+",
"value": "25+",
"colour": "#4A783C"
}]
}
6. Stacked bar chart - defined scaling§
As for the previous example but we'll explicitly define the axis → x
.
This example was made with config
:
data:
- Year: 2018
u19: 150
19-24: 15
25+: 20
- Year: 2019
u19: 190
19-24: 35
25+: 45
- Year: 2020
u19: 300
19-24: 65
25+: 55
stacked: true
legend:
show: true
position: top
axis:
x:
min: 0
max: 600
grid:
stroke-dasharray: 6 2
stroke-width: 1
ticks:
- value: 100
label: '100'
- value: 200
label: '200'
- value: 300
label: '300'
- value: 400
label: '400'
- value: 500
label: '500'
- value: 600
label: '600'
'y':
grid:
stroke-width: 0.5
category: Year
series:
- title: Under 19
value: u19
colour: '#69C2C9'
- title: 19-24
value: 19-24
colour: '#7D2248'
- title: 25+
value: 25+
colour: '#4A783C'
{
"data": [{
"Year": 2018,
"u19": 150,
"19-24": 15,
"25+": 20
},{
"Year": 2019,
"u19": 190,
"19-24": 35,
"25+": 45
},{
"Year": 2020,
"u19": 300,
"19-24": 65,
"25+": 55
}],
"stacked": true,
"legend": {
"show": true,
"position": "top"
},
"axis": {
"x": {
"min": 0,
"max": 600,
"grid": {
"stroke-dasharray": "6 2",
"stroke-width": 1
},
"ticks": [{
"value": 100,
"label": "100"
},{
"value": 200,
"label": "200"
},{
"value": 300,
"label": "300"
},{
"value": 400,
"label": "400"
},{
"value": 500,
"label": "500"
},{
"value": 600,
"label": "600"
}]
},
"y": {
"grid": {
"stroke-width": 0.5
}
}
},
"category": "Year",
"series": [{
"title": "Under 19",
"value": "u19",
"colour": "#69C2C9"
},{
"title": "19-24",
"value": "19-24",
"colour": "#7D2248"
},{
"title": "25+",
"value": "25+",
"colour": "#4A783C"
}]
}
7. Stacked bar chart - 100% chart§
Sometimes you want to show a part-to-whole relationship for each category i.e. you want the cumulative category bar to take up 100% of the chart width. This lets you see the relative contributions of each series to a category.
One way to do this would be to create new columns in your data - one for each series - that contain the percentage contribution of that series' value to the total for the category. If you don't have the ability to control the input data file we can create those columns for you with the percent: true
option. This will create a new virtual column of data for each series. These new columns will have the same name as the original columns but with _percent
appended. This lets you refer to the original values and the normalised values in any tooltips that you create. Note that the normalised columns will be created before any virtual columns that you have created.
In this example we will define the tooltip of the final series (25+
) so that you can see how you would be able to include both the percentage and original values. The tooltips for the first two series are auto-generated.
This example was made with config
:
data:
- Year: 2018
u19: 150
19-24: 15
25+: 20
- Year: 2019
u19: 190
19-24: 35
25+: 45
- Year: 2020
u19: 300
19-24: 65
25+: 55
stacked: true
percent: true
legend:
show: true
position: top
axis:
x:
grid:
stroke-dasharray: 6 2
stroke-width: 1
ticks:
- value: 20
label: '20'
- value: 40
label: '40'
- value: 60
label: '60'
- value: 80
label: '80'
- value: 100
label: '100'
'y':
grid:
stroke-width: 0.5
category: Year
series:
- title: Under 19
value: u19
colour: '#69C2C9'
- title: 19-24
value: 19-24
colour: '#7D2248'
- title: 25+
value: 25+
tooltip: |
25+
{{ Year }}: {{ 25+_percent | toFixed(1) }}% ({{ 25+ }})
colour: '#4A783C'
{
"data": [{
"Year": 2018,
"u19": 150,
"19-24": 15,
"25+": 20
},{
"Year": 2019,
"u19": 190,
"19-24": 35,
"25+": 45
},{
"Year": 2020,
"u19": 300,
"19-24": 65,
"25+": 55
}],
"stacked": true,
"percent": true,
"legend": {
"show": true,
"position": "top"
},
"axis": {
"x": {
"grid": {
"stroke-dasharray": "6 2",
"stroke-width": 1
},
"ticks": [{
"value": 20,
"label": "20"
},{
"value": 40,
"label": "40"
},{
"value": 60,
"label": "60"
},{
"value": 80,
"label": "80"
},{
"value": 100,
"label": "100"
}]
},
"y": {
"grid": {
"stroke-width": 0.5
}
}
},
"category": "Year",
"series": [{
"title": "Under 19",
"value": "u19",
"colour": "#69C2C9"
},{
"title": "19-24",
"value": "19-24",
"colour": "#7D2248"
},{
"title": "25+",
"value": "25+",
"tooltip": "25+\n{{ Year }}: {{ 25+_percent | toFixed(1) }}% ({{ 25+ }})\n",
"colour": "#4A783C"
}]
}
8. Data object§
Get the data for the bar chart from an object
This example was made with config
:
data: test.data.bar
category: category
series:
- title: Test values
value: value
stacked: false
legend:
show: true
position: top
axis:
x:
tick:
spacing: 10
'y':
grid:
stroke-width: 0.5
{
"data": "test.data.bar",
"category": "category",
"series": [{
"title": "Test values",
"value": "value"
}],
"stacked": false,
"legend": {
"show": true,
"position": "top"
},
"axis": {
"x": {
"tick": {
"spacing": 10
}
},
"y": {
"grid": {
"stroke-width": 0.5
}
}
}
}