[Chartjs]-ChartJS add text to canvas in linechart

1👍

You can make use of the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code snippet, I use the afterDraw hook to draw text at a position computed from the chart.scales.

plugins: [{
  afterDraw: chart => {
    let ctx = chart.chart.ctx;
    let xAxis = chart.scales['x-axis-0'];
    let yAxis = chart.scales['y-axis-0'];
    let maxValue = Math.max(...chart.data.datasets[0].data);
    let minValue = Math.min(...chart.data.datasets[0].data);
    ctx.save();
    ctx.textAlign = 'center';
    ctx.font = '12px Arial';
    ctx.fillStyle = 'white';
    ctx.textAlign = 'left';
    ctx.fillText('Dagens højeste temperatur = ' + maxValue + '°C', xAxis.left + 5, yAxis.top + 5);
    ctx.fillText('Dagens laveste temperatur = ' + minValue + '°C', xAxis.left + 5, yAxis.top + 18);
    ctx.restore();
  }
}],

In case you want to draw the text slightly above the top most grid line, you would need to define some extra padding at the top of the chart.

layout: {
  padding: {
    top: 20
  }
},

Please take a look at your amended code and see how it works with static data.

const now = new Date().getTime();
const times = new Array(10).fill().map((v, i) => now - i * 600000).reverse();

var charttempdata = {
  labels: times,
  datasets: [{
    label: 'Temperatur',
    pointRadius: 3,
    backgroundColor: 'rgba(26, 137, 245, 0.2)',
    borderColor: 'rgba(26, 137, 245, 1)',
    hoverBackgroundColor: 'rgba(255, 255, 255, 0)',
    hoverBorderColor: 'rgba(255, 255, 255, 0)',
    pointBackgroundColor: 'rgba(12, 68, 122,1)',
    pointHoverBorderColor: "rgba(255, 255, 255, 0.8)",
    data: [22, 23, 23, 23, 22, 20, 22, 22, 23, 25],
    datalabels: {
      align: function(context) {
        return context.active ? 'left' : 'left';
      }
    }
  }]
};

