2010-05-06 9 views
7

Tengo un gráfico que dibujo usando flot. Quiero cambiar los colores de los gráficos de datos cuando alguien pasa el cursor sobre el texto. Actualmente, estoy haciendo esto redibujando el cuadro completo cada vez que necesito resaltar algo. Esto es bastante lento (alrededor de 30 milisegundos para un gráfico simple, tanto como 100 para un gráfico más complicado). Como todo lo que quiero hacer es cambiar el color, ¿hay una solución más rápida?¿Hay alguna manera de cambiar el color de las trazas en jQuery flot sin volver a dibujar todo el gráfico?

Respuesta

12

Hay pasos inmediatos que puede tomar para optimizar el proceso de dibujo de Flot. Si no necesita puntos en su gráfico, desactívelos, esto puede reducir significativamente el tiempo de dibujo. También debe desactivar las sombras, configurando la opción shadowSize en 0, para mejorar la velocidad.

Además de esos dos ajustes, tendría que cambiar el código fuente de flot para poder resaltar una serie individualmente. Creé un parche que hace exactamente eso, junto con un pequeño complemento que le permite resaltar series automática o manualmente. El parche y el complemento pueden ser hasta tres veces más rápidos que redibujar todo el gráfico, también prácticamente elimina el tiempo que lleva desatar una serie, ya que utiliza la función de "superposición" de flot.

Hay un parche para jquery.flot.js y el código fuente para el complemento highlightSeries a continuación y he creado un demonstration page que le permite ver la diferencia entre varias configuraciones, así como la combinación de parche/complemento.

Flot parche

--- .\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 de

/* 
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); 
Cuestiones relacionadas