Reputation: 18670
I'm looking for a javascript charting API that would allow user to dynamically modify value points (through drag'n drop) and then provide some callbacks to get those new values.
Do you have any suggestions?
Upvotes: 0
Views: 399
Reputation: 18670
There is a custom plugin for highcharts that provides dragging of chart points: http://jsfiddle.net/highcharts/AyUbx/:
(function (Highcharts) { var addEvent = Highcharts.addEvent, each = Highcharts.each; /** * Filter by dragMin and dragMax */ function filterRange(newY, series, XOrY) { var options = series.options, dragMin = options['dragMin' + XOrY], dragMax = options['dragMax' + XOrY]; if (newY < dragMin) { newY = dragMin; } else if (newY > dragMax) { newY = dragMax; } return newY; } Highcharts.Chart.prototype.callbacks.push(function (chart) { var container = chart.container, dragPoint, dragX, dragY, dragPlotX, dragPlotY; chart.redraw(); // kill animation (why was this again?) addEvent(container, 'mousedown', function (e) { var hoverPoint = chart.hoverPoint, options; if (hoverPoint) { options = hoverPoint.series.options; if (options.draggableX) { dragPoint = hoverPoint; dragX = e.pageX; dragPlotX = dragPoint.plotX; } if (options.draggableY) { dragPoint = hoverPoint; dragY = e.pageY; dragPlotY = dragPoint.plotY + (chart.plotHeight - (dragPoint.yBottom || chart.plotHeight)); } // Disable zooming when dragging if (dragPoint) { chart.mouseIsDown = false; } } }); addEvent(container, 'mousemove', function (e) { if (dragPoint) { var deltaY = dragY - e.pageY, deltaX = dragX - e.pageX, newPlotX = dragPlotX - deltaX - dragPoint.series.xAxis.minPixelPadding, newPlotY = chart.plotHeight - dragPlotY + deltaY, newX = dragX === undefined ? dragPoint.x : dragPoint.series.xAxis.translate(newPlotX, true), newY = dragY === undefined ? dragPoint.y : dragPoint.series.yAxis.translate(newPlotY, true), series = dragPoint.series, proceed; newX = filterRange(newX, series, 'X'); newY = filterRange(newY, series, 'Y'); // Fire the 'drag' event with a default action to move the point. dragPoint.firePointEvent( 'drag', { newX: newX, newY: newY }, function () { proceed = true; dragPoint.update([newX, newY], false); chart.tooltip.refresh(chart.tooltip.shared ? [dragPoint] : dragPoint); if (series.stackKey) { chart.redraw(); } else { series.redraw(); } }); // The default handler has not run because of prevented default if (!proceed) { drop(); } } }); function drop(e) { if (dragPoint) { if (e) { var deltaX = dragX - e.pageX, deltaY = dragY - e.pageY, newPlotX = dragPlotX - deltaX - dragPoint.series.xAxis.minPixelPadding, newPlotY = chart.plotHeight - dragPlotY + deltaY, series = dragPoint.series, newX = dragX === undefined ? dragPoint.x : dragPoint.series.xAxis.translate(newPlotX, true), newY = dragY === undefined ? dragPoint.y : dragPoint.series.yAxis.translate(newPlotY, true); newX = filterRange(newX, series, 'X'); newY = filterRange(newY, series, 'Y'); dragPoint.update([newX, newY]); } dragPoint.firePointEvent('drop'); } dragPoint = dragX = dragY = undefined; } addEvent(document, 'mouseup', drop); addEvent(container, 'mouseleave', drop); }); /** * Extend the column chart tracker by visualizing the tracker object for small points */ var colProto = Highcharts.seriesTypes.column.prototype, baseDrawTracker = colProto.drawTracker; colProto.drawTracker = function () { var series = this; baseDrawTracker.apply(series); each(series.points, function (point) { point.graphic.attr(point.shapeArgs.height < 3 ? { 'stroke': 'black', 'stroke-width': 2, 'dashstyle': 'shortdot' } : { 'stroke-width': series.options.borderWidth, 'dashstyle': series.options.dashStyle || 'solid' }); }); }; })(Highcharts);
Upvotes: 0