Hitachi Vantara Pentaho Community Forums
Results 1 to 9 of 9

Thread: CCC2 BarChart color coding

  1. #1
    Join Date
    Dec 2012
    Posts
    121

    Default CCC2 BarChart color coding

    Hi all,
    i have a bar chart and i would obtain an effect as explained on the attachment.
    The image show the correct match between the lines color and the bars color, using a static format on color property.
    However, if some columns miss (e.g. since data not exists), the color coding not work.
    In fact, I want to associate a color to a serie on my chart, but how can i access to these properties and change them dynamicallly before the rendering on video?

    Yamas
    Name:  img.jpg
Views: 1246
Size:  19.1 KB

  2. #2
    Join Date
    Mar 2012
    Posts
    645

    Default

    Hi marcolino,

    COLOR MAP
    You might be looking for what is provided by the "colorMap" option and also, possibly, by the "color2AxisMap" option, in case you have a separate color scale for plot2.
    This is already more or less explained in this post: http://forums.pentaho.com/showthread...given-category!!! .

    RETHINKING
    But, by watching your example, what you might really want is that "color" would be applied according to the suffix ".../1, ".../2", that your series show.
    If that information ".../1" was available as a separate column you could do more interesting things.
    For instance, you would not have to "hard-code" specific series values in order to fixate colors, for use in the colorMap.

    I materialized the final solution here presented as a live example in: http://www.webdetails.pt/ctools.html#tabccc > "CCC . CHARTS" > "BAR" > "PAIRED BAR-LINE MEASURES".

    Suppose you had the following resultset, which is similar to that of your example:
    Code:
        Color                      Bars         Lines
          v                         v             v
    +------------+------------+------------+-------------+
    | Series     |  Category  | Count      | AvgLatency  |
    +------------+------------+------------+-------------+
    | 1          | 8          | 35000      + 140         |
    | 1          | 9          | 40000      + 120         |
    | 1          | 10         | 45000      + 115         |
    | 1          | 11         | null       + 110         |
    +------------+------------+------------+-------------+
    | 2          | 8          | 70000      | 220         |
    | 2          | 9          | 80000      | 180         |
    | 2          | 10         | 115000     | 170         |
    | 2          | 11         | 45000      | 145         |
    +------------+------------+------------+-------------+
    | 3          | 8          | 70000      | 200         |
    | 3          | 9          | 90000      | 190         |
    | 3          | 10         | 120000     | 180         |
    | 3          | 11         | 30000      | 130         |
    +------------+------------+------------+-------------+
    ...
    It contains 1 series column, 1 category column and two measure columns.
    If you use the cross-tab format, the first two columns would be identified as "row" columns and the remaining as "column/measure" columns.
    When the cross-tab translator reads this table it actually transforms it to an internal intermediate format where each "row", in CCC, is called the "virtual item" - a relational view of the cross-tab resultset:

    Code:
                    Color                      
                      v                     
    +------------+------------+------------+------------+
    | Measure    | Series     |  Category  | Value      |
    +------------+------------+------------+------------+
    | Count      | 1          | 8          | 35000      |
    | Count      | 1          | 9          | 40000      |
    | Count      | 1          | 10         | 45000      |
    | Count      | 1          | 11         | null       |
    | AvgLatency | 1          | 8          | 140        |
    | AvgLatency | 1          | 9          | 120        |
    | AvgLatency | 1          | 10         | 115        |
    | AvgLatency | 1          | 11         | 110        |
    +------------+------------+------------+------------+
    | Count      | 2          | 8          | 70000      |
    | Count      | 2          | 9          | 80000      |
    | Count      | 2          | 10         | 115000     |
    | Count      | 2          | 11         | 45000      |
    | AvgLatency | 2          | 8          | 220        |
    | AvgLatency | 2          | 9          | 180        |
    | AvgLatency | 2          | 10         | 170        |
    | AvgLatency | 2          | 11         | 145        |
    +------------+------------+------------+------------+
    | Count      | 3          | 8          | 70000      |
    | Count      | 3          | 9          | 90000      |
    | Count      | 3          | 10         | 120000     |
    | Count      | 3          | 11         | 30000      |
    | AvgLatency | 3          | 8          | 200        |
    | AvgLatency | 3          | 9          | 190        |
    | AvgLatency | 3          | 10         | 180        |
    | AvgLatency | 3          | 11         | 130        |
    +------------+------------+------------+------------+
    ...
    So now it is more clear that:
    • the "Measure" column value should be used to split rows between the bar and the line plots
    • the "Series" column value should be used to drive the color


    DATA TRANSLATION
    We must help the cross-tab translator, by telling him that the first two resultset columns are to be understood as cross-tab "rows":
    Code:
    crosstabMode: true,
    dataCategoriesCount: 2,
    Note that this is only needed because the "series" column contains numeric data.
    Otherwise, the translator is smart enough to conclude that the column would be a "row" column.

    Also, the default mapping, from virtual-item's columns into dimension names, that the coss-tab translator uses does not suit our needs.
    We must explicitly tell CCC what the mapping should be:
    Code:
    readers: ['measure, series, category, value'],
    DATA ROUTING
    Next, we need to make the "Count" rows go to the bars and the "AvgLatency" rows go to the lines.
    In CCC, data is split among plots by using a special hidden dimension called "dataPart".
    When a row has a "dataPart" equal to "0", it feeds the chart's main plot, in this case, the bar plot.
    When it has the value "1", it feeds the chart's second plot, in this case, the line plot.
    This dimension is calculated, by default, by using the values specified in the option "plot2Series", which you might already know.
    You can also calculate this dimension yourself, using some other logic, like the one we need for this example:

    • Measure = "Count" => dataPart = "0"
    • Measure = "AvgLatency" => dataPart = "1"


    In CCC options language, this can be expressed by using a dimension calculation:
    Code:
    calculations: [{
        names: 'dataPart',
        calculation: function(datum, atoms) {
            atoms.dataPart = 
                datum.atoms.measure.value === 'Count' ? 
                '0' :  // main plot:   bars
                '1' ;  // second plot: lines
        }
    }],
    LEGEND LABEL
    There's one last important detail. Without further configuration, the legend would show correct colors but the labels of both the bars and lines would be the same: "1", "2", "3" - the values of the series dimension.
    To fix this, we need to override the legend item's label description.
    I know you will jump immediately into adding the extension point "legendLabel_text":
    Code:
    legendLabel_text: function(scene) {
        return scene.vars.value.label + " / " + scene.atoms.measure.label;
    },
    Yet, although this effectively changes the text, you'll find that the layout of items will not take the extra text into account, causing legend items to overlap each other.
    This will work only if you can do with fixating the value of the "legendSize" option, which disables automatic size determination.
    If you want the layout to take the new text into account, you'll have to update the legend item text in a time sooner than when the label's extension point does.
    The way you do this in CCC2 is by extending the legend item "scene" object itself, and change the way in which the "value" variable's label is calculated:
    Code:
    legend: {
        scenes: {
           item: {
                value: function() {
                    // Obtain default variable
                    var v = this.base();
                    
                    // Add the measure label to the
                    // "value" variable's label
                    v.label += " / " +
                        this.firstAtoms.measure;
                    return v;
                }
            }
        }
    },
    COLOR2 AXIS
    Another thing you might notice is that the line colors are the same as bar colors, yet they are slightly brighter.
    The second plot uses the second color axis, by default. Also, by default, this axis uses the same colors as those of the first axis.
    The difference is that (in this situation and by default) the second color axis applies a transformation on each color, making each a brighter version of the source color.
    The reason is to make it possible to distinguish a line that overlaps a bar of same color.
    You might wanna take a look at the option "color2AxisTransform".
    Last edited by duarte.leao; 04-09-2013 at 07:04 AM.

  3. #3
    Join Date
    Dec 2012
    Posts
    121

    Default

    Great stuff man!!!
    I had found another solution, but i believe i will use it for another work!
    But, i didn't understand how to change the label of legend...

    legend: {
    scenes: {
    item: {
    value: function() {
    // Obtain default variable
    var v = this.base();

    // Add the measure label to the
    // "value" variable's label
    v.label += " / " +
    this.firstAtoms.measure;
    return v;
    }
    }
    }
    },


    Where have i to insert this code? I tried in PostExecution function, but it doesn't work...

    Any help is appreciated.

    Best Regards
    Yamas

  4. #4
    Join Date
    Mar 2012
    Posts
    645

    Default

    Thanks marcolino,

    Those options (legend.scenes.item.value) are to be placed in the same place as all the others: postFetch or postExecution (where postFetch is preferable because it is supported by CGG as well).
    That's a feature that only recently has been exposed. It's only available in the DEV branch, please update your CDF and CGG.

  5. #5
    Join Date
    Dec 2012
    Posts
    121

    Default

    Yes, i have CCC2.
    I downloaded it some weeks ago.
    You think this updates are included?

    Thanks in advance for the great great stuff!!!!!
    ;-)

    Yamas

  6. #6
    Join Date
    Dec 2012
    Posts
    121

    Default

    I have inserted the follow code both on PostFetch and in the PostExecution functions, obtaining an Error CHART (it is not displayed):

    function f(){
    Dashboards.log(this.legend.scenes.item.value);
    //$.each(this, function(i, n){
    // Dashboards.log(i +" " + n);
    //});

    }


    Any suggestions?

  7. #7
    Join Date
    Mar 2012
    Posts
    645

    Default

    Hi, you really need to update CDF and CGG. This feature is more recent than "some weeks ago" :-/

  8. #8
    Join Date
    Mar 2012
    Posts
    645

    Default

    Just a quick note on using postFetch, postExecution, or any other CDE Chart component handler.
    When you want to manually specify CCC options you should do it like this:

    Code:
    function f(<depends on the handler>) {
       
       var cccOptions = this.chartDefinition;
    
       cccOptions.crosstabMode = true;
       cccOptions.dataCategoriesCount = 2;
       cccOptions.legend = {
          scenes: {
              item: {
                   // ....
              }
          }
       };
    
       // For changing extension points, a little more work is required:
       var eps = Dashboards.propertiesArrayToObject(cccOptions.extensionPoints);
    
       // add extension points:
       eps.legendLabel_text = function(){ ... };
    
       // Serialize back eps into cccOptions
       cccOptions.extensionPoints = Dashboards.objectToPropertiesArray(eps);
    
       // return <depending on the handler, may need to return something>;
    }
    The postFetch handler has the following signature:
    Code:
    function f(data) {
        // change data, if desired
        
       // return new data
        return data;
    }

  9. #9

    Default

    Quote Originally Posted by marcolino View Post
    Name:  img.jpg
Views: 1246
Size:  19.1 KB
    How did you set the "Latenza Media" axis?
    I can't figure out how to do that!


    Thanks in advance.


    EDIT: Solved! Must change the index in plot2OrthoAxis property
    Last edited by emicarnicero; 02-26-2014 at 09:05 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Privacy Policy | Legal Notices | Safe Harbor Privacy Policy

Copyright © 2005 - 2019 Hitachi Vantara Corporation. All Rights Reserved.