chartjs-plugin-dragdata icon indicating copy to clipboard operation
chartjs-plugin-dragdata copied to clipboard

Dragging a Range Bar Chart

Open cfolan17 opened this issue 3 years ago • 4 comments

Hello,

I am trying to allow for users to move either end of a range bar chart that is also stacked.

Currently, when I begin to drag, the data on the bar chart disappears. When I take out the range aspect of the Chart it works fine. The code that I am using is below.

 data= {{
                    labels: ['Risk Level'],
                    datasets: [{
                        label: 'Low',
                        data: [[5,10]],
                        backgroundColor: '#D6E9C6',
                      },
                      {
                        label: 'Moderate',
                        data: [[10,13]],
                        backgroundColor: '#FAEBCC',
                      },
                      {
                        label: 'High',
                        data: [[15,17]],
                        backgroundColor: '#EBCCD1',
                      }
                    ]
                  }}
                
                options= {
                    {
                        responsive: true,
                        dragData: true,
                        dragX1:true,
                        dragX2:true,
                        dragDataRound: 1,
                        dragOptions: {
                          showTooltip: true
                        },
                        onDragStart: function(e) {
                            console.log(e)
                            
                        },
                        onDrag: function(point_end, datasetIndex, index, value) {
                            point_end.target.style.cursor = 'grabbing'
                            console.log(datasetIndex, index, value)
                        },
                        onDragEnd: function(point_end, datasetIndex, index, value) {
                            point_end.target.style.cursor = 'default' 
                            console.log(datasetIndex, index, value)
                        },
                        hover: {
                          onHover: function(e) {
                            const point = this.getElementAtEvent(e)
                            if (point.length) e.target.style.cursor = 'grab'
                            else e.target.style.cursor = 'default'
                          }
                        },
                        scales: {
                          xAxes: [{
                            stacked: true,
                            ticks: {
                              max: 100,
                              min: 0
                            }
                          }],
                          yAxes: [{
                            stacked: true,
                            ticks: {
                              max: 100,
                              min: 0
                            }
                          }]
                        }
                      }
                }  

Any help on this would be greatly appreciated.

cfolan17 avatar Dec 29 '20 00:12 cfolan17

Hey 👋

Sorry that it took me so long. Dragging range values is not supported by the plugin (yet). As you can see in the source code of the plugin (line 31, handling bar charts)

let curValue = chartInstance.data.datasets[datasetIndex].data[index]
initValue = newPos - curValue

we currently use the (data) value at the clicked / dragged index position for calculating the updated value. Since this returns an array and not a number in a range chart, the calculation yields NaN → This is why the bar disappears when you try to drag it.

Could you elaborate a little on what you are trying to achieve with this chart? Are these risk preferences (e.g. in a portfolio) where users should indicate the share of assets in each risk category? If this is the case you could probably just add a function to the onDrag callback, making sure the bars always add up to 100%. Here's an Observable showcasing how this could be done:

https://observablehq.com/@chrispahm/adjustable-risk-preferences

The implementation could definitely use some polishing and edge case fixing, but I'd argue it's less cumbersome than trying to grab the tiny edges of the range chart. What do you think?

P.S.: Here's the same thing in plunker (but vertical): https://plnkr.co/edit/nMbFZUT4v8as0FQ9?open=lib%2Fscript.js

chrispahm avatar Jan 08 '21 12:01 chrispahm

Hi Chris,

Thanks again for all of the work that you have done on this plug in. What I am trying to build is an interactive Gantt Chart that allows our team to move out projects into the future or closer to the date depending on how ready we are to working on them. The photo that I am uploading is different then the code that I provided above because I was trying to work with a simplified solution to try and understand how the plug in works.

image

My goal would be to keep the bar sizes the same but move the Start Date for the first section and the End Date for the last section the same distance. So if we were to look at specifically the use case of the risk that I have outlined above, by grabbing and dragging the range bar chart 3 units it would change the values to this: Low[8:13] Moderate[13:16] High[18:20]

The use case would probably make more sense if there was not a gap between the Moderate and High Values of the range bar chart.

Looking at the links that you provided above, it may not fit my use case.

Thanks again for all of the help!!

Conor

cfolan17 avatar Jan 08 '21 16:01 cfolan17

Hey :wave:

Thanks to a PR (#72) by @KlemenVovk, dragging range bars is supported now! Here's a simple example for a GANTT chart (that could still use some tweaking):

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

chrispahm avatar Jul 27 '21 21:07 chrispahm

Hi @cfolan17 , I saw you have a crosshair on your gantt chart. It is not working for me. Do you know how to fix it? Apparently the lack of documentation and poor code quality make it hard to acheave many of features chartjs promises.

Update 23/12/2021: Looks like the crosshair is only supported with Chartjs 3.4.*. Newest Chartjs versions are not supported at the moment.

fairking avatar Dec 17 '21 12:12 fairking