javascriptcanvaschart.jshtml5-canvascubic-bezier

Calculating point coordinates on a line in chartjs?


In this draggable ChartJS demo is it possible to derive a set of interpolated coordinates along one of the curves that ChartJS plots?

    var options = {
      type: 'line',
      data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
            fill: true,
            tension: 0.4,
            borderWidth: 1,
            pointHitRadius: 25
          },
          {
            label: '# of Points',
            data: [7, 11, 5, 8, 3, 7],
            fill: true,
            tension: 0.4,
            borderWidth: 1,
            pointHitRadius: 25
          }
        ]
      },
      options: {
        scales: {
          y: {
            min: 0,
            max: 20
          }
        },
        onHover: function(e) {
          const point = e.chart.getElementsAtEventForMode(e, 'nearest', { intersect: true }, false)
          if (point.length) e.native.target.style.cursor = 'grab'
          else e.native.target.style.cursor = 'default'
        },
        plugins: {
          dragData: {
            round: 1,
            showTooltip: true,
            onDragStart: function(e, datasetIndex, index, value) {
              // console.log(e)
            },
            onDrag: function(e, datasetIndex, index, value) {              
              e.target.style.cursor = 'grabbing'
              // console.log(e, datasetIndex, index, value)
            },
            onDragEnd: function(e, datasetIndex, index, value) {
              e.target.style.cursor = 'default' 
              // console.log(datasetIndex, index, value)
            },
          }
        }
      }
    }

    var ctx = document.getElementById('chartJSContainer').getContext('2d');
    window.test = new Chart(ctx, options);
<head>
  <meta charset="utf-8">
  <title>Chart.js Drag Data Points Plugin</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.min.js"></script>
  <script src="assets/chartjs-plugin-dragdata.min.js"></script>
  <style>
    html,
    body {
      margin: 0;
      padding: 0;
    }

    canvas {
      background-color: #eee;
      position: absolute;
    }
  </style>
</head>



<canvas id="chartJSContainer" style="height: 90%; width: 90%;"></canvas>

The demo plots an array of 5 values.

data: [12, 19, 3, 5, 2, 3],

Is there a way to use Javascript produce an array of 10 y values where the x coordinates are evenly spaced along the curve?

So for example if the canvas width is 200px, then the x coordinates would increment in values of 20px, and the y value would be the corresponding point on the bezier curve.

I looked through the ChartJS API documentation, and I don't see an API for the bezier curve function for each plot exposed, but perhaps there is a way around this?


Solution

  • Depending for what you want to use this, an easy workaround/solution is:

    Like this chartjs, fills in the gaps and you can space out the chart without manually calculating any extra values.

    Small Demo:

    var options = {
        type: 'line',
        data: {
          labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange", "Blue", "Yellow", "Green", "Purple", "Green"],
          datasets: [
            {
              label: '# of Points',
              data: [7, null, 11, null,  5 , null,  8, null,   3, null,  7],
              fill: true,
              tension: 0.4,
              borderWidth: 1,
              pointHitRadius: 25,
              spanGaps: true
            }
          ]
        },
        options: {
          scales: {
            y: {
              min: 0,
              max: 20
            }
          },
        }
      }
    
      let ctx = document.getElementById('chartJSContainer').getContext('2d');
      new Chart(ctx, options);
        html, body { margin: 0; padding: 0;}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.min.js"></script>
    <canvas id="chartJSContainer" style="height: 180px; width: 500px;"></canvas>