views:

316

answers:

4

Hi all,

I think I may have stumbled onto a limitation of Flot, but I'm not sure. I'm trying to represent a single data series over time. The items' "State" is represented on the Y-Axis (there are 5 of them), and time is on the X-Axis (items can change states over time). I want the graph to have points and lines connecting those points for each data series.

In addition to tracking an item's State over time, I'd also like to represent it's "Status" at any of the particular points. This I would like to do by changing the color of the points. What this means is a single item may have different Statuses at different times, meaning for a single data series I need a line that connects different points (dots) of different colors.

The only thing I've seen so far is the ability to specify the color for all points in a given dataseries. Does anyone know if there's a way to specify colors individually?

Thanks.

+2  A: 

With 3 views, it may not be worth answering my own question, but here's the solution:

My original problem was how to plot a dataseries of points and a line, but with each point being a color that I specify.

Flot only allows specifying colors of the dots at the dataseries level, meaning each color must be its own dataseries. With this in mind, the solution is to make a single dataseries for each color, and draw that dataseries with only points, and no lines. Then I must make a separate dataseries that is all of the dots I want connected by the line, and draw that one with no points, and only a line.

So if I want to show a line going through 5 points with five different colors, I need 6 dataseries: 5 for each point, and 1 for the line that connects them. Flot will simply draw everything on top of each other, and I believe there's a way to specify what gets shown on top (to make sure the dots are shown above the line).

Mega Matt
Thanks so much for posting this! It seems obvious now that I've read it, but I hadn't thought of it, so you saved me a lot of time.
Derek Kurth
+3  A: 

Actually, it's not very difficult to add a feature to flot that would call back into your code to get the color for each point. It took me about an hour, and I'm not a javascript expert by any measure.

If you look at drawSeriesPoints(), all you have to do is pass a callback parameter to plotPoints() which will be used to set ctx.strokeStyle. I added an option called series.points.colorCallback, and drawSeriesPoints() either uses that, or a simple function that always returns the series.color.

One tricky point: the index you should pass to your callback probably isn't the i in plotPoints(), but rather i/ps.

Hope this helps!

Gideon
A: 

Hi Matt,

Thanks a lot for posting your solution, even with only 3 views. Your clear explanation saved me of potentially a few hours of researching.

Thanks!

Ludovic
A: 

There you go mate. You need to use a draw hook.

$(function () {

  var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]];
  var colors = ["#cc4444", "#ff0000", "#0000ff", "#00ff00"];
  var radius = [10, 20, 30, 40];

  function raw(plot, ctx) {
    var data = plot.getData();
    var axes = plot.getAxes();
    var offset = plot.getPlotOffset();
    for (var i = 0; i < data.length; i++) {
        var series = data[i];
        for (var j = 0; j < series.data.length; j++) {
            var color = colors[j];
            var d = (series.data[j]);
            var x = offset.left + axes.xaxis.p2c(d[0]);
            var y = offset.top + axes.yaxis.p2c(d[1]);
            var r = radius[j];                
            ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.arc(x,y,r,0,Math.PI*2,true);
            ctx.closePath();            
            ctx.fillStyle = color;
            ctx.fill();
        }    
    }
  };  

    var plot = $.plot(
          $("#placeholder"),
          [{ data: d2, points: { show: true } }],
          { hooks: { draw  : [raw] } }
  );  
});
Tupak Goliam