Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example "Usage" config throws uncaught error, prevents chartjs from rendering (v2.2.1) #872

Open
julianna-langston opened this issue Mar 26, 2023 · 6 comments

Comments

@julianna-langston
Copy link

Backstory
I was trying to set up a codepen to try using chartjs-plugin-annotaiton. (If I just set it up wrong, I'm sorry). I created If you go look at the codepen, you'll notice that:

  1. It's the example config from the docs (docs page) (github page)
  2. there's an error message in the console.

chartjs-plugin-annotation.esm.js:940 Uncaught TypeError: Cannot set properties of undefined (setting 'backgroundColor')
at ht (chartjs-plugin-annotation.esm.js:940:9)
at dt (chartjs-plugin-annotation.esm.js:857:17)
at Ct.resolveElementProperties (chartjs-plugin-annotation.esm.js:1249:12)
at ne (chartjs-plugin-annotation.esm.js:2441:32)
at Object.afterUpdate (chartjs-plugin-annotation.esm.js:2614:5)
at callback (helpers.segment-1e4938ea.js:43:15)
at PluginService._notify (chartjs.js:5037:11)
at PluginService.notify (chartjs.js:5020:25)
at Chart.notifyPlugins (chartjs.js:6266:26)
at Chart.update (chartjs.js:5827:10)

So, I dug into the code. The error was thrown on this line:

function resolveLabelElementProperties(chart, properties, options) {
  const label = options.label;
  label.backgroundColor = 'transparent';

So, if options.label is considered undefined, where is options coming from?

export function resolveBoxAndLabelProperties(chart, options, centerBased) {
  const properties = resolveBoxProperties(chart, options);
  properties.initProperties = initAnimationProperties(chart, properties, options, centerBased);
  properties.elements = [{
    type: 'label',
    optionScope: 'label',
    properties: resolveLabelElementProperties(chart, properties, options),
    initProperties: properties.initProperties
  }];
  return properties;
}

which is called by

  resolveElementProperties(chart, options) {
    return resolveBoxAndLabelProperties(chart, options);
  }

...which is called from over here:

function updateElements(chart, state, options, mode) {
  const animations = resolveAnimations(chart, options.animations, mode);

  const annotations = state.annotations;
  const elements = resyncElements(state.elements, annotations);

  for (let i = 0; i < annotations.length; i++) {
    const annotationOptions = annotations[i];
    const element = getOrCreateElement(elements, i, annotationOptions.type);
    const resolver = annotationOptions.setContext(getContext(chart, element, annotationOptions));
    const properties = element.resolveElementProperties(chart, resolver);

and now we've switched from options to resolver. Maybe there's a mistake, and maybe the function is expecting an option and receiving a resolver? Maybe I'm providing the config in the wrong way? So I go look at the other pages in the docs, and I start recognizing options I saw in the code. So, I update my annotation to have these properties:

label: {
  callout: {}
}

and then I was able to move forward to another error message

Uncaught TypeError: Cannot read properties of undefined (reading 'family')
at de (chartjs-plugin-annotation.esm.js:2520:19)
at te (chartjs-plugin-annotation.esm.js:2397:57)
at de (chartjs-plugin-annotation.esm.js:2524:22)
at ae (chartjs-plugin-annotation.esm.js:2508:5)
at ie (chartjs-plugin-annotation.esm.js:2486:26)
at ne (chartjs-plugin-annotation.esm.js:2446:7)
at Object.afterUpdate (chartjs-plugin-annotation.esm.js:2614:5)
at callback (helpers.segment-1e4938ea.js:43:15)
at PluginService._notify (chartjs.js:5037:11)
at PluginService.notify (chartjs.js:5020:25)

which took me back to the updateElements function abov. So, another function that thought resolver would have something that it didn't. Suspicious...

What's the bug?

  1. I can't make this chart display.
  2. I found some weird console errors.

Maybe they're related?

@stockiNail
Copy link
Collaborator

@julianna-langston I think the issue is related to cdn.skypack, where we had already some issues (see #786).

If you use

import {Chart, registerables} from "https://cdn.jsdelivr.net/npm/[email protected]/+esm";

instead of

import {Chart, registerables} from "https://cdn.skypack.dev/[email protected]";

it works.

@stockiNail
Copy link
Collaborator

@julianna-langston let me explain better why the error is occurring. The annotation plugin is leveraging on fallback CHART.JS approach for the configuration options.

All annotation types are CHART.JS elements with their defaults. To enable it, it's mandatory to define the plugin globally because the plugin is catching the registration hook in order to register the annotation elements and then to activate the fallback.

When these kinds of errors are occurring means that the registration for whatever reason hasn't happened.

Even if we could of course check the consistency of the label object (in this case), we could have other issues (you have already seen for font) therefore the root cause is not the missing check but the missing registration of the elements.

@julianna-langston
Copy link
Author

Thank you so much, and you got me unblocked with your previous comment.

Is it possible to include links in the docs to a CodePen/JSFiddle/CodeSandbox example? I always the initial setup to be the hardest with chartjs plugins (since all the working example obfuscate how imports/registrations work), so a link to a fully functioning code example would be helpful, at least to me.

@stockiNail
Copy link
Collaborator

I think it's possible, I need to check if there is already ready something as community or chartjs org. Of course I have got my codepens but I think it' better to have something at community level in order to add links to the doc.
@kurkle @LeeLenaleee as far as you know, is there any community org in CodePen/JSFiddle/CodeSandbox to use to add some samples? Makes sense for you?

@LeeLenaleee
Copy link
Collaborator

I know there is a codepen account of chart.js that has some but verry outdated samples. Thats it. For the reproducible sample templates of the main repo for exaple I just used my personal account

@julianna-langston
Copy link
Author

I could come up with some codepen prefills, so that it doesn't have to be hosted by any account? If you think that's a workable approach, I can file a new issue and submit a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants