US and Worldwide: +1 (866) 660-7555
Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Bar chart colors dynamically changed based on data value. Along with JavaScript vars

  1. #1

    Default Bar chart colors dynamically changed based on data value. Along with JavaScript vars

    Hey Everyone,

    I am sorry if I am asking a question that has been asked before, but I have not been able to get the desired funtionality out of my bar chart.

    First my goal. I would like to change the bar chart individual bars to different colors based on the data that they represent. For example, if they are less than 1 the color would be green, if they are between 1 and 3 they would be yellow, and if they were above 3 they would be red.

    I have seen two approaches to manipulating the charts, one is through using the extension points and putting a function in the value. The second is by using the post execution scripts.

    I have tried some of these, for example with extension points:

    bar_fillStyle | function(a){if(a<99.8){return "red"}else{return "green"}}

    However this always returns green. I added an alert(a); at the beginning to see what my "a" variable returned, and the message I got was "pvc.visual.Scene". This was clearly not the variable I wanted, because I wanted the data for each bar chart.

    I guess this boils down to being new at JavaScript (and CDE), but how do I know what a variable represents? I noticed that a lot of people seem to pass through "d" as a data variable but that also returns "pvc.visual.Scene". Do I need to define the variable somewhere before I can use it, or is there a list of already defined variables? Any help would be appreiated. Thanks!

  2. #2

    Default

    In the latest version i.e. CCC2 you should be able to use the following in post fetch:

    function f() {
    // Series Value : Color
    this.chartDefinition.colorMap = {
    "10": 'red',
    "12": 'green'
    };
    }

    To get access to the actual data, in the same postfetch:

    function f(values)
    {
    console.log(values);
    }

    values has metadata and resultset.

  3. #3

    Default

    When I do this the log describes values as "undefined". Is there anywhere I can go to see all these variables, like values, metadata, or resultset?

  4. #4
    Join Date
    Mar 2012
    Posts
    642

    Default

    Hi decarlo,

    if I understand well, you want to assign colors to bars according to their value being in value bucket A, B, C,...

    See this example for a clean way to do this. It works well with the legend. Basically, you create an auxiliary data dimension (another column...) that calculates the bucket in which the value falls.
    Then, you bind the color role to that new dimension.

    In the future, we might provide a way to configure scales to do the quantization directly, given the value ranges.

  5. #5

    Default

    try the f(values) in postfetch

  6. #6

    Default

    The function f(values) is working, thanks.

    Duarte Leao,

    I have seen this jFiddle before but am not too familiar with it too much. I use the Community Dashboard Editor to create my dashboards, and it seems to hide the javascript from the user. How would I go about using the javascript that you showed me?

    Thanks!

  7. #7
    Join Date
    Mar 2012
    Posts
    642

    Default

    Hi decarlo,

    most CCC options are available directly as CDE properties.
    For the ones that are not, usually complex-valued options, you have to use JavaScript to set them.
    See how here, here and here.

  8. #8

    Default

    Thanks for these links, they are quite usefull.

    So I have been somewhat successful in getting the bars to change colors. I have added this to my post execution

    function f(){
    var bar = this.chart.barChartPanel.pvBar;
    var chart = this.chart;
    var resultset = this.query.lastResults().resultset;

    for(var i = 0; i < resultset.length; i++){
    var dataVal = resultset[i][1];
    var child = bar.childIndex[i];

    if(dataVal > 0 && dataVal <= 2){
    alert('green '+dataVal);
    bar.fillStyle("green").root.render();
    }
    else if(dataVal > 2 && dataVal <= 4){
    alert('yellow '+dataVal);
    bar.fillStyle("yellow").root.render();
    }
    else if(dataVal > 4 && dataVal <= 7){
    alert('red '+dataVal);
    bar.fillStyle("red").root.render();
    }
    else{
    alert('red '+dataVal+" "+bar);
    bar.fillStyle("black").root.render();
    }

    }
    }

    I have two bars one is about 4.5 and the other is 9.8, so in theory I should have one red bar and one black bar. I get the alert for both red and black but at the end of it both of my bars in the chart are black. I assume this is because when I call the bar.fillStyle("black").root.render(); "bar" refers to the entire bar chart and all the bars in the bar chart. Is there any way I can apply the colors to the separate bars? I havent been successful as of yet, but I think I am getting closer.

  9. #9
    Join Date
    Mar 2012
    Posts
    642

    Default

    Hi decarlo,

    it's good that you experiment with CCC and direct access to the underlying protovis marks, that CCC uses.
    But, or I didn't understand what you're trying to do, or you're totally missing the point.

    Your traversing the resultset. This is simply an array. But every time you change fillStyle with a constant value, you're changing it in every instance of the mark, whatever its index is.
    For what you want, just specify the "bar_fillStyle" extension point, directly in the CDE property, or in code, in preExecution or postFetch.
    Pass a function to it that tests the value of this.scene.vars.value.value and returns an appropriate color.

    Anyway, apart from learning and experimenting, please don't go, neither in the "postExecution" way, cause you're re-rendering the chart twice, without any need, neither in the extension point way I just described. You're missing and duplicating things that CCC already does, in other ways.

  10. #10

    Default

    Duarte, you are a life saver, thanks for taking the time to help me figure this out. I got the desired functionality by adding the following to the PreExecution.

    function changeBars(){
    var cccOptions = this.chartDefinition;

    // For changing extension points, a little more work is required:
    var eps = Dashboards.propertiesArrayToObject(cccOptions.extensionPoints);

    // add extension points:
    eps.bar_fillStyle = function getColor(){
    var val = this.scene.vars.value.value;

    if(val > 0 && val <= 2){
    return 'green';
    }
    else if(val > 2 && val <= 4){
    return 'yellow';
    }
    else if(val > 4 && val <= 7){
    return 'red';
    }
    else{
    return 'black';
    }
    };

    // Serialize back eps into cccOptions
    cccOptions.extensionPoints = Dashboards.objectToPropertiesArray(eps);
    }


    Thanks for all the help resolving this!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •