2010-05-06 41 views
7

我有我正在使用flot繪製的圖表。當某人懸停在文本上時,我想更改數據圖的顏色。目前,我通過在每次需要突出顯示某些內容時重新繪製整個圖表來完成此操作。這很慢(對於簡單的圖表來說,大約是30毫秒,對於更復雜的圖表來說可能是100)。因爲我想要做的只是改變顏色,是否有更快的解決方案?有沒有辦法在不重繪整個圖表的情況下更改jQuery flot中的圖的顏色?

回答

12

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

除了這兩項調整之外,您還必須更改flot源代碼才能單獨突出顯示一個系列。我已經創建了一個可以完全實現的補丁,以及一個允許您自動或手動高亮顯示系列的小插件。這個補丁和插件可以高達,比重繪整個圖形要快三倍,因爲它使用了flot的「疊加」功能,所以它實際上也消除了取消選中某個系列所需的時間。

下面是jquery.flot.js和用於highlightSeries插件的源代碼的補丁,我創建了一個demonstration page,可以讓您看到各種設置以及補丁/插件組合之間的區別。

海軍報修補

--- .\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); 
相關問題