简体   繁体   中英

Annotation don't show in vue-chartjs

I'm using vue-chartjs . I need annotations in my charts. I'm imported an annotation plugin

import chartjsPluginAnnotation from "chartjs-plugin-annotation"

Then add a plugin on mounted

this.addPlugin(chartjsPluginAnnotation)

Also, I added an annotation object to the options

plugins: {
  annotation: {
          drawTime: 'afterDraw',
            annotations: [
              {
                type: "line",
                id: 'BTV',
                mode: "horizontal",
                display: true,
                scaleID: "y-axis-0",
                borderColor: "red",
                value: 17000,
                borderDash: 4,
                label: {
                  content: 'aa',
                  enabled: true,
                  position: "top",
                  xAdjust: 15,
                  backgroundColor: '#4ecca3',
                  fontSize: 10,
                }
              }
          ]
  },
}

It works in all manuals what I find, but doesn't work in my project

If you are using the "chart.js" v2.9.4(latest), just DOWNGRADE it to v2.9.3 . Maybe they have some issues on that version.

Please check my "package.json" below.

"dependencies": {
  "chart.js": "^2.9.3",
  "chartjs-plugin-annotation": "^0.5.7",
  "vue": "^2.6.11",
  "vue-chartjs": "^3.5.1" 
}

It works properly for me.

One problem I see is that you've defined annotation under plugins whereas it should be defined directly under options . (I know this is confusing, because some of the chartjs-annotation-plugin documentation still shows an example with annotation as a property of plugins rather than options .)

There is, however, another issue which does appear to stem from a change that was made in Chart.js 2.9.4. The method of cloning an object was modified , such that it now utilizes Object.create() , which copies the properties from the source object into the target object's prototype . The problem, in the context of a Vue app, is that the options that you pass to the renderChart() method is very likely a Vue observer (eg, a prop or a member of data ), which means that its properties are all set (by Vue, under the hood) using Object.defineProperty() . Here's why that is important:

Setting a property to an object creates an own property. The only exception to the getting and setting behavior rules is when there is an inherited property with a getter or a setter.

(From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain )

The reason this is a problem is that, when Chart.js initializes a chart, it creates the options by recursively merging your configuration options with a bunch of global defaults; part of this merging behavior involves the aforementioned cloning if the property is a non-standard option, which will render your annotation object with its properties copied to its prototype, but with no properties of its own. Therefore, when the annotation plugin is initialized, it finds an annotation object, but one without any properties of its own, and when the annotation plugin initializes its configuration, it merges your annotation object with its defaults - which includes an empty annotations array.

It seems to me that downgrading Chart.js to 2.9.3 should work for you, provided that you also move your annotation property from plugins to directly under options . An alternative - if you want to continue using the latest version of Chart.js - is to ensure that the options you pass to the renderChart() method are non-reactive (that is, not a Vue observer). One way to accomplish that would be to copy your reactive annotation object's properties into a POJO (Plain Old Javascript Object), eg, by using Object.assign() :

this.renderChart(this.chartData, { 
  ...this.options, 
  annotation: Object.assign({}, this.options.annotation) 
})

I have filed an issue on the Chart.js GitHub: https://github.com/chartjs/Chart.js/issues/8382

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM