artus9033 / chartjs-plugin-dragdata

Draggable data points plugin for Chart.js
MIT License
261 stars 55 forks source link

Dragging a Range Bar Chart #62

Open cfolan17 opened 3 years ago

cfolan17 commented 3 years ago

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.

chrispahm commented 3 years ago

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

cfolan17 commented 3 years ago

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

chrispahm commented 3 years ago

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

fairking commented 2 years ago

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.