Donut
Basic Configuration
The minimum configuration for the Donut component looks like:
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
import { VisSingleContainer, VisDonut } from '@unovis/react'
function Component(props) {
const data: number[] = props.data
const value = (d: number) => d
return (
<VisSingleContainer data={data}>
<VisDonut value={value}/>
</VisSingleContainer>
)
}
@Component({
templateUrl: 'template.html'
})
export class Component {
@Input data: number[];
value = (d: number) => d
}
<vis-single-container [data]="data">
<vis-donut [value]="value"></vis-donut>
</vis-single-container>
<script lang='ts'>
import { VisSingleContainer, VisDonut } from '@unovis/svelte'
export let data: number[]
const value = (d: number) => d
</script>
<VisSingleContainer {data}>
<VisDonut {value}/>
</VisSingleContainer>
<script setup lang="ts">
import { VisSingleContainer, VisDonut } from '@unovis/vue'
const props = defineProps<{ data: number[] }>()
const value = (d: number) => d
</script>
<template>
<VisSingleContainer :data="data">
<VisDonut :value="value" />
</VisSingleContainer>
</template>
import { VisSingleContainer, VisDonut } from '@unovis/solid'
function Component(props) {
const data: number[] = () => props.data
const value = (d: number) => d
return (
<VisSingleContainer data={data()}>
<VisDonut value={value}/>
</VisSingleContainer>
)
}
import { SingleContainer, Donut } from '@unovis/ts'
import { data } from './data'
const container = new SingleContainer<number>(node, {
component: new Donut<number>({ value: (d: number) => d })
}, data)
Labels
Donut can have a label and a smaller sub-label in the center. You can provide them by using the centralLabel
and
centralSubLabel
config properties. The sub-label will automatically wrap onto multiple lines (unless you set
the centralSubLabelWrap
property to false
), while the main label is supposed to be short and doesn't have wrapping
implemented.
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut
value={value}
centralLabel="Label"
centralSubLabel="Long sub-label wraps onto the next line"
/>
<vis-donut
[value]="value"
centralLabel="Label"
centralSubLabel="Long sub-label wraps onto the next line"
></vis-donut>
<VisDonut
{value}
centralLabel="Label"
centralSubLabel="Long sub-label wraps onto the next line"
/>
<VisDonut
:value="value"
centralLabel="Label"
centralSubLabel="Long sub-label wraps onto the next line"
/>
<VisDonut
value={value}
centralLabel="Label"
centralSubLabel="Long sub-label wraps onto the next line"
/>
const donut = new Donut<number>({
value,
centralLabel: "Label",
centralSubLabel: "Long sub-label wraps onto the next line"
})
Angle Range
By default, a Donut will populate values in the angle range [0, 2π]
. You can adjust your Donut's angleRange
property to a [a,b]
of type [number, number]
where a[0] = the starting position and a[1] = the ending position (in radians). A common example might be when you want an incomplete/semi circle:
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut value={value} angleRange={[1,3.141592653589793]}/>
<vis-donut
[value]="value"
[angleRange]="[1,3.141592653589793]"
></vis-donut>
<VisDonut {value} angleRange={[1,3.141592653589793]}/>
<VisDonut :value="value" :angleRange="[1,3.141592653589793]" />
<VisDonut value={value} angleRange={[1,3.141592653589793]}/>
const donut = new Donut<number>({ value, angleRange: [1,3.141592653589793] })
Sorting
By default, each segment is placed in order of appearance within your data
array, from
To change this, provide a sorting function to the sortFunction
property. The following example displays the segments in descending order:
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
import { VisSingleContainer, VisDonut } from '@unovis/react'
function Component(props) {
const data: number[] = props.data
const value = (d: number) => d
const sortFunction = (a, b) => a - b
return (
<VisSingleContainer data={data}>
<VisDonut value={value} sortFunction={sortFunction}/>
</VisSingleContainer>
)
}
@Component({
templateUrl: 'template.html'
})
export class Component {
@Input data: number[];
value = (d: number) => d
sortFunction = (a, b) => a - b
}
<vis-single-container [data]="data">
<vis-donut [value]="value" [sortFunction]="sortFunction"></vis-donut>
</vis-single-container>
<script lang='ts'>
import { VisSingleContainer, VisDonut } from '@unovis/svelte'
export let data: number[]
const value = (d: number) => d
const sortFunction = (a, b) => a - b
</script>
<VisSingleContainer {data}>
<VisDonut {value} {sortFunction}/>
</VisSingleContainer>
<script setup lang="ts">
import { VisSingleContainer, VisDonut } from '@unovis/vue'
const props = defineProps<{ data: number[] }>()
const value = (d: number) => d
const sortFunction = (a, b) => a - b
</script>
<template>
<VisSingleContainer :data="data">
<VisDonut :value="value" :sortFunction="sortFunction" />
</VisSingleContainer>
</template>
import { VisSingleContainer, VisDonut } from '@unovis/solid'
function Component(props) {
const data: number[] = () => props.data
const value = (d: number) => d
const sortFunction = (a, b) => a - b
return (
<VisSingleContainer data={data()}>
<VisDonut value={value} sortFunction={sortFunction}/>
</VisSingleContainer>
)
}
import { SingleContainer, Donut } from '@unovis/ts'
import { data } from './data'
const container = new SingleContainer<number>(node, {
component: new Donut<number>({
value: (d: number) => d,
sortFunction: (a, b) => a - b
})
}, data)
Size
You can change the size of your Donut with the following properties:
Radius
radius
defines the outer/overall radius:
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut radius={50} value={value}/>
<vis-donut [radius]="50" [value]="value"></vis-donut>
<VisDonut radius={50} {value}/>
<VisDonut :radius="50" :value="value" />
<VisDonut radius={50} value={value}/>
const donut = new Donut<number>({ radius: 50, value })
Arc Width
arcWidth
defines the width of the circle's outer ring in pixels.
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut arcWidth={50} value={value}/>
<vis-donut [arcWidth]="50" [value]="value"></vis-donut>
<VisDonut arcWidth={50} {value}/>
<VisDonut :arcWidth="50" :value="value" />
<VisDonut arcWidth={50} value={value}/>
const donut = new Donut<number>({ arcWidth: 50, value })
For the appearance of a traditional pie chart, set Donut's arcWidth
to 0
.
Segment Appearance
Custom Color
Customize the colors for each segment with a colorAccessor
function:
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
function Component(props) {
const data: number[] = props.data
const value = (d: number) => d
const color = (d: number, i: number) => ['red', 'orange', 'blue', 'green'][i]
return (
<VisDonut value={value} color={color}/>
)
}
@Component({
template: '<vis-donut [value]="value" [color]="color"></vis-donut>'
})
export class Component {
@Input data: number[];
value = (d: number) => d
color = (d: number, i: number) => ['red', 'orange', 'blue', 'green'][i]
}
<script lang='ts'>
import { VisSingleContainer, VisDonut } from '@unovis/svelte'
export let data: number[]
const value = (d: number) => d
const color = (d: number, i: number) => ['red', 'orange', 'blue', 'green'][i]
</script>
<VisDonut {value} {color}/>
<script setup lang="ts">
import { VisSingleContainer, VisDonut } from '@unovis/vue'
const props = defineProps<{ data: number[] }>()
const value = (d: number) => d
const color = (d: number, i: number) => ['red', 'orange', 'blue', 'green'][i]
</script>
<template>
<VisDonut :value="value" :color="color" />
</template>
function Component(props) {
const data: number[] = () => props.data
const value = (d: number) => d
const color = (d: number, i: number) => ['red', 'orange', 'blue', 'green'][i]
return (
<VisDonut value={value} color={color}/>
)
}
const donut = new Donut<number>({
value: (d: number) => d,
color: (d: number, i: number) => ['red', 'orange', 'blue', 'green'][i]
})
Corner Radius
Providing a value to the cornerRadius
property adds rounded corners to your Donut's segments proportional to the Donut's arcWidth
.
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut cornerRadius={5} value={value}/>
<vis-donut [cornerRadius]="5" [value]="value"></vis-donut>
<VisDonut cornerRadius={5} {value}/>
<VisDonut :cornerRadius="5" :value="value" />
<VisDonut cornerRadius={5} value={value}/>
const donut = new Donut<number>({ cornerRadius: 5, value })
Pad angle
Pad each segment with the padAngle
property.
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut value={value} padAngle={0.1}/>
<vis-donut [value]="value" [padAngle]="0.1"></vis-donut>
<VisDonut {value} padAngle={0.1}/>
<VisDonut :value="value" :padAngle="0.1" />
<VisDonut value={value} padAngle={0.1}/>
const donut = new Donut<number>({ value, padAngle: 0.1 })
Empty Segments
When segments are empty (i.e. when their values are 0), you may still want them displayed in your Donut as thin slices.
To do this, set showEmptySegments
to true
:
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut showEmptySegments={true} value={value} padAngle={0.03}/>
<vis-donut
[showEmptySegments]="true"
[value]="value"
[padAngle]="0.03"
></vis-donut>
<VisDonut showEmptySegments={true} {value} padAngle={0.03}/>
<VisDonut :showEmptySegments="true" :value="value" :padAngle="0.03" />
<VisDonut showEmptySegments={true} value={value} padAngle={0.03}/>
const donut = new Donut<number>({ showEmptySegments: true, value, padAngle: 0.03 })
Customizing empty segment size
When showEmptySegments
is enabled, the default size for empty segments is 0.5 * π / 180
radians. You can tweak this to your
liking with the emptySegmentAngle
property which accepts a number
in radians.
For example, setting emptySegmentAngle
to Math.PI / 12
looks like:
Note that this property will have no effect if showEmptySegments
is false
.
Background
By default, Donut has a background underneath the segments, which is useful when your chart is empty. You can turn it off by setting
showBackground
to false
.
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut
showBackground={true}
value={value}
angleRange={[-1.5707963267948966,1.5707963267948966]}
/>
<vis-donut
[showBackground]="true"
[value]="value"
[angleRange]="[-1.5707963267948966,1.5707963267948966]"
></vis-donut>
<VisDonut
showBackground={true}
{value}
angleRange={[-1.5707963267948966,1.5707963267948966]}
/>
<VisDonut
:showBackground="true"
:value="value"
:angleRange="[-1.5707963267948966,1.5707963267948966]"
/>
<VisDonut
showBackground={true}
value={value}
angleRange={[-1.5707963267948966,1.5707963267948966]}
/>
const donut = new Donut<number>({
showBackground: true,
value,
angleRange: [-1.5707963267948966,1.5707963267948966]
})
Also, you can change the angular range of the background by providing a [number, number]
value (in radians) to backgroundAngleRange
.
By default, the background angular range will be the same as angleRange
.
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut
value={value}
showBackground={true}
angleRange={[0,1.0471975511965976]}
backgroundAngleRange={[0,6.283185307179586]}
/>
<vis-donut
[value]="value"
[showBackground]="true"
[angleRange]="[0,1.0471975511965976]"
[backgroundAngleRange]="[0,6.283185307179586]"
></vis-donut>
<VisDonut
{value}
showBackground={true}
angleRange={[0,1.0471975511965976]}
backgroundAngleRange={[0,6.283185307179586]}
/>
<VisDonut
:value="value"
:showBackground="true"
:angleRange="[0,1.0471975511965976]"
:backgroundAngleRange="[0,6.283185307179586]"
/>
<VisDonut
value={value}
showBackground={true}
angleRange={[0,1.0471975511965976]}
backgroundAngleRange={[0,6.283185307179586]}
/>
const donut = new Donut<number>({
value,
showBackground: true,
angleRange: [0,1.0471975511965976],
backgroundAngleRange: [0,6.283185307179586]
})
The color of the background can be changed via the --vis-donut-background-color
and
--vis-dark-donut-background-color
CSS variables.
Events
The following selectors are available for events:
import { Donut } from '@unovis/ts'
...
events = {
[Donut.selectors.segment]: { },
[Donut.selectors.background]: { },
[Donut.selectors.centralLabel]: { },
[Donut.selectors.centralSubLabel]: { },
}
- React
- Angular
- Svelte
- Vue
- Solid
- TypeScript
<VisDonut value={value} events={events}/>
<vis-donut [value]="value" [events]="events"></vis-donut>
<VisDonut {value} {events}/>
<VisDonut :value="value" :events="events" />
<VisDonut value={value} events={events}/>
const donut = new Donut<number>({ value, events })
CSS Variables
All supported CSS variables and their default values
--vis-donut-central-label-font-size: 16px;
--vis-donut-central-label-text-color: #5b5f6d;
--vis-donut-central-label-font-family
--vis-donut-central-label-font-weight: 600;
--vis-donut-central-sub-label-font-size: 12px;
--vis-donut-central-sub-label-text-color: #5b5f6d;
--vis-donut-central-sub-label-font-family
--vis-donut-central-sub-label-font-weight: 500;
--vis-donut-background-color: #E7E9F3;
--vis-dark-donut-central-label-text-color: #C2BECE;
--vis-dark-donut-central-sub-label-text-color: #C2BECE;
--vis-dark-donut-background-color: #18160C;
Component Props
Name | Type | Description |
---|---|---|
* required property |