zwalker
zwalker

Reputation: 346

Combining user seleted and auto generated colors in flot

I would like to use both the user selected and auto generated data series coloring in combination such that when a new data series is added colors are auto generated but all other data series already plotted will remain the same color.

When first adding a new data series, I leave the color option empty so that a color is auto assigned.

When re-plotting I extract color information from the an existing plot before re-plotting

I then look at the resulting color map and reassign the same color to the corresponding data series when re-plotting.

The problem is that when I add data series serially in this way with a call to $.plot between each data series addition, I end up with multiple data series assigned to the same color.

Example:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Color Test Harness</title>
        <script src="./lib/jquery.js"></script>
        <!--[if IE lte 8]><script src="../lib/excanvas.js"></script><![endif]-->
        <script src="./lib/jquery.flot.js"></script>
    </head>
    <body>
        <h1>Test graph</h1>
        <div id="graph1" style="width:600px;height:300px;"></div>

<script type="text/javascript">
$(function() {

    var data = [ [1, 2], [2, 3], [4, 1] ];
    var plot = $.plot($("#graph1"), {}, {});
    function findColors() {
        var c = {};
        if(plot != null) {
            var series = plot.getData();
            for(var i = 0; i < series.length; i++) {
               var aSeries = series[i];
               c[aSeries.label] = aSeries.color;
            }
        }
        return c;
    }

    var all_data = [];
    for(var i = 0; i < 5; i++) {
        var colors = findColors();
        var dataObj = { 'label' : "data" + i, 'data' : data };
        all_data.push(dataObj);

        for(var j = 0; j < all_data.length; j++) {
            if(colors.hasOwnProperty(all_data[j].label)) {
                all_data[j].color = colors[all_data[j].label];
            }
        }
        plot = $.plot($("#graph1"), all_data, {});
    }
})
</script>
    </body>
</html>

How can I get the color generator to make sure it uses a color that isn't already pre allocated to one of the other data series?

Upvotes: 0

Views: 582

Answers (1)

Ryley
Ryley

Reputation: 21226

The colors are just numbers, an index really. So when you are doing the findColors() thing, make an object that tracks which colors are already in use (i.e. right now you have label -> color, also make one that is just color -> 1). Then, later when you are creating new series, have a little function that goes through your colorsUsed object and looks for an unassigned color index:

var colors = findColors();

var colorsUsed = findUsedColors(colors);

function findUsedColors(c){
    var cu = {};

    $.each(c,function(k,v){
       cu[v] = 1;
    });
    return cu;
}

function findUnassignedColor(cu){
    for (var i=0;i<2000;i++){
      if (!cu[i]){
         cu[i] = 1;
         return i;
      }
    }
}


// then later, when assigning a color
   for(var j = 0; j < all_data.length; j++) {
        if(colors.hasOwnProperty(all_data[j].label)) {
            all_data[j].color = colors[all_data[j].label];
        } else {
            all_data[j].color = findUnassignedColor(colorsUsed);
        }
    }

Upvotes: 1

Related Questions