有没有办法在不重绘整个图表的情况下更改jQuery flot中的绘图颜色?

时间:2010-05-06 22:37:42

标签: jquery flot

我有一张图表,我正在使用flot绘图。当有人将鼠标悬停在文本上时,我想更改数据图的颜色。目前,我每次需要突出显示某些内容时重绘整个图表。这非常慢(简单图表大约30毫秒,更复杂的图表大约100毫秒)。既然我想做的就是改变颜色,那么有更快的解决方案吗?

1 个答案:

答案 0 :(得分:12)

您可以立即采取措施来优化Flot的绘图过程。如果图形上不需要点将其关闭,这可以显着缩短绘图时间。您还应通过将shadowSize选项设置为0来关闭阴影,以提高速度。

除了这两个调整之外,您还必须更改flot源代码才能单独突出显示一个系列。我已经创建了一个完全相同的补丁,以及一个允许您自动或手动突出显示系列的小插件。补丁和插件最多可以比重绘整个图表<强>三倍,它实际上也消除了取消突出显示系列所需的时间,因为它使用了flot的“叠加”功能。

下面有一个jquery.flot.js的补丁和highlightSeries插件的源代码,我创建了一个demonstration page,可以让你看到各种设置以及补丁/插件组合之间的区别。 / p>

Flot patch

--- .\jquery.flot.js
+++ .\jquery.flot.js
@@ -147,6 +147,7 @@
         plot.setData = setData;
         plot.setupGrid = setupGrid;
         plot.draw = draw;
+        plot.drawSeries = drawSeries;
         plot.getPlaceholder = function() { return placeholder; };
         plot.getCanvas = function() { return canvas; };
         plot.getPlotOffset = function() { return plotOffset; };
@@ -164,6 +165,7 @@
         plot.highlight = highlight;
         plot.unhighlight = unhighlight;
         plot.triggerRedrawOverlay = triggerRedrawOverlay;
+        plot.drawOverlay = drawOverlay;
         plot.pointOffset = function(point) {
             return { left: parseInt(axisSpecToRealAxis(point, "xaxis").p2c(+point.x) + plotOffset.left),
                      top: parseInt(axisSpecToRealAxis(point, "yaxis").p2c(+point.y) + plotOffset.top) };
@@ -1059,7 +1061,7 @@
                 drawGrid();

             for (var i = 0; i < series.length; ++i)
-                drawSeries(series[i]);
+                drawSeries(series[i], ctx);

             executeHooks(hooks.draw, [ctx]);

@@ -1265,16 +1267,16 @@
             placeholder.append(html.join(""));
         }

