Skip to content

(x|y)Adjust scriptable context not working properly (cached and overrided) #788

@guillaume-ro-fr

Description

@guillaume-ro-fr

Hello 👋

I'm using the yAdjust property on label annotation for a box.
The box is larger than the complete chart, which adjusts to the Y axis.
Until the previous version of this plugin, I used yAdjust to correct the centering of the title (which when the "center" option is used, is centered with respect to the whole box and not the chart).

For that, I used this code:

yAdjust: (ctx: PartialEventContext) => (ctx.chart.chartArea.height - ctx.element.y) / 2,

With the double execution, I can just return 0 (or any value) when ctx.element.y is not ready, and return the correct value on the second execution:

if (typeof ctx.element.label?.y === 'undefined') {
    return 0; // Any value
}
return (ctx.chart.chartArea.height - ctx.element.label.y) / 2;

But now, this code doesn't work anymore, (I think) because of the merge request #725: yAdjust is evaluated twice but cached by the Proxy object:

  • updateElements -> resolveElementProperties -> resolveLabelElementProperties -> calculateY
  • updateElements -> updateSubElements -> resolveAnnotationOptions -> resolveObj

The problem is at line 64: resolver.label object contains the cached value of yAdjust (first call) and resolveAnnotationOptions method override element.elements[0].options.yAdjust (correct value with second call) with resolver.label.yAdjust value.

const properties = element.resolveElementProperties(chart, resolver);
properties.skip = toSkip(properties);
if ('elements' in properties) {
updateSubElements(element, properties, resolver, animations);
// Remove the sub-element definitions from properties, so the actual elements
// are not overwritten by their definitions
delete properties.elements;
}
if (!defined(element.x)) {
// If the element is newly created, assing the properties directly - to
// make them readily awailable to any scriptable options. If we do not do this,
// the properties retruned by `resolveElementProperties` are available only
// after options resolution.
Object.assign(element, properties);
}
properties.options = resolveAnnotationOptions(resolver);

Here is an example of my code (the red zone is the one with title uncentered):

https://codepen.io/guillaume-ro-fr/full/jOzXpMz

Don't hesitate to tell me if you need more information (I tried to return a Proxy instead of a raw number, but I failed...).
Maybe related to #726

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions