最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Highcharts.js setting a threshold value for changing column color - Stack Overflow

programmeradmin0浏览0评论

I'm wondering if someone can help me adapt this Highcharts line graph: / to a column graph WHILE still maintaining the threshold coloring (red for value>0; blue for value<0).

The problem is if you simply change the graph type, type:'column', then the threshold-based coloring is lost and all the columns are blue.

The function that does the color change is applyGraphGradient(). I can't figure out how to change this function to preserve the threshold-based coloring.

/**
 * Event handler for applying different colors above and below a threshold value. 
 * Currently this only works in SVG capable browsers. A full solution is scheduled
 * for Highcharts 3.0. In the current example the data is static, so we don't need to
 * repute after altering the data. In dynamic series, the same event handler 
 * should be added to yAxis.events.setExtremes and possibly other events, like
 * chart.events.resize.
 */
function applyGraphGradient() {

    // Options
    var threshold = 0,
        colorAbove = '#EE4643',
        colorBelow = '#4572EE';

    // internal
    var series = this.series[0], 
        i,
        point;

    if (this.renderer.box.tagName === 'svg') {

        var translatedThreshold = series.yAxis.translate(threshold),
            y1 = Math.round(this.plotHeight - translatedThreshold),
            y2 = y1 + 2; // 0.01 would be fine, but IE9 requires 2

        // Apply gradient to the path
        series.graph.attr({
            stroke: {
                linearGradient: [0, y1, 0, y2],
                stops: [
                    [0, colorAbove],
                    [1, colorBelow]
                ]
            }
         });


    }

    // Apply colors to the markers
    for (i = 0; i < series.data.length; i++) {
        point = series.data[i];
        point.color = point.y < threshold ? colorBelow : colorAbove;
        if (point.graphic) {
            point.graphic.attr({
                fill: point.color
            });
        }
    }

    // prevent the old color from ing back after hover
    delete series.pointAttr.hover.fill;
    delete series.pointAttr[''].fill;

}

// Initiate the chart
var chart = new Highcharts.Chart({

    chart: {
        renderTo: 'container',
        events: {
            load: applyGraphGradient
        },
        defaultSeriesType : 'column'
    },

    title: {
        text: 'Average monthly temperature'
    },

    yAxis: {
        plotLines: [{
            value: 0,
            color: 'silver',
            width: 2,
            zIndex: 2
        }],
        title: {
            text: 'Temperature (°C)'
        }
    },

    xAxis: {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },

    series: [{
        name: 'Temperature (°C)',
        data: [-2, -3, -2, 2, 5, 9, 11, 11, 10, 8, 4, -1]
    }]

});
​

I'm wondering if someone can help me adapt this Highcharts line graph: http://jsfiddle/highcharts/PMyHQ/ to a column graph WHILE still maintaining the threshold coloring (red for value>0; blue for value<0).

The problem is if you simply change the graph type, type:'column', then the threshold-based coloring is lost and all the columns are blue.

The function that does the color change is applyGraphGradient(). I can't figure out how to change this function to preserve the threshold-based coloring.

/**
 * Event handler for applying different colors above and below a threshold value. 
 * Currently this only works in SVG capable browsers. A full solution is scheduled
 * for Highcharts 3.0. In the current example the data is static, so we don't need to
 * repute after altering the data. In dynamic series, the same event handler 
 * should be added to yAxis.events.setExtremes and possibly other events, like
 * chart.events.resize.
 */
function applyGraphGradient() {

    // Options
    var threshold = 0,
        colorAbove = '#EE4643',
        colorBelow = '#4572EE';

    // internal
    var series = this.series[0], 
        i,
        point;

    if (this.renderer.box.tagName === 'svg') {

        var translatedThreshold = series.yAxis.translate(threshold),
            y1 = Math.round(this.plotHeight - translatedThreshold),
            y2 = y1 + 2; // 0.01 would be fine, but IE9 requires 2

        // Apply gradient to the path
        series.graph.attr({
            stroke: {
                linearGradient: [0, y1, 0, y2],
                stops: [
                    [0, colorAbove],
                    [1, colorBelow]
                ]
            }
         });


    }

    // Apply colors to the markers
    for (i = 0; i < series.data.length; i++) {
        point = series.data[i];
        point.color = point.y < threshold ? colorBelow : colorAbove;
        if (point.graphic) {
            point.graphic.attr({
                fill: point.color
            });
        }
    }

    // prevent the old color from ing back after hover
    delete series.pointAttr.hover.fill;
    delete series.pointAttr[''].fill;

}

// Initiate the chart
var chart = new Highcharts.Chart({

    chart: {
        renderTo: 'container',
        events: {
            load: applyGraphGradient
        },
        defaultSeriesType : 'column'
    },

    title: {
        text: 'Average monthly temperature'
    },

    yAxis: {
        plotLines: [{
            value: 0,
            color: 'silver',
            width: 2,
            zIndex: 2
        }],
        title: {
            text: 'Temperature (°C)'
        }
    },

    xAxis: {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },

    series: [{
        name: 'Temperature (°C)',
        data: [-2, -3, -2, 2, 5, 9, 11, 11, 10, 8, 4, -1]
    }]

});
​
Share Improve this question edited Aug 29, 2012 at 15:16 Ryan Lynch 7,7861 gold badge27 silver badges34 bronze badges asked Aug 29, 2012 at 14:53 tim petersontim peterson 24.4k63 gold badges185 silver badges303 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Use the Highcharts drawing API, and it will work in VML browsers as well: http://jsfiddle/highcharts/XndxH/

How about this:

function applyGraphGradient() {

    // Options
    var threshold = 0,
        colorAbove = '#EE4643',
        colorBelow = '#4572EE';

    // internal
    var someSeries = this.series[0];

    $.each(someSeries.points, function(){
        if (this.y < threshold)
        {
            $(this.graphic.element).attr('fill', colorBelow);
        }
        else
        {
            $(this.graphic.element).attr('fill', colorAbove );
        }
    });

    delete someSeries.pointAttr.hover.fill;
    delete someSeries.pointAttr[''].fill; 
}

See fiddle here.

Your threshold that you are referring to is 0. For a column chart you could simple set the color for each bar individually like so: example

发布评论

评论列表(0)

  1. 暂无评论