2010-05-06 6 views
7

J'ai un graphique que je dessine en utilisant flot. Je veux changer les couleurs des tracés de données lorsque quelqu'un survole le texte. Actuellement, je le fais en redessinant l'ensemble du graphique chaque fois que je dois mettre en évidence quelque chose. C'est assez lent (environ 30 millisecondes pour un graphique simple, autant que 100 pour un graphique plus compliqué). Puisque tout ce que je veux faire est de changer la couleur, y a-t-il une solution plus rapide?Existe-t-il un moyen de changer la couleur des graphiques dans le flot jQuery sans redessiner tout le graphique?

Répondre

12

Il existe des mesures immédiates que vous pouvez prendre pour optimiser le processus de dessin de Flot. Si vous n'avez pas besoin de points sur votre graphique, désactivez-les, cela peut réduire considérablement le temps de dessin. Vous devez également désactiver les ombres en réglant l'option shadowSize sur 0 pour améliorer la vitesse. En plus de ces deux réglages, vous devrez changer le code source du flot pour pouvoir mettre en évidence une série individuellement. J'ai créé un patch qui fait exactement cela, avec un petit plugin qui vous permet de mettre en évidence les séries automatiquement ou manuellement. Le correctif et le plugin peuvent être jusqu'à trois fois plus rapides que le redessin de l'ensemble du graphique, il élimine également pratiquement le temps nécessaire pour mettre en surbrillance une série, car il utilise la fonction «overlay» de flot.

Il y a un correctif pour jquery.flot.js et le code source pour le plugin highlightSeries ci-dessous et j'ai créé un demonstration page qui vous permet de voir la différence entre différents réglages ainsi que la combinaison patch/plugin.

Le patch 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 de 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); 
Questions connexes