Scriptable options
Scriptable options are configuration items which can be configured at runtime, based on a callback which is called for each of the underlying data values and that takes a context representing contextual information.
All scriptable options callbacks can accept only 1 argument, the context, which can be different depending on the chart element which is triggering the callback.
Here is an example:
// creates datasets instance from chart
LineDataset dataset = chart.newDataset();
// sets callback for scriptable options
dataset.setBackgroundColor(new ColorCallback<DatasetContext>(){
@Override
public IsColor invoke(DatasetContext context){
return HtmlColor.PINK;
}
});
Options Context
The option context is used to give contextual information when resolving options. It applies to all scriptable options and their callbacks.
The object is preserved, so it can be used to store and pass information between calls.
There are the following different types of context objects, to be consumed on scriptable options on chart elements (plugins excluded):
- chart context used for scriptable options that apply at chart configuration level.
- dataset context used for scriptable options that apply at dataset or data configuration level.
- scale context used for scriptable options that apply at scale or ticks level.
Apart for the options stored by the user in the context (attributes), all other options must be considered as read-only properties.
Chart context
The chart context is used for scriptable options set in the chart configuration and is providing all necessary information about the chart in order to apply own logic.
The context object contains the following properties:
Name | Type | Description |
---|---|---|
chart | IsChart | Chart instance. |
type | ContextType | The type of the context. It can only be ContextType.CHART . |
attributes | NativeObjectContainer | User object which you can store your options at runtime. |
Custom attributes
You can set custom attributes in the context. When the context is persistent, this could be very helpful because can store attributes needed in the logic of the scriptable options.
Name | Type | Description |
---|---|---|
Key instance | boolean - double - int - String | The key could not be the same of the existing context properties and can set custom attributes. |
// creates datasets instance from chart
BarDataset dataset = chart.newDataset();
// sets callback for scriptable options
dataset.setBackgroundColor(new ColorCallback<DatasetContext>(){
private final Key myKey = Key.create("myKey");
@Override
public IsColor invoke(DatasetContext context){
// -------------------------------
// sets and gets boolean attribute
// -------------------------------
context.setAttribute(myKey, true);
boolean myKeyAsBoolean = context.getAttribute(myKey, false);
// -------------------------------
// sets and gets double attribute
// -------------------------------
context.setAttribute(myKey, 0D);
double myKeyAsDouble = context.getAttribute(myKey, Double.NaN);
// -------------------------------
// sets and gets int attribute
// -------------------------------
context.setAttribute(myKey, 1);
double myKeyAsInt = context.getAttribute(myKey, Integer.MIN_VALUE);
// -------------------------------
// sets and gets string attribute
// -------------------------------
context.setAttribute(myKey, "myString");
String myKeyAsString = context.getAttribute(myKey, null);
// logic
}
});
Dataset context
The dataset context is used for data set scriptable options which are providing all necessary information to get the data and data set links in order to apply own logic.
Here is an example:
// creates datasets instance from chart
BarDataset dataset = chart.newDataset();
// sets callback for scriptable options
dataset.setBackgroundColor(new ColorCallback<DatasetContext>(){
@Override
public IsColor invoke(DatasetContext context){
// gets chart from context
IsChart chart = context.getChart();
// gets data by indexes provided by context
Dataset dataset = chart.getData().getDatasets().get(context.getDatasetIndex());
Double value = dataset.getData().get(context.getDataIndex());
// my logic
if (value >= 85D){
return HtmlColor.RED;
} else if (value >= 60D){
return HtmlColor.ORANGE;
}
return HtmlColor.GREEN;
}
});
The context object contains the following properties:
Name | Type | Description |
---|---|---|
active | boolean | Whether the associated element is hovered. |
attributes | NativeObjectContainer | User object which you can store your options at runtime. |
chart | IsChart | Chart instance. |
dataIndex | int | The index of the current data. |
element | ChartElement | The element (point, arc, bar, etc.) for this data |
datasetIndex | int | The index of the current data set. |
datasetItem | DatasetItem | The data set information for this data |
mode | TransitionKey | The update mode, brought by conte |
type | ContextType | The type of the context. It can be ContextType.DATASET or ContextType.DATA . |
The following matrix will report which properties are available based on the context type.
Name | ContextType.DATASET | ContextType.DATA |
---|---|---|
active | Available | Available |
attributes | Available | Available |
chart | Available | Available |
dataIndex | NO | Available |
datasetElement | NO | Available |
datasetIndex | Available | Available |
datasetItem | Available | Available |
mode | Available | Available |
Scale context
The scale context is used for scales and ticks scriptable options which are providing all necessary information to get the scale and ticks links in order to apply own logic.
Here is an example:
// creates an axis
RadialAxis axis = new RadialAxis(chart);
// sets callback for scriptable options
axis.getPointLabels().setColor(new ColorCallback<ScaleContext>(){
@Override
public Object invoke(ScaleContext context){
// my logic
return context.getIndex() % 2 == 0 ? HtmlColor.RED : HtmlColor.BLACK;
}
});
The context object contains the following properties:
Name | Type | Description |
---|---|---|
attributes | NativeObjectContainer | User object which you can store your options at runtime. |
axis | Axis | Axis instance. |
chart | IsChart | Chart instance. |
index | int | The index of the current tick or the label (wfor point labels callback). |
label | String | the label that is shown on the perimeter of the scale. Only for point labels callback. |
scale | ScaleItem | The scale associated to this context. |
tick | ScaleTickItem | The tick associated to this context. |
type | ContextType | The type of the context. It can be ContextType.SCALE , ContextType.TICK or ContextType.POINT_LABEL . |
The following matrix will report which properties are available based on the context type.
Name | ContextType.SCALE | ContextType.TICK | ContextType.POINT_LABEL |
---|---|---|---|
attributes | Available | Available | Available |
axis | Available | Available | Available |
chart | Available | Available | Available |
index | NO | Available | Available |
scale | Available | Available | Available |
tick | NO | Available | NO |
label | NO | NO | Available |
Advanced usage of scriptable options
There are use cases where the scriptable options callbacks are called several hundreds because are related to the amount of data set on datasets of the charts.
When you are in above use case and you need the best performance, you can set a scriptable options by a native java script callback.
A native java script callback is built with java script code in order to be execute directly from Chart.JS.
// creates a callback
// using java script code and default "context" variable name
// for scriptable context
NativeCallback from = NativeCallback.create("return context.index === 0 ? context.chart.scales.y.getPixelForValue(100) : context.chart.getDatasetMeta(context.datasetIndex).data[context.index - 1].getProps(['y'], true).y;");
// creates a callback
// using java script code and my "ctx" variable name
// for scriptable context
NativeCallback loop = NativeCallback.create("ctx", "return ctx.active");
Animations animations = chart.getOptions().getAnimations();
AnimationCollection y = animations.create(DefaultAnimationPropertyKey.Y);
y.setFrom(from);
y.setLoop(loop);