I've been playing with the new v4 version with custom charts for a project, and I found that #raw_options array is marged in a way that options cannot be overriden. For exemple, Im trying to pass 'isStacked': true to Google chart.
'#type' => 'chart',
'#chart_type' => 'bar',
'#raw_options' => [
'options' => [
'isStacked' => TRUE,
],
],
I think the problem is in the order of the arguments to NestedArray::mergeDeepArray():
// Merge in chart raw options.
if (!empty($element['#raw_options'])) {
$chart_definition = NestedArray::mergeDeepArray([
$element['#raw_options'],
$chart_definition,
]);
}
If I change the order like the following, then it works:
// Merge in chart raw options.
if (!empty($element['#raw_options'])) {
$chart_definition = NestedArray::mergeDeepArray([
$chart_definition,
$element['#raw_options'],
]);
}
This affects Google and Chartjs, at least.
Comments
Comment #2
andileco commentedThanks for finding this, @markus_petrux! Will get it fixed soon.
Comment #3
andileco commentedFirst patch without tests.
Comment #4
nikathoneHere is an initial patch with tests. Unfortunately I started the test as unit test then I discovered that the chart element due to the plugin system integration it will need to be at least a kernel test. I will continue on this tomorrow evening and switch to kernel tests.
Comment #5
markus_petrux commentedI've been playing a bit more, trying to customize a few charts, and I've found the NestedArray::mergeDeepArray() mechanisme to merge raw_options does not work well for numeric array keys, because these are appended, not merged.
So it seems there's more control over the chart options by overriding js settings. :-/
Comment #6
guillaumeduveauSame as Markus, only that I see that specifically in charts_chartjs submodule.
For instance, populateOptions() in web/modules/contrib/charts/modules/charts_chartjs/src/Plugin/chart/Library/Chartjs.php adds an X axis with:
In your code if you have for instance:
Then basically mergeDeepArray adds another X axis, but also the one added by this module, and the options are not honored (the initial options take precedence)
Comment #7
guillaumeduveauHere's a simple patch to solve this in a super simple way: if you provide #raw_options, then by default don't add xAxes and yAxes options at all. That way, the default behaviour is the same, but you can customize things if you are a coder.
The code above in #6 now works with this patch.
What do you think? It would have to be done for other submodules of course, if this can be an acceptable solution.
Comment #8
andileco commentedComment #11
andileco commentedThank you, @nikathone!