2010-05-06 4 views
7

Ich habe ein Diagramm, das ich mit Flot zeichne. Ich möchte die Farben der Datendiagramme ändern, wenn jemand über Text schwebt. Derzeit mache ich das, indem ich jedes Mal das gesamte Diagramm neu zeichne, wenn ich etwas hervorheben muss. Dies ist ziemlich langsam (ungefähr 30 Millisekunden für ein einfaches Diagramm, so viel wie 100 für ein komplizierteres Diagramm). Da ich nur die Farbe ändern möchte, gibt es eine schnellere Lösung?Gibt es eine Möglichkeit, die Farbe von Plots in jQuery flot zu ändern, ohne das gesamte Diagramm neu zu zeichnen?

Antwort

12

Es gibt sofortige Schritte, um den Zeichnungsprozess von Flot zu optimieren. Wenn Sie keine Punkte in Ihrem Diagramm benötigen, schalten Sie diese aus, dies kann die Zeichnungszeit erheblich reduzieren. Sie sollten die Schatten auch ausschalten, indem Sie die Option shadowSize auf 0 setzen, um die Geschwindigkeit zu verbessern.

Neben diesen beiden Optimierungen müssen Sie den Flot-Quellcode ändern, um eine Reihe einzeln hervorheben zu können. Ich habe einen Patch erstellt, der genau das tut, zusammen mit einem kleinen Plugin, mit dem Sie Serien automatisch oder manuell hervorheben können. Der Patch und das Plugin können bis zu dreimal schneller als das gesamte Diagramm neu zeichnen, es beseitigt auch praktisch die Zeit, die es dauert, eine Serie un-markieren, da es flot "Overlay" -Funktion verwendet.

Es gibt einen Patch für jquery.flot.js und den Quellcode für das highlightSeries-Plugin unten und ich habe eine demonstration page erstellt, mit der Sie den Unterschied zwischen verschiedenen Einstellungen sowie der Patch/Plugin-Kombination sehen können.

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 Plugin

/* 
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); 
Verwandte Themen