Jens
Jens

Reputation: 11

Different xAxis label, max and colors for drilldown in Highcharts

I have a setup where I am generating multiple Highcharts with different sets of data. I now started implementing a drilldown, which needs different labels for xAxis, max needs to be changed and I would like to set the colors for each bar.

  1. regarding the xAxis, the object I am using get the data for the drilldown seems alright to me, but instead of using the name, the i of the loop is being displayed

    (5) […] ​ 0: {…} ​​ data: Array(5) [ 3, 8, 3, … ] ​​ id: "dd1" ​​ name: "Bad!" ​​ type: "column"

  2. for the max value, which should be 5 for the basic chart but unset for the drilldown, I tried

    drilldown: { yAxis: { max: 100 } }

but it did not do anything.

  1. TBH I did not try myself at colors yet, expected outcome would be that the bars are being colored according to the quality of the week, e.g. Bad week = red up to Fantastic = green

I also tried setting the chart type for the drilldown in general (right now I am setting 'type': 'column' for every data object, which appears redundant to me, but I could not figure out whether I can use something like ...drilldown.chart: { 'type':'column'} to define a general setting for the drilldown, but this too does not show any results.

I have tried implementing several setup examples using either functions bound to charts.events.drilldown or plotoptions.series.points.events.click but my very limited knowledge of Highcharts and JavaScript prevented me from succeeding.

Code:

// Fallback for browsers that cannot handle Object.values (i.e. that do not support ES6)
if (!Object.values) {
    Object.values = function(source) {
        var result = Object.keys(source).map(function(x) {
            return source[x];
        });
        return result;
    };
}

// Setting general HighCharts options
var options = {
    chart: {
        type: 'areaspline'
    },
    credits: {
        enabled: false
    },
    legend: {
        enabled: false
    },
    xAxis: {
        type: 'category'
    },
    yAxis: {
        title: {
            enabled: false
        },
        max: 5
    },
    series: [{
        fillColor: {
            linearGradient: {
                x1: 0,
                y1: 0,
                x2: 0,
                y2: 1
            },
            stops: [
                [0, '#F0A830'],
                [1, '#f4f4f4']
            ]
        },
        marker: {
            fillColor: 'white',
            lineWidth: 2,
            lineColor: '#F0A830',
            radius: 5
        },
        lineColor: '#F0A830',
        lineWidth: 5,
    }],
    plotOptions: {
        series: {
            marker: {
                enabled: false,
                symbol: 'circle'
            }
        }
    },
    drilldown: {
        yAxis: {
            max: 100
        },
        chart: {
            'type': 'column'
        },
        drillUpButton: {
            theme: {
                fill: 'white',
                'stroke-width': 1,
                stroke: 'silver',
                r: 0,
                states: {
                    hover: {
                        fill: '#a4edba'
                    },
                    select: {
                        stroke: '#039',
                        fill: '#a4edba'
                    }
                }
            }
        }
    }
};

// Temporary data delivery
var circlesData = {
    "0": {
        "title": "MyTeam",
        "values": [4, 3, 2, 3, 4],
        "weeks": [1, 2, 3, 4, 5],
        "weeksTotal": [6, 7, 8, 9, 10],
        "valuesDetail": {
            "valuesDetailLabel": ["Bad!", "Hmm", "Itwasokay", "Prettygood", "Fantastic"],
            "valuesDetailData": {
                0: [3, 4, 4, 1, 15],
                1: [2, 12, 5, 3, 1],
                2: [18, 2, 2, 2, 2],
                3: [3, 2, 4, 1, 5],
                4: [1, 2, 1, 1, 15]
            }
        }
    },
    "1": {
        "title": "YourTeam",
        "values": [1, 4, 5, 2, 3],
        "weeks": [1, 2, 3, 4, 5],
        "weeksTotal": [6, 7, 8, 9, 10],
        "valuesDetail": {
            "valuesDetailLabel": ["Bad!", "Hmm", "Itwasokay", "Prettygood", "Fantastic"],
            "valuesDetailData": {
                0: [3, 8, 3, 1, 4],
                1: [3, 12, 4, 3, 1],
                2: [4, 2, 2, 2, 2],
                3: [3, 2, 4, 5, 8],
                4: [1, 2, 1, 1, 15]
            }
        }
    }
}

console.log(circlesData);

var circlesDataString = JSON.stringify(circlesData); //this just turns the object array 'info' into a string

var obj = JSON.parse(circlesDataString);
console.log('Loading initiated...');

// Loop for creating individual HighCharts
Object.keys(obj).forEach(function(item) {
    // Create container div
    $('#outerContainer').append('<div class="innerContainer" id="circles' + item + '"></div>');

    // Get data of last iteration and determin quality of last week for color coding/wording
    var latestScore = circlesData[item].values.slice(-1)[0];
    console.log('latestScore: ' + latestScore)

    var chartColor = '';
    var weekText = '';
    var className = '';

    if (latestScore < 2.5) {
        chartColor = '#FD6E72';
        chartColorLight = '#fc8385';
        weekText = 'Bad week';
    } else if (latestScore >= 2.5 && latestScore < 3.5) {
        chartColor = '#FFCC73';
        chartColorLight = '#FBD486';
        weekText = 'Ok week';
    } else {
        chartColor = '#2CCC76';
        chartColorLight = '#82DB9D';
        weekText = 'Good week';
    }
    // create array for first chart view
    var chartData = [];
    var len = circlesData[item].values.length;
    for (i = 0; i < len; i++) {
        chartData.push({
            'name': 'w' + circlesData[item].weeks[i],
            'y': circlesData[item].values[i],
            'drilldown': 'dd' + circlesData[item].values[i]
        });
    };
    // set array for drilldown items
    var drillDown = [];
    for (i = 0; i < len; i++) {
        drillDown.push({
            'type': 'column',
            'id': 'dd' + circlesData[item].values[i],
            'data': circlesData[item].valuesDetail.valuesDetailData[i],
            'name': circlesData[item].valuesDetail.valuesDetailLabel[i]
        });
    };
    console.log('This is drillDown');
    console.log(drillDown);
    // Setting individual Highcharts options per Circle
    options.series[0] = {
        name: circlesData[item].title,
        data: chartData,
        color: chartColor,
        fillColor: {
            linearGradient: {
                x1: 0,
                y1: 0,
                x2: 0,
                y2: 1
            },
            stops: [
                [0, chartColor],
                [1, '#f4f4f4']
            ]
        },
    };
    // Set drilldown options
    options.drilldown.series = drillDown;
    options.title = {
        text: circlesData[item].title
    };
    options.subtitle = {
        text: weekText,
        style: {
            color: chartColor,
        }
    };
    console.log(options);

    // Call Highcharts
    $('#circles' + item).highcharts(options);
    console.log('Circle' + item + ' loaded...');
});

https://codepen.io/anon/pen/eqRPGV

Upvotes: 1

Views: 990

Answers (1)

Sohan
Sohan

Reputation: 66

  1. xAxis labels: For labels to have different names, each data point should have a name, like: 0: [["Bad!",3], ["Hmm",8], ["Itwasokay",3], ["Prettygood",1], ["Fantastic",4]]

  2. Max value: drilldown.yAxis is not an API and therefore it won't work. Instead, the global max value should be updated. In this case, we can set it to null conditionally, as: if(options.drilldown) options.yAxis.max = null;

  3. For each column to have different color, you need to overwrite the global colors array, options.colors with the desired one and define property: 'colorByPoint': true for each series object under drilldown object.

  4. For chart type, drilldown.chart: { 'type':'column'} won't work, because there is no chart API for drilldown. Though it appears redundant, but each drilldown.series object will have its own chart type. In this case 'column'.

Also, the id in each drilldown.series object should be unique. In your code instead of doing this way, 'id': 'dd' + circlesData[item].values[i], you can do it using weeks array like: 'id': 'dd' + circlesData[item].weeks[i]. Because circlesData["0"].values have duplicate data.

Below is the updated code. You can refer jsfiddle.

    // Fallback for browsers that cannot handle Object.values (i.e. that do not support ES6)
if (!Object.values) {
    Object.values = function(source) {
        var result = Object.keys(source).map(function(x) {
            return source[x];
        });
        return result;
    };
}

// Setting general HighCharts options
var options = {
    chart: {
        type: 'areaspline'
    },
  colors: ['#ED561B', '#DDDF00', '#24CBE5', '#058DC7', '#50B432'],
    credits: {
        enabled: false
    },
    legend: {
        enabled: false
    },
    xAxis: {
        type: 'category'
    },
    yAxis: {
        title: {
            enabled: false
        },
        max: 5
    },
    series: [{
        fillColor: {
            linearGradient: {
                x1: 0,
                y1: 0,
                x2: 0,
                y2: 1
            },
            stops: [
                [0, '#F0A830'],
                [1, '#f4f4f4']
            ]
        },
        marker: {
            fillColor: 'white',
            lineWidth: 2,
            lineColor: '#F0A830',
            radius: 5
        },
        lineColor: '#F0A830',
        lineWidth: 5,
    }],
    plotOptions: {
        series: {
            marker: {
                enabled: false,
                symbol: 'circle'
            }
        }
    },
    drilldown: {
        drillUpButton: {
            theme: {
                fill: 'white',
                'stroke-width': 1,
                stroke: 'silver',
                r: 0,
                states: {
                    hover: {
                        fill: '#a4edba'
                    },
                    select: {
                        stroke: '#039',
                        fill: '#a4edba'
                    }
                }
            }
        }
    }
};

// Temporary data delivery
var circlesData = {
    "0": {
        "title": "MyTeam",
        "values": [4, 3, 2, 3, 4],
        "weeks": [1, 2, 3, 4, 5],
        "weeksTotal": [6, 7, 8, 9, 10],
        "valuesDetail": {
            "valuesDetailLabel": ["Bad!", "Hmm", "Itwasokay", "Prettygood", "Fantastic"],
            "valuesDetailData": {
                0: [["Bad!",3], ["Hmm",4], ["Itwasokay",4], ["Prettygood",1], ["Fantastic",15]],
                1: [["Bad!",2], ["Hmm",12], ["Itwasokay",5], ["Prettygood",3], ["Fantastic",1]],
                2: [["Bad!",18], ["Hmm",2], ["Itwasokay",2], ["Prettygood",2], ["Fantastic",2]],
                3: [["Bad!",3], ["Hmm",2], ["Itwasokay",4], ["Prettygood",1], ["Fantastic",5]],
                4: [["Bad!",1], ["Hmm",2], ["Itwasokay",1], ["Prettygood",1], ["Fantastic",15]]
            }
        }
    },
    "1": {
        "title": "YourTeam",
        "values": [1, 4, 5, 2, 3],
        "weeks": [1, 2, 3, 4, 5],
        "weeksTotal": [6, 7, 8, 9, 10],
        "valuesDetail": {
            "valuesDetailLabel": ["Bad!", "Hmm", "Itwasokay", "Prettygood", "Fantastic"],
            "valuesDetailData": {
                0: [["Bad!",3], ["Hmm",8], ["Itwasokay",3], ["Prettygood",1], ["Fantastic",4]],
                1: [["Bad!",3], ["Hmm",12], ["Itwasokay",4], ["Prettygood",3], ["Fantastic",1]],
                2: [["Bad!",4], ["Hmm",2], ["Itwasokay",2], ["Prettygood",2], ["Fantastic",2]],
                3: [["Bad!",3], ["Hmm",2], ["Itwasokay",4], ["Prettygood",5], ["Fantastic",8]],
                4: [["Bad!",1], ["Hmm",2], ["Itwasokay",1], ["Prettygood",1], ["Fantastic",15]]
            }
        }
    }
}

console.log(circlesData);

var circlesDataString = JSON.stringify(circlesData); //this just turns the object array 'info' into a string

var obj = JSON.parse(circlesDataString);
console.log('Loading initiated...');

// Loop for creating individual HighCharts
Object.keys(obj).forEach(function(item) {
    // Create container div
    $('#outerContainer').append('<div class="innerContainer" id="circles' + item + '"></div>');

    // Get data of last iteration and determin quality of last week for color coding/wording
    var latestScore = circlesData[item].values.slice(-1)[0];
    console.log('latestScore: ' + latestScore)

    var chartColor = '';
    var weekText = '';
    var className = '';

    if (latestScore < 2.5) {
        chartColor = '#FD6E72';
        chartColorLight = '#fc8385';
        weekText = 'Bad week';
    } else if (latestScore >= 2.5 && latestScore < 3.5) {
        chartColor = '#FFCC73';
        chartColorLight = '#FBD486';
        weekText = 'Ok week';
    } else {
        chartColor = '#2CCC76';
        chartColorLight = '#82DB9D';
        weekText = 'Good week';
    }
    // create array for first chart view
    var chartData = [];
    var len = circlesData[item].values.length;
    for (i = 0; i < len; i++) {
        chartData.push({
            'name': 'w' + circlesData[item].weeks[i],
            'y': circlesData[item].values[i],
            'drilldown': 'dd' + circlesData[item].weeks[i]
        });
    };
    // set array for drilldown items
    var drillDown = [];
    for (i = 0; i < len; i++) {
        drillDown.push({
            'type': 'column',
            'id': 'dd' + circlesData[item].weeks[i],
            'data': circlesData[item].valuesDetail.valuesDetailData[i],
          'name':'w' + circlesData[item].weeks[i],
          'colorByPoint': true,
        });
    };
    console.log('This is drillDown');
    console.log(drillDown);
    // Setting individual Highcharts options per Circle
    options.series[0] = {
        name: circlesData[item].title,
        data: chartData,
        color: chartColor,
        fillColor: {
            linearGradient: {
                x1: 0,
                y1: 0,
                x2: 0,
                y2: 1
            },
            stops: [
                [0, chartColor],
                [1, '#f4f4f4']
            ]
        },
    };
    // Set drilldown options
    options.drilldown.series = drillDown;
    options.title = {
        text: circlesData[item].title
    };
    options.subtitle = {
        text: weekText,
        style: {
            color: chartColor,
        }
    };

  //do this conditionally
  if(options.drilldown) options.yAxis.max = null;

    console.log('option', options);

    // Call Highcharts
    $('#circles' + item).highcharts(options);
    console.log('Circle' + item + ' loaded...');
});

Hope this helps!

Upvotes: 1

Related Questions