2
votes

I have a stacked column chart . For highlighting any of the individual slices, we can make use of the "highlightColors" option, but if I have to highlight the entire bar is there any option available for the same. My current code looks like this:

     seriesDefaults : {
        renderer : $.jqplot.BarRenderer,
        rendererOptions : {
            barWidth : this.barWidth,
            barMargin : this.barMargin,
            highlightColors : '#fffefe'
                 }

This needs to be modified in such a way that the entire bar gets highlighted. Please advise

1

1 Answers

1
votes

I made something for it. The solution involves custom painting over the highlight canvas.

The sample is here.

It was integrated into a sample I made for a question asking how to add sums on top of a stacked bar chart, details are here. I also upgraded its code, so now it is 'bar chart orientation friendly'.

Just in case the JS code is also below:

$(document).ready(function() {
    var ins = [2, 2, 3, 5];
    var outs = [2, 4, 3, 5];
    var swaps = [2, 2, 6, 5];
    var passes = [2, 4, 6, 5];
    var data = [ins, outs, swaps, passes, [3, 3, 3, 3]];
    var series = [
        {
        label: 'IN',
        pointLabels: {
            labels: [2, 2, 3, 5]
        }},
    {
        label: 'OUT',
        pointLabels: {
            labels: [2, 4, 3, 5]
        }},
    {
        label: 'SWAP',
        pointLabels: {
            labels: [2, 2, 6, 5]
        }},
    {
        label: 'PASS',
        pointLabels: {
            labels: [2, 4, 6, 5]
        }},
    {
        label: 'INVISIBLE',
        pointLabels: {
            labels: ['∑ 8', '∑ 12', '∑ 18', '∑ 20']
        },
        show: false,
        shadowAngle: 90,//for horizontal use (180 istead of 90)
        rendererOptions: {
            shadowDepth: 25,
            shadowOffset: 2.5,
            shadowAlpha: 0.01
        }}
    ];
    var ticks = ['Oi', 'Bike', 'Car', 'Truck'];
    var plot = $.jqplot('chart', data, {
        stackSeries: true,
        seriesDefaults: {
            renderer: $.jqplot.BarRenderer,
            rendererOptions: {
                barMargin: 20
//for horizontal uncomment this                
//                ,barDirection: 'horizontal'
            },
            pointLabels: {
                show: true,
                stackedValue: false,
                location: 's'
            }
        },
        axes: {
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            }
//for horiozontal use the below instead
/*            
            yaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            }
*/        
        },
        legend: {
            show: true,
            location: 'ne',
            placement: 'outside'
        },
        series: series,
        title: "Oi title"
    });
    //color used for tooltip title
    var color = 'rgb(50%,50%,100%)';
    //start span of a tooltip's title
    var spanStart = '<span style="font-size:14px;font-weight:bold;color:' + color + ';">';
    $('#chart').bind('jqplotDataHighlight', function(ev, seriesIndex, pointIndex, data) {
        var chart_left = $('#chart').offset().left;
        var chart_top = $('#chart').offset().top;
        var x = ev.pageX;
        var y = ev.pageY;
        var left = x;
        var top = y;
        var chartTooltipHTML = spanStart;
        if (plot.axes.xaxis.u2p && plot.axes.yaxis.u2p) { // pierenderer do not have u2p
            left = chart_left + plot.axes.xaxis.u2p(data[0]); // convert x axis units to pixels on grid
            top = chart_top + plot.axes.yaxis.u2p(data[1]); // convert y axis units to pixels on grid
        }        
        var barWidth = plot.series[0].barWidth;
        //tells if the bar chart is vertical
        var isVertical = false;
        if (plot.series[0].barDirection === "vertical")
            isVertical = true;
        if (isVertical) left -= barWidth / 2;
        else top -= barWidth / 2;
        //for stacked chart
        if(isVertical){
            top = chart_top;
            var sum = 0;
            for (var i = 0; i < seriesIndex + 1; i++)
               sum += plot.series[i].data[pointIndex][1];
            top += plot.axes.yaxis.u2p(sum); 
        }else{
            left = chart_left;
            var sum = 0;
            for (var i = 0; i < seriesIndex + 1; i++)
               sum += plot.series[i].data[pointIndex][0];
            left += plot.axes.xaxis.u2p(sum); 
        }        
        var seriesName = plot.series[seriesIndex].label;
        console.log("seriesName = " + seriesName + "   seriesIndex = " + seriesIndex + "   pointIndex= " + pointIndex + "   data= "+data+ "   plot.series[seriesIndex].data= " + plot.series[seriesIndex].data[pointIndex]);

        chartTooltipHTML += 'My custom tooltip: </span>' 
        + '<br/><b>Count:</b> ' + data[1] //data[1] has count of movements
        + '<br/><b>Movement type:</b> ' + seriesName;

        //start of part highlighting whole bar --- all bars (other than this bar is related to custom tooltip)
        //for painting just grab the first highlight canvas as there could be 'n' of them where 'n' is the number of series, I think
        var drawingCanvas = $(".jqplot-barRenderer-highlight-canvas")[0];
        var rX = chart_left + plot.axes.xaxis.u2p(data[0]) - $(drawingCanvas).offset().left - barWidth/2;
        var rY = chart_top + plot.axes.yaxis.u2p(data[1]) - $(drawingCanvas).offset().top - barWidth/2;
        var rW = 0;
        var rH = barWidth;        
        if (isVertical){
            rW = rH;
            rH = 0;
        }
        for(var i = 0; i < plot.series.length; i++){
            if (isVertical) {
                rH += plot.series[i].data[pointIndex][1];
            }else{
                rW += plot.series[i].data[pointIndex][0];
            }
        }  
        var canvasLeft = parseInt($(drawingCanvas).css('left'),10);
        var canvasTop = parseInt($(drawingCanvas).css('top'),10);
        if(isVertical){
           rY = plot.axes.yaxis.u2p(rH) - canvasTop;//- $(drawingCanvas).offset().top;
           rH = drawingCanvas.height - plot.axes.yaxis.u2p(rH) + canvasTop;//$(drawingCanvas).css('top').; 
        }else{
           rX = 0; 
           rW = plot.axes.xaxis.u2p(rW) - canvasLeft;  
        }       
        console.log("rX= "+rX+";  rY= "+rY+";  rW= "+rW+";  rH = "+ rH + "  drawingCanvas.height= "+drawingCanvas.height);
        var context = drawingCanvas.getContext('2d');
        context.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);                  context.strokeStyle = "#000000";
        context.strokeRect(rX, rY, rW, rH);
        //end of part doing custom painting of frame around all bars              

        var ct = $('#chartTooltip');
        ct.css({
            left: left,
            top: top
        }).html(chartTooltipHTML).show();
        if (plot.series[0].barDirection === "vertical") {
            var totalH = ct.height() + ct.padding().top + ct.padding().bottom + ct.border().top + ct.border().bottom;
            ct.css({
                top: top - totalH
            });
        }
    });
    // Bind a function to the unhighlight event to clean up after highlighting.
    $('#chart').bind('jqplotDataUnhighlight', function(ev, seriesIndex, pointIndex, data) {
        $('#chartTooltip').empty().hide();
    });
});​