JS图表API与用户交互

JS charting API with user interaction

本文关键字:用户 交互 API 图表 JS      更新时间:2023-09-26

我正在寻找一个javascript图表API,它允许用户动态修改值点(通过拖放),然后提供一些回调来获得这些新值。

你有什么建议吗?

看看Awesome Free JavaScript Charts评论和另一篇

有一个用于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);