coding_bird
coding_bird

Reputation: 573

Parse JSON with containing function

I want to create a diagram like this:

I want to create this diagram

<script>
var chart = c3.generate(
    {
        data: {
            x: 'year',
            columns: [
                ['year', 1991, 1992, 1993, 1994, 1995, 1998],
                ['value', 1, -3, -6, -5, 2, -3]
                    ],
            type: 'bar',            
            labels: true,           
            color: function (color, d) {
                if(d.value < -1){
                    return d3.rgb('red');
                }
                else if(d.value >= -1 && d.value <= +1){
                    return d3.rgb('grey');
                }               
                else {
                    return d3.rgb('blue');
                }
            }
        }
    }
    );  

</script>

This works pretty well, but now I want to do the same with varying input data. My plan to do this like in this minimal example:

    <script>

    var myYears = ', 1991, 1992, 1993, 1994, 1995, 1998';  //shall be created automatically 
    var myValues = ', 1, -3, -6, -5, 2, -3'; //shall be created automatically 

    var textJSON = '{' +
            '"data": {' +
                '"x": "year",'  +
                '"columns": ['  +
                '   ["year"' + myYears +'],' +
                '   ["value"' + myValues +']' +
                '       ],' +
                '"type": "bar"' +
                '}' +
                '}' ;

    var c3JSON = JSON.parse(textJSON);
    var chart = c3.generate( c3JSON );   

    </script>

This works as well, but when I try to add the rule for the different colors into my text, it does not work to parse it to a JSON.

Do you know how I can insert the color function into my text in order to parse it correctly to a JSON?

        color: function (color, d) {
            if(d.value < -1){
                return d3.rgb('red');
            }
            else if(d.value >= -1 && d.value <= +1){
                return d3.rgb('grey');
            }               
            else {
                return d3.rgb('blue');
            }
        }

Upvotes: 3

Views: 85

Answers (1)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34234

Oh, you don't need to convert your values to a JSON string manually using concatenation, and then parse it back to the JS object. It looks really awful.

Just do the following:

var myYears = ', 1991, 1992, 1993, 1994, 1995, 1998';  //shall be created automatically 
var myValues = ', 1, -3, -6, -5, 2, -3'; //shall be created automatically 

var yearsArray = myYears.split(', '); 
yearsArray[0] = 'year';

var valuesArray = myValues.split(', '); 
valuesArray[0] = 'value';

String.prototype.split function will convert your string

, 1991, 1992, 1993, 1994, 1995, 1998

to the array by splitting it by ", " and will result in the following array:

["", "1991", "1992", "1993", "1994", "1995", "1998"]

As you need to specify a name of your column as the first item (or sort of it), you can simply assign it to yearsArray[0]. The logic is the same for values array.

Now, you can you use in your code:

var myYears = ', 1991, 1992, 1993, 1994, 1995, 1998';  //shall be created automatically 
var myValues = ', 1, -3, -6, -5, 2, -3'; //shall be created automatically 

var yearsArray = myYears.split(', '); 
yearsArray[0] = 'year';
var valuesArray = myValues.split(', '); 
valuesArray[0] = 'value';

var chart = c3.generate({
        data : {
            x : 'year',
            columns : [
                yearsArray,
                valuesArray
            ],
            type : 'bar',
            labels : true,
            color : function (color, d) {
                if (d.value < -1) {
                    return d3.rgb('red');
                } else if (d.value >= -1 && d.value <= +1) {
                    return d3.rgb('grey');
                } else {
                    return d3.rgb('blue');
                }
            }
        }
    });

At the same time, it is a good idea to improve the dynamically generated strings format, in case to make this much more transparent and clear.

Upvotes: 2

Related Questions