Writing plugins
What is a plugin
A plugin is a custom class that can change the chart config or data in runtime or it can even modify the displayed chart. It works by providing functions to the chart instance which will be called automatically or manually at certain points in the animation process. Plugins are recommended for custom charts when the available configuration options are not enough.
The functions of the plugin can be hooks which are called automatically at certain points during the rendering, API functions which can be called manually or listeners that are connected to certain (predefined) events.
How to write a plugin
To write a plugin, first import the Plugins
module.
import { type Plugins } from 'vizzu'
Create the plugin class implementing the Plugins.Plugin
interface.
export class ExamplePlugin implements Plugins.Plugin {
}
The class can have a meta
property which provides the basic configuration for
the plugin. It has the following fields:
name
: the name of the pluginversion
: the version of the library the plugin is compatible withdepends
: an array of strings describing other plugins this one depends on
export class ExamplePlugin implements Plugins.Plugin {
meta = {
name: 'examplePlugin',
version: '0.10.1',
depends: []
}
}
The main functionality of the plugin is provided by the hooks
property. Use a
getter function to define the object. There are three plugin hooks which can be
defined in the returned object:
prepareAnimation
: Called when the animate() parameters gets set in the library to prepare the animation.registerAnimation
: Called when the animate() method called, and the lib schedules the call to the animation queue.runAnimation
: Called when all animate() parameter set and animation can be started.
Let’s add a simple function to the prepareAnimation
phase. We’d like to
automatically set the chart title to the name of the data series which is
assigned to the color channel (if any). If no color is selected, then set a
default title.
Adding hooks
export class ExamplePlugin implements Plugins.Plugin {
get hooks(): Plugins.PluginHooks {
return {
prepareAnimation: (ctx: Plugins.PrepareAnimationContext, next: () => void): void => {
const config = ctx.target[0].target.config
if (config.channels.color) {
config.title = Object.values(config.channels.color)[0][0]
this.hasChanged = true
} else {
config.title = 'Example plugin'
}
next()
}
}
}
}
The hooks can also have a priority
number that decides the order the
registered plugins run. It’s a float value, ranging from 0 (last) to 1 (first).
export class ExamplePlugin implements Plugins.Plugin {
get hooks(): Plugins.PluginHooks {
return {
prepareAnimation: Object.assign(
(ctx: Plugins.PrepareAnimationContext, next: () => void): void => {
const config = ctx.target[0].target.config
if (config.channels.color) {
config.title = Object.values(config.channels.color)[0][0]
this.hasChanged = true
} else {
config.title = 'Example plugin'
}
next()
},
{ priority: .9 }
)
}
}
}
Adding API functions
The class can also define an api
property. It can contain one or more
functions which can be called from the original context using
chart.feature.<plugin name>.<function name>()
.
Let’s add an API function to our plugin which can tell if the default title has been changed.
import { type Plugins } from 'vizzu'
interface ExamplePluginApi extends Plugins.PluginApi {
hasDefaultTitle(): boolean
}
export class ExamplePlugin implements Plugins.Plugin {
meta: Plugins.PluginMeta = {
name: 'examplePlugin',
version: '0.10.1',
depends: []
}
private hasChanged: boolean = false
get hooks(): Plugins.PluginHooks {
return {
prepareAnimation: Object.assign(
(ctx: Plugins.PrepareAnimationContext, next: () => void): void => {
const config = ctx.target[0].target.config
if (config.channels.color) {
config.title = Object.values(config.channels.color)[0][0]
this.hasChanged = true
} else {
config.title = 'Example plugin'
}
next()
},
{ priority: .9 }
)
}
}
get api(): ExamplePluginApi {
return {
hasDefaultTitle: (): boolean => {
return !this.hasChanged
}
}
}
}
Listening to events
Define a getter method for the listeners property as follows:
get listeners(): Plugins.PluginListeners {
return {
[Events.EventType.pointerup]: (): void => {
console.log('You clicked on the chart')
}
}
}
The proper functions will be called when the defined event happens in the chart.
How to use plugins
After creating a new Vizzu
instance, enable the plugin using the feature()
method like this:
const chart = new Vizzu('vizzu')
chart.feature(new ExamplePlugin(), true)
The first parameter is a plugin instance, the second one is the enabled status
(true
for enabled and false
for disabled.) If the plugin is enabled, then
the hook functions will be automatically called at the proper animation phases.
The API functions must be called manually using the chart instance. Example:
anim.activated.then(() => {
if (chart.feature.examplePlugin.hasDefaultTitle()) {
console.log(`the title has not been changed`)
} else {
console.log(`the title has been changed`)
}
})
Info
For more information check out our plugins at https://github.com/vizzuhq/vizzu-lib-ext.