Draggable data points plugin for Chart.js

Overview

chartjs-plugin-dragdata.js

Now compatible with Chart.js v3 🎉
Looking for a version compatible to Chart.js < 2.9.x? Then visit the v2 branch!

A plugin for Chart.js >= 2.4.0
Makes data points draggable. Supports touch events.

Drag Data Animation

Online demos

Chart Type Demo Source
Bar - Simple Bar demo source
Bubble - Simple Bubble demo source
Floating bar - simple floating bars demo source
Floating bar - simple floating bars, horizontal demo source
Horizontal Bar - Simple Horizontal Bar demo source
Line - Single Y-Axis demo source
Line - Dual Y-Axis demo source
Line - Drag multiple points demo source
Line - Small demo source
Line - React Fiddle demo source
Line - Drag x-, and y-axis (scatter chart) demo source
Line - Drag dates (x and y axis) demo source
Line - Zoom, Pan, and drag data points (combination with chartjs-plugin-zoom demo source
Mixed - Bar, Bubble, and line Chart demo source
Radar - Simple Radar demo source
Polar - Simple Polar Area Chart demo source
Stacked Bar - Simple Stacked Bar demo source
Stacked Bar - GANTT Chart demo source
Stacked Horizontal Bar - Simple Stacked Horizontal Bar demo source

Click here to learn how to use this plugin in an Observable notebook.

Installation

npm

npm install chartjs-plugin-dragdata

CDN

In browsers, you may use the following script tag:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chartjs-plugin-dragdata.min.js"></script>

Or, download a release archive file from the dist folder.

Configuration

The following Chart.js sample configuration displays (most) of the available configuration options of the dragdata plugin.

const draggableChart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      fill: true,
      tension: 0.4,
      borderWidth: 1,
      pointHitRadius: 25 // for improved touch support
      // dragData: false // prohibit dragging this dataset
                         // same as returning `false` in the onDragStart callback
                         // for this datsets index position
    }]
  },
  options: {
    plugins: {
      dragData: {
        round: 1, // rounds the values to n decimal places 
                  // in this case 1, e.g 0.1234 => 0.1)
        showTooltip: true, // show the tooltip while dragging [default = true]
        // dragX: true // also enable dragging along the x-axis.
                       // this solely works for continous, numerical x-axis scales (no categories or dates)!
        onDragStart: function(e, element) {
          /*
          // e = event, element = datapoint that was dragged
          // you may use this callback to prohibit dragging certain datapoints
          // by returning false in this callback
          if (element.datasetIndex === 0 && element.index === 0) {
            // this would prohibit dragging the first datapoint in the first
            // dataset entirely
            return false
          }
          */
        },
        onDrag: function(e, datasetIndex, index, value) {         
          /*     
          // you may control the range in which datapoints are allowed to be
          // dragged by returning `false` in this callback
          if (value < 0) return false // this only allows positive values
          if (datasetIndex === 0 && index === 0 && value > 20) return false 
          */
        },
        onDragEnd: function(e, datasetIndex, index, value) {
          // you may use this callback to store the final datapoint value
          // (after dragging) in a database, or update other UI elements that
          // dependent on it
        },
      }
    },
    scales: {
      y: {
        // dragData: false // disables datapoint dragging for the entire axis
      }
    }
  }
})

Minimum and maximum allowed data values can also be specified through the min and max ticks settings in the scales options. By setting these values accordingly, unexpected (fast) changes to the scales, that may occur when dragging data points towards the outer boundaries of the y-axis, can be prohibited.

const myChartOptions = {
  type: 'line', // or radar, bar, horizontalBar, bubble
  data: {...}, 
  options: {
    plugins: {dragData: true},
    scales: {
      y: {
        max: 25,
        min: 0
      }
    }
  }
}

Applying a 'magnet'

In some scenarios, one might want to stop dragging at the closest (rounded) value, or even at a fixed value. This may be achieved by specifying a magnet callback function in the plugins settings:

