score:8

you can use the plugin core api that offers different hooks to perform custom code. the simplest way would be to define an inline plugin and draw the line directly on the canvas through the canvasrenderingcontext2d. i would use the afterdraw hook as follows:

plugins: [{
  afterdraw: chart => {
    if (chart.tooltip?._active?.length) {
      let x = chart.tooltip._active[0].element.x;
      let yaxis = chart.scales.y;
      let ctx = chart.ctx;
      ctx.save();
      ctx.beginpath();
      ctx.moveto(x, yaxis.top);
      ctx.lineto(x, yaxis.bottom);
      ctx.linewidth = 1;
      ctx.strokestyle = 'rgba(0, 0, 255, 0.4)';
      ctx.stroke();
      ctx.restore();
    }
  }
}]

please take a look at your amended code and see hot it works.

<body>
  <div class="chart-container">
    <canvas id="mychart"></canvas>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/chart.js@3.3.2/dist/chart.min.js"></script>

  <script>  
    
    var ctx = document.getelementbyid('mychart');
    buildchart();

    function buildchart() {

      var mychart = new chart(ctx, {
        plugins: [{
          afterdraw: chart => {
            if (chart.tooltip?._active?.length) {               
               let x = chart.tooltip._active[0].element.x;             
               let yaxis = chart.scales.y;
               let ctx = chart.ctx;
               ctx.save();
               ctx.beginpath();
               ctx.moveto(x, yaxis.top);
               ctx.lineto(x, yaxis.bottom);
               ctx.linewidth = 1;
               ctx.strokestyle = 'rgba(0, 0, 255, 0.4)';
               ctx.stroke();
               ctx.restore();
            }
          }
        }],
        data: {
          labels: ['1', '2', '2562-3', '4', '5', '2562-6', '7', '8', '2562-9', '10', '11', '2562-12',
            '1', '2', '2563-3', '4', '5', '2563-6', '7', '8', '2563-9', '10', '11', '2563-12',
            '1', '2', '2564-3', '4', '5', '2564-6', '7', '8', '2564-9', '10', '11', '2564-12'],
          datasets: [{
            type: 'line',
            label: 'price(thb)',
            data: [4.20, 4.30, 4.10, 3.90, 3.30, 3.40, 3.30, 3, 2.8, 2.2, 2.2, 2.2,
              2.0, 1.7, 1.4, 2.2, 3, 3.1, 3.6, 4.3, 5.1, 5, 4.8, 4.9,
              6, 6.2, 6.3, 7, 9.5, 10.3, nan, nan, nan, nan, nan, nan],
            backgroundcolor: 'rgba(71, 198, 241, 1)',
            bordercolor: 'rgba(71, 198, 241, 1)',
            borderwidth: 2,
            tension: 0,
            pointradius: 0,
          },
          {
            type: 'line',
            label: 'fv price(thb)',
            data: [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 1.9,
              nan, nan, 2.47, nan, nan, 3.87, nan, nan, 4.75, nan, nan, 6.16,
              nan, nan, 10.07, nan, nan, nan, nan, nan, nan, nan, nan, nan],
            backgroundcolor: 'rgb(108, 113, 114, 0.7)',
            bordercolor: 'rgb(108, 113, 114, 0.7)',
            borderwidth: 2,
            borderdash: [10, 5],
            tension: 0,
            pointradius: 0,
          },
          {
            label: 'revenue(millionthb)',
            data: [nan, nan, 482.97, nan, nan, 546.19, nan, nan, 590.11, nan, nan, 611.61,
              nan, nan, 656.77, nan, nan, 1033.46, nan, nan, 916.43, nan, nan, 1399.30,
              nan, nan, 1287.47, nan, nan, nan, nan, nan, nan, nan, nan, nan],
            backgroundcolor: 'rgb(255, 153, 51, 0.2)',
            bordercolor: 'rgb(255, 153, 51, 0.2)',
            borderwidth: 1,
            borderdash: [10, 5],
            type: 'bar',
            yaxisid: 'y1',
          },
          {
            label: 'profit(millionthb)',
            data: [nan, nan, 11.65, nan, nan, 9.43, nan, nan, 27.54, nan, nan, 13.36,
              nan, nan, 30.27, nan, nan, 55.26, nan, nan, 56.16, nan, nan, 59.40,
              nan, nan, 81.59, nan, nan, nan, nan, nan, nan, nan, nan, nan],
            backgroundcolor: 'rgb(255, 153, 51, 0.5)',
            bordercolor: 'rgb(255, 153, 51, 0.5)',
            borderwidth: 1,
            borderdash: [10, 5],
            type: 'bar',
            yaxisid: 'y1',
          },
          {
            type: 'line',
            label: 'forecast fv price(thb)',
            data: [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
              nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
              nan, nan, 10.07, nan, nan, 10.18, nan, nan, 11.05, nan, nan, 11.81],
            backgroundcolor: 'rgb(108, 113, 114, 0.3)',
            bordercolor: 'rgb(108, 113, 114, 0.3)',
            borderwidth: 2,
            borderdash: [10, 5],
            tension: 0,
            pointradius: 0,
          },
          {
            label: 'forecast revenue(millionthb)',
            data: [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
              nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
              nan, nan, nan, nan, nan, 1300, nan, nan, 1500, nan, nan, 2000],
            backgroundcolor: 'rgb(108, 113, 114, 0.1)',
            bordercolor: 'rgb(108, 113, 114, 0.1)',
            borderwidth: 1,
            borderdash: [10, 5],
            type: 'bar',
            yaxisid: 'y1',
          },
          {
            label: 'forecast profit(millionthb)',
            data: [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
              nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
              nan, nan, nan, nan, nan, 80, nan, nan, 80, nan, nan, 80],
            backgroundcolor: 'rgb(108, 113, 114, 0.3)',
            bordercolor: 'rgb(108, 113, 114, 0.3)',
            borderwidth: 1,
            borderdash: [10, 5],
            type: 'bar',
            yaxisid: 'y1',
          },
          ]
        },
        options: {
          scales: {
            y: {
              beginatzero: true,
              title: {
                display: true,
                text: 'price per share(thb)',
                //color: '#191',
                font: {
                  family: 'kanit',
                  //size: 20,
                  //style: 'normal',
                  lineheight: 1.2
                },
                padding: { top: 30, left: 0, right: 0, bottom: 0 }
              },
              position: 'right',
              //ticks: {
              //  // include a dollar sign in the ticks
              //  callback: function (value, index, values) {
              //    return '$' + value;
              //  }
              //}
            },
            y1: {
              beginatzero: true,
              title: {
                display: true,
                text: 'revenue/profit (million thb)',
                //color: '#191',
                font: {
                  family: 'kanit',
                  //size: 20,
                  //style: 'normal',
                  lineheight: 1.2
                },
                padding: { top: 30, left: 0, right: 0, bottom: 0 }
              },
              type: 'linear',
              display: true,
              position: 'left',
              // grid line settings
              grid: {
                drawonchartarea: false, // only want the grid lines for one axis to show up
              },
            },
            x: {
              grid: {
                drawonchartarea: false, // only want the grid lines for one axis to show up
              },
            },
          },
          plugins: {
            title: {
              display: true,
              text: 'set: wice'
            }
          },
          interaction: {
            intersect: false,
            mode: 'index',
          },
          spangaps: true,
        }
      });
    }

  </script>

</body>

</html>


Related Query

More Query from same tag