-        function drawSeries(series) {
+        function drawSeries(series, ctx) {
             if (series.lines.show)
-                drawSeriesLines(series);
+                drawSeriesLines(series, ctx);
             if (series.bars.show)
-                drawSeriesBars(series);
+                drawSeriesBars(series, ctx);
             if (series.points.show)
-                drawSeriesPoints(series);
+                drawSeriesPoints(series, ctx);
         }

-        function drawSeriesLines(series) {
+        function drawSeriesLines(series, ctx) {
             function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
                 var points = datapoints.points,
                     ps = datapoints.pointsize,
@@ -1522,7 +1524,7 @@
             ctx.restore();
         }

-        function drawSeriesPoints(series) {
+        function drawSeriesPoints(series, ctx) {
             function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) {
                 var points = datapoints.points, ps = datapoints.pointsize;

@@ -1675,7 +1677,7 @@
             }
         }

-        function drawSeriesBars(series) {
+        function drawSeriesBars(series, ctx) {
             function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
                 var points = datapoints.points, ps = datapoints.pointsize;

@@ -1942,7 +1944,7 @@

                 if (hi.series.bars.show)
                     drawBarHighlight(hi.series, hi.point);
-                else
+                else if (hi.series.points.show)
                     drawPointHighlight(hi.series, hi.point);
             }
             octx.restore();

highlightSeries插件

/*
Flot plugin for highlighting series.

    highlightSeries: {
        autoHighlight: true (default) or false
        , color: color
    }

If "autoHighlight" is true (the default) and the plot's "hoverable" setting is true
series are highlighted when the mouse hovers near an item.
"color" is the color of the highlighted series (default is "red").

The plugin also adds two public methods that allow you to highlight and
unhighlight a series manually by specifying a series by label, index or object.

    - highlightSeries(series, [color])

    - unHighlightSeries(series)
*/

(function ($) {
    var log = (function () {
        var out = $("#out");
        return function () {
            if (!arguments) { return; }
            var msg = Array.prototype.slice.call(arguments).join(" ");
            if (!out.length) {
                out = $("#out");
            }
            if (out.length) {
                out.text(msg);
            }
        };
    })();

    var options = {
        highlightSeries: {
            autoHighlight: true
            , color: "black"
            , _optimized: true
            , _debug: false
        }
    };

    function init(plot) {
        var highlightedSeries = {};
        var originalColors = {};

        function highlightSeries(series, color) {
            var
                seriesAndIndex = getSeriesAndIndex(series)
                , options = plot.getOptions().highlightSeries;

            series = seriesAndIndex[1];

            highlightedSeries[seriesAndIndex[0]] = series;
            originalColors[seriesAndIndex[0]] = series.color;

            series.color = color || options.color;

            if (options._debug) { var start = new Date(); }
            if (options._optimized) {
                if (plot.drawOverlay && options._debug) {
                    plot.drawOverlay();
                }
                else {
                    plot.triggerRedrawOverlay();
                }
            }
            else {
                plot.draw();
            }
            if (options._debug) { 
                log("Time taken to highlight:", (new Date()).getTime() - start.getTime(), "ms");
            }
        };
        plot.highlightSeries = highlightSeries;

        function unHighlightSeries(series) {
            var
                seriesAndIndex = getSeriesAndIndex(series)
                , options = plot.getOptions().highlightSeries;

            seriesAndIndex[1].color = originalColors[seriesAndIndex[0]];

            if (options._debug) { var start = new Date(); }
            if (options._optimized) {
                delete highlightedSeries[seriesAndIndex[0]];
                if (plot.drawOverlay && options._debug) {
                    plot.drawOverlay();
                }
                else {
                    plot.triggerRedrawOverlay();
                }
            }
            else {
                plot.draw();
            }
            if (options._debug) { 
                log("Time taken to un-highlight:", (new Date()).getTime() - start.getTime(), "ms");
            }
        };
        plot.unHighlightSeries = unHighlightSeries;

        plot.hooks.bindEvents.push(function (plot, eventHolder) {
            if (!plot.getOptions().highlightSeries.autoHighlight) {
                return;
            }

            var lastHighlighted = null;
            plot.getPlaceholder().bind("plothover", function (evt, pos, item) {
                if (item && lastHighlighted !== item.series) {
                    for(var seriesIndex in highlightedSeries) {
                        delete highlightedSeries[seriesIndex];
                    }
                    if (lastHighlighted) {
                        unHighlightSeries(lastHighlighted);
                    }
                    lastHighlighted = item.series;
                    highlightSeries(item.series);
                }
                else if (!item && lastHighlighted) {
                    unHighlightSeries(lastHighlighted);
                    lastHighlighted = null;
                }
            });
        });

        function getSeriesAndIndex(series) {
            var allPlotSeries = plot.getData();
            if (typeof series == "number") {
                return [series, allPlotSeries[series]];
            }
            else {
                for (var ii = 0; ii < allPlotSeries.length; ii++) {
                    var plotSeries = allPlotSeries[ii];
                    if (
                        plotSeries === series
                        || plotSeries.label === series
                        || plotSeries.label === series.label
                    ) {
                        return [ii, plotSeries];
                    }
                }
            }
        }

        plot.hooks.drawOverlay.push(function (plot, ctx) {
            for(var seriesIndex in highlightedSeries) {
                plot.drawSeries(highlightedSeries[seriesIndex], ctx);
            }
        });
    }

    $.plot.plugins.push({
        init: init,
        options: options,
        name: "highlightSeries",
        version: "1.0"
    });
})(jQuery);