2

Is it possible to find a better/ modular way to assign the same color to paired rather than hard-coding them as I currently implement?

If objects fname matches, then assign the same color.

The following is a subset of javascript objects.

data[0] = [{
    "value": 29,
    "series": 1,
    "category": "Men",
    "fname": "NY",
     "valueColor": "red"
},


data[1] = [{
    "value": 19,
    "series": 4,
    "category": "Women",
    "fname": "NY",
     "valueColor": "red"
},

data[2] = [{
    "value": 9,
    "series": 3,
    "category": "LG",
    "fname": "NY",
    "valueColor": "red"
},

Here is the full implementation in FIDDLE

First I assume, all objects are different and assign a different color, then I will check if there are any paired objects, if yes, then assign the same color.

Therefore it would be nice to generate colorSpectrum based on a number of objects in exists in datasets rather than assigning common colors such as red, green, yellow, etc.. because you cannot guess in advance how many different objects you would get. I might get around maybe 10 objects, maybe around 100 objects. Therefore, I am looking for a modular way to handle this difficulty.

Here is the colorSpectrum method implementation in COLOR SPECTRUM FIDDLE

Udara Abeythilake
  • 1,215
  • 1
  • 20
  • 31
casillas
  • 16,351
  • 19
  • 115
  • 215
  • You want all objects sharing a common *fname* value to have the same *valueColor* value as well? If so, how do you determine the appropriate color for a given *fname* value? – Sampson Jun 04 '15 at 22:43
  • Yes, Jonathan exactly. Please see my updated question. – casillas Jun 04 '15 at 22:44
  • Does your site use lodash by chance? – Kevin F Jun 04 '15 at 22:45
  • First time I heard `lodash`, it means no. – casillas Jun 04 '15 at 22:46
  • @AndreaBanderas What do you mean when you suggesting generating a color based on the number of objects that exist? Should objects with more instances have a *darker* color, for instance? – Sampson Jun 04 '15 at 22:47
  • Also, are you counting the number of objects across `data[0]`, `data[1]`, etc? Or are you only counting similar objects in the same top-level array index? – Sampson Jun 04 '15 at 22:49
  • Hello Jonathan, I have given code as well. Actually, I wont know how many objects will exist in total. Therefore, based on the number of objects, I generate colorspectrum, then check if `fname` is same, then assign the same color across. – casillas Jun 04 '15 at 22:49
  • Yes, I should count the number of objects in `data[0]`, `data[1]`, `data[2]`,. etc. First I assume, all objects are different and assign a different color, then I will check if there are any paired objects, if yes, then assign same color. – casillas Jun 04 '15 at 22:51
  • @JonathanSampson, is my question clear as it stands now? – casillas Jun 04 '15 at 23:01
  • So the common color should be the total number of objects with a shared *fname* property, used as an index in the color spectrum? So, if we have 25 "NY" objects, they should have whatever color is at `colorSpectrum[24]`? – Sampson Jun 04 '15 at 23:05
  • Lets assume `data[0].length+data[1].length+data[2].length` is 20. Than it means I should have 20 different colors and assigned each object initially. Then I will check if there is any common `fname`'s name in the `dataset [data[0],data[1], data[2]]`, if yes, then make/assign the same color for these objects.please let me know , if that is clear? – casillas Jun 04 '15 at 23:10
  • 1
    Assigning same color to objects with same `fname` is clear. To me, understanding the spectrum was difficult. Anyways, are you looking for something like this http://jsfiddle.net/dhirajbodicherla/fm79hsms/7/ ? In this example, 18 spectrum colors are generated as per the data and objects with same fname have same color. – Dhiraj Jun 04 '15 at 23:25
  • Yes, exactly. please provide as an answer, then I will upvote and mark it. The only thing that bothers me, legends colors is not updated afterwards. – casillas Jun 04 '15 at 23:29

1 Answers1

2

You can do something like this.

function colorSpectrum(N) {
    var colorMap = [], inc = 50, start = 1000;
    for (i = start; i < start+N*inc; i+=inc) {
        var num = ((4095 * i) >>> 0).toString(16);
        while (num.length < 3) {
            num = "0" + num;
        }
        colorMap.push("#" + num);
    }
    return colorMap;
}

function process(data){
    var map = {}, colorMap = colorSpectrum(data.length);
    data.forEach(function(item, index){
        if(!map.hasOwnProperty(item.fname)){
            map[item.fname] = colorMap[index];
        }
        data[index].valueColor = map[item.fname];
    }); 

    return data;
}

data = process(data);

Here is a demo http://jsfiddle.net/dhirajbodicherla/fm79hsms/7/

Dhiraj
  • 33,140
  • 10
  • 61
  • 78
  • Do you have any idea why legends do not match with bar stack chart colors? – casillas Jun 05 '15 at 02:30
  • 1
    @AndreaBanderas: That is so weird. No matter which color the chart is, the legend color doesn't seem to change. I will let you know once I figure out something. – Dhiraj Jun 05 '15 at 03:02
  • I have got an answer, but when I combine it, it does not work. http://stackoverflow.com/questions/30656016/legend-and-bar-chart-colors-do-not-match – casillas Jun 05 '15 at 03:33
  • 1
    @AndreaBanderas: looks super hacky. But only the last 3 legend items are working. Insane ! – Dhiraj Jun 05 '15 at 03:50
  • I think we are doing something fundamentally wrong in grouping. If I give this `group: { field: "fname" }` the legend seems to be working. I cannot totally conclude, but having same colors based on `fname` might be the problem because the chart itself gives a color based on groups – Dhiraj Jun 05 '15 at 04:21
  • could u please share fiddle? – casillas Jun 05 '15 at 04:23
  • http://jsfiddle.net/dhirajbodicherla/9t1gnfrk/6/ in this sample, colors are set based on `series` instead of `fname` and legend colors work perfectly – Dhiraj Jun 05 '15 at 04:25
  • But now you lost paired object same color. Just watch `NY` object color across the bar stack. – casillas Jun 05 '15 at 04:27
  • True. That is exactly my point. Kendo generates charts by grouping `series` and the legend color is based on that grouping. By explicitly setting legends colors based on `fname`, the original legend coloring is violated. – Dhiraj Jun 05 '15 at 04:31
  • 1
    Check the following jsfiddle that I made it work http://jsfiddle.net/1ost124j/1/ I have added `e.series.data[i].fname != ""` into `if (e.series.data[i].valueColor != "" && e.series.data[i].fname != "")` – casillas Jun 05 '15 at 04:35
  • @AndreaBanderas: NICE !! How ? – Dhiraj Jun 05 '15 at 04:36
  • Because your solution looks for dataset length, even there is no `fname`, but still generates color for that objects as well, therefore I need to add that criteria to make it work properly. When I debug , then I have realized there is a bug. – casillas Jun 05 '15 at 04:38
  • Now, I need to figure out, how to assign `fname` as a legend! Do you have any thing in your mind? I need to tweak the following `var label = new kendo.drawing.Text(e.series.name, [0, 0]`.. Thanks a lot Dhiraj for helping me out. Appreciated! – casillas Jun 05 '15 at 04:39
  • Here is my question http://stackoverflow.com/questions/30658508/custom-legend-label – casillas Jun 05 '15 at 04:46