Divya Bharathi
Divya Bharathi

Reputation: 103

How to incorporate draggable feature into vue-chartjs?

I created a BarChart using vue-chartjs and have marked the threshold values using arrows Image of the graph

Here's the code

<template>
  <Bar :data="data" :options="options" />
</template>

<script lang="ts">
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale
} from 'chart.js'
import { Bar } from 'vue-chartjs'
import annotationPlugin from 'chartjs-plugin-annotation'

ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend,
  annotationPlugin
)

export default {
  name: 'App',
  components: {
    Bar
  },
  data() {
    return {
      data: {
        labels: ['January', 'February', 'March'],
        datasets: [
          {
            data: [40, 60, 60],
            base: -20,
            backgroundColor: ['#4CAF50', '#FFC107', '#2196F3']
          }
        ]
      },
      options: {
        responsive: true,
        scales: {
          y: {
            min: -20,
            max: 70,
            title: {
              display: true,
              text: 'Values'
            },
            beginAtZero: false,
            ticks: {
              stepSize: 10
            }
          }
        },
        plugins: {
          annotation: {
            annotations: {
              arrow1: {
                type: 'polygon',
                xValue: 0.39, // Position of first arrow
                yValue: 20, // Threshold value for the first arrow
                backgroundColor: 'blue',
                borderColor: 'black',
                borderWidth: 1,
                sides: 3, // Triangle shape
                rotation: -90, // Points left
                radius: 10,
                draggable: true, // Enable dragging
                dragX: true, // Allow dragging along the X axis
                dragY: true, // Allow dragging along the Y axis
                onDrag: (event, annotation) => this.handleArrowDrag(event, annotation)
              },
              arrow2: {
                type: 'polygon',
                xValue:1.39, // Position of second arrow
                yValue: 20, // Threshold value for the second arrow
                backgroundColor: 'green',
                borderColor: 'black',
                borderWidth: 1,
                sides: 3,
                rotation: -90,
                radius: 10,
                draggable: true,
                dragX: true,
                dragY: true,
                onDrag: (event, annotation) => this.handleArrowDrag(event, annotation)
              },
              arrow3: {
                type: 'polygon',
                xValue: 2.39, // Position of third arrow
                yValue: 20, // Threshold value for the third arrow
                backgroundColor: 'red',
                borderColor: 'black',
                borderWidth: 1,
                sides: 3,
                rotation: -90,
                radius: 10,
                draggable: true,
                dragX: true,
                dragY: true,
                onDrag: (event, annotation) => this.handleArrowDrag(event, annotation)
              }
            }
          }
        }
      }
    }
  },
  methods: {
    // This method will update the position of the arrows when they are dragged
    handleArrowDrag(event, annotation) {
      // Update annotation position (this is where you handle the new position)
      console.log(`Arrow dragged to new position: x=${annotation.xValue}, y=${annotation.yValue}`);
      // You can implement any custom logic here to update your data or trigger re-renders
    }
  }
}
</script>

I'm trying to make the arrows draggable along y-axis, but the solutions I try are making the Bars draggable instead. I used chartjs-plugin-dragdata. I also tried incorporating similar code as in https://www.chartjs.org/chartjs-plugin-annotation/latest/samples/interaction/dragging.html. But it doesn't work. How can I incorporate draggable feature to just the arrows. Do we have any other plugins to bring up draggable feature, if this is not the ideal solution?

Here's the code, I tried for draggable arrows

<template>
  <Bar :data="data" :options="options" />
</template>

<script lang="ts">
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale
} from 'chart.js'
import { Bar } from 'vue-chartjs'
import annotationPlugin from 'chartjs-plugin-annotation'
import dragdataPlugin from 'chartjs-plugin-dragdata'

ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend,
  annotationPlugin,
  dragdataPlugin
)

export default {
  name: 'App',
  components: {
    Bar
  },
  data() {
    return {
      data: {
        labels: ['January', 'February', 'March'],
        datasets: [
          {
            data: [40, 26, 60],
            base: -20,
            backgroundColor: ['#4CAF50', '#FFC107', '#2196F3']
          }
        ]
      },
      options: {
        responsive: true,
        scales: {
          y: {
            min: -20,
            max: 70,
            title: {
              display: true,
              text: 'Values'
            },
            beginAtZero: false,
            ticks: {
              stepSize: 10
            }
          }
        },
        plugins: {
          annotation: {
            annotations: {
              arrow1: {
                type: 'polygon',
                xValue: 0.39, // Position of first arrow
                yValue: 20, // Threshold value for the first arrow
                backgroundColor: 'blue',
                borderColor: 'black',
                borderWidth: 1,
                sides: 3, // Triangle shape
                rotation: -90, // Points left
                radius: 10,
                draggable: true, // Enable dragging
                dragX: true, // Allow dragging along the X axis
                dragY: true, // Allow dragging along the Y axis
              },
              arrow2: {
                type: 'polygon',
                xValue: 1.39, // Position of second arrow
                yValue: 20, // Threshold value for the second arrow
                backgroundColor: 'green',
                borderColor: 'black',
                borderWidth: 1,
                sides: 3,
                rotation: -90,
                radius: 10,
                draggable: true,
                dragX: true,
                dragY: true,
              },
              arrow3: {
                type: 'polygon',
                xValue: 2.39, // Position of third arrow
                yValue: 20, // Threshold value for the third arrow
                backgroundColor: 'red',
                borderColor: 'black',
                borderWidth: 1,
                sides: 3,
                rotation: -90,
                radius: 10,
                draggable: true,
                dragX: true,
                dragY: true,
              }
            }
          },
          dragdata: {
            // Disable dragging for the bars by specifying 'draggable: false' for bars
            dragData: false, // This disables dragging for the bars
            dragDataOnly: true, // Allow only annotation (arrows) to be draggable
            showTooltip: true, // Optionally show tooltip while dragging
          }
        }
      }
    }
  }
}
</script>

Upvotes: 1

Views: 45

Answers (0)

Related Questions