我正在寻找一个 javascript 图表 API,它允许用户动态修改值点(通过拖放),然后提供一些回调来获取这些新值。
你有什么建议吗?
highcharts 有一个自定义插件,可以拖动图表点: 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);