cpopolo
Posts: 28
Joined: Thu Feb 08, 2018 7:01 pm

Individual column colors based on data value in styled mode

I am transitioning several charts to styled mode but have lost the ability to set point colors (column colors) based on the data value. The specific case is a weather plot where the column height is temperature, but the color of the column is a hex value returned from a chroma.js https://gka.github.io/chroma.js/ function call.

E.g., I build the series data in a loop that pushes data in the following way:

Code: Select all

data.push({x: dtimevalue, y: thevalue, color: chromafunction(thevalue).css()});
The chromafunction can return any number of hex colors in a range. For example, with temperatures between 0 and 100, it's reasonable that 100 different colors might be returned over a full year of weather data, so setting up classes won't work for my purposes.

I have tried several things to no avail:

-- colorByPoint set true doesn't work; it uses the class names to generate random colors. The class overrides the SVG fill which does show my preferred color.

-- setting fillColor and marker: fillColor in the data series does not work, they seem to be ignored.

Any help appreciated. In summary, I would like to use the styled mode to leverage classes to separate markup from styling, but I need to dynamically override colors on occasion, preferably while setting up the data (and not later with a load function), and without setting up hundreds of specific classes.
cosy
Posts: 118
Joined: Fri Feb 02, 2018 10:22 am

Re: Individual column colors based on data value in styled m

Hello!

In style mode, Highcharts expect you in general to use CSS classes for coloring everything. In your case your have therefor add a custom solution with the help of a chart events (https://api.highcharts.com/highcharts/chart.events). Just add your data as usual without using chroma and then use chroma inside the load and redraw events:

Code: Select all

function colorPoints() {
    var series = this.series;
    for (var i = 0, ie = series.length; i < ie; ++i) {
        var points = series[i].data;
        for (var j = 0, je = points.length; j < je; ++j) {
            if (points[j].graphic) {
                points[j].graphic.element.style.fill = chromafunction(points[j].y).css();
                points[j].graphic.element.style.stroke = chromafunction(points[j].y).css();
            }
        }
    }
}

Code: Select all

Highcharts.chart('container', {
    chart: {
        events: {
            load: colorPoints,
            redraw: colorPoints
        }
    },
    ...
Best regards,
Sophie
cpopolo
Posts: 28
Joined: Thu Feb 08, 2018 7:01 pm

Re: Individual column colors based on data value in styled m

Thanks - your solution matches my expectation, although I was hoping to avoid using events if only because of the redraw and extra work associated with a chart that may have 8k boxplot or column points.

Follow-up question: I tried to give the series a className = "highcharts-color-999" thinking that I might specify a non-styled class to override the default assignment of "highcharts-color-0", and then the rects would use the inline style assigned by the data. But the series seems to default to the light blue color-0 regardless of my className override.

Can you think of a creative way to allow classes to be manipulated in this way so that the SVG fill assigned through the data might be used when the className doesn't provide a fill color?
torstein.honsi
Site Admin
Posts: 9215
Joined: Thu Nov 09, 2006 11:22 am
Location: Vik i Sogn, Norway

Re: Individual column colors based on data value in styled m

I agree with you that keeping the events out of the chart configuration would be preferable. Here's a plugin-style solution: http://jsfiddle.net/highcharts/3gL5r99y/
Torstein Hønsi
CTO, Founder
Highsoft
cosy
Posts: 118
Joined: Fri Feb 02, 2018 10:22 am

Re: Individual column colors based on data value in styled m

Hello!

I like to answer the other open questions.

1) The property className is only adding additional names to the class property, but it is not replacing existing one. So in your case you will end up with property class="highcharts-point highcharts-color-0 highcharts-color-999" for your data point. But you can still kind of overwrite color like this:

Code: Select all

.highcharts-point.highcharts-color-999 {
    fill: #F0F !important;
    stroke: #F0F !important;
}
2) You can actually define property-dependent styles, that might solve the problem in uncommon way, but CSS definitions are not supposed to be in the number of several thousands. The chart may also never change in dimension, to work this way. Your approach would be like this:

Code: Select all

.highcharts-point[d*=" 70 "] {
    fill: #F0F !important;
    stroke: #F0F !important;
}
The example: http://jsfiddle.net/0f984n5r/

Best regards,
Sophie

Return to “Highcharts Usage”