一千萬個為什麽

搜索

有沒有辦法在不重繪整個圖表的情況下改變jQuery flot中的繪圖顏色?

我有一張圖表,我正在使用flot繪圖。當有人將鼠標懸停在文本上時,我想更改數據圖的顏色。目前,我每次需要突出顯示某些內容時都會重新繪制整個圖表。這非常慢(簡單圖表大約30毫秒,更復雜的圖表大約100毫秒)。既然我想做的就是改變顏色,那麽有更快的解決方案嗎?

最佳答案

您可以立即采取措施來優化Flot的繪圖過程。如果圖表上不需要點,請將其關閉,這可以顯著縮短繪圖時間。您還應通過將 shadowSize 選項設置為0來關閉陰影,以提高速度。

除了這兩個調整之外,您還必須更改flot源代碼才能單獨突出顯示一個系列。我創建了一個完全相同的補丁,以及一個允許您自動或手動突出顯示系列的小插件。補丁和插件最多可以比重繪整個圖表<�強>三倍,它實際上也消除了取消突出顯示系列所需的時間,因為它使用了flot的“疊加”功能。

有一個jquery.flot.js的補丁和下面的highlightSeries插件的源代碼,我創建了一個演示頁面,可以讓您看到各種設置之間的差異以及補丁/插件組合。

Flot補丁

--- .\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);

轉載註明原文: 有沒有辦法在不重繪整個圖表的情況下改變jQuery flot中的繪圖顏色?