In fact, you can attach draggable widgets to data labels. However, since they are SVG data labels, they completely ignore the changes made to their CSS position , left and top properties.
Instead, the <g> elements that wrap the labels expose the transform attribute:
<g zIndex="1" transform="translate(9, 152)"> </g>
We can still use the draggable widget (which is quite convenient as it abstracts the lower-level drag events) and updates the transform attribute of the data label wrappers in the drag event handler. Since the coordinates are relative, we will have to analyze the original transform attribute and use the resulting coordinates as the origin.
Now all label wrappers themselves are child groups of groups decorated with the highcharts-data-labels class. This gives us a good starting point, so we can write something like:
$(".highcharts-data-labels").children().filter(function() { var $this = $(this); // Parse original translation. var coords = $this.attr("transform") .match(/translate\((-?\d+),\s*(-?\d+)\)/); if (coords) { // Associate origin with element. return $this.data("origin", { x: +coords[1], y: +coords[2] }); } else { // Parsing failed, reject element. return false; } }).draggable({ drag: function(event, ui) { var $this = $(this); // Fetch back origin. var origin = $this.data("origin"); // Update current transform. $this.attr("transform", "translate(" + (origin.x + ui.position.left) + ", " + (origin.y + ui.position.top) + ")"); } });
Here you will find an updated script.
A few notes about the code above:
filter () is used instead of each () , because it allows you to filter out elements whose transform attributes cannot be parsed (you never know), instead of directly crashing or garbage-feeding calculations in the drag handler,
attr () is used instead of prop () to emphasize the fact that we modify the attributes in the SVG fragment. prop() will probably work the exact same way, so this is just a matter of style and personal preference.
Finally, a caveat: at the moment, I can only check this on Firefox, but it seems very difficult to fire mousedown events on some shortcuts, especially in the "crowded" areas with parts of the curve and the data tip competing for space. Fine-tuning the zIndex attributes of data label wrappers did not achieve great results. Sometimes a few clicks help. If this is consistent across all browsers, you may have to develop additional solutions (perhaps transparent overlays or just passing mousedown events from the data points themselves to the data labels).