Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chartjs adding icon to tooltip and label

I want to add a prefix to the tooltip and y-label in chartjs, but the problem is, when I put the <i class='fa fa-sampleicon'></i> it is returned as string not as an html tag as you can see on the image

label and tooltips chartjs

Here's my code:

<script>

$(document).ready(function(){
    var lineLabel = <?php echo json_encode(array_reverse( $ch1_arrDate)); ?>;
    var dataVal1 = <?php echo json_encode(array_reverse( $ch1_arrRevenue_conf)); ?>;
    var dateFilter = <?php echo json_encode(array_reverse($ch1_arrDate2)); ?>;

    var lineData = {
        labels: lineLabel,
        datasets: [
            {
                label: 'Confirmed Revenue',
                backgroundColor: 'rgba(0,0,0,0.03)',
                data: dataVal1,
                borderColor: 'rgba(163,216,3,1)',
                borderWidth:1,
            },
        ]
    };


    var lineOptions = {
        responsive: true,
        maintainAspectRatio: true,
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true,
                    userCallback: function(value, index, values) {
                        return "<i class='fa fa-sampleicon'></i>"+addCommas(value);
                    }
                }
            }]
        },
        legend: {
            display: true,
            position: 'bottom'
        },
        tooltips: {
          callbacks: {
            label: function(tooltipItem, data) {
              return "<i class='fa fa-sampleicon'></i>"+addCommas(tooltipItem.yLabel);
            }
          }
        }

    }


    var ctx = document.getElementById("chart1").getContext("2d");

    if($(window).width()>748){
        ctx.canvas.height = 160;
    }
    else{
        ctx.canvas.height = 300;
    }

    var chartDisplay = new Chart(ctx, {
        type: 'line',
        data: lineData,
        options: lineOptions
    });

    $("#chart1").click( 
       function(e){
            var activeLines= chartDisplay.getElementsAtEvent(e);
            var index = activeLines[0]["_index"];
            window.open(
            "dash_chartdeals.php?from=past&filter_date="+fixedEncodeURIComponent(dateFilter[index]),
            '_blank'
            )
    });


    $("#chart1").mouseenter(function(){
        $("#chart1").css("cursor", "pointer");
    });
});
function addCommas(nStr)
{
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

</script>
like image 891
Christopher Avatar asked Sep 05 '25 03:09

Christopher


1 Answers

I've found an answer to this, So basically as @jordanwillis said, it's only string painted on canvas therefore you can't add html tags.

So the concept is to create a seperate div where you will put your custom tooltip(text / icons / image) onto, then positioning that div to where the default tooltip shows.

under my chart I added a new div chartjs-tooltip3

<div class="row">
    <div class="col-xs-12">
        <canvas id="chart3" width="500" height="300" style="border:1px solid #f1f1f1; padding:20px; padding-top:40px; box-shadow:2px 2px 2px rgba(0,0,0,0.2);"></canvas>
        <div id="chartjs-tooltip3"></div>
    </div>
</div>

then on my script:

I changed my default tooltip configuration to show false so it wont get in the way of my new tooltip.

$(document).ready(function(){
    Chart.defaults.global.tooltips.enabled = false; //disable default tooltip

And at the lineOptions, instead of calling callbacks

tooltips: {
          callbacks: {
            label: function(tooltipItem, data) {
              return "<i class='fa fa-sampleicon'></i>"+addCommas(tooltipItem.yLabel);
            }
          }
        }

I've called custom, here you can freely manipulate your div and other things inside the function..

tooltips: {
            custom: function(tooltip) {
                var tooltipEl = $('#chartjs-tooltip3');

                if (!tooltip) {
                    tooltipEl.css({
                        opacity: 0
                    });
                    return;
                }

                if(tooltip.body){ // if the cursor hits the point

                    value = addCommas(tooltip.body["0"].lines["0"].substring(18)); //the data i need to add on my custom tooltip

                    tooltipEl.html(icon+" "+value); //icon is the html tag <i class="fa fa-sampleicon"></i>

                    //set the custom div to where the default tooltip is supposed to show.
                    tooltipEl.css({
                        opacity: 1,
                        left: tooltip.x + 'px',
                        top: tooltip.y + 'px',
                        fontFamily: this.fontFamily,
                        fontSize: this.fontSize,
                        fontStyle: this.fontStyle,
                    });
                    $("#chart3").css("cursor", "pointer");
                }
                else
                {
                    // if outside of the point, it'll hide the custom div
                    tooltipEl.css({
                        opacity: 0
                    });
                    //change my cursor to default
                    $("#chart3").css("cursor", "default");
                }
            }

        }

to get the data you wanted to get, you can always log the tooltip.. It'll give you the list of the array objects.

console.log(tooltip);

Here is the basic css of my custom div:

#chartjs-tooltip3{
     opacity: 0;
     position: absolute;
     background: rgba(0, 0, 0, .6);
     color: white;
     padding: 5px 12px 3px 12px;
     border-radius: 3px;
     -webkit-transition: all .1s ease;
     transition: all .2s ease;
     pointer-events: none;
     -webkit-transform: translate(-50%, 0);
     transform: translate(-50%, 0);
 }

I've gathered my answer from these threads Chart JS Show HTML in Tooltip and How to add image to chart.js tooltip? and

like image 79
Christopher Avatar answered Sep 07 '25 20:09

Christopher