2

I have a bar chart that I want to display a second label in the tooltip box that will be populated from my database. You can see from my code below that I have started to set it up so that multiple labels can be displayed in the tooltips (short,long) and also I want to be able to show multiple values coming from my database as labels.

For example I have a bridge ID of 135554 (bridge_id_grab) and that bridge is 35 years old (bridge_age_grab) and is located at milepost 13.34 (bridge_mp_grab).

So I want this to display in the tooltip as

"Bridge ID: 135554, Bridge Age: 35, Milepost: 13.34"

I think I am close - just can't figure out how to use get just one value for bridge_mp_grab - it's showing as a string of all the values in the database.

Here is my code:

             function Label(short, long) {
              this.short = short;
              this.long = long
             }
             Label.prototype.toString = function() {
              return this.short;
             }

        var barChartData2 = {
            //labels : bridge_id_grab,
            labels: [ 
              new Label("J", bridge_mp_grab), 
              new Label("F", "FEB"), 
              new Label("M", "MAR"),
              new Label("A", "APR"),
              new Label("M", "MAY"),
              new Label("J", "JUN"),
              new Label("J", "JUL")
            ],
            datasets : [
                {
                    label: "My First dataset",
                    fillColor : ["rgba(220,220,220,0.5)"],
                    strokeColor : "rgba(151,187,205,1)",
                    pointColor : "rgba(151,187,205,1)",
                    pointStrokeColor : "#fff",
                    data : bridge_age_grab,
                }
            ]
          }

            var context = document.getElementById('serviceLife').getContext('2d');

             window.myObjBar2 = new Chart(context).Bar(barChartData2, {
                scaleOverride : true,
                scaleSteps : 10,
                scaleStepWidth : 10,
                scaleStartValue : 0,
                barShowStroke: false,
                barStrokeWidth : 0,
                barValueSpacing : 2,
                 customTooltips: function (tooltip) {
                        var tooltipEl = $('#chartjs-tooltip');

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

                        // split out the label and value and make your own tooltip here
                        var parts = tooltip.text.split(":");
                        var re = new RegExp('\b', 'g');
                        var innerHtml = '<span><b>' + parts[1].trim() + '</b></span>';
                        tooltipEl.html(innerHtml);

                        tooltipEl.css({
                            opacity: 1,
                            // the minimum amount is half the maximum width of the tooltip that we set in CSS ...
                            // ... + the x scale padding so that it's not right at the edge
                            left: Math.max(75 + 10, tooltip.chart.canvas.offsetLeft + tooltip.x) + 'px',
                            top: tooltip.chart.canvas.offsetTop + tooltip.y + 'px',
                            fontFamily: tooltip.fontFamily,
                            fontSize: tooltip.fontSize,
                            fontStyle: tooltip.fontStyle,
                        });
                    },
                animation: false,
                responsive: true,
                tooltipTemplate: "<%if (label){%><%=value%>: <%}%><%= label.long %>",
                maintainAspectRatio: true,
               onAnimationComplete: function () {

                    var ctx = this.chart.ctx;
                    ctx.font = this.scale.font;
                    ctx.fillStyle = this.scale.textColor
                    ctx.textAlign = "center";
                    ctx.textBaseline = "bottom";

                    this.datasets.forEach(function (dataset) {
                        dataset.bars.forEach(function (bar) {
                            ctx.fillText(bar.value, bar.x, bar.y - 5);
                        });
                    })
                }
            });

             var bars = myObjBar2.datasets[0].bars;
            for(i=0;i<bars.length;i++){
               var color="#07c602";
               //You can check for bars[i].value and put your conditions here

               if(bars[i].value<11){
                color="#07c602"
               }    
               else if(bars[i].value<21){
                color="#61e738"
               }    
               else if(bars[i].value<31){
                color="#b6f277"
               }    
               else if(bars[i].value<41){
                color="#ffffb2"
               }    
               else if(bars[i].value<51){
                color="#fed976"
               }    
               else if(bars[i].value<61){
                color="#feb24c"
               }                  
               else if(bars[i].value<71){
                color="#fd8d3c"
               }
               else if(bars[i].value<81){
                color="#fc4e2a"
               }                  
               else if(bars[i].value<91){
                color="#e31a1c"
               }
               else{
                color="#b10026"
               }

               bars[i].fillColor = color;

            }
            myObjBar2.update(); 

Here is a couple of fiddles that I am using as reference: https://jsfiddle.net/gf3g4b55/ http://jsfiddle.net/tpydnyx6/

3
  • can you create a fiddle for us to work with? Commented Apr 27, 2016 at 18:37
  • Sorry for the delay - I had a bunch of stuff I had to do to make it work on the fiddle: jsfiddle.net/s8yfqvdc Commented Apr 27, 2016 at 22:59
  • Sorry for the delay... got busy at work.... there were many issues with the fiddle you posted... I'll add an answer shortly but you can see the updated fiddle here jsfiddle.net/s8yfqvdc/6 Commented Apr 28, 2016 at 17:59

1 Answer 1

6

I am not 100% sure of the desired output but this is my take.

In short, when you define your own customTooltips you are overriding the default tooltipTemplate stated in the options.

So, removing the customTooltips and defining an output format for the template yields the (I think) desired results.

To accomplish the output neatly, however, I added a new object called DataPoint and defined as this:

function DataPoint(id, age, milepost) {
    this.id = id;
    this.age = age;
    this.milepost = milepost;
    this.tooltip = "Bridge ID:" + id + ", Bridge Age: " + age +", Milepost: " + milepost;
}

DataPoint.prototype.toString = function () {
        return this.id;
};

This allows me to contain all the necessary data bits into one object (and then I only manipulate an array of those instead of multiple arrays)

Then, you set up your array of objects as your Labels for the table

 var barChartData2 = {
        labels: bridgeDataPoints, /* this is the array of DataPoints */
        datasets: [{
            fillColor: ["rgba(220,220,220,0.5)"],
            strokeColor: "rgba(151,187,205,1)",
            pointColor: "rgba(151,187,205,1)",
            pointStrokeColor: "#fff",
            data: bridge_age_grab,
        }]
    };

Finally, the tooltipTemplate was defined as follows:

OLD Version (prior to v3)

tooltipTemplate: "<%if (label){%><%=label.tooltip%><%}%>",

UPDATE: NEW for ChartJS v3

put it inside options object.

options: {
          tooltips: {
            callbacks: {
              label: function(tooltipItem, data) {
                  // console.log(tooltipItem);
                  // return 'id: ' + tooltipItem.xLabel.id+' | '+' age: '+tooltipItem.xLabel.age;
                },
                title: function(tooltipItem, data) {
                    // return 'Date: ' + tooltipItem[0].xLabel.date;
                    return 'id: ' + tooltipItem[0].xLabel.id+'\nage: ' + tooltipItem[0].xLabel.age;
                }
            }
          }
// try out your combinations
}

which means, if a label exists for each element, display the tooltip property for it. Since we defined the tooltip property for our DataPoint elements as this.tooltip = "Bridge ID:" + id + ", Bridge Age: " + age +", Milepost: " + milepost; the desired output is obtained.

Let me know if this helps.

See the updated fiddle here

Sign up to request clarification or add additional context in comments.

2 Comments

This is perfect. Thank you this exactly what I was trying to achieve.
@Kop4lyf glad I could help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.