I'd like to be able to use scriptable options in the same way I can use indexable options currently and callbacks after #70.
Which charts does this feature request apply to?
All charts
Describe the solution you'd like
When the option is scriptable, I'd like to be able to assign it an IMethodHandler which will resolve the option dynamically.
Implementation draft/idea
When thinking about implementing this, I imagine a generic ScriptableOption<T> class. Along with that there would be a ScriptableOptionCallback<T> delegate which returns T and receives a ScriptableOptionContext (reference).
Then there would be an implicit conversion to T and to IMethodHandler<ScriptableOptionCallback<T>>. These two possibilities are also available as constructors. This way you can either assign a value of type T directly or a JavaScriptHandler / DelegateHandler with the delegate ScriptableOptionCallback<T>.
We'll have to make sure these get serialized correctly so when setting up the chart there would be a lot more IMethodHandler objects to restore. Also there would be a lot more callbacks to resolve on the JavaScript-side.
function getLineColor(ctx) {
return utils.color(ctx.datasetIndex);
}
function alternatePointStyles(ctx) {
var index = ctx.dataIndex;
return index % 2 === 0 ? 'circle' : 'rect';
}
function makeHalfAsOpaque(ctx) {
return utils.transparentize(getLineColor(ctx));
}
function adjustRadiusBasedOnData(ctx) {
var v = ctx.dataset.data[ctx.dataIndex];
return v < 10 ? 5
: v < 25 ? 7
: v < 50 ? 9
: v < 75 ? 11
: 15;
}
var options = {
legend: false,
tooltips: true,
elements: {
line: {
fill: false,
backgroundColor: getLineColor,
borderColor: getLineColor,
},
point: {
backgroundColor: getLineColor,
hoverBackgroundColor: makeHalfAsOpaque,
radius: adjustRadiusBasedOnData,
pointStyle: alternatePointStyles,
hoverRadius: 15,
}
}
};
Describe alternatives you've considered
There's currently not an easy alternative I know of.
Additional context
This can only be done after #70 and can only be released in 2.0 or later.
It's a breaking change because many properties will change type to ScriptableOption. However, the migration for customers should be easy since there has to be an implicit conversion operator anyway just like with IndexableOptions.
This feature means a lot of additional code for setting up the chart. All the IMethodHandlers have to be restored as long as we're still on json.net and all the IMethodHandlers have to be converted to functions in JavaScript. On the JavaScript-side, it would make sense to make it more dynamic. By that I mean you'd have a list of paths that are potentially IMethodHandlers and then we just loop through that list and convert them to methods if there is indeed an IMethodHandler at the given path. Because of #70 which makes all IMethodHandlers equal, this is possible. We could also choose this approach for the C#-side while we're still on json.net but I don't know if that makes sense. Also performance might come into play when implementing that.
For options that are both scriptable and indexable, we should just be able to use ScriptableOption<IndexableOption<string>>.
Those methods receive a scriptable option context which contains a chart field with the entire chart object. This will drain performance a lot because stringifying it on JavaScript-side is expensive and then parsing it on C# side is also expensive. I have not tested it but I can imagine that it wouldn't be usable with DelegateHandler because of the horrible performance. This might make it necessary to extend the IgnoreCallbackValue attribute to allow filtering out specific properties of a callback parameter like for example the chart field of ScriptableOptionContext.
Diving deeper into the callback world, we'll need to make sure that things get deserialized correctly. It'll make sense to do more unit testing around that area.
Just like callbacks with return value, scriptable options could only be supported on client-side blazor. The reasons have been discussed in #90.
Describe the feature request
While indexable options are already supported, there is currently no way to use scriptable options.
I'd like to be able to use scriptable options in the same way I can use indexable options currently and callbacks after #70.
Which charts does this feature request apply to?
All charts
Describe the solution you'd like
When the option is scriptable, I'd like to be able to assign it an
IMethodHandler
which will resolve the option dynamically.Implementation draft/idea
When thinking about implementing this, I imagine a generic
ScriptableOption<T>
class. Along with that there would be aScriptableOptionCallback<T>
delegate which returnsT
and receives aScriptableOptionContext
(reference).Then there would be an implicit conversion to
T
and toIMethodHandler<ScriptableOptionCallback<T>>
. These two possibilities are also available as constructors. This way you can either assign a value of typeT
directly or aJavaScriptHandler
/DelegateHandler
with the delegateScriptableOptionCallback<T>
.We'll have to make sure these get serialized correctly so when setting up the chart there would be a lot more
IMethodHandler
objects to restore. Also there would be a lot more callbacks to resolve on the JavaScript-side.JavaScript equivalent
Here's an example of scriptable options taken from the chart.js scriptable line sample.
Describe alternatives you've considered
There's currently not an easy alternative I know of.
Additional context
ScriptableOption
. However, the migration for customers should be easy since there has to be an implicit conversion operator anyway just like withIndexableOptions
.IMethodHandler
s have to be restored as long as we're still on json.net and all theIMethodHandler
s have to be converted to functions in JavaScript. On the JavaScript-side, it would make sense to make it more dynamic. By that I mean you'd have a list of paths that are potentiallyIMethodHandler
s and then we just loop through that list and convert them to methods if there is indeed anIMethodHandler
at the given path. Because of #70 which makes allIMethodHandler
s equal, this is possible. We could also choose this approach for the C#-side while we're still on json.net but I don't know if that makes sense. Also performance might come into play when implementing that.ScriptableOption<IndexableOption<string>>
.chart
field with the entire chart object. This will drain performance a lot because stringifying it on JavaScript-side is expensive and then parsing it on C# side is also expensive. I have not tested it but I can imagine that it wouldn't be usable withDelegateHandler
because of the horrible performance. This might make it necessary to extend theIgnoreCallbackValue
attribute to allow filtering out specific properties of a callback parameter like for example thechart
field ofScriptableOptionContext
.