const myChartOptions = {
  type: 'line', // or radar, bar, bubble
  data: {...}, 
  options: {
    plugins: {
      dragData: {
        magnet: {
    		    to: Math.round // to: (value) => value + 5
        }
      }
    }
  }
}

Touch devices

In order to support touch events, the pointHitRadius option should be set to a value greater than 25. You can find working example configurations in the docs/*.html files. Also note, that mobile devices (and thus touch events) can be simulated with the device mode in the Chrome DevTools.

Gotchas

When working with a module bundler (e.g. Rollup/Webpack) and a framework (e.g. Vue.js/React/Angular), you still need to import the plugin library after installing. Here's a small example for a Vue.js component

<template>
  <div>
    <canvas id="chart"></canvas>
  </div>
</template>
<script>
import { Chart, registerables } from 'chart.js'
// load the options file externally for better readability of the component.
// In the chartOptions object, make sure to add "dragData: true" etc.
import chartOptions from '~/assets/js/labour.js'
import 'chartjs-plugin-dragdata'

export default {
  data() {
    return {
      chartOptions
    }
  },
  mounted() {
    Chart.register(...registerables)
    this.createChart('chart', this.chartOptions)
  },
  methods: {
    createChart(chartId, chartData) {
      const ctx = document.getElementById(chartId)
      const myChart = new Chart(ctx, {
        type: chartData.type,
        data: chartData.data,
        options: chartData.options,
      })
    }
  }
}
</script>
<style>
</style>

Contributing

Please feel free to submit an issue or a pull request! If you make changes to the src/index.js file, don't forget to npm run build and manually test your changes against all demos in the docs folder.

License

chartjs-plugin-dragdata.js is available under the MIT license.

Comments
  • Tooltip values are not being updated when dragging fast

    Tooltip values are not being updated when dragging fast

    Hi,

    When dragging points fast or in some other times, tooltip is not being updated (in Line chart). This is happenning also in your examples here:

    https://chrispahm.github.io/chartjs-plugin-dragdata/

    Can you please suggest?

    Thanks in advanced!

    opened by YahavTheKing123 31
  • trigger an event onDragEnd

    trigger an event onDragEnd

    I am trying to call a function onDragEnd. I want to pass the values as an arguments where the script displays the updated values in the console.

    ` onDragEnd: function (e, datasetIndex, index, value) {

    				console.log(datasetIndex, index, value)
    				
    				this.modifyDataSet(datasetIndex, index, value);
    			}`
    

    Console.log works fine. But I dont know how to trigger a custom function. I need to project the values in a datagrid in parallel to the chart. Your help would be highly appreciated. Thanks

    opened by krishRamalingam 11
  • Drag on X axis somehow...

    Drag on X axis somehow...

    Hi! Thanks for this library. I have somehow managed to be able to drag the points on the X axis with previous chart js version. Now i want to upgrade to the newsest chart js and still try to drag the X axis.

    The problem is that i have a time axis on X, and i know it does not possible to compute this but still i need some workaround for this because i was able to do that with prev versions.

    My case is that the graph is a shutter/blinder graph. The user has to be able to set a specific time point in a day from 00:00 to 23:50 to a specific % from 0 to 100. It will be a dataset on an MCU, this MCU will loop trought this dataset and if the time matches with the actual time it will turn the shutter/blinder on the windows to the specified % value.

    Here is a jsfiddle from what i try to do

    So the user should be able to drag a point to the Y and the X axes as well. A point represents the shutter percentage in a day on the window.

    If the problem is the x axes label format like "13:00" it would be ok for it to be a timestamp in millis or something else if the user sees the correct time in string.

    Any suggestion? Sorry if it was not clear enough.

    opened by zekageri 8
  • horizontal bar chart drag x axis

    horizontal bar chart drag x axis

    Hi,

    Thanks for your plugin, I found that with vertical bar chart the dragging works fine. However when I use the horizontal bar chart, it drags but along the Y axis, i.e. moving the mouse up and down, will move the horizontal bar left and right. I tried the DragX/Y options but did not get it to work, also putting DragData within the X/Y axis.

    Also a smaller issue, was when I dragged to zero, I could not drag it out of zero, so I had to set the minimum to be 1 instead of 0.

    Any fixes appreciated. Thanks

    opened by carlgrayau 8
  • Thank you!

    Thank you!

    I was looking for this exact functionality, and I found your repository, added the tag, and boum! It just worked! Thank you so much, so wonderful when the stars align! <3

    opened by vsoch 8
  • Toggle dragData to true/false

    Toggle dragData to true/false

    Hi Christoph,

    I am looking for an option to toggle the dragging feature. I placed a button for toggle dragData property to true or false and updated the chart but it doesn't work.

    By default, it considers the value set on page load. I can't change it afterwards.

    Could you please provide me with a solution?

    opened by krishRamalingam 7
  • Touch compatible

    Touch compatible

    I am using this in an angular 7 application and it works fine in a PC but I can't get it to work on an iPad. Here is a stackblitz of the example: https://stackblitz.com/edit/ng2-charts-g . Is touch fully supported on this?

    Thank you.

    question 
    opened by gauravshrestha 7
  • Select a single point to drag when multiple points are at the same location

    Select a single point to drag when multiple points are at the same location

    I have a scatter plot that will have multiple points at the same location.

    I can easily determine the n points at that location, but is there a way to select only the one I want to drag.

    Is this some sort of z-index problem, needing to bring the one I want to the top?

    BTW, I am loving this plugin!

    opened by samcov 6
  • Dragging does not work with panning plugin

    Dragging does not work with panning plugin

    Hi, thanks for this great plugin. Is it possible to make it compatible with the zoom/panning plugin? https://github.com/chartjs/chartjs-plugin-zoom

    I can only get either panning or data-dragging to work. Example (works in Safari): https://jsfiddle.net/zpq8an40/1/

    Would be nice to have both, like eg here http://bl.ocks.org/stepheneb/1182434

    Is there any workaround available?

    Thank you!

    enhancement 
    opened by Zuckerbrot 6
  • 'dragData' Not Recognized as Options Property in Angular

    'dragData' Not Recognized as Options Property in Angular

    'dragData' Option Not Recognized:

    Using Chart.js 2.9.3 in Angular. Imported plugin: import 'chartjs-plugin-dragdata' However, dragData is not recognized as a chart option.

    Receiving the following error: index.d.ts(278, 9): The expected type comes from property 'options' which is declared here on type 'ChartConfiguration'

    Please let me know how to fix this issue.

    opened by rkp8 5
  • Very difficult to drag once bar size reaches 0

    Very difficult to drag once bar size reaches 0

    Using the multiple horizontal example, once any of the bars reaches 0, it is very difficult to move it from there since the bar has disappeared. On laptop, with a little bit of care, it is doable. On mobile, though, I haven't been able to succeed yet.

    opened by rgupta33 5
  • Vue3 compability

    Vue3 compability

    Events are not working on Vue3 (composition api)

    Example:

    const chartPlugins = [{
            id: 'mousedownCatcher',
            dragData: {
              round: 1,
              showTooltip: true,
              onDragStart: function (e, datasetIndex, index, value) {
                console.log(e)
              },
              onDrag: function (e, datasetIndex, index, value) {
                e.target.style.cursor = 'grabbing'
                console.log(e, datasetIndex, index, value)
              },
              onDragEnd: function (e, datasetIndex, index, value) {
                e.target.style.cursor = 'default'
                console.log(datasetIndex, index, value)
              },
            }
      }]
    
      const draggableChart = new Chart('draggableChart', {
            type: 'line',
            data: chartData,
            options: chartOptions,
            plugins: chartPlugins
      })
    
      + dragData: true on datasets in chartData
    

    Result: no console logs, no changes in chart behaviour on click/ drag etc.

    Plugin installed by npm

    opened by Mikolaj-Graja 1
  • Added the `beforeDatasetsUpdate` lifecycle hook in order to refresh the callbacks

    Added the `beforeDatasetsUpdate` lifecycle hook in order to refresh the callbacks

    Problem

    • If a chart's onDragStart, onDrag, or onDragEnd callbacks are changed as a form of data update and the chart.update() function is called then the old callbacks are still run instead of potential new ones.

    Solution

    • The beforeDatasetsUpdate lifecycle hook was added as per the diagram found here. The documentation can be found here.
    • The callbacks are compared with the cached callbacks from the initial on afterInit hook. If the callbacks are different then the listeners are re attached.
    opened by DuartBreedt 0
  • Drag over X axis doesnt work on react app

    Drag over X axis doesnt work on react app

    Describe the bug Drag action over X axis doesnt work when the library is used in react app.

    To Reproduce jsFiddle

    Hey, @chrispahm can you please jump in and see what's happening here. There is code snippet in jsfiddle that I've provided. I followed instructions in documentation and added dragX property, to enable dragging over X axis, but it doesn't work.

    duplicate 
    opened by selimovicz 2
  • Precise dragging is required when moving points within a radar chart.

    Precise dragging is required when moving points within a radar chart.

      Precise dragging is required when moving points within a radar chart.
    

    If you pass from the center point, the point will stretch in the opposite direction, and so on.

    What I want to do is in the second table. Dragging only operates within the axis and has no effect on other axes. (It does not extend to the other side even if it passes the center.

    bug 
    opened by shochu-hiracchi 2
  • pie chart having Error

    pie chart having Error

    pie chart having Error - Cannot read properties of undefined (reading 'getValueForPixel')

    To Reproduce I have implemented this on pie chart , while dragging any point it's showing below error

    TypeError Cannot read properties of undefined (reading 'getValueForPixel')

    here is a codesandbox where i have wrapped the chartjs pie chart with draggable link: https://codesandbox.io/s/chartjs-draggable-bmnzog

    enhancement 
    opened by fazlay 1
  • Feature request: 'round' option for individual x/y axis

    Feature request: 'round' option for individual x/y axis

    Hello,

    Currently there is 'round' option - it helps my use-case tremendously. On the other hand, the x and y axes require different precision. 0.1 for x and 0 for y. Now I would do a Math.round() on the y-axis value given by onDrag(). Therefore, I think it would be useful to be able to set 'round' value on individual axis.

    enhancement 
    opened by ffongmdsp 2
Releases(v2.2.3)
Owner
Christoph Pahmeyer
Agricultural economics research assistant University Bonn
Christoph Pahmeyer
Chart.js plugin to defer initial chart updates

Chart.js plugin to defer initial chart updates until the user scrolls and the canvas appears inside the viewport, and thus trigger the initial chart a

Chart.js 97 Nov 9, 2022
A Simple Dashboard Chart in Laravel Nova using Chart JS

A Simple Dashboard Chart in Laravel Nova using Chart JS. Starting create your own dashboard with Chart JS Integration can save your time and help you maintain consistency across standard elements such as Bar, Stacked, Line, Area, Doughnut and Pie Chart.

Kuncoro Wicaksono 177 Jan 4, 2023
Bar Funnel Chart extension for Chart.js

Chart.BarFunnel.js Provides a Bar Funnel Chart for use with Chart.js Documentation To create a Bar Funnel Chart, include Chart.BarFunnel.js after Char

Chart.js 58 Nov 24, 2022
TradeX-chart is a trade chart written in plain (vanilla) JavaScript with minimal dependencies

TradeX-chart is a trade chart written in plain (vanilla) JavaScript with minimal dependencies; use it with any framework or backend.

null 24 Dec 12, 2022
API to generate candlestick chart data for any time period based on transactions data

candel-maker API to generate candlestick chart data for any time period based on transactions data Installation clone repo git clone https://github.co

null 2 Aug 18, 2022
Chart.js plugin for live streaming data

chartjs-plugin-streaming Chart.js plugin for live streaming data chartjs-plugin-streaming 2.x requires Chart.js 3.0.0 or later. If you need Chart.js 2

Akihiko Kusanagi 401 Dec 27, 2022
Chart.js plugin for Prometheus data loading

Welcome to chartjs-plugin-datasource-prometheus ?? A Prometheus datasource for ChartJS. Dependencies: requires chart.js 2.7 or later. requires moment.

Samuel Berthe 77 Dec 6, 2022
Chart.js plugin to display labels on data elements

Overview Highly customizable Chart.js plugin that displays labels on data for any type of charts. Requires Chart.js 3.x. Documentation Introduction Ge

Chart.js 753 Dec 24, 2022
🍞📊 Beautiful chart for data visualization.

?? ?? Spread your data on TOAST UI Chart. TOAST UI Chart is Beautiful Statistical Data Visualization library. ?? Packages The functionality of TOAST U

NHN 5.2k Jan 2, 2023
🍞📊 Beautiful chart for data visualization.

?? ?? Spread your data on TOAST UI Chart. TOAST UI Chart is Beautiful Statistical Data Visualization library. ?? Packages The functionality of TOAST U

NHN 5.2k Jan 6, 2023
Chart.js scale for hierarchical tree-like data structure

Chart.js Hierarchical Scale Plugin Chart.js module for adding a new categorical scale which mimics a hierarchical tree. Related Plugins Check out also

Samuel Gratzl 40 Dec 17, 2022
Timeline/Graph2D is an interactive visualization chart to visualize data in time.

vis-timeline The Timeline/Graph2D is an interactive visualization chart to visualize data in time. The data items can take place on a single date, or

vis.js 1.2k Jan 3, 2023
Zoom and pan plugin for Chart.js

chartjs-plugin-zoom A zoom and pan plugin for Chart.js >= 3.0.0 For Chart.js 2.6.0 to 2.9.x support, use version 0.7.7 of this plugin. Panning can be

Chart.js 510 Jan 2, 2023
Chart.js plugin for more styling options

chartjs-plugin-style Chart.js plugin for more styling options This plugin requires Chart.js 2.6.0 or later. Installation You can download the latest v

Akihiko Kusanagi 57 Oct 27, 2022
Chart.js plugin to create charts with a hand-drawn, sketchy, appearance

chartjs-plugin-rough Chart.js plugin to create charts with a hand-drawn, sketchy, appearance Version 0.2 requires Chart.js 2.7.0 or later, and Rough.j

Akihiko Kusanagi 73 Dec 1, 2022
Chart.js plugin to calculate and draw statistical linear, exponential, power, logarithmic, and polynomial regressions.

chartjs-plugin-regression Chart.js plugin to calculate and draw statistical linear, exponential, power, logarithmic, and polynomial regressions using

Wilfredo Pomier 14 Dec 18, 2022
Annotation plugin for Chart.js

chartjs-plugin-annotation.js An annotation plugin for Chart.js >= 3.0.0 This plugin needs to be registered. It does not function as inline plugin. For

Chart.js 515 Dec 30, 2022
Make Your Company Data Driven. Connect to any data source, easily visualize, dashboard and share your data.

Redash is designed to enable anyone, regardless of the level of technical sophistication, to harness the power of data big and small. SQL users levera

Redash 22.4k Dec 30, 2022
Redefined chart library built with React and D3

Recharts Introduction Recharts is a Redefined chart library built with React and D3. The main purpose of this library is to help you to write charts i

recharts 19.4k Jan 2, 2023