JS图表API与用户交互

时间:2013-06-28 08:37:01

标签: javascript charts

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

你有什么建议吗?

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

有一个自定义插件,用于提供拖动图表点的高级图表: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);