var linetempGraph = new Chart('tempgraphCanvas', {
  type: 'line',
  plugins: [{
    afterDraw: chart => {
      let ctx = chart.chart.ctx;
      let xAxis = chart.scales['x-axis-0'];
      let yAxis = chart.scales['y-axis-0'];
      let maxValue = Math.max(...chart.data.datasets[0].data);
      let minValue = Math.min(...chart.data.datasets[0].data);
      ctx.save();
      ctx.textAlign = 'center';
      ctx.font = '12px Arial';      
      ctx.fillStyle = 'white';
      ctx.textAlign = 'left';
      ctx.fillText('Dagens højeste temperatur = ' + maxValue + '°C', xAxis.left + 5, yAxis.top + 5);
      ctx.fillText('Dagens laveste temperatur = ' + minValue + '°C', xAxis.left + 5, yAxis.top + 18);
      ctx.restore();
    }
  }],
  data: charttempdata,
  options: {
    maintainAspectRatio: false,
    tooltips: {
      enabled: false,
    },
    legend: {
      display: false,
    },
    scales: {
      xAxes: [{
        type: 'time',
        time: {
          unit: 'minute',
          displayFormats: {
            hour: 'HH:mm'
          },
          tooltipFormat: 'HH:mm',
        },
        gridLines: {
          color: '#999999',
          lineWidth: 1
        },
        ticks: {
          fontColor: "#fff",
        }
      }],
      yAxes: [{
        type: 'linear',
        position: 'left',
        gridLines: {
          color: '#999999',
          lineWidth: 1
        },
        ticks: {
          fontColor: "rgba(255, 255, 255, 1)",
          stepSize: 1
        }
      }]
    },
  }
});
body {
  background-color: #242e42;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<canvas id="tempgraphCanvas"></canvas>

1👍

You could attempt to manually write on the canvas using js, however the example below modifies your code to

  1. Move the Axis to the Left
  2. Print the highest and lowest values as the first two ticks

NB. Since I don’t have access to the data return from the ajax call, i have generated data and called the function. You may use the code below by simply commenting the line with generateAndHandleTemperatureData() in showtempGraph() and uncommenting $.post("temperaturedata.php", handleTemperatureData);

Working Demo

$(document).ready(function() {
    showtempGraph();
});

function handleTemperatureData(data) {
    //console.log(data);
    var temptime = [];
    var temp = [];

    for (var i in data) {
        temptime.push(data[i].timestamp);
        temp.push(data[i].temperature);
    }

    var tempmin = Math.min(...temp);
    var tempmax = Math.max(...temp);

    var charttempdata = {
        labels: temptime,
        datasets: [{
            label: 'Temperatur',
            pointRadius: 3,
            backgroundColor: 'rgba(26, 137, 245, 0.2)',
            borderColor: 'rgba(26, 137, 245, 1)',
            hoverBackgroundColor: 'rgba(255, 255, 255, 0)',
            hoverBorderColor: 'rgba(255, 255, 255, 0)',
            pointBackgroundColor: 'rgba(12, 68, 122,1)',
            pointHoverBorderColor: "rgba(255, 255, 255, 0.8)",
            data: temp,
            datalabels: {
                align: function(context) {
                    return context.active ? 'left' : 'left';
                }
            }
        }]
    };

    var graphtempTarget = $("#tempgraphCanvas");

    var linetempGraph = new Chart(graphtempTarget, {
        type: 'line',
        data: charttempdata,
        options: {
            plugins: {
                datalabels: {
                    backgroundColor: null,
                    borderColor: null,
                    borderRadius: function(context) {
                        return context.active ? 0 : 0;
                    },
                    borderWidth: 1,
                    color: 'rgba(255, 255, 255, 1)',
                    font: {
                        size: 18,
                        color: 'rgba(255, 255, 255, 1)'
                    },
                    formatter: function(value, context) {
                        value = Math.round(value * 100) / 100;
                        if (context.dataIndex === context.dataset.data.length - 1) {
                            return value + '°C';
                        } else {
                            return context.active ?
                                value + '°C' :
                                ''
                        }
                    },
                    offset: 8,
                    padding: 0,
                    textAlign: 'center'
                }
            },
            maintainAspectRatio: false,
            tooltips: {
                enabled: false,
            },
            legend: {
                display: false,
            },
            responsive: true,
            scales: {
                xAxes: [{
                    type: 'time',
                    time: {
                        displayFormats: {
                            hour: 'HH:mm'
                        },
                        tooltipFormat: 'HH:mm',
                    },
                    unit: 'day',
                    gridLines: {
                        color: '#999999',
                        lineWidth: 1
                    },
                    ticks: {
                        fontColor: "#fff",
                    }
                }],
                yAxes: [{
                    type: 'linear',
                    position: 'left',
                    gridLines: {
                        color: '#999999',
                        lineWidth: 1
                    },
                    ticks: {
                        fontColor: "rgba(255, 255, 255, 1)",
                    }
                }, {
                    type: 'linear',
                    position: 'left',
                    afterUpdate: function(scaleInstance) {
                        //console.dir(scaleInstance);
                    },
                    ticks: {
                        // stepSize: 1 || tempmin - tempmax,
                        min: tempmin,
                        max: tempmax,
                        mirror: true,
                        padding: -30,
                        fontColor: "rgba(255, 255, 255, 1)",
                        fontSize: 14,
                        callback: function(value,index) {
                          // console.log(arguments)
                          if(index == 0){
                              return ' Dagens højeste temperatur = ' + tempmax + '°C';
                          }else if(index == 1){
                              return ' Dagens laveste temperatur = ' + tempmin + '°C';
                          }else{
                            return ""
                          }
                          
                           
                        }
                    },
                    gridLines: {
                        drawOnChartArea: false,
                    },
                    scaleLabel: {
                        display: true,
                        // labelString: '°C',
                        fontColor: "rgba(255, 255, 255, 1)",
                        fontSize: 14,
                        fontStyle: 'bold',
                        //adjust the properties below to change the spacing between the lines
 //reference: https://www.chartjs.org/docs/latest/axes/labelling.html
                        //padding: 30, //
                        //lineHeight:30 //
                    }
                }]
            },
        }
    });
}

function generateAndHandleTemperatureData() {
    //TODO: generate data
    var data = [];
    var currentDate = new Date();
    var startTime = currentDate.getTime() - 1*60*60*1000;
    for(var i=startTime;i<currentDate.getTime();i+=(60*1000*15)){ 
      data.push({
        timestamp:i,
        temperature: Math.random()*30+1
      })
    }

    handleTemperatureData(data);
}

function showtempGraph() {
    generateAndHandleTemperatureData()
    // $.post("temperaturedata.php", handleTemperatureData);

}
body {
  font-family: Roboto;
  background-color: #242e42;
  color: white;
  width: 98%;
    }

#chart-container {
    width: 100%;
    height: 100%;
}
<html>
<head>
<title>Temperatur</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/0.7.0/chartjs-plugin-datalabels.min.js"></script>

</head>
<body>
  
    <div id="chart-container">
        <canvas id="tempgraphCanvas" style="width:100%;height:100%;"></canvas>
    </div>
   

