Stacked Bar
Basic configuration
The Stacked Bar component has been designed to work together with XY Container. The minimal Stacked Bar configuration looks like:
- React
- Angular
- Svelte
- TypeScript
import { VisXYContainer, VisStackedBar } from '@unovis/react'
function Component(props) {
const data: DataRecord[] = props.data
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
return (
<VisXYContainer data={data}>
<VisStackedBar x={x} y={y}/>
</VisXYContainer>
)
}
@Component({
templateUrl: 'template.html'
})
export class Component {
@Input data: DataRecord[];
x = (d: DataRecord) => d.x
y = (d: DataRecord) => d.y
}
<vis-xy-container [data]="data">
<vis-stacked-bar [x]="x" [y]="y"></vis-stacked-bar>
</vis-xy-container>
<script lang='ts'>
import { VisXYContainer, VisStackedBar } from '@unovis/svelte'
export let data: DataRecord[]
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
</script>
<VisXYContainer {data}>
<VisStackedBar {x} {y}/>
</VisXYContainer>
import { XYContainer, StackedBar } from '@unovis/ts'
import { data, DataRecord } from './data'
const container = new XYContainer<DataRecord>(node, {
components: [
new StackedBar<DataRecord>({
x: (d: DataRecord) => d.x,
y: (d: DataRecord) => d.y
})
]
}, data)
Multiple Stacked Bars
Stacked Bar can accept an array of y accessors to display values as a stack of bars:
- React
- Angular
- Svelte
- TypeScript
import { VisXYContainer, VisStackedBar } from '@unovis/react'
function Component(props) {
const data: DataRecord[] = props.data
const x = (d: DataRecord) => d.x
const y = [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
return (
<VisXYContainer data={data}>
<VisStackedBar x={x} y={y}/>
</VisXYContainer>
)
}
@Component({
templateUrl: 'template.html'
})
export class Component {
@Input data: DataRecord[];
x = (d: DataRecord) => d.x
y = [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
}
<vis-xy-container [data]="data">
<vis-stacked-bar [x]="x" [y]="y"></vis-stacked-bar>
</vis-xy-container>
<script lang='ts'>
import { VisXYContainer, VisStackedBar } from '@unovis/svelte'
export let data: DataRecord[]
const x = (d: DataRecord) => d.x
const y = [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
</script>
<VisXYContainer {data}>
<VisStackedBar {x} {y}/>
</VisXYContainer>
import { XYContainer, StackedBar } from '@unovis/ts'
import { data, DataRecord } from './data'
const container = new XYContainer<DataRecord>(node, {
components: [
new StackedBar<DataRecord>({
x: (d: DataRecord) => d.x,
y: [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
})
]
}, data)
Orientation
Stacked Bar supports horizontal and vertical orientation.
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar orientation="vertical" x={x} y={y}/>
<vis-stacked-bar
orientation="vertical"
[x]="x"
[y]="y"
></vis-stacked-bar>
<VisStackedBar orientation="vertical" {x} {y}/>
const stackedBar = new StackedBar<DataRecord>({ orientation: "vertical", x, y })
Bar Width
By default, the width of the bars is calculated automatically based on their count. But you can also strictly set the bar's width in pixels using the barWidth property:
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar barWidth={5} x={x} y={y}/>
<vis-stacked-bar [barWidth]="5" [x]="x" [y]="y"></vis-stacked-bar>
<VisStackedBar barWidth={5} {x} {y}/>
const stackedBar = new StackedBar<DataRecord>({ barWidth: 5, x, y })
Limiting Dynamic Bar Width
When you don't know the number of bars in advance, and you're relying on automatic bar width calculation, you might want to limit the maximum bar width to prevent the bars from being too wide when there are just a few of them. That can be achieved by setting the barMaxWidth property.
Bar Padding
Another way to control the bar's width is by changing the barPadding property, which specifies how much of the available sector should be empty, in the range of [0,1).
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar barPadding={0.5} x={x} y={y}/>
<vis-stacked-bar [barPadding]="0.5" [x]="x" [y]="y"></vis-stacked-bar>
<VisStackedBar barPadding={0.5} {x} {y}/>
const stackedBar = new StackedBar<DataRecord>({ barPadding: 0.5, x, y })
Bar Height Limit
When you have highly scattered data with very low and high values, the bars corresponding to the lower values can be so small, so they become invisible.
If you want to prevent that you can set the minimum bar height to 1 pixel using the barMinHeight1Px
boolean property.
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar barMinHeight1Px={undefined} x={x} y={y}/>
<vis-stacked-bar
[barMinHeight1Px]="undefined"
[x]="x"
[y]="y"
></vis-stacked-bar>
<VisStackedBar barMinHeight1Px={undefined} {x} {y}/>
const stackedBar = new StackedBar<DataRecord>({ barMinHeight1Px: undefined, x, y })
Dealing With Inconsisent Data
When your data has gaps, it's impossible to do calculate of the bar width automatically. The visualization will still try to do that, but most likely the result will be wrong,
and you'll see wide overlapping bars. However, you can help the calculation by setting your data step implicitly using the dataStep property.
Consider the following example, with data mainly clumped in the domain 0 < x < 1
:
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar x={x} y={y}/>
<vis-stacked-bar [x]="x" [y]="y"></vis-stacked-bar>
<VisStackedBar {x} {y}/>
const stackedBar = new StackedBar<DataRecord>({ x, y })
<VisStackedBar x={x} y={y} dataStep={0.1}/>
<vis-stacked-bar [x]="x" [y]="y" [dataStep]="0.1"></vis-stacked-bar>
<VisStackedBar {x} {y} dataStep={0.1}/>
const stackedBar = new StackedBar<DataRecord>({ x, y, dataStep: 0.1 })
Rounded Corners
You can apply rounded corners to the top bar in your Stacked Bar component using the roundedCorners
property, which accepts
either a number
(in pixels) or boolean
argument.
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar roundedCorners={true} x={x} y={y}/>
<vis-stacked-bar
[roundedCorners]="true"
[x]="x"
[y]="y"
></vis-stacked-bar>
<VisStackedBar roundedCorners={true} {x} {y}/>
const stackedBar = new StackedBar<DataRecord>({ roundedCorners: true, x, y })
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar roundedCorners={5} x={x} y={y}/>
<vis-stacked-bar
[roundedCorners]="5"
[x]="x"
[y]="y"
></vis-stacked-bar>
<VisStackedBar roundedCorners={5} {x} {y}/>
const stackedBar = new StackedBar<DataRecord>({ roundedCorners: 5, x, y })
Bar Color
Set the color of the bar by assigning the color property to a hex string and/or by assigning the color property to a function evaluated per each bar. In this example, each bar's color is assigned based on it's value:
- React
- Angular
- Svelte
- TypeScript
function Component(props) {
const data: DataRecord[] = props.data
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
const color = (d: DataRecord, i: number) => d.y>7?'#FF4F4E':'#1acb9a'
return (
<VisStackedBar x={x} y={y} color={color}/>
)
}
@Component({
template: '<vis-stacked-bar [x]="x" [y]="y" [color]="color"></vis-stacked-bar>'
})
export class Component {
@Input data: DataRecord[];
x = (d: DataRecord) => d.x
y = (d: DataRecord) => d.y
color = (d: DataRecord, i: number) => d.y>7?'#FF4F4E':'#1acb9a'
}
<script lang='ts'>
import { VisXYContainer, VisStackedBar } from '@unovis/svelte'
export let data: DataRecord[]
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
const color = (d: DataRecord, i: number) => d.y>7?'#FF4F4E':'#1acb9a'
</script>
<VisStackedBar {x} {y} {color}/>
const stackedBar = new StackedBar<DataRecord>({
x: (d: DataRecord) => d.x,
y: (d: DataRecord) => d.y,
color: (d: DataRecord, i: number) => d.y>7?'#FF4F4E':'#1acb9a'
})
Ordinal Data
Read our guide about using ordinal/categorical values with XY Components here
Events
import { StackedBar } from '@unovis/ts`
...
events = {
[StackedBar.selectors.bar]: {
click: (d: DataRecord) => {},
...
},
[StackedBar.selectors.barGroup]: {
mouseover: (d: DataRecord[]) => {},
...
},
}
- React
- Angular
- Svelte
- TypeScript
<VisStackedBar x={x} y={y} events={events}/>
<vis-stacked-bar [x]="x" [y]="y" [events]="events"></vis-stacked-bar>
<VisStackedBar {x} {y} {events}/>
const stackedBar = new StackedBar<DataRecord>({ x, y, events })
Additional Styling: CSS Variables
The Stacked Bar component supports additional styling via CSS variables that you can define for your visualization container. For example:
.custom-stacked-bar {
--vis-stacked-bar-stroke-color: #000;
--vis-stacked-bar-stroke-width: 5px;
--vis-stacked-bar-hover-stroke-width: 10px;
--vis-stacked-bar-hover-stroke-color: #8777d9;
}
Supported CSS variables and their default values
--vis-stacked-bar-cursor: default;
--vis-stacked-bar-fill-color: var(--vis-color-main);
--vis-stacked-bar-stroke-color: none;
--vis-stacked-bar-stroke-width: 0px;
--vis-stacked-bar-hover-stroke-width: none;
--vis-stacked-bar-hover-stroke-color: none;
/* Dark Theme */
--vis-dark-stacked-bar-stroke-color: none;
Component Props
Name | Type | Description |
---|---|---|
* required property |