artus9033 / chartjs-plugin-dragdata

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

Very difficult to drag once bar size reaches 0 #52

Closed rgupta33 closed 4 years ago

rgupta33 commented 4 years ago

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.

rgupta33 commented 4 years ago

https://github.com/chrispahm/chartjs-plugin-dragdata/issues/24

I just found this previous issue and it seems to be the same issue I am having currently. One possible solution I have thought of is to have to the bar automatically resize on mousedown. Would it be possible to include such a feature?

chrispahm commented 4 years ago

Hey @coder2036,

Thanks for raising an issue! This post in #24 highlights the minBarLength property, which should essentially do what you want.

It's a little tricky to get it right when using this plugin, as the UX issues I outlined in this post still persist: If you define a minBarLength, there might be a bar with the value of 0 having the same length as a bar with e.g. the value of 10, so for a user their values are indistinguishable (until they hover over the bars, as seen in this fiddle).

As the property prohibits dragging the bar below the specified minBarLength, it also prohibits users to actually drag to values below this point. In order to fix this, you'd need to disable the minBarLength property while dragging:

       options: {
           dragData: true,
           onDragStart: (e) => {
              // remove bar length while dragging
              yourChart.options.scales.yAxes[0].minBarLength = 0
            },
            onDragEnd: (e, datasetIndex, index, value) => {
              e.target.style.cursor = 'default'
              // and reset afterwards
              yourChart.options.scales.yAxes[0].minBarLength = 10
              yourChart.update()
            },
}           

Here's a working fiddle: https://jsfiddle.net/nc0fh3su/2/

There might be another way to solve this, but that's the first thing that came to my mind. Does this solve your issue?

rgupta33 commented 4 years ago

Thanks for getting back to me @chrispahm. I think I've found a good solution for my use case:

What I did was place duplicate bars with max length and dragData: false and with the same color as the background of the canvas by creating a second dataset. Thus, I could detect any click in that row even if the visible bar was at 0. Then I modified your plugin's code by changing datasetIndex to 0 everywhere. Finally, for onDragStart, I wrote a function to get the new x-axis value based on the event location (I was using a horizontal bar graph). This change makes the bar adjust right away onmousedown or touchstart instead of waiting for the user to drag somewhere.

Here's a fiddle: [https://jsfiddle.net/aso5w7nr/2/]

The first 1196 lines are your plugin's code, and everything after is mine. It works beautifully on both laptops and phones so far. Maybe this approach is worth exploring for your plugin too.

chrispahm commented 4 years ago

That's a really nice way of doing it! I really like how zero values are actually portrayed 'correctly', while still being draggable by the user. I think for this plugin, it would actually be useful to be able to toggle between the current method and the 'row' method you propose. I'm planning to refactor the plugin soon (to ensure compatibility to Chart.js > v3.x), so this would be a nice feature.

If you got some time on your hands, I'm always welcoming PRs 😏

rgupta33 commented 4 years ago

Unfortunately, I've got my hands full at the moment. I'm also not really sure how to implement this approach in a general way, and this was my first experience with Chart.js and your plugin. Thank you for your help!