无法从Chart.js BoxAnnotation读取上下文元素的Y属性

ekqde3dh  于 2024-01-07  发布在  Chart.js
关注(0)|答案(1)|浏览(260)

我是Chart.js的新手,我做了大量的研究,但没有发现任何可以帮助我的东西,所以我向社区寻求帮助。
我正在使用Chart.js版本3.2.1和chartjs-plugin-annotation版本1.0.1处理一个项目。不幸的是,目前无法更新库。
场景如下:我需要用渐变填充BoxAnnotation插件的背景。好了,我知道怎么做了。问题是这个BoxAnnotation的位置会根据用户应用的过滤器而变化。因此,createLinearGradient的Y坐标需要在运行时从BoxAnnotation中获得。
现在的问题是,我无法读取上下文元素的Y属性。它总是返回undefined。因此,我无法正确设置渐变的起始位置。
下面是BoxAnnotation的代码:

  1. boxDeficitStatus: !this.onlyVirtualSensors && {
  2. type: 'box',
  3. yScaleID: 'right-y-axis',
  4. drawTime: 'beforeDatasetsDraw',
  5. yMin: 0,
  6. yMax: $this.moistureCritical,
  7. backgroundColor: function(context) {
  8. const chart = context.chart;
  9. const {ctx, chartArea} = chart;
  10. return getGradient(ctx, chartArea);
  11. },
  12. borderWidth: 0,
  13. display: !this.onlyVirtualSensors,
  14. }

字符串
下面是getGradient函数的代码:

  1. function getGradient(ctx, chartArea) {
  2. const chartHeight = chartArea.bottom - chartArea.top;
  3. //Instead of 246, the Y coordinate value I'm trying to obtain should go there.
  4. const gradient = ctx.createLinearGradient(67.7, 246, 67.7, chartHeight);
  5. gradient.addColorStop(0, "rgba(255, 255, 255, 0.3)");
  6. gradient.addColorStop(1, "rgba(255, 0, 0, 0.3)");
  7. return gradient;
  8. }


运行console.log('$context', context.element['$context'])
浏览器终端中的结果如您提供的图像所示:
x1c 0d1x的数据
但是,当尝试使用下列任一项存取Y属性时:

  1. console.log('y', context.element['$context']['element'].y)
  2. console.log('y', context.element.y)
  3. console.log('y', context.element['y'])


其结果始终是未定义的。
我的问题是,是否有可能以某种方式访问这个Y属性,或者是否有另一种方法来获得我需要的坐标。
不客气!提前感谢您的耐心!

vzgqcmou

vzgqcmou1#

我成功地克服了这个挑战,我将与未来可能需要它的任何人分享解决方案。
问题是上下文中的“元素”的值是在图表初始化后立即计算的。因此,我需要找到一种方法在图表渲染后立即访问我需要的值。为了实现这一点,我使用了setTimeoutchart.update,正如我们的朋友@kikon所建议的那样。
最终的解决方案基本如下:

  1. import { Component, OnInit } from '@angular/core';
  2. import { Chart } from 'chart.js';
  3. @Component({
  4. selector: 'my-app',
  5. templateUrl: './app.component.html',
  6. styleUrls: ['./app.component.css'],
  7. })
  8. export class AppComponent implements OnInit {
  9. myChart: Chart;
  10. chartCtx: any;
  11. elementCtx: any;
  12. ngOnInit() {
  13. this.plotChart();
  14. this.getStatusBoxCoordinates(this.elementCtx);
  15. }
  16. getStatusBoxCoordinates(element) {
  17. setTimeout(() => {
  18. const boxStatus=
  19. this.myChart.options.plugins.annotation.annotations[
  20. 'boxStatus'
  21. ];
  22. boxStatus.backgroundColor = this.getGradient(
  23. element?.x,
  24. element?.y,
  25. this.chartCtx
  26. );
  27. this.myChart.update();
  28. }, 50);
  29. }
  30. getGradient(coordinateX, coordinateY, chart) {
  31. const { ctx, chartArea } = chart;
  32. const x = coordinateX || 0;
  33. const y0 = coordinateY || 0;
  34. const y1 = chartArea.bottom - 50 || 295;
  35. const gradient = ctx.createLinearGradient(x, y0, x, y1);
  36. gradient.addColorStop(0, 'rgba(255, 229, 229,0.1)');
  37. gradient.addColorStop(0.2, 'rgba(255, 198, 198,0.1)');
  38. gradient.addColorStop(0.4, 'rgba(252, 175, 175,.1)');
  39. gradient.addColorStop(0.6, 'rgba(249, 130, 130,0.1)');
  40. gradient.addColorStop(0.8, 'rgba(242, 109, 109, .1)');
  41. gradient.addColorStop(1, 'rgba(224, 76, 76, 0.1)');
  42. return gradient;
  43. }
  44. plotChart() {
  45. let $this = this;
  46. const xValues = [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150];
  47. const yValues = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15];
  48. this.myChart = new Chart('myChart', {
  49. type: 'line',
  50. data: {
  51. labels: xValues,
  52. datasets: [
  53. {
  54. fill: false,
  55. backgroundColor: 'rgba(0,0,255,1.0)',
  56. borderColor: 'rgba(0,0,255,0.1)',
  57. data: yValues,
  58. },
  59. ],
  60. },
  61. options: {
  62. plugins: {
  63. annotation: {
  64. annotations: {
  65. boxStatus: {
  66. type: 'box',
  67. yScaleID: 'y',
  68. yMin: 0,
  69. yMax: 10,
  70. backgroundColor: function (context) {
  71. $this.elementCtx = context.element;
  72. $this.chartCtx = context.chart;
  73. return 'rgba(255, 255, 255, 0)';
  74. },
  75. },
  76. },
  77. },
  78. },
  79. },
  80. });
  81. }
  82. }

字符串
我利用整个组件中可访问的变量来存储boxStatus的上下文,然后在图表已经计算出y 0之后,基于此上下文更新backgroundColor。
好吧,就是这样!我希望这对将来的人有帮助!

展开查看全部

相关问题