ChartJS 如何用vuejs在图表中画一条线?

izkcnapc  于 2023-04-30  发布在  Chart.js
关注(0)|答案(1)|浏览(207)

我正在做一个数据可视化项目。我使用Django作为后端,Vue作为前端。我使用chartjs来绘制图表。对于散点图,我需要绘制中线(垂直和水平)。通过跟踪其中一个tutorials,我了解到我需要添加一个插件。我尝试了不同的方法来启动插件:作为一种方法或计算。或者只是将其添加到插件。

  1. <template>
  2. <Scatter :style="{ height: '400px' }" :data="chartData" :options="chartOptions" />
  3. </template>
  4. <script>
  5. import {
  6. Chart as ChartJS,
  7. LinearScale,
  8. PointElement,
  9. LineElement,
  10. Tooltip,
  11. Legend
  12. } from 'chart.js'
  13. import { Scatter } from 'vue-chartjs'
  14. ChartJS.register(LinearScale, PointElement, LineElement, Tooltip, Legend)
  15. export default {
  16. name: 'ScatterChart',
  17. components: {
  18. Scatter
  19. },
  20. props: {
  21. homeTeam: Boolean,
  22. playerStats: Array,
  23. },
  24. mounted() {
  25. },
  26. watch: {
  27. playerStats() {
  28. this.setDataSets();
  29. }
  30. },
  31. methods: {
  32. setDataSets() {
  33. this.datasets = [];
  34. this.playerStats.forEach(player => {
  35. let dataset = {
  36. label: player.player_name,
  37. data: [
  38. {
  39. x: player.attack,
  40. y: player.defense
  41. }
  42. ],
  43. backgroundColor: this.bgColor
  44. };
  45. this.datasets.push(dataset);
  46. });
  47. },
  48. },
  49. computed: {
  50. chartData() {
  51. return {
  52. datasets:
  53. this.datasets
  54. }
  55. },
  56. chartOptions() {
  57. return {
  58. responsive: true,
  59. maintainAspectRatio: false,
  60. scales: {
  61. x: {
  62. type: 'linear',
  63. position: 'bottom',
  64. title: {
  65. display: true,
  66. text: 'Attack',
  67. },
  68. },
  69. y: {
  70. type: 'linear',
  71. position: 'left',
  72. title: {
  73. display: true,
  74. text: 'Defense',
  75. },
  76. }
  77. },
  78. plugins: [
  79. {
  80. id: 'horizontalMedianLine',
  81. beforeDraw (chart) {
  82. console.log('horizontalMedianLine called');
  83. const yScale = chart.scales['y'];
  84. const xScale = chart.scales['x'];
  85. const ctx = chart.ctx;
  86. const yValue = yScale.getPixelForValue(1.25);
  87. const xValue = xScale.getPixelForValue(2.5);
  88. console.log('yValue:', yValue);
  89. console.log('xValue:', xValue);
  90. ctx.save();
  91. ctx.beginPath();
  92. ctx.moveTo(xScale.left, yValue);
  93. ctx.lineTo(xScale.right, yValue);
  94. ctx.moveTo(xValue, yScale.top);
  95. ctx.lineTo(xValue, yScale.bottom);
  96. ctx.setLineDash([5, 5]);
  97. ctx.strokeStyle = 'red';
  98. ctx.lineWidth = 2;
  99. ctx.stroke();
  100. ctx.restore();
  101. },
  102. },
  103. ],
  104. }
  105. },
  106. },
  107. data() {
  108. return {
  109. datasets: [],
  110. bgColor: this.homeTeam ? 'rgb(255, 99, 132)' : 'rgb(54, 162, 235)',
  111. }
  112. },
  113. }
  114. </script>

因此,我希望在图表上看到两条线:

我做错了什么?请帮帮我

g2ieeal7

g2ieeal71#

您放错了内联插件对象。它不应该在options下,而应该在用于构造图表的对象的顶层。
在您的设置中,指定插件的一种可能方法是声明一个计算方法chartPlugins

  1. computed: {
  2. chartData(){
  3. return {
  4. datasets: this.datasets,
  5. };
  6. },
  7. chartPlugins(){
  8. return [{
  9. id: "horizontalMedianLine",
  10. beforeDraw(chart){
  11. //......
  12. }
  13. }]
  14. }
  15. }

并在模板中使用:

  1. <template>
  2. <Scatter
  3. :style="{ height: '400px' }"
  4. :plugins="chartPlugins"
  5. :data="chartData"
  6. :options="chartOptions"
  7. />
  8. </template>

而且,你不需要一个插件来绘制这些线条;使用两个新的数据集来实现这一目标会更有效。这是水平的:

  1. methods: {
  2. setDataSets(){
  3. this.datasets = [];
  4. chartConfig.playerStats.forEach((player) => {
  5. //.......
  6. });
  7. const attack = this.playerStats.map(({attack}) => attack);
  8. this.datasets.push({
  9. borderColor: 'red',
  10. showLine: true,
  11. pointRadius: 0,
  12. segment: {borderDash: [5, 5]},
  13. data: [[Math.min(...attack), 1.25], [Math.max(...attack), 1.25]]
  14. });
  15. }
  16. }
展开查看全部

相关问题