Skip to content

Class instances not handled properly in configuration #7340

Closed
@iddings

Description

Expected Behavior

Class instances should be preserved in chart options, including instance methods.

Current Behavior

Only an object's own enumerable properties (returned by Object.keys) are preserved.
helpers.merge appears to be at fault here, as instance methods are not enumerable properties.

Possible Solution

Cloning an instance of a class is possible with something like:

Object.assign( Object.create( original ), original );

This would only be a shallow copy, but that seems reasonable in the context of a class instance.

Steps to Reproduce (for bugs)

class MyConfigClass {
  
  constructor(parameter) {
    this._private_parameter = parameter;
  }
  
  getParameter() {
    return this._private_parameter;
  }
  
}

  
Chart.plugins.register({
  id: 'example',
  beforeInit: function(chartInstance, pluginOptions) {

    // expect: an instance of MyConfigClass
    // actual: { _private_parameter: 'a value' }
    console.log(pluginOptions);

  }
});

const chart = new Chart(document.querySelector("#chart"), {
  options: {
    plugins: {
      'example': new MyConfigClass("a value")
    }
  }
});

CodePen

Context

Our use case is displaying climate data in either UTC, or local standard time (of the station at which the data was collected). We essentially pretend that DST doesn't exist, so we use fixed offsets from UTC to present data.

CodePen

Without a workaround, passing an instance of FixedOffsetZone results in no data being displayed (because Luxon sees the object it is passed as an invalid zone).

This example has a relatively easy workaround (i.e. using a number instead of a FixedOffsetZone instance), however, in our actual use case, we're accepting any valid Luxon zone (string, number, or any instance that implements luxon.Zone) from an external source, and passing it to the adapter options in Chart.js. This makes it impossible to convert every possible zone to something that Chart.js can handle, as the external source could pass in an instance of a custom class which implements luxon.Zone.

Environment

  • Chart.js version: 2.9.3
  • Browser name and version: Chrome 81.0.4044.129
  • Link to your project: N/A

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions