Skip to main content

Bullet Legend

Overview

BulletLegend is a stand-alone component that can be used alongside your visualization to label colored data.

Legend Items

BulletLegend requires the items property, an array of items that will be displayed in the legend. Each item has type BulletLegendItemInterface:

interface BulletLegendItemInterface {
name: string | number;
color?: string;
shape?: BulletShape;
inactive?: boolean;
hidden?: boolean;
pointer?: boolean;
}

Note that the only required property, name corresponds to the legend items' label. Here is an example of a basic configuration, where labels is an array of strings:

component.tsx
import { VisBulletLegend } from '@unovis/react'
import { labels } from './data'

function Component(props) {
const items = labels.map(label => ({ name: label }))

return (
<VisBulletLegend items={items}/>
)
}
Loading...

Color

By default, our color palette will be used to color each legend item, but you can provide your own colors in the legend item array.

const colors = ['red', 'blue', 'green']
const items = labels.map((label, i) => ({ name: label, color: colors[i] }))

or manually:

const items = [
{ name: 'A', color: 'red' },
{ name: 'B', color: 'blue' },
{ name: 'C', color: 'green' }
]

Either will produce the following result:

Loading...

Shape

You can specify the shape of individual bullets with the shape property or with the bulletShape component config property. This is useful when you want to have the legend with a line chart or shaped scatter plot.

The supported shapes are apart of the BulletShape enum.

import { BulletShape } from '@unovis/ts'

const items = [
{ name: 'Circle', shape: BulletShape.Circle },
{ name: 'Square', shape: BulletShape.Square },
{ name: 'Triangle', shape: BulletShape.Triangle }
{ name: 'Star', shape: BulletShape.Star }
]
Loading...
All supported shapes:
  • BulletShape.Circle or "circle"
  • BulletShape.Cross or "cross"
  • BulletShape.Diamond or "diamond"
  • BulletShape.Line or "line"
  • BulletShape.Square or "square"
  • BulletShape.Star or "star"
  • BulletShape.Triangle or "triangle"
  • BulletShape.Wye or "wye"

Inactive Items

In some cases you may want to have some legend items look inactive, which reduces the opacity of the bullet. See how the initial legend looks when all of the items are inactive:

const items = labels.map(label => ({ name: label, inactive: true }))
Loading...

Pointer

The pointer property in the BulletLegendItemInterface refers to the cursor CSS property. Note that there is no specified default value unless onLegendItemCilck property is provided, in which case the cursor will be pointer.

Bullet Shapes

You can specify the bullet shapes with bulletShape property. By default, the bullet shape is circle unless an individual item has a configured shape (see Shape section).

You can provide this property with a BulletShape enum value or string. Or a constant value. This might be preferable if you want each shape to be the same. For example:

<VisBulletLegend items={items} bulletShape="line"/>
Loading...

Alteratively, you can provide an accessor function of type:
function (d: BulletLegendItemInterface, i: number): BulletShape | string {}
note

If bulletShape is supplied, it will take precedence over the shape property in the items array.

Label Configuration

Font Size

The label's font size can be changed with a valid font-size CSS string provided to the labelMaxWidth property.

<VisBulletLegend items={items} labelFontSize="x-large"/>
Loading...

Max Width

Limit the label lengths with the labelMaxWidth property, which corresponds to the max-width CSS property. For example,

Loading...

providing labelMaxWidth will trim the contents of the item that exceeds the width.

<VisBulletLegend items={items} labelMaxWidth="50px"/>
Loading...

Custom Class

You can also add any further configuration for your labels by providing labelClassName with your custom css class.

Interactive Legend

You can provide an event listener to onLegendItemClick to create interactive legends for your graph. It accepts a function that has the following signature:

function (item: BulletLegendItemInterface, index: number): void

where the parameters correspond to the clicked item.

One common configuration is when you want to filter a data in your chart based on the "active" legend items. Consider the following StackedBar chart example, where onLegendItemClick updates the yAccessors to return 0 when the corresponding legend item is inactive. Try clicking to see the result:

component.tsx
export function Chart({ data, x, y }): JSX.Element {
const [items, setItems] = useState([
{ name: 'Class A', inactive: false },
{ name: 'Class B', inactive: false },
{ name: 'Class C', inactive: false },
])

const toggleItem = useCallback((item: BulletLegendItemInterface, i: number) => {
const itemsCopy = [...items]
itemsCopy[i].active = !itemsCopy[i].active
setItems(itemsCopy)
}, [items])

return (<>
<VisBulletLegend items={items} onLegendItemClick={toggleItem}/>
<VisXYContainer data={data}>
<VisStackedBar x={x} y={useMemo(() => items.map((item, i) => item.inactive ? 0 : y[i]), [items])}/>
<VisAxis type='y'/>
</VisXYContainer>
</>)
}

Component Props

NameTypeDescription
* required property