</body>
</html>

0👍

This is the final look of things now. I’m pleased. Might do a few edits, but overall this is what i wanted to achieve.

$(document).ready(function() {
    showtempGraph();
});

function handletemperatureData(data) {
    var temptime = [];
    var temp = [];

    for (var i in data) {
        temptime.push(data[i].timestamp);
        temp.push(data[i].temperature);
    }

    var tempmin = Math.min(...temp);
    var tempmax = Math.max(...temp);

    var charttempdata = {
        labels: temptime,
        datasets: [{
            label: 'Luftfugtighed',
            pointRadius: 3,
            backgroundColor: 'rgba(26, 137, 245, 0.2)',
            borderColor: 'rgba(26, 137, 245, 1)',
            hoverBackgroundColor: 'rgba(255, 255, 255, 0)',
            hoverBorderColor: 'rgba(255, 255, 255, 0)',
            pointBackgroundColor: 'rgba(12, 68, 122,1)',
            pointHoverBorderColor: "rgba(255, 255, 255, 0.8)",
            data: temp,
            datalabels: {
                align: function(context) {
                    return context.active ? 'left' : 'left';
                }
            }
        }]
    };

    var graphtempTarget = $("#tempgraphCanvas");
    Chart.defaults.global.defaultFontFamily = "Roboto";
    var linetempGraph = new Chart(graphtempTarget, {
        type: 'line',
        plugins: [{
            afterDraw: chart => {
            let ctx = chart.chart.ctx;
            let xAxis = chart.scales['x-axis-0'];
            let yAxis = chart.scales['y-axis-0'];
            let maxValue = Math.max(...chart.data.datasets[0].data);
            let minValue = Math.min(...chart.data.datasets[0].data);
            ctx.save();
            ctx.textAlign = 'center';
            ctx.font = '14px Roboto';
            ctx.fillStyle = 'white';
            ctx.textAlign = 'left';
            ctx.fillText('Dagens max. temperatur = ', xAxis.left + 5, yAxis.top + 15);
            ctx.fillText('Dagens min. temperatur = ', xAxis.left + 5, yAxis.top + 40);
            ctx.fillText(maxValue + '°C', xAxis.left + 200, yAxis.top + 15);
            ctx.fillText(minValue + '°C', xAxis.left + 200, yAxis.top + 40);
            ctx.restore();
            }
        }],
        data: charttempdata,
        options: {
            plugins: {
                datalabels: {
                    backgroundColor: null,
                    borderColor: null,
                    borderRadius: function(context) {
                        return context.active ? 0 : 0;
                    },
                    borderWidth: 1,
                    color: 'rgba(255, 255, 255, 1)',
                    font: {
                        size: 18,
                        color: 'rgba(255, 255, 255, 1)'
                    },
                    formatter: function(value, context) {
                        value = Math.round(value * 100) / 100;
                        if (context.dataIndex === context.dataset.data.length - 1) {
                            return value + '°C';
                        } else {
                            return context.active ?
                        value + '°C' :
                        ''
                        }
                    },
                    offset: 8,
                    padding: 0,
                    textAlign: 'center'
                }
            },
            maintainAspectRatio: false,
            tooltips: {
                enabled: false,
            },
            legend: {
                display: false,
            },
            responsive: true,
            scales: {
                xAxes: [{
                    type: 'time',
                    time: {
                        displayFormats: {
                            hour: 'HH:mm'
                        },
                        tooltipFormat: 'HH:mm',
                    },
                    unit: 'day',
                    gridLines: {
                        color: 'rgba(153, 153, 153, 1)',
                        lineWidth: 1
                    },
                    ticks: {
                        fontColor: 'rgba(255, 255, 255, 1)',
                    }
                }],
                yAxes: [{
                    type: 'linear',
                    position: 'left',
                    gridLines: {
                        color: 'rgba(153, 153, 153, 1)',
                        lineWidth: 1
                    },
                    ticks: {
                        fontColor: "rgba(255, 255, 255, 1)",
                    }
                }, {
                    type: 'linear',
                    position: 'right',
                    weight: 50,
                    gridLines: {
                        drawOnChartArea: false,
                    },
                    ticks: {
                        display: false
                    },
                    scaleLabel: {
                        display: true,
                        labelString: '°C',
                        fontColor: "rgba(255, 255, 255, 1)",
                        fontSize: 14,
                        fontStyle: 'bold'
                    }               
                }]
            },
        }
    });
}

function showtempGraph() {
    $.post("temperaturedata.php", handletemperatureData);
}

Weather Station

Leave a comment